tag:blogger.com,1999:blog-30585352691609216612024-03-06T13:07:42.220+09:00xawa雑記帳とりあえずいろいろ書いてみる。<br>
Scala や タートルグラフィックス言語のドリトル、Google App Engine、Blogger などについてのメモ書きがメイン。xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.comBlogger166125tag:blogger.com,1999:blog-3058535269160921661.post-6008074674830374462015-07-29T22:08:00.000+09:002015-07-29T23:07:06.270+09:00[PowerShell] ファイル名のインデックスの桁数をそろえるフォルダ内に以下のようなファイル群がある。
<pre class="code">
<code>
Image-1.jpg
Image-2.jpg
...
Image-9.jpg
Image-10.jpg
Image-11.jpg
...
Image-99.jpg
Image-100.jpg
Image-101.jpg
...
Image-150.jpg
</code>
</pre>
<br />
Explorer ではこの順に並ぶが、単純にアルファベット順に処理するアプリでは
Image-1.jpg、Image-10.jpg、Image-11.jpg … といった順序で処理されてしまう。
<br />
そこで PowerShell を使ってファイル名部分の桁数を、Image-1.jpg → Image-001.jpg
というように揃えてみる。
<a name='more'></a>
<br /><br />
<hr />
<h2>正規表現を使ってファイル名を生成する</h2>
<br />
ファイル名を変更したいファイルがあるフォルダで、以下の2つのコマンドを実行することで期待通りに変更することができる。
<pre class="brush:powershell">
Get-ChildItem . | Rename-Item -NewName { $_.Name -replace 'Image\-([0-9])\.jpg','Image-00$1.jpg' }
Get-ChildItem . | Rename-Item -NewName { $_.Name -replace 'Image\-([0-9])([0-9])\.jpg','Image-0$1$2.jpg' }
</pre>
<br />
1つ目のコマンドで <code>Image-1.jpg</code> といった一桁ファイル名を <code>Image-001.jpg</code> と3桁化する。
2つ目のコマンドでは2桁ファイル名を3桁化する。
1つのコマンドでまとめてできないかとも思ったが実用上問題ないのでこれで良しとしよう。
Alias を 使って、
<pre class="brush:powershell">
dir . | ren -NewName { $_.Name -replace 'Image\-([0-9])\.jpg','Image-00$1.jpg' }
dir . | ren -NewName { $_.Name -replace 'Image\-([0-9])([0-9])\.jpg','Image-0$1$2.jpg' }
</pre>
<br />
とやっても可。これで、
<pre class="code">
<code>
Image-001.jpg
Image-002.jpg
...
Image-009.jpg
Image-010.jpg
Image-011.jpg
...
Image-099.jpg
Image-100.jpg
Image-101.jpg
...
Image-150.jpg
</code>
</pre>
<br />
とよい感じになった。
<br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-73274755211707194882015-07-28T02:12:00.002+09:002015-07-28T02:32:14.404+09:00[javascript] 配列の引数の実数を渡してはいけない当たり前のことなのかもしれないが、少しはまったのでメモ。
<br />
JavaScriptのインデックスを指定するとき、
インデックスのもとになる値が実数値の場合、
Java の習慣でそのまま整数値に切り捨てられるつもりでいた。<br />
<pre class="brush:html">
var anArray = new Array(10);
...
anArray[Math.random() * 10] += 1;
...
</pre>
上記のコードは期待通りに動かない。<br />
Math.random() * 10 を Math.floor() で整数化しておく必要がある。
<a name='more'></a>
<br /><br />
<hr />
<h2>動作を確認してみる</h2>
<br />
インデックスに実数値を指定して、実際の動作を確認してみる。
<br />
<pre class="brush:html">
<html>
<p id="output"></p>
<script>
var anArray = new Array(2);
anArray[0]= 100;
anArray[1]= 200;
anArray[0.5] = 50;
var result = "";
result = "anArray[0] = " + anArray[0] + "<br>"
+ "anArray[1] = " + anArray[1] + "<br>"
+ "anArray[0.5] = " + anArray[0.5] + "<br>"
+ "anArray.length = " + anArray.length + "<br>";
document.getElementById("output").innerHTML = result;
</script>
</html>
</pre>
<div style="text-align:right;">
<font size=-2 >※ <br> が全角なのは Syntax Highlighter が誤解釈してしまうため</font><br />
</div>
<br />
この実行結果は以下のようになる。
<pre class="code">
<code>
anArray[0] = 100
anArray[1] = 200
anArray[0.5] = 50
anArray.length = 2
</code>
</pre>
インデックスに実数を指定してセットした値はそのまま、
Array オブジェクトのプロパティとして登録されてしまう。
<br />
JavaScript で Array に値を格納する際には、
必ずインデックス値を整数化してから登録する必要がある。
<br /><br />
もともとは、Google Apps Script ではまったのだが、
この挙動は JavaScript に起因しているものだった。xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-76878312646523588492014-03-16T09:00:00.000+09:002014-03-16T09:00:02.004+09:00[Android] MEDIAS X N-07Dでの fastboot と Recovery モード前回の記事で、Nexus 7 (2012) での fastboot モードと Recovery モードへの
入り方を確認したので、今回は NEC MEDIAS X N-07D で確認してみた。<br />
<ul><li>
<a href="http://xawa99.blogspot.jp/2014/03/Android-Next7-Fastboot.html" target="_blank">
[Android] Nexus 7 の fastboot モード / Recovery Mode への入り方</a>
</li></ul>
<br />
N-07D では fastboot モードへ入ることはできない模様。<br />
Recovery モードへは入ることができる。
<br />
<br />
<a name='more'></a>
<hr>
<h4>fastboot モード</h4>
<br />
fastboot 画面に入ることはできない。<br />
電源ボタンとボリュームボタンを組合わせても通常起動する。<br />
<br />
ADB 接続した状態で <code>adb reboot bootloader</code> (または<code>adb reboot-bootloader</code> )
としても通常起動する。
<br />
<br />
<hr>
<h4>Recovery モード</h4>
<br />
ADB 接続した状態から
<code>adb reboot recovery</code> でリカバリーモードに入り、切腹ドロイド画面になる。<br />
電源ボタンとボリュームボタンを組合わせなど、UI操作だけで Recovery モードに入る方法はなさそう。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1AdbnDEUdPuEqRkYblOC1KTf4cVyLv4qwqMqihceq7cTpZ_QnSt5fj9S6cNjHd4YBPFg6yZzhToTRbUHp0ttmIWsAnmVvk_yBzYPyAHlVIEFo6tgG_ZLNI3TCgH1xDRl8B4RKZwSKJKs/s1600/N07D-RecoveryMode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1AdbnDEUdPuEqRkYblOC1KTf4cVyLv4qwqMqihceq7cTpZ_QnSt5fj9S6cNjHd4YBPFg6yZzhToTRbUHp0ttmIWsAnmVvk_yBzYPyAHlVIEFo6tgG_ZLNI3TCgH1xDRl8B4RKZwSKJKs/s320/N07D-RecoveryMode.png" /></a></div>
<br />
切腹ドロイド画面で [ボリュームアップ]→[ボリュームダウン] の順で押すと(同時にではない)、
メニュー画面が表示される。
Nexus7と違い、<b>[ボリュームダウン]でカーソル移動、「ボリュームアップ」で選択実行</b>になる。
カーソルが行き過ぎて上に戻そうとうっかり「ボリュームアップボタン」を押すと実行されてしまうので要注意。
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilrtUSzhnYig2Fn-xKiuDo8dR4r2gZzxaHs42al0QqSNKKxy5yAWKAuPAeB3vvZhrZphYIcml4sM2Hk0Bhh4lSoohdvzXMOSnBcE74Ym0WQNK_eAAtffIS_mGJMbJY6a8xvSNAzjh1FUA/s1600/N07D-RecoveryMenu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilrtUSzhnYig2Fn-xKiuDo8dR4r2gZzxaHs42al0QqSNKKxy5yAWKAuPAeB3vvZhrZphYIcml4sM2Hk0Bhh4lSoohdvzXMOSnBcE74Ym0WQNK_eAAtffIS_mGJMbJY6a8xvSNAzjh1FUA/s320/N07D-RecoveryMenu.png" /></a></div>
<br />
ここでできる操作は以下の通り:
<ul>
<li>Reboot system now: 通常モードで起動</li>
<li>wipe data/factory reset: ユーザーデータのクリア</li>
<li>wipe cache partition: キャッシュパーティションのクリア</li>
<li>repair software by sdcard: SDCardからの修復</li>
<li>maintenance: メンテナンスモードへの移行</li>
<li>check system: システムのチェック?</li>
</ul>
<br />
<code>maintenance</code> や <code>check system</code> にはパスワードが必要。<br />
N-04C なら「IMEIの上から2桁目+下4桁目~2桁目の4文字」という解析結果がある。 例えば、IMEIが「0123456789abcde」なら、パスワードは「1bcd」になる。<br />
IMEI はアプリケーション一覧画面で「設定」→「端末情報」→「端末の状態」→「IMEI」で 確認できる。<br />
<br />
N-07D では <code>maintenance</code> のパスワードが違っているようでこのパスワードでは入れなかった。<br />
<code>check system</code> は このパスワードで実行できる。<br />
<br />
<code>wipe cache partition<code> はパスワードなしで実行可能。
Recovory メニューから <code>wipe cache partition</code> を選ぶと直ちに実行される。<br />
<code>wipe data/factory reset</code> と <code>repair software by sdcard</code> は実行されてしまうと困るので未確認。<br />
<br />
下は <code>check system</code> を実行したときの画面。
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilz76sTOgGBWKygS0PgaOKKFcubdvzuV7JddvKW7HXKbwznCjNCngVHfxyMiiFA73oc4c5eyM3bQnLvSW1YLde61HRlBFK-rSezFZdvF_4NixWzzXnVfeMAhNWVLuRjxCitarHWFBmDo8/s1600/N07D-RecoveryCheckSystem.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilz76sTOgGBWKygS0PgaOKKFcubdvzuV7JddvKW7HXKbwznCjNCngVHfxyMiiFA73oc4c5eyM3bQnLvSW1YLde61HRlBFK-rSezFZdvF_4NixWzzXnVfeMAhNWVLuRjxCitarHWFBmDo8/s320/N07D-RecoveryCheckSystem.png" /></a></div>
<br />
<br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-88926812149183106542014-03-11T07:00:00.000+09:002014-03-16T01:32:20.216+09:00[Android] Nexus 7 の fastboot モード / Recovery Mode への入り方先日、Nexus 7 (2012) が (半)文鎮化してしまったので、
キャッシュやユーザーパーティションをクリアしてみた。
結局それでは復活せずに、初期イメージをロードすることになったのだが、
fastboot モード やリカバリーモードへの入り方のメモ。<br />
<br />
<a name='more'></a><hr />
<h4>fastboot モードへの入り方</h4>
<br />
<b><u>Nexus 7 上での操作</u></b><br />
<br />
電源を切った状態なら、[電源ボタン] + [Volumeダウンボタン(Volumeボタン下側)] を
押しているとfastboot の画面に入る。<br />
電源が切れない(起動中のまま先に進まないなど半文鎮状態の時に使う)の場合は、
上記のボタンを10秒くらい押し続けているとリセットがかかって fastboot で再起動する。<br />
<br />
ネット上では、[電源ボタン] +[Volumeアップ]+[Volumeダウン] と記載されているようだが、
[Volumeアップ]ボタンは必要ない模様。
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWDMngBLVkrKRvDJjlYRkM-19bKdawCdokGryeaDFCO2vzX4rmxGS5hS6KriziItTCNFcOidIQM_n9C-fQEIBVCjVu9lS3qt1zJaEnhTJVvedxS0pS1jTqaVulaBi4oHbsF7cdqaT8VDY/s1600/Nexus-Fastboot-web.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWDMngBLVkrKRvDJjlYRkM-19bKdawCdokGryeaDFCO2vzX4rmxGS5hS6KriziItTCNFcOidIQM_n9C-fQEIBVCjVu9lS3qt1zJaEnhTJVvedxS0pS1jTqaVulaBi4oHbsF7cdqaT8VDY/s320/Nexus-Fastboot-web.png" /></a></div>
[Volumeアップ] と [Volumeダウン] でアクションを選択する。
<ul>
<li>Start : 通常起動開始</li>
<li>Restart bootloader : bootloader を再起動して、再度 fastboot モードへ入る。</li>
<li>Recovery mode : Recovery モードへ入る。</li>
<li>Power off : 電源を切る。</li>
</ul>
電源ボタンを押すと、選択したアクションが実行される。
<br />
<br />
<br />
<b><u>ADB接続経由での操作</u></b><br />
<br />
ADB接続できている状態なら、
<ul><li><code>adb reboot bootloader</code> 、または</li>
<li><code>adb reboot-bootloader</code></li>
</ul>
で fastboot モードで再起動することができる。<br />
<br />
<hr />
<h4>
Recovery モード への入り方</h4>
<br />
<b><u>Nexus 7 上での操作</u></b><br />
<br />
fastboot モードの画面から 「Recovery mode」を選択して電源ボタンを押すと
リカバリーモードへ移行する。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgk-RpyMke6BxZxfWCGoGStM4zzIdaPHRk27MvvyI9CuxiTpHra364SN6engmKBGXVi5NWbe40nI7hY-BA0esE2nF8nrEyEVzDVTnOWOm847x_5h7ND2YVhqdyaVxkqoAROOHFMmQnBL3s/s1600/Nexus-Recovery.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgk-RpyMke6BxZxfWCGoGStM4zzIdaPHRk27MvvyI9CuxiTpHra364SN6engmKBGXVi5NWbe40nI7hY-BA0esE2nF8nrEyEVzDVTnOWOm847x_5h7ND2YVhqdyaVxkqoAROOHFMmQnBL3s/s320/Nexus-Recovery.png" /></a></div>
<br />
赤い警告マーク付きの切腹ドロイド画面に
「コマンドが指定されていません」と表示されるので、
電源ボタン+[Volumeアップボタン] で、メニュー画面に入ることができる。
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLDUfu_gu1tOAQqG38x44FnzYi8wMe0X_vLNOrV28A0XY5NT69SBI1If8Ph1jPnIQFAlx5DuIecbUKnmAWjF9RB68W_5nK4X7L6RMT1_lGSDbZT0ColYlI-EO7vLmtdHWtNIbmczg-wlY/s1600/Nexus-Recovery-Menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLDUfu_gu1tOAQqG38x44FnzYi8wMe0X_vLNOrV28A0XY5NT69SBI1If8Ph1jPnIQFAlx5DuIecbUKnmAWjF9RB68W_5nK4X7L6RMT1_lGSDbZT0ColYlI-EO7vLmtdHWtNIbmczg-wlY/s320/Nexus-Recovery-Menu.png" /></a></div>
この画面では以下の操作ができる。<br />
<ul>
<li>reboot system now : 通常再起動</li>
<li>apply update from ADB : ADB 経由でのイメージのアップデート</li>
<li>wipe data/factory reset : ユーザーデータのクリア</li>
<li>wipe cache partition : キャッシュパーティションのクリア</li>
</ul>
<br />
<b><u>ADB接続経由での操作</u></b><br />
<br />
ADB接続できている状態なら、
<ul><li>
<code>adb reboot recovery</code>
</li></ul>
で 「コマンドが指定されていません」画面に入ることができる。<br />
<br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-54730826325621316612014-03-02T09:00:00.000+09:002014-03-02T14:30:21.592+09:00[Android] ADB接続とUSB接続モード<br />
Android デバイスを ADB 接続する時には、USB の接続モードによっては認識されないことがある。
ひとハマリしたのでメモ。
<br /><br />
手元のデバイスでの結果は、
<ul>
<li>Nexus7 では MTP を無効にする</li>
<li>Medias N07D では カードリーダーモードにする</li>
</ul>
ことで、ADB接続ができる。<br /><br />
<a name='more'></a>
<hr />
<h2> Nexus 7 (2012) の場合 (Android OS 4.2.2)</h2>
<br />
USB接続モードの切り替えは、<br />
<ul><li>
「設定」→「ストレージ」→右上のメニューボタン→「USBでパソコンに接続」<br />
</li></ul>
から変更できる。<br />
案外わかりにくいところにあるので、忘れているとひと苦労する。<br />
<br />
接続モードは、
<ul>
<li>メディアデバイス(MTP)</li>
<li>カメラ(PTP)</li>
</ul>
の2種類あり、それぞれ独立にオンオフできる。
<br />
この時、MTPが有効になっていると ADB接続できない。<br />
PTPは有効・無効 関係なく接続できる。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUqnSJhAmpKtD04oA6dtfdzibEmy2O0JlrEwKYaoZC726TktEemNRazoKFvbSZkipOBUdn7ESVJM0Kavvc02dxW5qPJ8RW7_OYggJyOfE3Jl_t8YWXi-nV8lN3Fj0CjteYUx7GXB7weoA/s1600/Nexus-UsbMode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUqnSJhAmpKtD04oA6dtfdzibEmy2O0JlrEwKYaoZC726TktEemNRazoKFvbSZkipOBUdn7ESVJM0Kavvc02dxW5qPJ8RW7_OYggJyOfE3Jl_t8YWXi-nV8lN3Fj0CjteYUx7GXB7weoA/s320/Nexus-UsbMode.png" /></a></div>
<br />
<hr />
<h2> NEC MEDIAS X N07Dの場合 (Android OS 4.1.2)</h2>
<br />
USB接続モードの切り替えは、<br />
<ul><li>
「設定」→「ストレージ」→左下のメニューボタン→「USBでパソコンに接続」<br />
</li></ul>
<br />
接続モードは
<ul>
<li>カードリーダーモード</li>
<li>USBテザリング</li>
<li>USB PC Link</li>
<li>メディアデバイス(MTP)</li>
<li>カメラ(PTP)</li>
</ul>
の5種類あり、いずれか一つのモードを選択する。
<br />
ADB 接続ができるためには、「カードリーダーモード」を選択しておく必要がある。<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTmVAhaLqtbH-ZgsQFtgBiYaz7fMyq9mY7v3S-rARM3NKRmT9phgkyLQ7v3WYxeH-I5JW-4omKNdIynPr8yZ3xgYpU_fQkedXgF6XTbIblESlARnjr0WAXAQjumz7kuF_-2iy9A4veOFc/s1600/Medias-UsbMode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTmVAhaLqtbH-ZgsQFtgBiYaz7fMyq9mY7v3S-rARM3NKRmT9phgkyLQ7v3WYxeH-I5JW-4omKNdIynPr8yZ3xgYpU_fQkedXgF6XTbIblESlARnjr0WAXAQjumz7kuF_-2iy9A4veOFc/s320/Medias-UsbMode.png" /></a></div>
<br />
<hr />
<br />
先日、Nexus7 が (半)文鎮化してしまったので、初期イメージを焼き直すことになった。<br />
無事起動したのだが、ADB 接続できなくなってしまったのだが、
どうも初期イメージにしたことで、USB接続モードが MTPモード になってしまったことが原因だったようだ。
<br /><br />
ちなみに、
<ul>
<li>PTP: <a
href="http://ja.wikipedia.org/wiki/%E7%94%BB%E5%83%8F%E8%BB%A2%E9%80%81%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB"
target="_blank">
Picture Transfer Protocol</a><br />
デジタルカメラから画像を転送するためのプロトコル</li>
<li>MTP: <a
href="http://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2%E8%BB%A2%E9%80%81%E3%83%97%E3%83%AD%E3%83%88%E3%82%B3%E3%83%AB" target="_blank">
Media Transfer Protocol</a><br />
PTPを拡張したもので、音楽ファイルや動画ファイルを転送するためのプロトコル</li>
</ul>
とのこと。
<br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-26185234320230585892014-02-23T19:00:00.000+09:002014-03-01T14:21:44.097+09:00[Blogger] 「このブログは Blogger の利用規約に違反しているため…」への対応<br />
突然、自分のブログが表示されなくなった。 <br /><br />
<div class="code">
このブログは Blogger の利用規約に違反しているため、現在は投稿者のみが表示可能です。
</div>
<br />
最近、ブログを更新していなかったし、もちろん、利用規約に違反するような内容は
記載していないつもりだったので意味が分からない。<br />
<br />
幸い、すぐに解除できたので今回はその記録。<br />
<br />
<a name='more'></a>
<hr />
<h2>原因不明</h2><br />
Blogger の管理画面ではこのような表示になっている。<br />
<br />
<div class="separator" style="clear: both; text-align: center; border:#000000 solid 1px"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEituvoR0nIdY4fzTSGT3EGVKfrrrgTo1Kv0ByfJ-9jKGrSa9jUsLGQpft25QVD1XOxGbhoax05kJ-E0GuZKjkhvFjjmtHentCAxxCIVJ-S74Rx4PU2WQBijlaH8NtC0BcotZOAOaHDuxXg/s1600/Locked-Web-true.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEituvoR0nIdY4fzTSGT3EGVKfrrrgTo1Kv0ByfJ-9jKGrSa9jUsLGQpft25QVD1XOxGbhoax05kJ-E0GuZKjkhvFjjmtHentCAxxCIVJ-S74Rx4PU2WQBijlaH8NtC0BcotZOAOaHDuxXg/s400/Locked-Web-true.png" /></a></div>
<br />
早速「ロック画面の解除」から解除申請をする。<br />
アカウントの確認画面が出たので確認コードを入手してアカウント確認を実行。<br />
<br />
「ロック解除のリクエスト」画面が表示される。<br /><br />
<div class="separator" style="clear: both; text-align: center; border:#000000 solid 1px"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPamLXekuhSWD4-Jhxz2tBp1uoB7BubTGdq_NMSHHh_A5nAxEAPe5tbxyCdNS5NOXoxKGMoyccyD3ZjnBvWvPK5UngdeJjAtusu-SdgiZzHBtk6HodaMrd83dRXINyivn2Q0pFr4o_0oI/s1600/UnlockRequest-Web.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPamLXekuhSWD4-Jhxz2tBp1uoB7BubTGdq_NMSHHh_A5nAxEAPe5tbxyCdNS5NOXoxKGMoyccyD3ZjnBvWvPK5UngdeJjAtusu-SdgiZzHBtk6HodaMrd83dRXINyivn2Q0pFr4o_0oI/s400/UnlockRequest-Web.png" /></a></div>
<br />
「ウェブマスターツールで確認せよ」とのことなので、
「ロック解除のリクエスト」画面の「Google ウェブマスター ツールを開く」をクリックすると、<br />
<br />
<div class="code">
アクセスしようとしたページは存在しません(404)
</div><br />
となってしまう。<br />
普通にウェブマスターツールを開いてみるとブログに問題があるようには見えない。<br />
安全性でも問題なし。対策のしようがない。<br />
ウェブマスターツールではロックされている状況になっていないため、
アンロックリクエストをするリンクもない。<br />
<br />
<hr />
<h2>ロック解除リクエスト画面を直接開いて解決</h2><br />
同様にブログがロックされた時の対処をした記事があったので、
そこに記載されていた URL を直接開いてロック解除申請画面を開く。
<ul><li><a href="http://variousdiary.blogspot.jp/2013/07/bloggergoogle.html" target="_blank">
blogger使っていたらgoogleにスパムブログと間違われた件</a><br />
--- いろいろ書いてみる日記</li>
</ul>
<br />
<div class="code">
http://www.blogger.com/unlock-blog.g?lockedBlogID=<i>XXXXXXXX</i>
</div>
<br />
<i>XXXXXXXX</i> のところはロック解除したい ブログのblogId にする。<br />
<br />
ブログの復元要求の画面が表示される。
原因が全く分からないので、ブログ自体は何も手を入れずに、
この画面から復元要求を出しておく。
<br />
<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqM_ZJGDdQxBKYyoKqAsXoE1H0H66dWb-jP7AUcoNdd2AuVkAmmJqdsNf5R32Lk1Km2WmPjonnOipz9ZqxVYQWOS5hSWPGRjOMa0RwLwOn0bE8MslBdgKB_fhKUbjn-r4rNmqZ7NXAZH8/s1600/UnlockRequest2-Web.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqM_ZJGDdQxBKYyoKqAsXoE1H0H66dWb-jP7AUcoNdd2AuVkAmmJqdsNf5R32Lk1Km2WmPjonnOipz9ZqxVYQWOS5hSWPGRjOMa0RwLwOn0bE8MslBdgKB_fhKUbjn-r4rNmqZ7NXAZH8/s400/UnlockRequest2-Web.png" /></a></div>
<br />
<br />
一日もしないでロックは解除されて、今まで通りアクセスできるようになった。<br />
<br />
上記の「いろいろ書いてみる日記」の場合、最初にロックされたことを知らせるメールが来て、
そこに復元要求の URL が記載されていたようだが、
今回はそのようなメールもなく、突然ブロックされてしまっていた。<br /><br />
ウェブマスターツールからも解除する方法がなかったので、
この URL を知らないと解除できないままだったかもしれない。
結局、ブログ自体にも何も悪いところはなかったようだし・・・。なんだったのだろう。
<br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com1tag:blogger.com,1999:blog-3058535269160921661.post-82787518873498712092013-11-04T07:00:00.000+09:002013-11-04T16:55:23.048+09:00[Android] GridView で列数を固定する。<code>GridView</code> は列数を <code>numColumns</code> で指定すると、
<code>GridView</code> の横幅に応じて セルの幅を自動的に決めてくれる。<br />
<br />
しかし、縦幅はセルに指定したアイテムの縦幅が採用されるので、
行数も固定して <code>GridView</code> を綺麗に固定するには
<code>GridView</code> のサイズに応じて、アイテムの縦幅を調整する必要がある。
<br /><br />
<a name='more'></a>
<hr />
<h3>高さ設定のための独自 Adapter の実装</h3>
<br />
<code>GridView</code> に設定する <code>ArrayAdapter</code> をカスタマイズして、
<code>getView</code> で各ビューに <code>GridView</code> の高さを
行数で割った値を設定することで 各行の高さを調整する。
<br /><br />
<pre class="brush: java highlight:[15]">
public class MainActivity extends Activity {
private static final int ROW = 7;
private static final int COLUMN = 5;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<String> list = new ArrayList<String>();
for (int i=1; i<=ROW*COLUMN; i++) {
list.add(String.valueOf(i));
}
MyAdapter adapter = new MyAdapter(
getApplicationContext(), android.R.layout.simple_list_item_1,
list);
GridView gridView = (GridView) findViewById(R.id.gridView1);
gridView.setAdapter(adapter);
}
...
</pre>
<br /><br />
GridView には、高さ調整をするための <code>MyAdapter</code> をアダプターとして与えておく。<br />
MyAdapter はまずはこんな感じで実装する。
<pre class="brush: java">
...
public class MyAdapter extends ArrayAdapter<String> {
public MyAdapter(Context context, int layoutId, List<String> objects) {
super(context, layoutId, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
TextView textView = new TextView(MainActivity.this);
textView.setText(this.getItem(position));
textView.setBackgroundColor(Color.parseColor(
position % 2 == 1 ? "green" : "blue"));
int parentHeight = parent.getHeight();
textView.setHeight(parentHeight / ROW);
return textView;
}
return convertView;
}
}
}
</pre>
<br />
しかし、<code>position == 0</code> になる最初の呼び出しの時には、
<code>parent.getHeight()</code> の値が 0 になってしまい、最初の
<code>TextView</code> の高さが 0 になってしまう。
<br /><br />
<hr />
<h3>parent.getHeight() == 0 の対策</h3>
<br />
最初の呼び出しで <code>parent.getHeight()</code> が0になる対策として、
<code>parent.getHeight()</code> になった TextView を保持しておいて、
<code>parent.getHeight()</code> で正しい値が取得できるようになった時に、
以前の<code>TextView</code> に改めて正しい高さを設定するようにする。
<br /><br />
<pre class="brush: java highlight:[3,19,20,21,22,23,24,25,26]">
...
public class MyAdapter extends ArrayAdapter<String> {
private ArrayList<TextView> m_unstableView = new ArrayList<TextView>();
public MyAdapter(Context context, int layoutId, List<String> objects) {
super(context, layoutId, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
TextView textView = new TextView(MainActivity.this);
textView.setText(this.getItem(position));
textView.setBackgroundColor(Color.parseColor(
position % 2 == 1 ? "green" : "blue"));
int parentHeight = parent.getHeight();
textView.setHeight(parentHeight / ROW);
if (parentHeight != 0 && m_unstableView.size() > 0) {
for (TextView v : m_unstableView) {
v.setHeight(parentHeight / ROW);
}
m_unstableView.clear();
} else {
m_unstableView.add(textView);
}
return textView;
}
return convertView;
}
}
}
</pre>
<br /><br />
これで以下のような表示になった。<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj17LRPJf6-VgDMvghI9dis2e6KdBcqdvaxtp-qBZT8LIq0e_xSkN48am1vrnWFSO5Asn8MzF7jRaD9CVV4K-UUesZ56ZZdmBpGg1gVdUK8NEb8uNaMD5SOVhoQAkv6w0P8K_ElqMmiC4U/s1600/GridViewFixedRowSize.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj17LRPJf6-VgDMvghI9dis2e6KdBcqdvaxtp-qBZT8LIq0e_xSkN48am1vrnWFSO5Asn8MzF7jRaD9CVV4K-UUesZ56ZZdmBpGg1gVdUK8NEb8uNaMD5SOVhoQAkv6w0P8K_ElqMmiC4U/s320/GridViewFixedRowSize.png" /></a>
<br /><br />
解決策としては強引な気がするし、もっと適切なやり方があるような気がするが、
とりあえずはこれで目的の表示にはなった。
<br /><br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-45382574053766887002013-10-27T23:00:00.000+09:002014-03-16T04:04:16.852+09:00NEC MEDIAS X N-07D の ADB Interface を使うNEC の MEDIAS N-07D を ADB 接続しようとしたのだが公式ドライバではうまくいかなかったのでメモ。
<br/><br />
NECカシオモバイルコミュニケーションズ の公式ダウンロードページから
ドライバをダウンロードしてインストールした。
<ul>
<li><a href="http://www.n-keitai.com/guide/download/n07d/usb/" target="_blank">
公式ドライバ ダウロードページ</a></li>
</ul>
<br />
しかし、正常にデバイスとして認識されない。
USB Storage デバイスとしては見えているのだが、ADB デバイスとしては機能していない。<br />
<br />
公式ドライバの使用を断念し、Android SDK に入っているドライバを使用して解決。<br />
以下、そのメモ。
<br />
<br />
<a name='more'></a>
<hr >
<br />
デバイスマネージャで見るとドライバが正しく動作していないように見える。<br />
ドライバの詳細を見ると、ドライバーを再インストールする必要があるという表示になっている。<br />
もちろん、再インストールしても解決しない。<br /><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_0r0S1QIHT6XUiGf34_MErZ8iAe4isBW0d2-BWZ-gSic2Uju7haHIjmfBz7H6juFmRjE2ONiRe1kRaalfHgUTAUOxGcoziKjqE73FMpqoZrsQcnzC9oxvLfz-PSkchk5FAW1wZWGzJZU/s1600/Android-N07D-ADB-NG.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_0r0S1QIHT6XUiGf34_MErZ8iAe4isBW0d2-BWZ-gSic2Uju7haHIjmfBz7H6juFmRjE2ONiRe1kRaalfHgUTAUOxGcoziKjqE73FMpqoZrsQcnzC9oxvLfz-PSkchk5FAW1wZWGzJZU/s400/Android-N07D-ADB-NG.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUnvP2e9BOtvAL9mkBjgvGmqVTfOeGyjX8vXYCHuMwuBK3mDOqHAA7dE5f1qDZG_MzZAVFRITSRk2hY0F49nCTwK9WLBELvGrWVtk3f4w29rEmBTEYlaa5nGEsBg5YuqAe3JKjNnzlNGs/s1600/Android-N07D-ADB-NG-Prop.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUnvP2e9BOtvAL9mkBjgvGmqVTfOeGyjX8vXYCHuMwuBK3mDOqHAA7dE5f1qDZG_MzZAVFRITSRk2hY0F49nCTwK9WLBELvGrWVtk3f4w29rEmBTEYlaa5nGEsBg5YuqAe3JKjNnzlNGs/s320/Android-N07D-ADB-NG-Prop.png" /></a></div>
<br /><br />
<hr >
<br />
すでに入っている公式ドライバーをアンインストールして、AndroidSDK のドライバをインストールする。
AndroidSDK は <code>adt-bundle-windows-x86_64-20130917</code> を使用。<br /><br />
<h3><u>公式ドライバーのアンインストール</u></h3>
<br />デバイスマネージャからデバイスごと、
N-07D Android ADB Interface を削除。<br />
<br />
<h3><u>Android SDK のドライバの INF ファイルを編集</u></h3>
<br />
<code>adt-bundle-windows-x86_64-20130917\sdk\extras\google\usb_driver</code> の
<code>android_winusb.inf</code> を編集して、N07-D 用のエントリを追加する。<br /><br />
OS が Windows7 64bit なので、[Google.NTamd64] セクションに以下の3行を追加。<br />
<pre class="brush: plain">
; NEC MEDIAS N-07D
%SingleAdbInterface% = USB_Install, USB\VID_0409&PID_0340
%CompositeAdbInterface% = USB_Install, USB\VID_0409&PID_0340&REV_0100&MI_01
</pre>
<br />
デバイスマネージャの ADB Interface のエントリの<br />
[プロパティ>詳細>ハードウェアID] を確認すると、
<pre class="brush: plain">
USB\Vid_0409&Pid_0340&Rev_0100&Mi_01&Os_NT
USB\Vid_0409&Pid_0340&Rev_0100&Mi_01
USB\Vid_0409&Pid_0340&Mi_01&Os_NT
USB\Vid_0409&Pid_0340&Mi_01
USB\Vid_0409&Pid_0340&Class_ff&SubClass_42&Prot_01&Os_NT
USB\Vid_0409&Pid_0340&Class_ff&SubClass_42&Prot_01
USB\Vid_0409&Pid_0340&Class_ff&SubClass_42&Os_NT
USB\Vid_0409&Pid_0340&Class_ff&SubClass_42
USB\Vid_0409&Pid_0340&Class_ff&Os_NT
USB\Vid_0409&Pid_0340&Class_ff
</pre>
と10個ほどのエントリが見えるが、上記の2つだけ記載しておけば大丈夫だった。<br />
<br />
<h3><u>ドライバのインストール</u></h3><br />
デバイスをいったん抜いて、再度USBケーブルで接続する。<br />
デバイスを検知してインストールが始まるがドライバが見つからずに失敗する。<br />
デバイスマネージャ上からドライバの更新で、<br />
<code>adt-bundle-windows-x86_64-20130917\sdk\extras\google\usb_driver<code>
フォルダを指定して、ドライバをインストール。
<br /><br />
<hr >
<br />
これで N-07D が ADB 接続できるようになった。<br />
<br />
ドライバーのアンインストールをせずに、「ドライバの更新」から、<br />
<code>adt-bundle-windows-x86_64-20130917\sdk\extras\google\usb_driver</code><br />
を選択しても「最新のドライバがインストールされています」と出て、
SDK版のドライバがインストールされない。<br />
<br />
今回は、USBストレージとしては見えていたので、
NEC 公式ドライバー全体のアンインストールは行わずに、ADB Interface のドライバのみアンインストールした。<br />
NEC 公式ドライバー全体をアンインストールして Android SDK版のみで行けるかどうかは未確認。<br /><br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com4tag:blogger.com,1999:blog-3058535269160921661.post-12730497915660406662013-10-20T10:00:00.000+09:002014-07-07T02:29:17.201+09:00[どうぶつしょうぎ] 相腰掛ゾウ基本定跡 23手目 ▲C4ライオン の変化 <table><tbody>
<tr><td style="vertical-align: top;"><br />
図1は、相腰掛ゾウ基本定跡(相ゾウ冠基本定跡)で 22手目に後手が △A3ゾウ とした局面。<br />
本筋では先手は ▲A4ライオン として、以下△C1ライオン、▲C4キリン、△B2ゾウ と進む。<br /><br />
今回は、23手目に先手が ▲A4ライオン に替えて ▲C4 ライオンとしてきた場合の変化を見てみる。<br />
先手の狙いは ▲A4ヒヨコ打。後手は A3 のゾウの捌き方が焦点になる。<br />
<br />
棋譜はこちら → <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-b2Hb2Z-b3Za2K-a2Za2L-b3Kc2Z-b2Kb2L-a3Za2L-c3Kb2H-b2Zb2L-b3Hb1L-a3La2K-b4La3Z-c4L.txt" target="_blank">棋譜</a>
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgczAPSBYTpjhunwtTz3pboLIait0yml7mj7U9dqLMwVaWotXyISRfGnZIBGXWEjPvbjgyea4AE2WI5vLdF3VH_KsLLVSLeByDr8l7xZ5A70rdQyXwXfujqrdlb2Q4iKGnPx8gzklMRPE0/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E7%9B%B8%E8%85%B0%E6%8E%9B%E3%82%BE%E3%82%A623%E6%89%8B%E7%9B%AE.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgczAPSBYTpjhunwtTz3pboLIait0yml7mj7U9dqLMwVaWotXyISRfGnZIBGXWEjPvbjgyea4AE2WI5vLdF3VH_KsLLVSLeByDr8l7xZ5A70rdQyXwXfujqrdlb2Q4iKGnPx8gzklMRPE0/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E7%9B%B8%E8%85%B0%E6%8E%9B%E3%82%BE%E3%82%A623%E6%89%8B%E7%9B%AE.png" /></a>
</td></tr>
<tr><td class="tr-caption" style="text-align: center;">図1 △A3ゾウ打 まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<a name='more'></a><hr />
<h2><u>▲A4ヒヨコを打たせる</u></h2>
<table><tbody>
<tr><td style="vertical-align: top;"><br />
<b>▲C4ライオン、△A1キリン、▲A4ヒヨコ、△A2キリン
</b><br /><br />
先手の▲C4ライオンに対して、後手は△A1キリンと手待ちをして ▲A4ヒヨコを甘んじて受けたあと△A2キリンとキリンを戻す。<br />
△A1キリン に替えて △C1ライオン でもヒヨコ打から △C2ライオン で合流する。<br />
<br />
△A2キリン のところで、△B2ゾウと引くと▲同ヒヨコ、△同ライオン、▲C2キリン、△同ライオン、▲B3ゾウ打 と捌かれる。まだ後手勝ち局面だが最善で60手以上と難解になってしまう。<br />
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6tPH0bLT9JUqhi7TUqNENEoBsVmeob8ynDcjTur11R9wM0rByV7Ist4zZbALVdekLWzMT9vazPhu9GaD92A8FFPFLI5F1ceT4r4GNdRP1gSMQOOstj6bjHZ9i4P0YgWxU1KoLr70dszc/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E7%9B%B8%E8%85%B0%E6%8E%9B%E3%82%BE%E3%82%A6C4%E3%83%A9%E3%82%A4%E3%82%AA%E3%83%B3-27%E6%89%8B%E7%9B%AE.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6tPH0bLT9JUqhi7TUqNENEoBsVmeob8ynDcjTur11R9wM0rByV7Ist4zZbALVdekLWzMT9vazPhu9GaD92A8FFPFLI5F1ceT4r4GNdRP1gSMQOOstj6bjHZ9i4P0YgWxU1KoLr70dszc/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E7%9B%B8%E8%85%B0%E6%8E%9B%E3%82%BE%E3%82%A6C4%E3%83%A9%E3%82%A4%E3%82%AA%E3%83%B3-27%E6%89%8B%E7%9B%AE.png" /></a>
</td></tr>
<tr><td class="tr-caption" style="text-align: center;">図2 △A2キリン まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<hr />
<h2><u>ヒヨコゾウ交換</u></h2>
<table><tbody>
<tr><td style="vertical-align: top;"><br />
<b>▲A3ヒヨコ、△同キリン、▲B4ライオン、△A2ライオン
</b><br /><br />
先手は当然 A3のゾウをとる。先手は図1の段階でゾウヒヨコ交換でコマ損をしていたが
このヒヨコゾウ交換でコマ割りは互角に戻る。<br />
後手は駒損をしたが△A2ライオンと出て好調。
<br /><br />
△A2ライオン で C2の後手ゾウがただ取りになっているが ▲C2キリン と取ると △B3キリン 以下即勝ちになる。<br />
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZ1fM7hrnnQsaD_3DI_-vmoBlMukOx5CrInHT93F1Tzo9csWzfdwdBYkpOj9wUeMiMarPXGJ5MuuNh0jLOOiW9FoHkVotOj0xGteDIr-Difbixg8XzPwqOrWlOeF9Ytb13gDnnEcDnCOE/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E7%9B%B8%E8%85%B0%E6%8E%9B%E3%82%BE%E3%82%A6A4%E3%83%A9%E3%82%A4%E3%82%AA%E3%83%B3-31%E6%89%8B%E7%9B%AE.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZ1fM7hrnnQsaD_3DI_-vmoBlMukOx5CrInHT93F1Tzo9csWzfdwdBYkpOj9wUeMiMarPXGJ5MuuNh0jLOOiW9FoHkVotOj0xGteDIr-Difbixg8XzPwqOrWlOeF9Ytb13gDnnEcDnCOE/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E7%9B%B8%E8%85%B0%E6%8E%9B%E3%82%BE%E3%82%A6A4%E3%83%A9%E3%82%A4%E3%82%AA%E3%83%B3-31%E6%89%8B%E7%9B%AE.png" /></a>
</td></tr>
<tr><td class="tr-caption" style="text-align: center;">図3 △A2ライオン まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<hr />
<h2><u>後手ヒヨコ得で優勢</u></h2>
<table><tbody>
<tr><td style="vertical-align: top;"><br />
<b>▲B2ゾウ打、△B3キリン、▲同キリン、△同ゾウ<br />
▲A3キリン打、△B2ライオン、▲B3キリン、△B1ライオン
</b><br /><br />
先手の応手は ▲B2ゾウ打 か ▲C4またはA4ゾウ打 でB3のヒヨコを守るかのどちらか。<br /><br />
▲B2ゾウ打が最善で△B3キリン から △B1ライオン の手順で後手がヒヨコ得になりはっきり優勢。
<br /><br />
▲C4またはA4ゾウ打 では △B1ゾウ とゾウを引く。<br />
先手は手詰まりになり、▲B2ヒヨコ とヒヨコを突き捨てざるを得ずこの順でもヒヨコ損は避けられない。<br />
▲A4ゾウ打、 △B1ゾウ、▲C4キリン とキリンを引いて粘っても △C2ヒヨコ打 でますます悪くなる。<br />
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVg0XO7yFmRrU1qHjiunNCXm3R_30RZ4Kao39IsHWKD6INxf4fwBjJyhdAhsIHcUu-OOayHuGtiUCHCDZ3srR2aNNa12hfFA89TyrxPif6zDIRUZ9f7t2PnUsUjlpbH1nusabjbYIkONo/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E7%9B%B8%E8%85%B0%E6%8E%9B%E3%82%BE%E3%82%A6A4%E3%83%A9%E3%82%A4%E3%82%AA%E3%83%B3-39%E6%89%8B%E7%9B%AE.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVg0XO7yFmRrU1qHjiunNCXm3R_30RZ4Kao39IsHWKD6INxf4fwBjJyhdAhsIHcUu-OOayHuGtiUCHCDZ3srR2aNNa12hfFA89TyrxPif6zDIRUZ9f7t2PnUsUjlpbH1nusabjbYIkONo/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E7%9B%B8%E8%85%B0%E6%8E%9B%E3%82%BE%E3%82%A6A4%E3%83%A9%E3%82%A4%E3%82%AA%E3%83%B3-39%E6%89%8B%E7%9B%AE.png" /></a>
</td></tr>
<tr><td class="tr-caption" style="text-align: center;">図4 △B1ライオン まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<hr />
<h2><u>後手勝ち</u></h2>
<table><tbody>
<tr><td style="vertical-align: top;"><br />
<b>▲C3ゾウ打、△C2キリン打、▲A3キリン、△B2ヒヨコ打<br />
▲同ゾウ、△同キリン、▲C3ライオン、△B3ゾウ打(!)、<br />
▲同キリン、△同キリン、▲同ライオン、△A2ゾウ打
</b><br /><br />
以下は普通に指せば後手勝ち。<br />
△B2ヒヨコ打では単に△C3キリンの方がわかりやすいかも。4手ほど長くなるが勝ちは変わらない。<br /><br />
△B3ゾウ打が最短勝ちを狙う妙手だが、
普通に△C2ヒヨコ打と追っても一手長くなるだけで大差はない。<br />
△A2ゾウ打 まで進んであとは10手ほどで後手勝ち。
<br /><br />
図4から▲C3ライオン と上がってきたら、△C2ヒヨコ、△B2ヒヨコとヒヨコを並べて追い立てて勝ちになる。
<br />
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_01-yCrYW8j9sc9DyANrIBCX02zrrRQKwYYP4CWPVRKjFfFiAFXZeJo8wn8MWTpY866VZOKEvXrXdeG9L96Pb3-I0RNiBImZak4dSKoeqHlFaDzi2dQRoxR-ae6_mQYzsy5aUXx_q8i0/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E7%9B%B8%E8%85%B0%E6%8E%9B%E3%82%BE%E3%82%A6A4%E3%83%A9%E3%82%A4%E3%82%AA%E3%83%B3-51%E6%89%8B%E7%9B%AE.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_01-yCrYW8j9sc9DyANrIBCX02zrrRQKwYYP4CWPVRKjFfFiAFXZeJo8wn8MWTpY866VZOKEvXrXdeG9L96Pb3-I0RNiBImZak4dSKoeqHlFaDzi2dQRoxR-ae6_mQYzsy5aUXx_q8i0/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E7%9B%B8%E8%85%B0%E6%8E%9B%E3%82%BE%E3%82%A6A4%E3%83%A9%E3%82%A4%E3%82%AA%E3%83%B3-51%E6%89%8B%E7%9B%AE.png" /></a>
</td></tr>
<tr><td class="tr-caption" style="text-align: center;">図5 △A2ゾウ打 まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com3tag:blogger.com,1999:blog-3058535269160921661.post-4152422575530353702013-09-29T01:00:00.000+09:002013-09-29T01:00:05.977+09:00[Java] Java Image は透過色をサポートしていない?Java7 の ImageIO は PNG の透過色指定をサポートしていないらしい。<br />
<br />
<pre class="brush: java">
package kuro.misc.image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class TransparentColor {
private static String FILE_IN = "C:/work/temp/test.png";
private static String FILE_OUT = "C:/work/temp/test-out.png";
public static void main(String[] args) throws IOException {
BufferedImage image = ImageIO.read(new File(FILE_IN));
ImageIO.write(image, "PNG", new File(FILE_OUT));
}
}
</pre>
<br />
こんな感じのコードを書いて、透過色指定をした「test.png」を読み込ませると、
出力される「test-out.png」は透過色指定がなくなってしまう。
<br />
<br />
<pre class="brush: java">
BufferedImage image = ImageIO.read(new File(FILE_IN));
System.out.println(
"Image transparency = " + image.getTransparency());
-----------
Image transparency = 1
</pre>
<br />
getTransparency の出力値の意味は以下の通り。<br />
<pre class="brush: java">
package java.awt;
public abstract interface Transparency
{
public static final int OPAQUE = 1;
public static final int BITMASK = 2;
public static final int TRANSLUCENT = 3;
public abstract int getTransparency();
}
</pre>
<br />
読み込んだ時点で 透過情報のあるImageだとは扱われていない模様。
<br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-8183857607168649062013-09-02T01:00:00.000+09:002013-09-02T02:52:40.713+09:00[Java] Image の拡大Image を拡大して PNG に保存する方法。<br />
PNGに保存するには ImageIO.wtite を使いたいので、
<code>BufferedImage</code> にしておく必要がある。
<br /><br />
<hr />
<h2><code>Image</code> の拡大</h2>
<br />
いろいろ方法はありそうだが、一番簡単そうなのは
<code>java.awt.Image#getScaledInstance</code> を使う方法。
<pre class="brush: java">
private static Image magnifyImage(Image img, int scale) {
int width = img.getWidth();
int height = img.getHeight();
Image scaledImage = img.getScaledInstance(
width * scale, height*scale, Image.SCALE_DEFAULT);
return scaledImage;
}
</pre>
<br />
<hr />
<h2><code>Image</code> から <code>BufferedImage</code> に変換する方法</h2>
<br />
<code>Image#getScaledInstance</code> を使うと、拡大したイメージは、
<code>java.awt.Image</code> になってしまうので、
<code>ImageIO.write</code> を使うためには、
<code>java.awt.image.BufferedImage</code> に変換する必要がある。<br />
<pre class="brush: java">
private static BufferedImage convertImageToBufferedImage(Image img) {
BufferedImage bimg = new BufferedImage(
img.getWidth(null), img.getHeight(null),
BufferedImage.TYPE_INT_ARGB);
Graphics g = bimg.getGraphics();
g.drawImage(img, 0, 0, null);
g.dispose();
return bimg;
}
</pre>
<br />
すでに大きさが確定しているイメージを使うので Image.getWidth で Observer を指定する必要はない。<br />
<br />
<br />この方法の難点は透過情報(アルファチャンネル)を失ってしまうことだが、
今回は アルファ情報はいらないのでこれで良しとする。
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-55298905115169550942013-08-05T01:00:00.000+09:002013-09-01T01:53:31.551+09:00[どうぶつしょうぎ] ぴよ替わり後の▲C3きりん の変化<table><tbody>
<tr><td style="vertical-align: top;"><br />
ぴよ替わり後の▲C3きりん型 (相キリンの翼)の変化を見てみる。<br />
図1は12手目に後手が △C1ヒヨコ打 とした局面。<br />
本筋では ▲C4ライオン と引いたが、実戦では ▲B4ライオンと引くことが多い。<br />
<br />
▲C4ライオン の場合は、△B3キリン と奥のゾウを取り込んだが、
▲B4ライオン の場合は △B3キリン では負けになってしまう。
ここは、△C2ヒヨコ とする必要がある。
この場合の棋譜はこちら(→<a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-b2Hb2Z-b3Za2K-c3Kc3Z-c3Lb2K-a2Za1L-a3Hc1H-b4L.txt" target="_blank">棋譜</a>)。
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmvfy6l_Q_bKO1udkI7Vh1aWj6wsaXJnY0iHpQpjykbN-O47H25GokLTLUwA5OmSyNvRa5RvSGqBtH4AbxKZtG7Uidsa6GhW9ctfNaCzTm6LIQxAZliU7ryWsolf_Q_SXQLu_WXxyGIRM/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-A3%E3%82%AD%E3%83%AA%E3%83%B313%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmvfy6l_Q_bKO1udkI7Vh1aWj6wsaXJnY0iHpQpjykbN-O47H25GokLTLUwA5OmSyNvRa5RvSGqBtH4AbxKZtG7Uidsa6GhW9ctfNaCzTm6LIQxAZliU7ryWsolf_Q_SXQLu_WXxyGIRM/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-A3%E3%82%AD%E3%83%AA%E3%83%B313%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図1 △C1ヒヨコ打 まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<a name='more'></a><hr />
<table><tbody>
<tr><td style="vertical-align: top;"><br />
<h2>
<u>△C2ヒヨコからの手順</u></h2>
<br />
<b>
▲B4ライオン、△C2ヒヨコ、▲A4ライオン、△A2キリン<br />
▲A2同ゾウ、△B2ライオン、<br />
</b>
<br />
△C2ヒヨコ に対して先手はライオンが寄るかB3のゾウが引くしかないが、
ゾウが引くと△A2キリン、▲同ヒヨコ、△B2ライオン、▲B3キリン打、△A2ライオンと、
ヒヨコ得になり後手勝勢。<br />
▲C4ライオンはヒヨコ前でC3ヒヨコやC3キリン打などが危険なのでA4ライオンの一手。<br />
<br />
▲A4ライオンに対しては、△A2キリンと手前のゾウをとる。<br />
△B3キリンと奥のゾウをとっても手数は同じで後手の勝ちになる。<br />
△A2キリン に対して同ヒヨコは △B2ライオンで次の△A3キリン打と△C3ライオンの
両狙いが受けられないので▲同ゾウとする。
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8LjYje02xBHGo9ul2fdEht1W-Ju9L1r3H-x3kmr9zt9mZFdkPXxz_gxlHaE_0qC_at3HDOmXOddScHcQeyTEcfZ7tnChRXaceVA7idrDKjyt9TQpC4GuEvHCZCehyiOi8YXCTqpCMzmA/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-A3%E3%82%AD%E3%83%AA%E3%83%B319%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8LjYje02xBHGo9ul2fdEht1W-Ju9L1r3H-x3kmr9zt9mZFdkPXxz_gxlHaE_0qC_at3HDOmXOddScHcQeyTEcfZ7tnChRXaceVA7idrDKjyt9TQpC4GuEvHCZCehyiOi8YXCTqpCMzmA/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-A3%E3%82%AD%E3%83%AA%E3%83%B319%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図2 △B2ライオン まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<br />
<hr />
<table><tbody>
<tr><td style="vertical-align: top;"><br />
<h2>
<u>後手攻勢</u></h2>
<br />
<b>
▲B4キリン打、△C3ライオン、▲B3ゾウ、△B1ゾウ打<br />
▲C4キリン、△B2ライオン、▲B4ライオン、△C3キリン打<br />
</b>
<br />
△B2ライオン に対して先手は▲B4キリン打と受ける。<br />
▲B3キリンと受けると、
△C1ライオン、▲B4ライオン、△B2ゾウ打、▲同キリン という展開になる。<br />
<br />
後手はいったんライオンで敵陣を覗いてA2のゾウを引かせて△B1にゾウを打つ。<br />
そして△C3キリン打から仕掛けていく。
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglIwM7jtqAcZrruYZGi5uuhbuiXsqutqWtohUDVALekFrqr3sU4DWZ0JvE2PGEu7yTx03_88X2sDTMlOXHvExMZ5NYmdDcOTiWWdVVA6FvHfxzHFAolJGMthWAmM-6cDRdjB9Mt2KAoVo/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-A3%E3%82%AD%E3%83%AA%E3%83%B327%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglIwM7jtqAcZrruYZGi5uuhbuiXsqutqWtohUDVALekFrqr3sU4DWZ0JvE2PGEu7yTx03_88X2sDTMlOXHvExMZ5NYmdDcOTiWWdVVA6FvHfxzHFAolJGMthWAmM-6cDRdjB9Mt2KAoVo/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-A3%E3%82%AD%E3%83%AA%E3%83%B327%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図3 △C3キリン打 まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<br />
<hr />
<table><tbody>
<tr><td style="vertical-align: top;"><br />
<h2>
<u>後手勝ち</u></h2>
<br />
<b>
▲C3同キリン、△同ヒヨコ、▲A4ライオン、△C4ヒヨコ成<br />
▲同ゾウ、△C3ライオン、▲B4キリン打、△C2ゾウ<br />
▲B3ヒヨコ打、△B1ゾウ<br />
</b>
<br />
C筋でキリン交換後、△C4ヒヨコ成 とヒヨコをただ捨てにする。<br />
▲同ゾウに△C3ライオンは▲B4キリン打の一手。<br />
以下△B1ゾウで先手は手詰まり。<br />
<br />
以下は、▲A2ヒヨコなら△同ゾウ、▲A3ライオン、△B1ゾウ。<br />
▲B2ヒヨコなら△C2ゾウから△B3キリンがあり、後手の勝ち。
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi-fXGw-v_9WW_Q0kykxlRUVFpqZ00Ku6UjXHgtY9-UCHMor7QGnwSTo0iU2drv7phRNK8aEjYKY1CH9BXSKnMhGCPpZh0wVdPkLQBa86C6MBbv9sADpBAwpImdpKNU4CaAkCooMDqh-E/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-A3%E3%82%AD%E3%83%AA%E3%83%B337%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhi-fXGw-v_9WW_Q0kykxlRUVFpqZ00Ku6UjXHgtY9-UCHMor7QGnwSTo0iU2drv7phRNK8aEjYKY1CH9BXSKnMhGCPpZh0wVdPkLQBa86C6MBbv9sADpBAwpImdpKNU4CaAkCooMDqh-E/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-A3%E3%82%AD%E3%83%AA%E3%83%B337%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図4 △B1ゾウ まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<br />xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com2tag:blogger.com,1999:blog-3058535269160921661.post-41928322446411978282013-07-22T01:00:00.000+09:002013-07-29T04:09:26.147+09:00[どうぶつしょうぎ] ▲A4ゾウ -先手待機策- への対応 ▲B3ヒヨコ型<table><tbody>
<tr><td style="vertical-align: top;"><br />
前回、5手目に先手が ▲A4ゾウ と引く場合の変化を調べてみた。
<br />
<ul>
<li><a href="/2013/07/DoubutsuShougi-Kaiseki-A4Z.html" target="_blank">[どうぶつしょうぎ] ▲A4ゾウ -先手待機策- への対応</a></li>
</ul>
この後、△A3キリン、▲B3ゾウ という手順だったが、
実戦では △A3キリン に対して、ほとんどの場合先手は ▲B3ヒヨコ打 と応じてくるので、
この変化も調べておく。<br />
<br />
図1までの手順は、<br />
<br />
<b>
▲B2ヒヨコ、△同ゾウ、▲B3ゾウ、△A2キリン、<br />
▲A4ゾウ、△A3キリン、▲B3ヒヨコ打</b>
<br />
棋譜はこちらを参照(→ <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-b2Hb2Z-b3Za2K-a4Za3K-b3H.txt" target="_blank">棋譜</a> )
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZZLAatPBclfCKDXEvSH8nIZ1cFk4BA7YkdM67SJRCRIH3uNQrxTVeTQRuaZYVDvuozU9-8NileNP6HrvUIWpT7p4ugIFriFC86GqVU2fs9OnF3-7ke-0dlgwIk75bu5w44PPzbK8or3k/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9FB3%E3%83%92%E3%83%A8%E3%82%B3%E6%89%9307%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img alt="" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZZLAatPBclfCKDXEvSH8nIZ1cFk4BA7YkdM67SJRCRIH3uNQrxTVeTQRuaZYVDvuozU9-8NileNP6HrvUIWpT7p4ugIFriFC86GqVU2fs9OnF3-7ke-0dlgwIk75bu5w44PPzbK8or3k/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9FB3%E3%83%92%E3%83%A8%E3%82%B3%E6%89%9307%E6%89%8B%E7%9B%AE.png" title="" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図1 ▲B3ヒヨコ打 まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<a name='more'></a><br />
<hr />
<table><tbody>
<tr><td style="vertical-align: top;"><h2>
<u>後手 △C2ヒヨコ打</u></h2>
<br />
<b>
△C2ヒヨコ打、▲B2ヒヨコ、△同ライオン</b><br />
<br />
図1から後手は当たりのゾウを無視して△C2ヒヨコと打ち込む。<br />
<br />
図1では、△A4キリン、▲同ライオン としてからゾウを引く手がありそうだが、
引き分けの局面になってしまうので、△C2ヒヨコ打一択。<br />
<br /></td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgai-A9SkseJTGzab6yLXtAmBukJD-Z7FI5l53ENo_Su8Fgn59AOsG7DOvxhmvKW9E_dWC7xEBSkCFMpCuwC2Hhssc2iwCq6RuPgu6ni00z23b4D2vW_CqHs63Ol5d6UKndx8KKYbl4q3s/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9FB3%E3%83%92%E3%83%A8%E3%82%B3%E6%89%9311%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgai-A9SkseJTGzab6yLXtAmBukJD-Z7FI5l53ENo_Su8Fgn59AOsG7DOvxhmvKW9E_dWC7xEBSkCFMpCuwC2Hhssc2iwCq6RuPgu6ni00z23b4D2vW_CqHs63Ol5d6UKndx8KKYbl4q3s/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9FB3%E3%83%92%E3%83%A8%E3%82%B3%E6%89%9311%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図2 ▲B2 同ライオンまで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<hr />
<table><tbody>
<tr><td style="vertical-align: top;"><h2>
<u>▲A1ゾウで反撃</u></h2>
<br />
<b>
▲A1ゾウ打、△A2ライオン、▲C3キリン、△同ヒヨコ<br />
▲同ライオン、△A4キリン、▲C2ライオン、△B1キリン打
</b><br />
<br />
先手は▲A1ゾウ打と反撃するのが最善。<br />
後手はこのゾウをとると ▲A3ライオン とキリンをとられて逆転を許してしまうので、
△A2ライオンと寄る。<br />
<br />
有効手のない先手はC筋からキリンを捨ててトライを図るが、
先手はゾウをとった後で△B1キリンとトライを阻止して勝ち。<br />
<br />
ゾウをとる前に、△C1ヒヨコ打などの待ちゴマでも勝てる。<br />
以下終局までは <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-b2Hb2Z-b3Za2K-a4Za3K-b3H.txt" target="_blank">棋譜</a> を参照。
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5yI0rTH5AA-WeY94h4uAqEoK2upNMxsM3GNlAPbIeqswwdY8y6yLWTWidyFtK2QSh91SEVzVNULu4a4ZccI5Fq-SiF6kuIO1h7Y20I9KdPocOUchZXdXYDx9sYDhNkCygS_ejKYJP4Tw/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9FB3%E3%83%92%E3%83%A8%E3%82%B3%E6%89%9319%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5yI0rTH5AA-WeY94h4uAqEoK2upNMxsM3GNlAPbIeqswwdY8y6yLWTWidyFtK2QSh91SEVzVNULu4a4ZccI5Fq-SiF6kuIO1h7Y20I9KdPocOUchZXdXYDx9sYDhNkCygS_ejKYJP4Tw/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9FB3%E3%83%92%E3%83%A8%E3%82%B3%E6%89%9319%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図3 △B1キリン打まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<br />
<hr />
<table><tbody>
<tr><td style="vertical-align: top;"><h2>
<u>▲B3ゾウ打への対応</u></h2>
<br />
図2からの先手の応手としては ▲A1ゾウ打 の他に
▲B3ゾウ打もある。<br />
<br />
<b>
▲B3ゾウ打、△C3ヒヨコ打、▲同キリン、△同ヒヨコ<br />
▲C4ゾウ、△同ヒヨコ成、▲同ライオン、△A4キリン
</b><br />
<br />
▲B3ゾウ打 へは、△C3ヒヨコ打 とヒヨコの重ね打ちが厳しい。<br />
先手は同キリンと取るしかなく、△同ヒヨコ。<br />
この局面は、△B3キリン以下の詰めろになっているので、
先手は▲C4ゾウしかなく、以下一方的な展開になる。<br />
<br />
棋譜はこちらを参照(→ <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-b2Hb2Z-b3Za2K-a4Za3K-b3Hc2H-b2Hb2L-b3Z.txt" target="_blank">棋譜</a> )
<br />
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimEnIleoSH_s6D95DOrIEzF3hiBkG1364Ffc3V1Aaq-kLJOYCl04wNembT59Pc3HJ8vwSxyrrTKRe7Jo6TekDN2w7-EesHNAKJs0JgINvXjO-T1bPb6TIAOKC9um2oP27-cKScairTHjo/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9FB3%E3%83%92%E3%83%A8%E3%82%B3%E6%89%93B3%E3%82%BE%E3%82%A6%E5%9E%8B.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimEnIleoSH_s6D95DOrIEzF3hiBkG1364Ffc3V1Aaq-kLJOYCl04wNembT59Pc3HJ8vwSxyrrTKRe7Jo6TekDN2w7-EesHNAKJs0JgINvXjO-T1bPb6TIAOKC9um2oP27-cKScairTHjo/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9FB3%E3%83%92%E3%83%A8%E3%82%B3%E6%89%93B3%E3%82%BE%E3%82%A6%E5%9E%8B.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図4 △A4キリンまで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<br />xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-19424728945116263712013-07-13T01:00:00.000+09:002013-07-29T04:19:24.693+09:00[どうぶつしょうぎ] ▲A4ゾウ -先手待機策- への対応<table><tbody>
<tr><td style="vertical-align: top;"><br />
ヒヨコ交換後、△A2キリン を見て先手が ▲A4ゾウ と手を戻して様子見で来ることがある。<br />
<br />
図1までの手順は、<br />
<b>▲B2ヒヨコ、△同ゾウ、▲B3ゾウ、△A2キリン、<br />
▲A4ゾウ</b><br />
<br />
後手は間違わずに指せば24手の短手順で勝ちになるので確実に勝ち切りたい局面。<br />
<br />
正解は、△A3キリンとキリンを突き出す一手(→ <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-b2Hb2Z-b3Za2K-a4Z.txt" target="_blank">棋譜</a>)。<br />
<br />
△C2ライオン とライオンを上がりたくなる局面だが ▲B3ゾウ の反撃を受けてしまう。このあと <a href="http://xawa99.blogspot.jp/2013/04/DoubutsuShougi-Kaiseki-B2Hiyoko.html" target="_blank">相腰掛ゾウ基本定跡</a> に合流するので勝ち局面であることは変わらないが、手数も長くなりまぎれも多くなってしまう(→ <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-b2Hb2Z-b3Za2K-a4Zc2L.txt" target="_blank">棋譜</a>)。
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpZ7LvtoQ4HsKr3VSkdbm86qRv4IIRVwbhs6ZM_PuhoU6v8NrrJPytzHrKciBckX9MPBDNzFPGj2hyphenhyphenFnmDb5bmXmEormfhND6FI9rJzvDidYJpRShAwO9Gr3TtfODaK7L0Jz8uL99FxpU/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9F06%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpZ7LvtoQ4HsKr3VSkdbm86qRv4IIRVwbhs6ZM_PuhoU6v8NrrJPytzHrKciBckX9MPBDNzFPGj2hyphenhyphenFnmDb5bmXmEormfhND6FI9rJzvDidYJpRShAwO9Gr3TtfODaK7L0Jz8uL99FxpU/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9F06%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図1 ▲A4ゾウ まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<a name='more'></a><br />
<hr />
<table><tbody>
<tr><td style="vertical-align: top;"><h2>
<b><u>ゾウ打はキリン側 C2</u></b></h2>
<br />
<b>△A3キリン、▲B3ゾウ、△同キリン、<br />▲同ライオン、△C2ゾウ</b><br />
<br />
△A3キリン に対して先手は ▲B3ゾウ。<br />
ここで ▲C3キリン とした場合は、△A4キリン、▲同ライオン、△C3ゾウ でゾウ丸得になり後手必勝。<br />
<br />
△A3キリン に対して ▲B3ヒヨコ打 も有力な応手。むしろ直観的にはこちら。
▲B3ゾウ に比べて双方最善の場合、2手ほど短く終局してしまうが後手側の応手も難しい。<br />
この変化については以下の記事を参照。<br />
<ul>
<li><a href="/2013/07/DoubutsuShougi-Kaiseki-A4ZB3H.html" target="_blank">
▲A4ゾウ -先手待機策- への対応 ▲B3ヒヨコ型</a></li>
</ul>
<br /><br />
ゾウ-キリン 交換後、後手は2段目にゾウを打って先手ライオンを押し戻すが、ゾウの打つ場所が問題。<br />
次に先手ライオン側に後手ライオンが上がれるように 先手キリン側のC2にゾウを打つ。<br />
<br />
一見、△A2ゾウ としたくなるが、▲B4ライオン、△C3ヒヨコ打 以下引き分け局面になってしまう(→ <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-b2Hb2Z-b3Za2K-a4Za3K-b3Zb3K-b3La3Z.txt" target="_blank">棋譜)</a>。<br />
△C3ヒヨコ打 に替えて、△C2ライオンと出ても ▲C3キリン打 と受けられて以下引き分け。
(→ <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-b2Hb2Z-b3Za2K-a4Za3K-b3Zb3K-b3La3Z-b4Lc2L.txt" target="_blank">棋譜)</a>。</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX9a4TVKWbLziCu1pWuECPU0YJMzJzcemNmlNUUl8Dxpy1GhdPvyjN8jhXE9YyCiZ15BJHFZZfEaIQ0Qg05WUFrL2DbQCnXambXUbZbZUuhDMpGRuEQHgUFoUv9R4b85GybqCHW9WSj2A/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9F11%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX9a4TVKWbLziCu1pWuECPU0YJMzJzcemNmlNUUl8Dxpy1GhdPvyjN8jhXE9YyCiZ15BJHFZZfEaIQ0Qg05WUFrL2DbQCnXambXUbZbZUuhDMpGRuEQHgUFoUv9R4b85GybqCHW9WSj2A/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9F11%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図2 △C2ゾウ まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<br />
<hr />
<table><tbody>
<tr><td style="vertical-align: top;"><h2>
<b><u>後手勝ち</u></b></h2>
<br />
<b>
▲A4ライオン、△A2ライオン、▲C3キリン打、△同ゾウ、<br />
▲同キリン、△A3キリン打、▲B4ライオン、△C3ゾウ</b><br />
<br />
先手はA4にライオンを引き、後手はA2にライオンが進出する。<br />
次に後手にB3ゾウや、A3ヒヨコ打があるので先手はB3キリン打と受けざるを得ない。<br />
以下、ゾウヒヨコ交換から△C3ゾウまで進む。<br />
<br />
△A4キリンの詰めろになっており、▲B3キリンとしても△同キリン以下簡単な詰みなので、先手万事休す。<br />
以下は <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-b2Hb2Z-b3Za2K-a4Z.txt" target="_blank">棋譜</a> 参照。
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9cFKzarBTUJgGxjkFubzuTA1MkMZxolrO9G1GjN73D-mT255jGTv21xG68ljR1UdNULJP7DdM5L9dynI-h9YYSHNwOm4AcW5TJcAhO0i_PZI_A-h85SB6OIiTt7_z6DbHA_4VSD81A_Q/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9F19%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9cFKzarBTUJgGxjkFubzuTA1MkMZxolrO9G1GjN73D-mT255jGTv21xG68ljR1UdNULJP7DdM5L9dynI-h9YYSHNwOm4AcW5TJcAhO0i_PZI_A-h85SB6OIiTt7_z6DbHA_4VSD81A_Q/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E5%85%88%E6%89%8B%E5%BE%85%E6%A9%9F19%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図3 △C3ゾウ まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<br />
<hr />
<h2>
<b><u>先手▲B4ライオンの変化</u></b></h2>
<br />
図2から先手がB4にライオンを引いた場合の変化。<br />
▲A4ライオンの時と同様に△A2ライオンと出る。<br />
ここで▲C3キリン打に対して、△B3ヒヨコ打の王手が痛打になる。<br /><br />
▲同キリンは△同ゾウ、<br/>
▲A4ライオンと逃げても△C3ゾウとキリンをとって、<br />
▲A3ヒヨコ打、△B2ライオン、▲C3キリン、△同ライオン以下後手トライ勝ち。<br />
<br /><br />xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-22405057811824108902013-07-07T01:00:00.000+09:002013-07-07T01:00:00.743+09:00[どうぶつしょうぎ] 完全解析ツールを引き分け局面の追跡に対応させてみる田中先生の<a href="http://media.itc.u-tokyo.ac.jp/ktanaka/dobutsushogi/" target="_blank">どうぶつしょうぎ完全解析ツール</a>の checkState コマンドは、開始局面が引き分け局面だとその時点で手順の追跡を打ち切ってしまい、引き分けに至る手順は出力されない。
<br />
そこで、引き分け局面でも手順が出力されるように checkState コマンドを改造してみた。<br />
<br />
<ul>
<li>引き分け局面を発見したら探索を終了するロジックを除去</li>
<li>引き分け局面の追跡では、通過した局面を覚えておいて通過済み局面に到達したら追跡終了</li>
</ul><br />
という作戦で行く。<br />
ざっと読んでみた感じだと、<code>winLoseTable.cc</code> (と <code>winLoseTable.h</code> ) に手を入れれば何とかなりそう。
<br /><br />
<a name='more'></a>
<hr />
<h2>WinLoseTable::showSequence</h2>
<br />
解析結果の出力は、<code>winLoseTable.cc</code> 内に定義されている、<code>WinLoseTable::showSequence</code> で行っている。<br /><br />
与えられた現局面と可能な次手を出力し、最善手を選択してその手を適用した新局面で再帰的に <code>WinLoseTable::showSequence</code> を実行する。<br />
<code>WinLoseTable::showSequence</code> の冒頭で局面の勝ち負け判定を行い、最終局面および引き分け局面であれば終了するようになっているので、引き分け局面で終了しないようにする。<br />
<br />
次に、勝ち局面、負け局面それぞれで最善手選択、<code>showSequence</code> 再帰呼び出しを行っているので、ここに引き分け局面用の手順を追加する。通過局面記憶用の <code>set</code> を作成して、引き分け専用に新設した<code>showDrawSequence</code> 呼び出しをする。
<br /><br />
<hr />
<h2>WinLoseTable::showDrawSequence</h2>
<br />
新設した <code>showDrawSequence</code> では、最初に与えられた局面が通過局面か否かを判定し、新局面であれば通過局面リストに追加したのち、局面と次手の出力、最善手の選択、適用後の新局面での <code>showDrawSequence</code> 再起呼び出しを行う。<br />
<br />
引き分け局面では双方が最善を尽くしていれば勝ちになる手は出現しないので、次手は「引き分け」か「負け」になる手なので、「引き分け」になる手を双方選択し続けることになる。
<br /><br />
<hr />
<h2>結果</h2>
<br />
期待通りに引き分け局面でも再度同じ局面が登場するまで追跡するようになった。<br /><br />
が、解析結果テーブルでは、引き分け局面は終局までの手数が常に「0」扱いになるため、引き分けになる手が複数あった場合に、「最短でループする手」を選択することができず、最初に見つかった「引き分けになる手」を選択することになる。<br />
<br />
そのため、出力結果がややgdgdになる傾向があるが、多少なりとも役には立つと思う。
<br /><br />
<hr />
<h2>パッチ</h2>
<br />
winLoseTable.h:<br />
<pre class="brush: cpp highlight: [1]">
$ diff -u dobutsu-org/winLoseTable.h dobutsu
--- dobutsu-org/winLoseTable.h 2009-06-29 20:28:40.000000000 +0900
+++ dobutsu/winLoseTable.h 2013-06-30 13:39:11.387990571 +0900
@@ -2,6 +2,7 @@
#define _WIN_LOSE_TABLE_H
#include "dobutsu.h"
#include "allStateTable.h"
+#include <set>
class WinLoseTable {
AllStateTable const& allS;
@@ -37,5 +38,6 @@
int getWinLose(State const& s, int& wlc) const;
int getWinLose(State const& s, Move const& m,int& wlc) const;
void showSequence(State const& s) const;
+ void showDrawSequence(State const& s, set<int>& pastSeq) const;
};
#endif
</pre>
<br />
winLoseTable.cc:<br />
<pre class="brush: cpp highlight: [1]">
$ diff -u dobutsu-org/winLoseTable.cc dobutsu
--- dobutsu-org/winLoseTable.cc 2009-06-29 20:28:40.000000000 +0900
+++ dobutsu/winLoseTable.cc 2013-06-30 13:47:28.079978110 +0900
@@ -90,22 +90,10 @@
std::cerr << s << std::endl;
std::cerr << (int)(s.turn==BLACK ? getWinLose(index) : -getWinLose(index)) <<
"(" << (int)getWinLoseCount(index) << ")" << std::endl;
- if(getWinLoseCount(index)==0){
- if(getWinLose(index)==0){
- vMove moves=s.nextMoves();
- for(size_t i=0;i<moves.size();i++){
- int wl,wlc;
- wl=getWinLose(s,moves[i],wlc);
- std::cerr << i << " : " << moves[i] << " " << wl << "(" << wlc << ")" << std::endl;
- }
- }
+
+ if(getWinLoseCount(index)==0 && getWinLose(index)!=0){
return;
}
- if(getWinLose(index)==0){
- std::cerr << s << std::endl;
- std::cerr << "winLose=0" << std::endl;
- throw InconsistentException();
- }
vMove moves=s.nextMoves();
for(size_t i=0;i<moves.size();i++){
int wl,wlc;
@@ -130,8 +118,7 @@
throw InconsistentException();
}
}
- else{
- assert(getWinLose(index)==1);
+ else if(getWinLose(index)==1){
if(wl==-1){
if(getWinLoseCount(index)-1==wlc){
std::cerr << "Move : " << moves[i] << " " << wl << "(" << wlc << ")" << std::endl;
@@ -144,6 +131,58 @@
throw InconsistentException();
}
}
+ } else {
+ assert(getWinLose(index)==0);
+ if(wl==0){
+ std::cerr << "Move : " << moves[i] << " " << wl << "(" << wlc << ")" << std::endl;
+ State news(s);
+ news.applyMove(moves[i]);
+ set<int> pastSeq;
+ showDrawSequence(news, pastSeq);
+ break;
+ }
+
+ }
+
+ }
+}
+
+void WinLoseTable::showDrawSequence(State const& s, set<int>& pastSeq) const
+{
+ if(!s.isConsistent()) throw InconsistentException();
+ uint64 v=s.normalize();
+ int index=allS.find(v);
+ assert(getWinLose(index)==0);
+ if (pastSeq.find(index) != pastSeq.end()) {
+ std::cerr << std::endl;
+ std::cerr << "--- " << pastSeq.size() << std::endl;
+ return;
+ }
+ pastSeq.insert(index);
+
+ std::cerr << "------------------" << std::endl;
+ std::cerr << s << std::endl;
+ std::cerr << (int)(s.turn==BLACK ? getWinLose(index) : -getWinLose(index)) <<
+ "(" << (int)getWinLoseCount(index) << ")" << std::endl;
+
+ vMove moves=s.nextMoves();
+ for(size_t i=0;i<moves.size();i++){
+ int wl,wlc;
+ wl=getWinLose(s,moves[i],wlc);
+ std::cerr << i << " : " << moves[i] << " " << wl << "(" << wlc << ")" << std::endl;
+ }
+ for(size_t i=0;i<moves.size();i++){
+ int wl,wlc;
+ wl=getWinLose(s,moves[i],wlc);
+ if(wl==-1){
+ throw InconsistentException();
+ }
+ if(wl==0){
+ std::cerr << "Move : " << moves[i] << " " << wl << "(" << wlc << ")" << std::endl;
+ State news(s);
+ news.applyMove(moves[i]);
+ showDrawSequence(news, pastSeq);
+ break;
}
}
}
</pre>xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-77647132243419756222013-07-06T18:10:00.000+09:002013-07-06T18:10:00.350+09:00UUID の Version の見分け方UUID には いくつかのバージョンがあり、生成方法が定められている。
<ul>
<li><a href="http://ja.wikipedia.org/wiki/UUID" target="_blank">UUID - Wikipedia -</a></li>
<li><a href="http://tools.ietf.org/html/rfc4122" target="_blank">RFC4112 - IETF -</a></li>
</ul>
<br />
現在定義されているバージョンは以下の5つ。
<br /><br />
<table class=standard frame="box" rules="all">
<thead style="background: #D5D5D5"><td>Version</td><td>生成方法</td></tr>
<tbody><tr><td>1</td>
<td>MAC-Address と 生成時刻によるもの</td></tr>
<tr><td>2</td>
<td>DCE Security version</td></tr>
<tr><td>3</td>
<td>名前(byte列)のMD5 ハッシュによるもの</td></tr>
<tr><td>4</td>
<td>ランダム</td></tr>
<tr><td>5</td>
<td>名前(byte列)の SHA-1 ハッシュによるもの</td></tr>
</tbody></table>
<br />
<br />
UUID の形式は以下のようになっている。<br /><br />
<pre class="code">
xxxxxxxx-xxxx-<b style="color:red">V</b>xxx-xxxx-xxxxxxxxxxxx
</pre>
<br />
赤字の「V」のところがバージョン番号。
<br />
<br />
<a name='more'></a>
<hr />
<h2>バージョン4</h2>
<br />
Java の標準ライブラリで生成できるのは、Version 4 と Version 3 の2つ。<br />
まずは、Version 4。<br />
<code>UUID.randomUUID()</code> で生成する。<br />
<br />
<pre class="brush: java">
for (int i = 0; i<10; i++) {
UUID uuid = UUID.randomUUID();
System.out.println(uuid);
}
</pre>
<br />
<pre class="code">
b048c6b3-b36f-4c8d-97ea-96828a50a44c
84e291f7-4b37-4767-97c2-b0fea0fc5936
94cc812c-727f-49b0-85dd-e65a9afdeb65
99d57582-dd58-46cc-81e9-1449f2bfd761
ccd8505e-3fff-4a50-b671-d9adce7e896c
e6bf67b4-5f5a-4d37-aa26-f69aa670d747
a87db9b3-cd3c-4a80-a224-a809bf51905b
9639dca5-9bb0-4507-9baa-6bb07ba674e8
e95f8e5e-585d-4cd0-8751-beb0e183d3d2
0e99f22c-5608-4db9-a2b8-2c81c284b164
</pre>
<br />
バージョン番号の部分だけ常に4になっている。
<br /><br />
<hr />
<h2>バージョン3</h2>
<br />
次に、Version 3。<br />
Version 3 は 生成元になる byte 列を与えて、<br />
<code>UUID.nameUUIDFromBytes(bytes)</code> で生成する。<br />
<br />
<pre class="brush: java">
Random rnd = new Random(System.currentTimeMillis());
for (int i = 0; i<10; i++) {
byte[] bytes = new byte[10];
rnd.nextBytes(bytes);
UUID uuid = UUID.nameUUIDFromBytes(bytes);
System.out.println(uuid);
}
</pre>
<br />
<pre class="code">
736dd106-0e66-3210-bc16-62fb09bb8240
40f13c0b-c669-36b8-adb1-f545254d84f5
521ce8b4-731c-3fb0-adf7-3c224ae30883
81c30ad9-aac4-3aed-9865-2160f6913f8e
01da84aa-9805-352d-ab17-8c36620f9a4b
8bb1af96-e9d7-3770-8f77-9ec7a7f1e87a
de5b8017-f80e-3433-b7c8-5a8fed4afe22
9538654f-cd0b-3527-9d99-f4197a071afc
e7a00f80-0e01-316b-bcf2-b0f3764a576d
17276e00-279b-3049-b19f-205568a3cb72
</pre>
<br />
バージョン番号の部分だけ常に3になっている。
<br /><br />
<hr />
<h2>バージョン1</h2>
<br />Version 1 の UUID は、Java の標準ライブラリでは生成できない。<br />
<a href="http://johannburkard.de/software/uuid/">http://johannburkard.de/software/uuid/</a> の UUID Generator を使ってみる。
<br />
<br />
<pre class="brush: java">
for (int i = 0; i<10; i++) {
com.eaio.uuid.UUID uuid = new com.eaio.uuid.UUID();
System.out.println(uuid);
}
</pre>
<br />
<pre class="code">
cb251350-e0a0-11e2-99aa-XXXXXXXXXXXX
cb251351-e0a0-11e2-99aa-XXXXXXXXXXXX
cb251352-e0a0-11e2-99aa-XXXXXXXXXXXX
cb251353-e0a0-11e2-99aa-XXXXXXXXXXXX
cb251354-e0a0-11e2-99aa-XXXXXXXXXXXX
cb251355-e0a0-11e2-99aa-XXXXXXXXXXXX
cb251356-e0a0-11e2-99aa-XXXXXXXXXXXX
cb251357-e0a0-11e2-99aa-XXXXXXXXXXXX
cb251358-e0a0-11e2-99aa-XXXXXXXXXXXX
cb251359-e0a0-11e2-99aa-XXXXXXXXXXXX
</pre>
<br />
バージョン1のUUIDが生成できた。<br />
XXXXX の部分は 実際は、MACアドレスが入っている。
<br />
<br />
生成間隔を少し空けてみる。
<br /><br />
<pre class="brush: java" highlight="[4]">
for (int i = 0; i<10; i++) {
com.eaio.uuid.UUID uuid = new com.eaio.uuid.UUID();
System.out.println(uuid);
Thread.sleep(100);
}
</pre>
<br />
<pre class="code">
15641320-e0a2-11e2-a4a2-XXXXXXXXXXXX
15735560-e0a2-11e2-a4a2-XXXXXXXXXXXX
158297a0-e0a2-11e2-a4a2-XXXXXXXXXXXX
1591d9e0-e0a2-11e2-a4a2-XXXXXXXXXXXX
15a11c20-e0a2-11e2-a4a2-XXXXXXXXXXXX
15b05e60-e0a2-11e2-a4a2-XXXXXXXXXXXX
15bfa0a0-e0a2-11e2-a4a2-XXXXXXXXXXXX
15cee2e0-e0a2-11e2-a4a2-XXXXXXXXXXXX
15de2520-e0a2-11e2-a4a2-XXXXXXXXXXXX
15ed6760-e0a2-11e2-a4a2-XXXXXXXXXXXX
</pre>
<br />
生成間隔をあけると生成時刻のフィールドの間隔も変わる。<br />
先ほどは time-low 部の末尾が0からインクリメントされていたが、
今回は常に0になっている。<br />
同一ID生成を防ぐために予備フィールドを持っていて、
前回生成時のIDを覚えておき、
同じ時刻に生成された場合にはインクリメントするようになっているのだろう。
<br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-5174826344065662572013-07-01T01:00:00.000+09:002013-07-02T16:22:51.940+09:00Google Apps Script から Twitter を使うGoogle Apps Script から Twitter API を使ってみよう。<br />
今回の目標は、Google Apps Script から Twitter の認証を経由して
Tweet することにする。
<br /><br />
<hr />
<h2>Callback URLの指定</h2>
<br />
まず、Twitter の <a href="https://dev.twitter.com/apps" target="_blank">連携アプリケーション管理画面</a> で
Google Apps Script 用に Callback URL を設定する。<br /><br />
<pre class="code">
<code><b style="color:red">https://spreadsheets.google.com/macros/</b></code>
</pre>
<a name='more'></a>
<br /><br />
<hr />
<h2>Consumer key と Consumer secret の設定</h2>
<br />
Google ドキュメント(今回は Spread Sheet)に Script 用のプロジェクトを作成し、
プロジェクトプロパティを設定する。<br />
プロジェクトプロパティ は、スクリプト エディタ の「ファイル>プロジェクトのプロパティ…」から設定する。
ユーザープロパティとプロジェクトのプロパティがあるが指定するのは「プロジェクトのプロパティ」。
<br /><br />
ここでは以下の2つのキーを設定する。
<ul>
<li>twitterConsumerKey: コンシューマーキー</li>
<li>twitterConsumerSecret: コンシューマーシークレット</li>
</ul>
<br />
ここで指定した値は、スクリプトからは、
<pre class="brush: javascript">
oAuthConfig.setConsumerKey(
ScriptProperties.getProperty("twitterConsumerKey"));
oAuthConfig.setConsumerSecret(
ScriptProperties.getProperty("twitterConsumerSecret"));
</pre>
のように指定できる。<br />
キーとシークレットをoAuthConfig.setConsumerKey("XXXX") とコードに直接書いてももちろん動作する。<br />
<br />
<hr />
<h2>OAuth 認証をして Tweetする</h2>
<br />
コードはこんな感じ。<br />
<pre class="brush:javascript">
function oAuthTest() {
var oAuthConfig = UrlFetchApp.addOAuthService("twitter");
oAuthConfig.setAccessTokenUrl("https://api.twitter.com/oauth/access_token");
oAuthConfig.setAuthorizationUrl("https://api.twitter.com/oauth/authorize");
oAuthConfig.setRequestTokenUrl("https://api.twitter.com/oauth/request_token");
oAuthConfig.setConsumerKey(ScriptProperties.getProperty("twitterConsumerKey"));
oAuthConfig.setConsumerSecret(ScriptProperties.getProperty("twitterConsumerSecret"));
var payload = {
"status": "test from Google Apps " + new Date().getTime()
}
var options = {
"method" : "POST",
"oAuthServiceName" : "twitter",
"oAuthUseToken" : "always",
"payload" : payload
};
var result = UrlFetchApp.fetch(
"https://api.twitter.com/1.1/statuses/update.json", options);
Logger.log("result of RequestToken: " + result);
}
</pre>
<br />
<code>UrlFetchApp.addOAuthService</code> で取得した <code>OAuthConfig</code> に
アクセス先のURLやコンシューマキー/シークレット を設定して、
Twitter の REST API にアクセスすれば、
認証画面が表示されて認証が完了する。<br />
<br />
<pre class="code">
...
"status": "こんにちは① " + new Date().getTime()
...
</pre>
のように日本語でも大丈夫。<br />
<br />
Twitter の REST API v1.1 の Documentation は こちらから。<br />
<ul>
<li><a href="https://dev.twitter.com/docs/api/1.1">Twitter REST API v1.1 Resources</a></li>
</ul>
<br />
ちなみに、UrlFetchApp.fetch を GETリクエストで使うときには、
options から method と payload を除去して、<br />
<pre class="brush: javascript">
var result = UrlFetchApp.fetch(
"https://XXXXX?" + encodeURIComponent(str));
</pre>
<br />
のように、<code>encodeURIComponent</code> を使うとよいみたい。
<br />
<br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-59110092855560237892013-06-23T01:00:00.000+09:002013-06-30T16:43:21.871+09:00Play Framework から Twitter4J を使う。Twitter 上でのログイン込みで OAuth 認証をを、
Play Framework で Twitter4J を使って試してみる。
せっかく Play を 2.1.1 に上げたところなので、
Play 2.1 の新機能である Filter 機能を使ってみよう。<br />
<br />
アプリにアクセスすると Twitter の認証画面が出て、
認証すると Tweet するような感じで作ってみる。<br />
<br />
<a name='more'></a>
<hr />
<h2>準備</h2><br />
<u>CallbackUrl の設定</u><br /><br />
Twitter の認証画面から Play の Webアプリに戻ってくるので、
Twitter の <a href="https://dev.twitter.com/apps" target="_blank">連携アプリケーション管理画面</a> で
アプリケーションに Callback URL を設定する。<br />
今回は ローカルPCで動いているWebアプリなのでCallback先としてローカルホストを指定する。<br />
localhost や localhost.localdomein を指定するとエラーになるので、127.0.0.1 を使う。<br />
ここでは、<code>http://127.0.0.1:9000/authCallback</code>を指定。<br />
<br />
<u>Twitter4J の準備</u><br /><br />
play new xxx でアプリケーションを作成後、Twitte4J への dependency を追加する。<br />
lib ディレクトリを作成して jar を入れるという方法もあるそうだが、
<code>Build.scala</code> にdependency を追加することにした。
<pre class="brush: scala highlight:[6]">
...
val appDependencies = Seq(
// Add your project dependencies here,
jdbc,
anorm,
"org.twitter4j" % "twitter4j-core" % "3.0.3"
)
...
</pre>
<br />
こうしておくと、Play run したときに Maven の セントラルリポジトリ から自動的に持ってくる。<br />
持ってきたライブラリは Play のリポジトリのローカルキャッシュに保存される。<br />
Twitter4J の最新は 3.0.4 になっているが、セントラルリポジトリには配備されていないようなので 3.0.3 を使用。
<br/>
「"org.twitter4j" % "twitter4j-core" % "3.0.3"」という構文は Scala の構文にはないので、
import している sbt あたりで定義されている演算子 なのだろう。
<br /><br />
<hr />
<h2>routes と TwitterHolder </h2><br />
TwittするAction、認証のCallBackを受け取るアクション、ログアウトするActionの3つを用意する。<br />
conf/routes はこんな感じ。
<pre class="brush: plain">
...
GET / controllers.Application.index
GET /authCallback controllers.Application.authCallback
GET /logout controllers.Application.logout
...
</pre>
<br />
Callback が挟まるため、リクエストを越えて Twitter や RequestToken インスタンスを保持する必要があるので、
それらの保持用のオブジェクトを作っておく。
<pre class="brush: scala">
package twittertest
import twitter4j._
import twitter4j.auth._
object TwitterHolder {
val CONSUMER_KEY = "xxxxxx";
val CONSUMER_SECRET = "yyyyyyyyyyyyyy";
private var twitter : Twitter = null;
def getTwitter() : Twitter =
if (twitter == null) getNewTwitter() else twitter;
def getNewTwitter() : Twitter = {
shutdown;
twitter = (new TwitterFactory()).getInstance();
twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
return twitter;
}
private var requestToken : RequestToken = null;
def setRequestToken(aRequestToken : twitter4j.auth.RequestToken) {
requestToken = aRequestToken;
}
def getRequestToken = requestToken;
private var accessToken : AccessToken = null;
def setAccessToken(aAccessToken : AccessToken) {
accessToken = aAccessToken;
}
def getAccessToken = accessToken;
def shutdown {
if (twitter != null) twitter.shutdown();
twitter = null;
requestToken = null;
accessToken = null;
}
}
</pre>
<br />
Twitter 側の認証画面でエラーになったりして、RequestToken は作ったが AccessToken がなくなったり、
認証が切れて AccessToken が無効になったりした場合には、
現在の Twitter オブジェクトを破棄して (new TwitterFactory()).getInstance() で新たに Twitter オブジェクトを生成しなおす。
<br /><br />
<hr />
<h2>Filter の実装</h2><br />
Filter は play.api.mvc.Filter から派生して作る。
<br />
<pre class="brush: scala">
import play.api._
import play.api.mvc._
import twitter4j._
import twittertest.TwitterHolder;
object Global extends WithFilters(
AuthFilter("authCallback", "logout")) with GlobalSettings;
object AuthFilter {
def apply(withoutAuthActions : String*) =
new AuthFilter(withoutAuthActions);
}
class AuthFilter(withoutAuthActions : Seq[String]) extends Filter {
import AuthFilter._;
override def apply(next : (RequestHeader) => Result)
(request : RequestHeader) : Result = {
val actionInvoked: String
= request.tags.getOrElse(play.api.Routes.ROUTE_ACTION_METHOD, "")
println("AuthFilter called: " + actionInvoked);
if (needsAuth(request)) {
auth(request);
} else {
next(request);
}
}
private def needsAuth(request : RequestHeader) : Boolean = {
val actionInvoked: String = request.tags.getOrElse(
play.api.Routes.ROUTE_ACTION_METHOD, "")
if (! withoutAuthActions.contains(actionInvoked)) {
return TwitterHolder.getAccessToken == null;
} else {
return false;
}
}
private def auth(request : RequestHeader) : Result = {
val twitter = TwitterHolder.getNewTwitter();
val requestToken : twitter4j.auth.RequestToken = twitter.getOAuthRequestToken();
TwitterHolder.setRequestToken(requestToken);
controllers.Default.Redirect(requestToken.getAuthorizationURL());
}
}
</pre><br />
作成したフィルタオブジェクトは、Global オブジェクトに登録しておくことで リクエストごとに Play Framework から apply が実行される。
フィルタを複数作ったり、グローバルオブジェクトにほかの設定をしたりすることもあるので、
普通は Global オブジェクトの作成はこんなところについでみたいに書かないでちゃんとしたところに書くのだろうが、
今回はここに書いておいた。<br />
<br />
<a href="http://www.playframework.com/documentation/2.1.1/ScalaInterceptors" target="_blank">Play Framework の Filter のサンプル</a> では、「認証が必要な Action を指定して」 Filter を作るようになっているが、
全体に認証を書けるようなアプリでは、上のように 認証を実行するAction のように「認証を必要としない Action」を指定するほうがいいと思う。<br />
認証が必要なら、<code>RequestToken</code>を取得して Twitter の認証画面にリダイレクトする。
リダイレクトは、デフォルトコントローラを使って行う。<br />
<br /><br />
<hr />
<h2>Action の実装</h2><br />
Application.scala はこんな感じ。<br />
<pre class="brush: scala">
package controllers
import play.api._
import play.api.mvc._
import twitter4j._;
import twitter4j.auth._;
import twittertest.TwitterHolder;
object Application extends Controller {
def index = Action {
val twitter = TwitterHolder.getTwitter();
val message = "Tweet from Play " + scala.compat.Platform.currentTime;
twitter.updateStatus(message);
Ok(views.html.index(message));
}
def authCallback = Action.apply { request =>
val twitter = TwitterHolder.getTwitter();
val authToken : String = request.queryString.get("oauth_token").get.head;
val authVerifier : String = request.queryString.get("oauth_verifier").get.head;
val accessToken : AccessToken = twitter.getOAuthAccessToken(TwitterHolder.getRequestToken, authVerifier);
twitter.verifyCredentials();
TwitterHolder.setAccessToken(accessToken);
Redirect("/");
}
def logout = Action.apply { request =>
TwitterHolder.shutdown;
Redirect("/");
}
}
</pre>
<br />
Callback 処理アクション( authCallback ) ではQueryString の <code>oauth_verifier</code> に渡ってくる verifier を使って AccessToken を作成し、verifyCredentials で確認したのちに TwitterHolder に格納して / にリダイレクトする。<br /><br />
index アクションに来たときには もう認証は終わっているはずなので Twitter オブジェクトを取得してupdateStatus する。現在時刻が付加されているのは Twitter の同一内容Tweet拒否機能避け。<br /><br />
再度認証するときには、/logout を実行して認証情報を削除する。
<br /><br />
index.scala.html は以下の通り。
<pre class="brush: html">
@(message: String)
<!DOCTYPE html>
<html><body>
@message<br />
<a href="/"> again </a><br />
<a href="/logout"> logout </a>
</body></html>
</pre>
<br /><br />
<hr />
今回は認証情報をアプリケーションレベルで保持しているので、すべてのセッションで同じログインになってしまう。<br />
ちゃんと実装するなら、セッションごとにセッションIDを発行して、セッションIDをキーにして Cache に そのセッション用のTwitterHolder のインスタンスを保持するようにしないといけない。<br /><br />
Play Framework 自体は ステートレス施行だが、この手のリクエストをまたがってオブジェクトを使うようなライブラリを使う場合には ステートフルにならざるを得ない。<br /><br />
<a href ="http://www.playframework.com/documentation/2.1.1/ScalaOAuth" target="_blank">
Play Framework の OAuth サンプル</a> では Sesssion Cookie の Secret 情報も含めて載せてしまっているようだ。このあたりも今度見てみよう。
</br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-81329773068649791352013-06-22T01:00:00.000+09:002013-06-22T01:00:05.824+09:00[Play] Play 2.0.3 から Play 2.1.1 へバージョンアップ最近 これまで使っていた Play 2.0.3 のバージョンを変えていなかったので、
Play 2.1.1 にバージョンアップしたらいろいろ動かなくなった。<br />
そもそもコンパイルが通らない。<br />
<br />
<pre class=code>
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: UNRESOLVED DEPENDENCIES ::
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn] :: play#sbt-plugin;2.0.3: not found
[warn] ::::::::::::::::::::::::::::::::::::::::::::::
[warn]
[warn] Note: Some unresolved dependencies have extra attributes.
Check that these dependencies exist with the requested attributes.
[warn] play:sbt-plugin:2.0.3 (sbtVersion=0.12, scalaVersion=2.9.2)
[warn]
sbt.ResolveException: unresolved dependency:
play#sbt-plugin;2.0.3: not found
</pre>
<br />
いくつか手を入れないといけなかったのでメモ。
<ul>
<li><a href="http://www.playframework.com/documentation/2.1.0/Migration" target="_blank">
Play Framework の Migration Guide</a></li>
<li><a href="http://d.hatena.ne.jp/k4200/20130414/1365906535" target="_blank">
Play! 2.0から2.1にアップデート</a> - k4200’s notes and thoughts<br />
アップデート作業について記載されている。今回はここにお世話になりました。
</li>
</ul>
<a name='more'></a>
<br /><br />
<hr />
<h2>build.properties と plugins.sbt の修正</h2>
<br />
まずは、project ディレクトにある <code>build.properties</code> と
<code>plugins.sbt</code> に記載されている
sbt と sbt-plugin のバージョンを修正する。
<br /><br />
<pre class=code>
<b><code>build.properties</code></b>
sbt.version=<b style="color:red">0.12.2</b>
</pre>
<br />
<pre class=code>
<b><code>plugins.sbt</code></b>
// Comment to get more information during initialization
logLevel := Level.Warn
// The Typesafe repository
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
// Use the Play sbt plugin for Play projects
addSbtPlugin("play" % "sbt-plugin" % "<b style="color:red">2.1.1</b>")
</pre>
<br />
もとの値は <code>0.11.3</code> と <code>2.0.3</code>。<br />
Migration Guide には sbt-plugin は 2.1.0 と記載されているが、
これは Play 2.1.0 の情報で今入れている Play は 2.1.1 なので、
sbt-plugin は 2.1.1 を指定する。<br />
<br />
<code>Play new hoge</code> で新規にプロジェクトを作ってそこからコピーするのが確実。
<br /><br />
<hr />
<h2><code>Build.scala</code> の修正</h2>
<br />
project ディレクトにある <code>Build.scala</code> を修正する。<br />
<br />
Play 2.0 の <code>PlayProject</code> オブジェクト が
Play 2.1 で <code>play.Project</code> に変更になり、apply() の引数も変わったことに対する対応をする。<br />
dependencies も jdbc と anorm を明示的に指定する必要があるようになったのでこれも対応する。
<br /><br />
<pre class=code>
<b><code>Build.scala</code></b>
import sbt._
import Keys._
<b style="color:red">import play.Project._</b>
object ApplicationBuild extends Build {
val appName = "sessiontest"
val appVersion = "1.0-SNAPSHOT"
val appDependencies = Seq(
// Add your project dependencies here,
<b style="color:red">jdbc, anorm</b>
)
val main = <b style="color:red">play.Project</b>(
<b style="color:red">appName, appVersion, appDependencies</b>).settings(
// Add your own project settings here
)
}
</pre>
<br />
play.Project() の引数は、Play 2.0 では第4引数に <code>mainLang = SCALA</code> を指定していたが、
これはなくなった。<br />
<br />
あとは、<code>play clean</code> をして <code>play run</code> で動くはずなのだが、
Play 2.0 でのコンパイル済のファイルが残っている影響か、以前 eclipsify した影響か play.Project が見つからない旨のエラーがでて Build.scala のコンパイルに失敗するので、
.cache、.project、.classpath、.settings/、.target/、bin、target、project/project、project/target など、
Play 2.1 で存在しない2次的なファイルやフォルダを消すことで動作することができるようになった。
<br /><br />
他にも Scala のバージョンが変わったことによる対応などが必要なこともあるようだが、
今回はこれだけで移行できた。<br />
その他の詳細は上記のリンク先を参照。<br />
<br />
無理に互換性がなくなるような変更をしなくてもよさそうな内容なのだが、
まだまだ発展途上でいろいろ変わるよ、ということなのだろうか?<br />
<br />
<hr />
<h2><code>play.Project</code> の謎</h2>
<br />
Build.scala の <code>play.Project()</code> のところは、
単に <code>Project</code> と書いても動きそうなものだが、引数の型が違うというエラーになり、
コンパイルが通らない。<br />
どうもほかのクラス(オブジェクト)として解釈されているようだ。
気になったので調べてみた。<br />
<br />
Build.scala の <code>main</code> の中身を少し細工して何が生成されているのかを見てみた。
<br /><br />
<pre class=code>
val main = {
val proj = play.Project(appName, appVersion, appDependencies).settings(
// Add your own project settings here
);
val name = Project("aaa", null).getClass().getName();
println (name);
proj;
}
<hr />
sbt.Project$$anon$1
</pre>
<br />
<code>sbt.Project</code> だった。<br />
一般名詞にしてバッティングするなら、<code>PlayProject</code> にしておけばいいのに・・・
<br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-49347136465847680152013-06-16T01:00:00.000+09:002013-06-30T16:36:52.529+09:00[Play] Play Framework のセッションPlay Framework には Tomcat のような HTTP セッションがない。<br />
Play でのセッションは Cookie として実現されている。<br />
Play でセッションを使う場合にはこのようなコードになる。
<pre class="brush: scala">
package controllers
import play.api._
import play.api.mvc._
import play.api.mvc.RequestHeader
object Application extends Controller {
def index = Action.apply { request =>
val currentVal : String = request.session.get("hoge") match {
case Some(x) => x;
case None => "";
}
Ok("hoge = " + currentVal).withSession(
request.session + ("hoge" -> "hogege"));
}
}
</pre>
<br />
<code>request.session.get</code> は Option を返すので、
パターンマッチで <code>Some</code> か <code>None</code> かを判定して、<code>Some</code> から値を取り出す必要がある。<br />
もしくは、Option.getOrElse を使って、<br />
<pre class="brush: scala">
...
val currentVal : String = request.session.get("hoge").getOrElse("");
...
</pre>
とする。こっちの方が簡単でいい。<br /><br />
<a name='more'></a>
<br />
<hr />
<h2>レスポンスヘッダ</h2><br />
このApplication へのアクセスの Response ヘッダは以下のようになっている。
<br />
<br />
<pre class=code>
Content-Length:7
Content-Type:text/plain; charset=utf-8
Set-Cookie:PLAY_SESSION=086cb3ef28d787e60a6a1dfd4f880c201de6521e-<b style="color:red">hoge%3Ahogege</b>;Path=/;HTTPOnly
</pre>
<br />
PLAY_SESSION という Cookie に Application でセッションにセットした値がそのまま入っている。<br />
したがって、セッションに保持できるのは 文字列にした情報のみで あまり長い値を保持することはできない
(<a href="http://www.ietf.org/rfc/rfc2965.txt" target="_blank">RFC-2965</a> によると 少なくとも1Cookie あたり 4096 バイトまで実装せよ、とのことなのでそれ以上は保証されない)。<br />
また、サーバー側でセットした値がそのまま平文で繰り返し流されることになるので秘密情報を載せることもできない。<br /><br />
<hr />
<h2><code>PLAY_SESSION</code> クッキーは編集不可</h2><br />
<code>PLAY_SESSION</code> クッキーの前半部分の文字列は署名になっているらしく、
<code>PLAY_SESSION</code> クッキーの値をクライアント側で勝手に編集すると、
Play側では<code>PLAY_SESSION</code> クッキーはなかったものと扱われる。
<br /><br />
実際に Chrome の <a href="https://chrome.google.com/webstore/detail/edit-this-cookie/fngmhnnpilhplaeedifhccceomclgfbg?hl=ja" target="_blank">Edit This Cookie</a> Plugin 等を使って値を編集すると Play 側で値を取得できない。
<pre class="code">
<b>Request Header</b>
....
Cookie:PLAY_SESSION=086cb3ef28d787e60a6a1dfd4f880c201de6521e-<b style="color:red">hoge%3Ahogaga</b>
Host:localhost:9000
....
<b>Applicationの表示</b>
hoge =
</pre>
<br />
クライアント側で <code>PLAY_SESSION</code> クッキーの hoge 値を編集したものが リクエストヘッダに乗っかっているが、Application では この値は取得されない。
<br />
<br />
<hr />
<h2><code>PLAY_SESSION</code> を HTTPSession のように使いたいのなら Cache を使う。</h2><br />
HTTPSession のように Cookie に保持できない値は サーバー側で保持するなら
play.api.Cache を使う。
<pre class="brush: scala">
package controllers
import play.api._
import play.api.cache._
import play.api.mvc._
import play.api.mvc.RequestHeader
object Application extends Controller {
def index = Action.apply { request =>
var sessionId : String = request.session.get("id") match {
case Some(x) => x;
case None => java.util.UUID.randomUUID().toString();
}
import play.api.Play.current;
var value : String = Cache.get(sessionId) match {
case Some(x) => Cache.set(sessionId, x, 10); x.asInstanceOf[String];
case None => Cache.set(sessionId, "hoge", 10); "";
}
Cache.set(sessionId + "hoge", "hogege", 10);
Ok("value = " + value).withSession(
request.session + ("id" -> sessionId));
}
}
</pre>
<br />
Cache を使う際には、「import play.api.Play.current」を入れておかないとエラーになる。<br />
<pre class="code">
You do not have an implicit Application in scope.
If you want to bring the current running Application into context,
just add import play.api.Play.current
</pre>
<br />
Play の セッションには位置な識別子がないので、UUIDなどを自分で生成して Session に格納しておく。<br />
Cache にセットする際には Expire(秒)が指定できるが、「取得しただけでは更新されない」ので、
毎回、新たにセットしなおして更新しないと、最初に入れてから Expire 時間が過ぎると
期限切れでなくなってしまう。
<br />
<br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-42584400199991894072013-06-15T01:00:00.000+09:002013-06-15T04:00:33.857+09:00[Play] Play の Welcome ApplicationPlay Framework 2.0.3 で 「play new XXX」で simple Scala application を作成したときに生成される Application.scala は 以下のようになっている。<br />
<br />
<pre class="brush: scala">
package controllers
import play.api._
import play.api.mvc._
object Application extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
}
</pre><br />
ここで、Application#index メソッドの返り値は、
<pre class=code>
play.api.mvc.Action[play.api.mvc.AnyContent]
</pre>
になっている。<br />
何が起きているのか分かりずらいので少し中を見てみることにしよう。<br /><br />
<a name='more'></a>
<hr /><br />
上のコードは例によって apply() が省略されている。<br />
省略せずに書くとこのようになる。<br /><br />
<pre class="brush: scala">
def index = Action.apply(
{
Ok(views.html.index("Your new application is ready."))
}
);
</pre><br />
上で実行されている apply() は、Action オブジェクトのメソッドで以下のように定義されている。<br />
<br />
<pre class="brush: scala">
object Action {
...
def apply(block: Request[AnyContent] => Result): Action[AnyContent] = {
Action(BodyParsers.parse.anyContent)(block)
}
...
def apply(block: => Result): Action[AnyContent] = {
this.apply(_ => block)
}
}
</pre><br />
ここで呼ばれるのは2番目の apply()。<br />
ブロックを引数にとって、 Action[AnyContent] を返している。<br />
このため、index() の型が Action[AnyContent] と type parameter が決定されている。<br />
<br />
「def index = Action { ... 」 は一見、Action トレイト の匿名サブクラスを作成しているように見えるが、Action.apply が呼ばれているに過ぎない( 実際には Action.apply の実行中に Action トレイトの匿名サブクラスが作成されている)。<br /><br />
<hr /><br />
引数としてRequest をとる形式の場合は、
<pre class="brush: scala">
object Application extends Controller {
def index = Action { request =>
Ok(views.html.index("Your new application is ready."))
}
}
</pre><br />
となっているので、Apply.apply の引数は、「引数を一つとる関数」になるので、
先の Apply オブジェクトの1番目の apply が呼び出される。<br />
返り値は同じくAction[AnyContent]。
<br /><br />
<hr /><br />
index() の定義中で使われている Ok() は Controller の親クラスである Status のメンバーで、<br /><br />
<pre class=code> val Ok = new Status(OK)</pre><br />
と定義されている。<br />
Ok(views.html.index("Your new application is ready.")) は、<br />
Ok.apply(....) の省略形で、ここでも apply() が省略されている。<br />
Status クラスの apply は以下のようになっている。<br /><br />
<pre class="brush: scala">
package play.api.mvc
...
class Status {
...
def apply[C](content: C)(implicit ....
</pre><br />
<br />
<hr /><br />
views.html.index は、index.scala.html テンプレートをコンパイルした結果生成されるオブジェクトで、
ここでもapplyが省略されている。<br />
すべてと省略せずに書くとこんな感じになる。
<pre class="brush: scala">
def index = Action.apply(
{
Ok.apply(views.html.index.apply(
"Your new application is ready."))
}
);
</pre><br />
これでなんとなく構造が理解できた気がする。
<br /><br />xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-32349769194410191132013-06-10T01:00:00.000+09:002013-06-11T20:40:02.945+09:00Twitter4J の OAuth 認証を使ってみる<a href="http://ja.wikipedia.org/wiki/OAuth" target="_blank">OAuth</a> を調べてみようとしてとりあえず OAuth 認証をサポートしている Twitter の Java 用ライブラリの Twitter4J を使ってみた。
<ul>
<li><a href="http://twitter4j.org/ja/index.html" target="_blank"> Twitter4J </a></li>
<li><a href="http://twitter4j.org/ja/code-examples.html" target="_blank"> Twitter4J コード例</a></li>
</ul>
<br />
OAuth の基本的な使い方
<ol>
<li>事前のアプリケーション(Consumer)用に サービスプロバイダにアプリケーションを登録して、
アプリケーション用の Consumer Key と Consumer Secret を入手する。</li>
<li>アプリケーションはサービスプロバイダにアクセスして認証用の RequestTokenを入手する。</li>
<li>ResuestToken を引数に Twitter の認証画面を表示する。</li>
<li>RequestToken が認証されたら AccessToken を取得する。</li>
<li>AccessToken を使用して サービスプロバイダの機能を呼び出す。</li>
</ol>
大体こんな感じだと思う。
<br /><br />
<a name='more'></a>
<hr />
<h2>事前準備</h2><br />
OAuth を使うには、サービスプロバイダ(Twitter) に認証情報を要求するアプリケーション(自分で作成するアプリ)を登録して、Consumer Key と Consumer Secret という2つの文字列情報を入手する。
<ul><li>
<a href="https://dev.twitter.com/apps">Twitter Dev. My applications</a><br />
登録済みアプリケーション一覧。新規登録もここから可能
</li></ul>
callback url は Twitter の認証後にリダイレクトされる URL。Twitter の認証画面を出して認証結果を使うWebアプリの場合には
ここを指定する。省略可能であり、今回は省略。
<br /><br />
アプリ用のAccessToken もここで作ることができる。<br />
Twitter 認証画面を要求するアプリの場合には、認証結果をもとにログインしたユーザーの AccessToken が生成されるが、
固定ユーザーでアクセスするようなアプリケーションの場合にはここで事前にユーザー固定の AccessToken と AccessToken Secret を作成しておくことができる。
<br /><br />
<hr />
<h2>AccessToken が既にある場合の例</h2>
<pre class="brush: java">
Twitter twitter = TwitterFactory.getSingleton();
twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
AccessToken accessToken = new AccessToken(
ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
twitter.setOAuthAccessToken(accessToken);
Status status = twitter.updateStatus(
"test from twitter4J " + System.currentTimeMillis());
System.out.println(
"status updated to [" + status.getText() + "].");
</pre>
<br />
すでに AccessToken を持っているので AccessToken オブジェクトだけ作成して Twitter の APIを実行すればいい。
<br /><br />
OAuth とは関係ないが、Twitter の場合、同じ status は一定時間内は tweet できないので内容が毎回変わるようにしておかないとエラーになってしまう。最初知らなかったので結構はまった。<br />
ついでに retweet も 自分の status に対してはできないので これもテストコード書いているときにはまった。
<br /><br />
Local Proxy を通して Twitter へのアクセスを見ても、このコードの場合には<br />
<code> http://api.twitter.com/1.1/statuses/update.json </code><br />
へのアクセスが1回あるだけで特に認証用のアクセスが発生することはない。<br />
OAuth関連情報としては、このアクセスの Authorizationヘッダに Token 関連の情報が載っている。<br /><br />
<pre class=code>
Authorization: OAuth
oauth_consumer_key="XXXXXXXXXXXXXXXXX",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1370784442",
oauth_nonce="2413164847",
oauth_version="1.0",
oauth_token="XXXXXXX-XXXXXXXXXXXXXXXXXXXXXXX",
oauth_signature="XXXXXXXXXXXXXXXXXXXXXX"
</pre><br />
oauth_consumer_key に記載されているのがアプリ登録時に取得した Consumer Key、
oauth_token に 記載されているのが AccessToken。<br />
Consumer Secret や Access Token Secret は秘密情報なのでここに記載されることはない。
<br /><br />
ちなみに、Twitter4J で Proxy を通すにはシステムプロパティに <code>twitter4j.http.proxyHost</code> と
<code>twitter4j.http.proxyPort</code> を指定すればいい。<br />
<pre class=code>
System.setProperty("twitter4j.http.proxyHost", "localhost");
System.setProperty("twitter4j.http.proxyPort", "8080");
</pre>
<br /><br />
<hr />
<h2>AccessToken を毎回作る場合の例</h2>
<pre class="brush: java">
Twitter twitter = TwitterFactory.getSingleton();
twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
RequestToken requestToken = twitter.getOAuthRequestToken();
System.out.println(
"AuthorizationUrl: " + requestToken.getAuthorizationURL());
String pin = inputLine("Pin: ");
AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, pin);
twitter.setOAuthAccessToken(accessToken);
Status status = twitter.updateStatus(
"test from twitter4J " + System.currentTimeMillis());
</pre>
<br />
最初に未認証のRequestTokenを作成する。<br />
<code>requestToken.getAuthorizationURL()</code> では<br />
<code>http://api.twitter.com/oauth/authorize?oauth_token=eHgGY86046kdC6TnfMdJp31CBvGnZJ73JfGiecrK1t4</code><br />
のような、生成した RequestToken を引数にした認証用の URL が取得できる。<br />
<br />
この URL にブラウザでアクセスすると <br />
「XawaSampleApplication1があなたのアカウントを利用することを許可しますか?」<br />
のような認証画面が表示されるので、ID/パスワードを入力して「連携アプリを認証」を押す。
(すでにログイン済みだった場合には認証画面ではログインは求められずに「連携アプリを認証」ボタンの押下のみが求められる。)<br />
すると PIN コードが出力されるので、
RequestToken と PINコードをセットにして AccessToken をTwitter に要求して AccessToken を入手できる。<br />
<br />
AccessToken を入手した後は先ほどの例と同じ。ただ、今度はユーザーは固定ではなく、
認証画面でログインしたユーザーによるアクセスとして扱われる。<br />
<br />
<br />
今回は、(ブラウザによるアクセスを除いて) Twitter への3回のリクエストが発生する。<br />
<div class=code>
<ol>
<li>http://api.twitter.com/oauth/request_token<br />
リクエストトークン の要求</li>
<li>http://api.twitter.com/oauth/access_token<br />
アクセストークンの要求</li>
<li>http://api.twitter.com/1.1/statuses/update.json<br />
ステータス更新(Twitt)要求</li>
</ol>
</div><br />
最初のリクエストトークン要求では、Authorization ヘッダで oauth_consumer_key を渡しているが、
アクセストークン要求では oauth_token が増えている。
おそらく入力した PIN に起因する情報だと思う。<br />
ステータス更新でも oauth_token を渡しているが アクセストークン要求時とは違う値になっている。
<br />
ステータス更新で渡しているのが本当の AccessToken になる。<br /><br />
<pre class=code>
<b>リクエストトークン要求 (/oauth/request_token)</b>
Authorization: OAuth
oauth_consumer_key="XXXXXXXXXXXXXXXX",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1370786130",
oauth_nonce="2475682075",
oauth_version="1.0",
oauth_signature="SSSSSSSSSSSSSSSSSSS"
<b>アクセストークン要求 (/oauth/access_token)</b>
Authorization: OAuth
oauth_consumer_key="XXXXXXXXXXXXXXXX",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1370786148",
oauth_nonce="616082455",
oauth_version="1.0",
oauth_token="YYYYYYYYYYYYYYYYYYYYY",
oauth_signature="SSSSSSSSSSSSSSSSSSS"
<b>ステータス更新 (/1.1/statuses/update.json)</b>
Authorization: OAuth
oauth_consumer_key="XXXXXXXXXXXXXXXX",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1370786148",
oauth_nonce="1470961812",
oauth_version="1.0",
oauth_token="ZZZZZZZZZZZZZZZZZ",
oauth_signature="SSSSSSSSSSSSSSSSSSS"
</pre>
<br /><br />
<hr />
<h2>signature の作り方</h2><br />
今回は、Twitter4J が自動的にやってくれているので何も気にしなくて済むのだが、
<a href="https://dev.twitter.com/docs/auth/creating-signature" target="_blank">Twitter DEV の Creating a signature のページ</a> に作り方が詳しく書いてある。<br /><br />
HTTP Method、Base URL、Request Parameter、OAuth系ヘッダ をかき集めて文字列にし、Consumer Secret と Auth Token Secret を結合したものをキーとして HMAC-SHA1 hashing algorithm で署名するらしい。<br />
具体例が載っているのでいつかやってみよう。
<br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-67878587525828973012013-06-09T01:00:00.000+09:002014-10-31T03:06:20.604+09:00[どうぶつしょうぎ] ▲B3キリン - 中キリン-<table><tbody>
<tr><td style="vertical-align: top;"><br />
図1は序盤によく出てくる先手が中央にキリンを持ってきた中キリン局面。<br />
初手からの典型的な手順は<br />
<br />
<b>▲C3キリン、△A2キリン、 ▲B2ヒヨコ、 △同ゾウ、</b><br />
<b>▲B3キリン</b><br />
<br />
他にもいろいろな手順でこの局面に行き着く。<br />
<br />
後手勝ち局面で先手後手最善を尽くすとあと68手で後手が勝つ。<br />
この手順(中キリン定跡)を見てみよう。<br />
棋譜は <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-c3Ka2K-b2Hb2Z-b3K.txt" target="_blank">こちら</a> 。
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8ODimns1Rh7IA8RYxpyZa3TG6mPa6uEvpOjk17PVTuqlb635My6SmUmKxHLRTnRCuMwv5Z1DUdig1ksctV_PJntpj-AtMZQ0S0D9GCvxsd1R_HF8NvI1KaW3WFlvYrLdqU5Zf45OewpU/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B306%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8ODimns1Rh7IA8RYxpyZa3TG6mPa6uEvpOjk17PVTuqlb635My6SmUmKxHLRTnRCuMwv5Z1DUdig1ksctV_PJntpj-AtMZQ0S0D9GCvxsd1R_HF8NvI1KaW3WFlvYrLdqU5Zf45OewpU/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B306%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図1 ▲B3キリン まで</td></tr>
</tbody></table>
<br /></td></tr>
</tbody></table>
<br />
<a name='more'></a><hr />
<table><tbody>
<tr>
<td style="vertical-align: top;"><h2>
<u>序盤</u></h2>
<br />
<b>△C2ライオン、▲B2キリン、△同キリン、<br />
▲B3ゾウ打、△B1ライオン</b><br />
<br />
後手がライオンを上がった後、キリン-ゾウ交換になり後手はいったんライオンを引く。<br />
<br />
▲B2キリン のところは▲C3ヒヨコ打 もありそうだが、そのあと△A3ヒヨコ打や△A3ゾウがありよくない(→ <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-c3Ka2K-b2Hb2Z-b3Kc2L-c3H.txt" target="_blank">棋譜</a>) 。<br />
△B2同キリンを△B2同ライオンとすると千日手の引き分けになってしまうので後手は勝ち局面を維持するためには同キリンの一手。<br />
<br />
▲B3ゾウ打 に替えて ▲C3ヒヨコ打 は、双方最善の場合 終局まで32手と本筋よりかなり短くはなるが有力な変化。<br />
△B1ライオン、▲A3ゾウ打 で後手は △A2ヒヨコ打 と応じるのが最善。ここで、△A2キリン とすると ▲B3ゾウ と手順にゾウを繰り出される。まだ後手勝ちの局面だが勝ちまで 95手 と事実上互角の局面になってしまう。<br />
▲C3ヒヨコ打 の変化の棋譜はこちら(→ <a href="https://googledrive.com/host/0B8twch0Omq9ycU9zM2ZNNWtKX3M/out-c3Ka2K-b2Hb2Z-b3Kc2L-b2Kb2K-c3H.txt" target="_blank">棋譜</a> )。
<br />
<br />
▲A3ヒヨコ打 は△同キリン、▲同キリン、△同ゾウ、▲同ライオン、△C3ライオンでC筋のトライを受けられない。
<br />
</td><td><table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjEilO1t-VyaD3xAmOPd6KJhOyq4IU_4RFjBehfqkgypaY0UhXen90HH7OtHJH1D5zYeLYBZkEWCvWG6KhcoEPhYD2TvW1IN83gUk8xav49bVp9sTiL__zez48g059-BufVhFykiPvG-U/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B311%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjEilO1t-VyaD3xAmOPd6KJhOyq4IU_4RFjBehfqkgypaY0UhXen90HH7OtHJH1D5zYeLYBZkEWCvWG6KhcoEPhYD2TvW1IN83gUk8xav49bVp9sTiL__zez48g059-BufVhFykiPvG-U/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B311%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図2 △B1ライオン まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<hr />
<table><tbody>
<tr>
<td style="vertical-align: top;"><h2>
<u>位置争い</u></h2>
<br />
<b>▲C4ゾウ、△A2キリン、▲B3ゾウ左、△A1キリン、<br />
▲C3ライオン、△C1ライオン、▲C2ゾウ、△A2キリン、<br />
▲B3ゾウ引、△A3キリン</b><br />
<br />
ここから先手後手ともに盤上のコマだけで位置争いになる。<br />
<br />
後手は中央の キリン を A1 まで引き戻す。狙いはB2ライオン。
先手もそれを阻止するべく、▲C3ライオン と進出する。<br />
<br />
▲C2ゾウ と右側に駒が集まったところで後手はA筋からキリンを上げていく。
</td><td>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6f_Cao03e9rDak-bCCddm3zMBHAtQFTROfpiYCve5KXach26sSMkvqJhZV13GGFEm1u063gpriZcGQh0W7WmWu_33WDuK_SFga1uoUYV5R4qvxxgyfymkop4N3Zczr8sRs-hVqPMfnZg/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B321%E6%89%8B%E7%9B%AE.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6f_Cao03e9rDak-bCCddm3zMBHAtQFTROfpiYCve5KXach26sSMkvqJhZV13GGFEm1u063gpriZcGQh0W7WmWu_33WDuK_SFga1uoUYV5R4qvxxgyfymkop4N3Zczr8sRs-hVqPMfnZg/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B321%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図3 △A3キリン まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<hr />
<table><tbody>
<tr>
<td style="vertical-align: top;"><h2>
<u>後手攻勢</u></h2>
<br />
<b>▲A4ヒヨコ打、△B3キリン、▲同ライオン、△B2キリン打、<br />
▲B4ライオン、△A2ゾウ打、<br />▲C3キリン打、△C2ヒヨコ打、<br />
▲B3キリン、△同ゾウ、▲同ゾウ、△B1ライオン</b><br />
<br />
先手はB3に引いたゾウをC2に戻すと △B2キリン打 と攻められるので ▲A4ヒヨコ打 と突出してきたキリンを攻める。<br />
後手は下段にヒヨコを打たせたことで満足し△B3キリンとキリンを捌く。<br />
<br />
さらに、△B2キリン打、△A2ゾウ打と攻め立てて中央でゾウ/キリン交換をして再び先手がゾウ2枚、後手がキリン2枚になる。
<br />
</td><td>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmHEOailHsPJXyC3I9kpvr4sJovojPPDCJ-p-nJw0eJsFsMZWQoa1zvRxd-GI1d0iRdFP0Gvk800FQPNYRQAvZ8CL0xuljUctMHhFpPM0LZLrAOz-YXwV9tjLnqlUuOicxr05CEWwSZ9A/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B333%E6%89%8B%E7%9B%AE.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmHEOailHsPJXyC3I9kpvr4sJovojPPDCJ-p-nJw0eJsFsMZWQoa1zvRxd-GI1d0iRdFP0Gvk800FQPNYRQAvZ8CL0xuljUctMHhFpPM0LZLrAOz-YXwV9tjLnqlUuOicxr05CEWwSZ9A/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B333%E6%89%8B%E7%9B%AE.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">図4 △B1ライオン まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<hr />
<table><tbody>
<tr>
<td style="vertical-align: top;"><h2>
<u>▲B2ライオンで位をとる</u></h2>
<br />
<b>▲C4ゾウ、△A2ライオン、▲A3ヒヨコ、△B1ライオン、<br />
▲A4ゾウ打、△C1ライオン、▲B3ゾウ左、△B1キリン、<br />
▲A2ゾウ、△A1キリン、▲B3ゾウ引、△B2ライオン</b><br />
<br />
先手は▲C4ゾウ打で再び同筋ゾウ2枚の形になる。<br />
これを見て後手はいったん▲C1ライオンをライオンを退避してから、
B2のキリンをB1→A1と下げる。<br />
B2が空いたところで△B2ライオンと好位置に持っていく。<br />
ここで先手は次の手に困ることになる。<br />
</td><td>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiU8duUW9DgKT3z4w5DCSRT3AA19_1iEXhTRIjIAM5Db7EkrFZTBXBOSCmopxVdTocx8NkcEkmZLO98x1QgoNgXDaQ73FLlsaaetthjfDH8ZmVyPMSo8p1Q8n4lEKilWnTnk_eDWod0Bc/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B345%E6%89%8B%E7%9B%AE.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiU8duUW9DgKT3z4w5DCSRT3AA19_1iEXhTRIjIAM5Db7EkrFZTBXBOSCmopxVdTocx8NkcEkmZLO98x1QgoNgXDaQ73FLlsaaetthjfDH8ZmVyPMSo8p1Q8n4lEKilWnTnk_eDWod0Bc/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B345%E6%89%8B%E7%9B%AE.png" /></a>
</td></tr>
<tr><td class="tr-caption" style="text-align: center;">図5 △B2ライオン まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>
<br />
<hr />
<table><tbody>
<tr>
<td style="vertical-align: top;"><h2>
<u>A4ゾウ打で後手勝ち</u></h2>
<br />
<b>▲C2ゾウ、△同ライオン、▲B3ゾウ、△B2ライオン、<br />
▲C4ヒヨコ打、△B1キリン、▲A4ライオン、△C2ゾウ打、<br />
▲同ゾウ、△同ライオン、▲B3ゾウ打、△B2ライオン<br />
▲B4ライオン、△A1キリン、▲C3ヒヨコ、△B1キリン<br />
▲C2ゾウ、△A4ゾウ打(!)</b><br />
<br />
先手は有効な手がなく、やむなく▲C2ゾウとしてゾウ/ヒヨコ交換になる。
▲C2ゾウの代わりに▲A4ゾウとしても△B1キリンと手待ちされ、
次にどちらのゾウが上がっても△C3ヒヨコとされてしまう。<br /><br />
後手のライオンがB2に居座っているので王手がかけられない先手はこの後逆襲に転じる手がない。<br />
手番争いの末▲C3ヒヨコ、▲C2ゾウと後手キリンに圧力をかけに行くが
ここで後手の△A4ゾウ打が好手。<br />
<br />
以下、A4ゾウを取れば△C3ライオンでトライか先手ライオン詰み。
△B1のキリンをとっても△B3キリン打以下即詰みになってしまう。
</td><td>
<table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1UytDN34zwAj20XsIa2Sl01E9C_NsnEbpFq_3E85xc4id2lHEKc9UnQSxI01koIk_3zgk0ES9JhdL5YXks9viMHaSrjUmsYBN0pX3yx-g4sJWzaf0CWPtE3MRWhWVX8pYsHni9a_PayU/s1600/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B363%E6%89%8B%E7%9B%AE.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1UytDN34zwAj20XsIa2Sl01E9C_NsnEbpFq_3E85xc4id2lHEKc9UnQSxI01koIk_3zgk0ES9JhdL5YXks9viMHaSrjUmsYBN0pX3yx-g4sJWzaf0CWPtE3MRWhWVX8pYsHni9a_PayU/s320/%E3%81%A9%E3%81%86%E3%81%B6%E3%81%A4%E3%81%97%E3%82%87%E3%81%86%E3%81%8E-%E4%B8%AD%E3%82%AD%E3%83%AA%E3%83%B363%E6%89%8B%E7%9B%AE.png" /></a>
</td></tr>
<tr><td class="tr-caption" style="text-align: center;">図6 △A4ゾウ打 まで</td></tr>
</tbody></table>
</td></tr>
</tbody></table>xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com2tag:blogger.com,1999:blog-3058535269160921661.post-57006034167206688772013-06-03T01:00:00.000+09:002013-06-03T01:00:02.998+09:00[どうぶつしょうぎ] 完全解析ツールのバグについて以前、東京大学情報基盤センターの田中先生による「どうぶつしょうぎ完全解析ツール」をUbuntu環境で使うとエラーになる件について環境依存かもしれないと書いたのだが、
ちゃんと調べてみたら単なるバグだったことが分かった。<br />
<br />
環境によって動いたり動かなかったりしたのはたまたまの模様。<br />
<ul>
<li><a href="http://media.itc.u-tokyo.ac.jp/ktanaka/dobutsushogi/" target="_blank">「どうぶつしょうぎ」の完全解析</a> (田中先生のサイト)</li>
<li><a href="/2013/05/DoubutsuShougi-Ubuntu.html" target="_blank">[どうぶつしょうぎ] 完全解析ツール on Ubuntu</a></li>
</ul>
<br />
<a name='more'></a>
<hr />
<br />
<code>dobutsu.cc</code> の <code>State:<<</code> オペレータの定義中で、戻り値として ostream を返していなかったのが原因。
そのため、<br /><br />
<pre class="code">
State s;
...
std::cerr << s << std::endl;
</pre>
<br />
のようなコードで Segmentation fault になっていた。<br />
<code>dobutsu.cc</code> の <code>State:<<</code> オペレータの定義の最後に、<br />
<br />
<pre class="code">
return os;
</pre>
<br />
の一行を入れておけばよい。<br />
これで、Ubuntu - 13.04 の 32bit 版でも正常に動作するようになった。<br />
<br />
パッチ:
<pre class="code">
$ <b>diff -u dobutsu-org/dobutsu.cc dobutsu</b>
--- dobutsu-org/dobutsu.cc 2009-06-29 20:28:40.000000000 +0900
+++ dobutsu/dobutsu.cc 2013-05-26 22:55:44.006474987 +0900
@@ -99,6 +99,9 @@
os << "+\n";
else
os << "-\n";
+
+ // ADDED BY XAWA
+ return os;
}
</pre>
<br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0tag:blogger.com,1999:blog-3058535269160921661.post-46505744436418427302013-06-02T01:00:00.000+09:002013-06-02T01:00:02.190+09:00Google サイト の サイトマップ以前、Blogger の サイトマップを ウェブマスターツールに登録した。
<UL><LI>
<a href="/2012/07/blog-post_3740.html" target="_blank">サイトマップの登録</a>
</LI></UL>
同じようにして、Googleサイト のサイトマップも登録してみる。<br /><br />
<a name='more'></a>
Google サイトの サイトマップは 以下のURLで取得できる。
<pre class=code>
http://sites.google.com/site/(サイト名)/system/feeds/sitemap
</pre>
<br />
このブログの別館として使っている Googleサイトの場合、URLは<br />
<pre class=code>https://sites.google.com/site/xawa99/</pre><br />
なので、サイトマップは<br />
<pre class=code>https://sites.google.com/site/xawa99/system/feeds/sitemap</pre><br />
になる。<br />
<br />
中身はこんな感じ。シンプルだ。<br />
<pre class="brush: xml">
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<script/>
<url>
<loc>https://sites.google.com/site/xawa99/dobutsu</loc>
<priority>0.5</priority>
</url>
<url>
<loc>https://sites.google.com/site/xawa99/home</loc>
<priority>0.8</priority>
</url>
</urlset>
</pre><br />
サイトマップのURLがわかれば、後は Blogger を登録したときと同じ。<br />
<a href="/2012/07/blog-post_3740.html" target="_blank">サイトマップの登録</a> の記事を参照。
<br /><br />
xawahttp://www.blogger.com/profile/05124243938746138469noreply@blogger.com0