2023/11/25
話題その1 五目並べの続き Read問題&乱数問題
前回の続きで盤面のコマがいくつ連続してるのかを返す関数。前半
正負を逆転させて負方向へのチェックを行う後半。
ではテスト。Bについて調べる。35番にBを置いても連続はないので1でOK
7にBを置いた場合斜めで連続が発生するので2でOK
試しにWを0個にしてテストしてみたところエラー発生。初期配置で1つは配置される予定なのでありえない事だけど・・最初からリストがNullの場合でもLoop内でチェックするというのか・・。修正が面倒なのでまたもやGuardを持ち出してエラーが出たら0を返すようにする。めちゃ便利じゃないかw
で、盤面上の最大連続コマ数を返す関数が出来たので実験。画面端で連続はちゃんと切れていてBの最大数が3、白は(普通ありえないが)0ということで・・バッチリ!
続いてStrategy部分に入っていくわけですが・・まずは人間が入力するHumanを作ろうと思ったら・・やっぱりRead関係がうまく動かない。なんかLetで束縛して入力するようにしても勝手にEof(?)ってのが返ってくるだけ。WEBサービスだからなのか?
まあ、そっちはRacketで実現するか・・と置いといてRandom-strategyへ。しかし!GaucheにはRandomが無い!Srfi27でRandom-integerってのがあるので使ってみるが・・これまたWEBサービスの限界なのか、テストするたびに全く同じ乱数が発生するのだった。参ったなぁ・・探せば現在時刻などから乱数を乱数として取り出す方法があるのだろうか?これもRacketだったら問題ないのだが。
話題その2 リートン
生成AIの亜種がボンボン生まれてきてて興味深いけど、なかでwrtnってのがあるのを知った。ちょっとした登録でGPT4が使えるというので早速導入。
例によってRacketのMinimaxを作ってもらったが・・同じGPT4だからしょうがないけどこっちでも動くコードは出してもらえなかった。
丸投げしてみたらRacketは専門外だった模様。詳しく聞いたらC#、Python、JS、JAVAあたりだったら出来ないこともないとのこと。頼み込んで作ってもらったけどAI部分とかエラー処理とかは「自分でどうぞ」ということだった。まだまだやのう(-_-;)
2023/11/22
話題その1 オセロの続き Forをやめて名前付きLetにしてみる
こいつを実行するとVoidが返ってきてどうしようもなかったんだったね
なのでLet Loopに書き換えてみる。Breakとか使わなくてもCondで場合分けすれば普通に実現できるな。
これだとAlpha-beta単品であればちゃんと?動くな~
が、実際の場面では・・やっぱりLet-valuesでの多値を返す方式が駄目なんだよなぁ・・CL版もコレちゃんと動くのか?
というわけでSearcherの方もBest-moveだけを受け取るようにして、Alpha-betaもBest-move単値を返すようにする。値の更新は禁じ手かも知れないけどSet!を使いまくることでLet loopの引数はMovesだけで良い、と。
結果、ある程度は動くようになった。が、最後までは動かず。まあとりあえずエラーが出なければ後はなんとかあるだろう・・ということで以下次回。
話題その2 Udemyのブラックフライデーセール
Udemyがセール中ということで最安の1コース1200円。これは本を買うより安い!
ということでまだWebDevelopperコースもPythonコースも全くやってないのにまた買ってしまった。結局UnrealEngineもGodotもコレ!って感じのコースが見つからないんだよなぁ・・ということで結局Unityのコースが充実してるということで・・こちら講義のビデオが78時間とお得感がすごい。さまざまな種類のゲームを作るっぽいので「数打て」るのが魅力的で(^_^;)
次々やってかないとな~
2023/11/21 五目並べの続き 例外処理
前回で表示部分は解決したと思ったけどテストしたら最下段がおかしい。あ、自作関数Devide-listで最後の連結前にReverseするのを忘れてた
こういう感じで。
そう言えば盤面の四方では連続が続かないようにしないといけないのを忘れていた。ということで・・17番目にコマを置くようにする。うまく行ってれば2になるはず、失敗すれば3。ま、2で大丈夫ってことで。問題はリストの範囲外をスキャンする可能性があるので・・例外処理をしないといかん。うーん、RacketでもPaiza.io(Gauche)でも動くようにしたいんだけど・・とりあえず動かないとどうしようもないのでGaucheで。ドキュメントを調べるとGuardかな?
使ったことがないのでテスト。ほうほう・・判定部分でエラーじゃなくて#fを返してくれたら良いだけだからね
確実にエラーが出る数値で実験。ちゃんと動いてる!けど、うーん・・なんと冗長なw
多分Ifの上に持ってこれると思うんだよなぁ
うおお、出来た!よしよし、後はLoopBも同じように書いて・・これでほぼゲーム部分は終わりじゃないかな?
それが終わったらようやく探索の探求に入っていけるよ〜(^_^;)
2023/11/19 オセロの続き Break問題は解決した
Forの中で途中で止めてしまう機能が無いとは思えない・・ということでドキュメントを見ると。なんだ、やっぱりあるじゃないか!ちょっと書き方にクセがある模様
解説は英語なのでDeepLにて翻訳。まあ、結局分からないのだけど。ただ、気になる記述を発見。シーケンスが空の場合には#<void>が返ってくるだと・・?もしやVoid問題はこれが影響してるのか?
GPTに使い方を教えてもらう。が、こんなシンプルな事でさえデタラメを教えてくるのであった。頼りにならねぇなぁ
ForのWhenとかBreakはオプション形式で書くようだ。ところで興味深いことを発見。オプションを別にしてもBody部分でこのように返り値だけを求める書き方をするとVoidが返ってきてしまうのだ
このように書けば思ったように動くのか・・ふんふん
オプションを入れて思ったように動く一番簡単な書き方はこうか。オプションは最初の束縛部分に入れるのかぁ・・ドキュメントによるとBreakはBody部分に入れることも出来るようだが?そっちの書き方も実験してみないとなぁ。Finalはその時点で返したい値を指定できる、と
Breakの場合は狙った値で強制終了なのでキーとなる値は返らないと。なるほど~
じゃあBreakを取り入れて書いてみて・・
問題のAlpha-betaで実験してみるか。どこかの段階でVoidが返ってくるのが問題なのでまずはPlyがどの数値になってるかで場合分けするか0なら当然値が返るが
1でもう駄目。次回はこのVoid問題を引き続き探っていくか・・Forの問題っぽいけどなぁ
2023/11/18 五目並べの続き データ修正編
いざ座標をいじる関数を書いていこうと思って気がついた。どういうわけか元のリストに禁止エリアも書き込んでしまってて、このままでは書き換えが困難であると。なんでREPLの基本事項を忘れてしまってたかなぁ・・表示部分はPRINTにまかせてデータ部分では考えないって事を!
前回は禁止エリアも含めてデータに入れてたのでえらい苦労して盤面データを作る座標データを作ってたが・・データのみ、しかも1からにこだわらずList-refにそのまま使える0スタートにすることで・・Iotaだけで済んでしまう
座標データを元にしてInitial-boardデータを作る。以前のように禁止エリアを作らなくても良いので超楽ちん
打てる座標も0と35だけを超えなければいいのでこんだけ
表示部分は・・10x10なら見やすいけど6x6なので・・左端は行番号に列番号を足してもらうってことで勘弁してもらおう。
これでようやく盤面のデータ操作が分かりやすくなった。というか、なんであんな方法で盤面データを作ってたのか?うーんバカバカ!
2023/11/17 五目並べの続き
五目並べのメイン関数を作ってる最中。
終了条件は5連続してればイイんだから・・こんな感じ?
で、打つ場所に決まりは無いので空きコマがなければ引き分けって事でイイな?
で、Loopで盤面の各プレイヤーの連続コマを更新すると・・あ、今気づいたけどこの書き方だと更新されたBoardを参照できてないから駄目だわ。
だが気づいてなかったので、BoardとPlayerから各Playerの連続コマ数を返す関数を書かないといかんわ・・と
前に作ったRenzoku-komaをそのまま使えるかと思ってたけど、いざ書いてみようとして駄目なことに気づいた。引数PlayerとBoardだけで返さないといけないから・・盤面の各コマをRenzoku-komaのKoma引数に当たる部分を盤面からリストとして抜き出す関数がいるような気がする・・ということで書く
Player-koma-listで得られたコマ(座標)を元にして、Renzoku-komaでリストを作成。出来た入れ子のリストにMaxで取り出した最大数を返す関数を書く。
Initial-boardで実験。オッケイ(^o^) これを使ってメインに組み込めば・・でも参照するタイミングを改善しないと駄目ですけどね
2023/11/16
話題その1 今度はαβカットでエラー
Minimaxは一分納得行かないところもあるけど、そこは五目並べで考え直すとして次のαβカットに行ってみようと思ったわけ
こちらがCL版原作の一部、Loop部分から。うーん、一見して悪い予感がする部分があるUntilか・・Scheme系でこの配置は見たことがない
ほぼそのままで書いてみるがUntil部分はGPTによると途中で条件が合えば脱出するためのものであるという。(break)使えばいいよ!と教えてくれたが、もちろんそんなものはSchemeには無いのだった。
脱出といえば大域脱出、Call/ccがあるけど・・
Cametanさんの過去記事を拝見させてもらって復習。ふーむ・・これ今回の場合はどこに入れたら良いんだw? Let loopの中に書くってことになりそうだけど?まあ、色々と試してみるか・・
と、思ったらそもそもちゃんと動かない。うーん・・Displayを入れてみるとどうもValが最後でVoidになってしまってるからか・・
多値で返すのがまずいのかと思って単品で返すようにしたけど同じ。うーん?
しょうがないのでガンガンDisplayを入れて値をチェックや
うーん・・最深部では動いてるのにPlyが上がってくる(再帰なので)段階でおかしくなってるな。というところで探索の探索は続くのであった
話題その2 カラー変更
Racketのオートコンプリートを導入すると問題になるのが候補の表示部分。お気に入りのカラーリングだと運悪くすごく見づらくなってしまう!
色々と試したけど、この配色であれば候補表示も見やすいので・・残念ながら変更することにした。候補表示のバックは変更不能。文字部分は()の色設定が反映されるのでピンクや緑だと全然見えないのです。
2023/11/15 Minimaxの謎が解けたのは気のせいだった
多値を受け取る中間の関数minimax-searcherをチェックする。これが現在の状態・・原作は多値を受け取るようになってたけどMinimaxでBest-moveだけを返すように変えたのでこうなってたのだった。自分でやってて完全に忘れてた
で、こちらを原作通りに多値を受け取るように改良して・・
そうするとここまでは動く。んだけど、その後
ここで多値を返す場面になってMinimax内で対応してないのでエラーが出る。あ~・・・
じゃあValに多値をそのまま入れられるのか?と思ったけど駄目だった。
昨夜はここまでで時間切れ。で、帰宅して飯を食べながら考えてて抜け道を考えついた。(val (if (number? ... って感じで多値と数値を場合分けしたらいけんじゃないかな!と。Gitを遡って明日もう一度挑戦だ!
2023/11/13 Minimaxの謎が解けた
ぐわぁ!!何気なく実用CLを読み返してたらちゃんと「Minimax関数は多値で返ってくるので戦略関数としては使えないのでMinimax-Searcherが適切な戦略を返す」とあるじゃないか!なんだそういう仕組みだったのか〜(-_-;)
2023/11/12まで
話題その1 五目並べの続き
宿直Aで五目並べ。あるコマに対して評価関数Renzoku-komaを適用して得られる全方向の連続したコマを返す関数・・がオセロで言うところのMake-moveになるのかなぁ?とりあえず作る。
あと、LispなんだからListでやれや!と思って途中でVectorに変換するのをやめてずっとListで行くように変更しました
話題その2 オセロw
Valuesで多値を返すのにValが単数のみを引き受ける仕組みになってるのが納得できない!というところから。最終的にはMoveを返す仕掛けになってるので多値を返すのは都合が悪い。しょうがないのでPlyが0になった時点でValにはBest-moveじゃなくて0を返す・・という風にしてみる
まあ、負けまくるんですけど(^_^;) うーん? いやもう良いかなあ・・オセロの厄介なところは多分打つ手がない場合に相手に手が移動してしまうところだと思われる?ここはこのまま進めて普通の探索木の勉強は五目並べでやるかなぁ・・と。
続きのαβに進みますわ
話題その3 ドットインストールでLuaとPico8入門動画を発見
Tic-80を遊び始めるのに何かとっかかりが欲しいな・・ということで検索したらま懐かしのドットインストールにて入門講座があるという。ついでに使用言語であるLuaも入門コースが無料であったので拝見してみる。
まずは言語の概要を知りたいな・・ということでLua入門から。ふーん、型宣言もいらないしパラメータの与え方が合理的だな〜・・だが()がないので寂しい(-_-;) 書き方は懐かしのBasicに似てるが行番号が無くて融通が利きそう(というか行番号が必要な言語っていまどきあるんだろうか?)。
一気に17動画全部見る。当然ながらプログラムの動かし方など全然書かれてないので、なるほどこれを見て動くものを作れるヤツなんていないだろうなぁ〜と。
2023/11/10 五目並べの評価関数
宿直AはChromebookしか無い環境なので五目並べの時間。
オセロで言うところの「Count-difference」のようなものを作る。一列に連続している自コマの数を数える関数ってところか。
任意の方向(今回は左隣を表す−1)に自コマがある場合はカウントを増やして更に−1を調べて・・と続き、違った時点でローカル変数Totalにカウントを足して、今度は(- (-1))で方向を反転させた方向も同様に探索。合計を返すというもの。実用CLでもRoRでも破壊的なデータ変更が堂々と行われてることだし見習うことにする。思うに、大域変数だとヤバいけどローカル変数においてのSet!は許されるのでは無かろうか?
あ、そうか・・Set!じゃなくてSetを自作で作れば良いだけだった(^_^;)
次回作るとしよう。テストの結果は・・成功。その後、布団をかぶりつつ考えてたけど、これってall-directionを(-7 -6 -5 -1 1 5 6 7)じゃなくて(1 5 6 7)の半分で済むってことか〜
ところで五目並べのルールを調べたんだけど別にどこに置いても良いみたい(その場合最適な方法を取り続ければ先手が必ず勝てるらしい)。対策された連珠ってのは禁じ手とかあるみたいけど・・ま、面倒だし普通の何でもアリで良いや。
あ〜早くオセロをクリアして、五目並べを作って、RacketでKatan-Oを作って、とっととTic-80を体験してみたいぜ〜
2023/11/09
話題その1 まだオセロの探索をやっているw
正直、もとのCL用コードの返り値がValuesで多値になってるのが納得できない!ということでCLのDolistに対応するかな?と思われるForに書き換えて実験。けどやっぱりそうすると「受け取る数が違うよ」とエラーが出る。いやまあ、そうだよね?もとのコードを見てもLet-vaules的なものが書かれてないし・・どうなってんだ?CLだったら許されるのか?
具体的に言うと最後の部分、原作に準拠させるとこういうValuesで返してるんだよなぁ・・
動かすためには最後をBest-moveだけにしてるんだけど、そのせいでMovesの次の候補を調べるときにValにCount-difference(盤面のコマ数を数える評価関数)の数値がBest-moveで上書きされてしまうのだ。AIのBardに聞いたけど頓珍漢な返答でガックリですよ。次回の宿直Bではこれを書き換えるか・・
話題その2 宿直AにてChromebookで五目並べの続き
ちょっと盤面が小さすぎたので6x6に変更。
打つことが許されるかを調べる関数を2つ。オセロだと最低でも相手を挟めるかどうか?が条件になるんだけど・・五目並べってそういうの無いですよね?あんのかなぁ・・少なくとも自コマに隣接してないといけないとか?考えたら生まれて一度も五目並べを遊んだことがない。ちょっと次回の宿直Aではルールを確認して続きを書くとしよう。遅々!
話題その3 ゲームエンジンあれこれ
Racketで一通りプログラミングをした後、多分Unityでゲームでも作るんじゃないかなぁ?とか思ってたんだけど・・料金プランの一件で一気に風向きが変わってしまってUnity離れが進んでいるとか!?
代替の無料開発エンジンの候補として「Godot」なるものをよく見るので試しにインストールしてみるか・・
しかし!最近復活させたTiny10入りのVersaPro君に入れようとしたら「OpenGL3.3に対応してないので無理」とのこと。更に他のLinuxマシンにも入れようとしたらC#対応モードか専用スクリプト言語専用モード?とかややこしいし、そもそもインストールに失敗した。キィィ!
いやもう・・もっとサクッと手軽に環境作れて軽めのゲームらしきものを作れるモンないのかよ?3Dとか全く興味ないし!などと思ってたらハンドヘルドPC98の記事を書かれてる方のブログで「Pico8」なるものを知る。ぬっ!?敢えてキツい制限を設けた環境で8Bitゲーム時代リスペクトのゲームを作れるエンジンとな!?
大いに興味がそそられた!
が!15ドルの有料ソフトなのだ。うーん・・いやまあ、バイトで一晩泊まったら4〜5本は買えますよ?けどなぁ・・ほら〜僕ってドケチやん?なんとか無料で体験できたりしないの?とさらなる探索。
結果、Pico8リスペクトの無料エンジン「Tic-80」なるものの存在を知る。記事を読むと感覚的にはPico8に非常にそっくり(使用言語もLua)で、解像度やプログラムの長さの縛りを緩くしてあるという。
おお・・(・。・;
スプライトに背景、効果音にBGMなどのエディタも一式揃っている統合環境なのが嬉しい(Racketは音関係がね・・)。おいおい楽しみになってきたぜ!引き続き実用CLやSICPなんかでコンピュータ・サイエンス的な勉強もしつつ、これでゲーム作りに挑戦するってのは・・・天国かな?
あと、一応良く似たコンセプトでゲームボーイ準拠のゲームが作れるGB-Studioってのもあるらしい。こっちも良いなぁ・・
どちらも出来たプログラムはイメージとして出力してWEBなんかでもプレイ出来るみたいなので誰かにプレイしてもらうのに一苦労のRacketと比べるとモチベーションが高まりやすいかな?と。
LuaはDSのゲームを作ったりするのにも使えるそうなのでLisp系とは全く違う第二言語として挑戦するのも良さげかも。
うーん、また楽しくなってきた!
2023/11/06
話題その1 Paiza.ioで5目並べ的なものを作るつもり
実用Common-lipのオセロ作成の手順をなぞって
Paiza.ioをエディタを使用し
Racketでも動くものを作って
探索をちゃんと理解しよう、と。
大域変数関連は前回までに作っていたので、次は画面表示系を・・
Paiza.ioのScheme(と言うかGauche)にはRacketにはある「ist-set関数」が無いので自作する。多分探せばよく似たものはあると思うんですけどねぇ・・探すほうが面倒だったので。
盤面のデータを作る関数、Initial-boardを作る。原作ではCL独特のLoopマクロを使って作られてた。それをRacket版ではForを使って書きましたが・・SchemeにはForが無いので普通に名前付きLetで。
原作だと1が黒、2が白、空白が0で外壁が3・・となってて、表示するときにわざわざ変換してるんだけど・・意味ある?そもそもデータ作成時点で文字列にしておいてもいいのでは・・?
ということで変更。
もっと言うと、Vector形式にする必要があるのか・・ってのも気になってる。
List形式だとConsの集合なので操作が遅くなると言うが・・Racketで作ってるオセロも結局→List→操作→Vector再変換してるからなぁ・・一度Racketで速度の実験をしてみるか?
オセロの時にはできるだけ「RacketでCLの書き方を再現する」ってのを狙って書いてたつもり。
でも今回はSchemeって事もあるし発想と手順だけいただいて、思いついたやり方で書いてしまおう。
盤面データを表示するときは行の要素数で区切ったリストを作って表示するという事でいかが?遅くなるのかなぁ?
MapとLambdaでそのために必要な関数を書く。
SchemeにはFormatが(多分)無いので超基本的な書き方で表示。ま、表示はこれで良いんじゃないだろうか?SchemeでもRacketでも動く風に書いていこうと思います。
ただ・・今までの経験だとPaiza.ioでは(read-lines)が使えないんだよなぁ・・探索の学習ってことなら自動で動かすのがテーマだから問題は無いが。
というわけでようやく面白くなってきた。
話題その2 オセロの移植プログラムが変な理由
Racketでのオセロの問題もようやく問題点が分かってきた。思考部分は最終的にBest-move(指し手)の数値だけを返すように設計されてるのだけど、Racketでの書き方は再帰でBest-move とBest-valの2つを求めてるんだよな。だから最終の最終でBest-moveだけを返すようにすれば良いんじゃないか!?と。次回の宿直で挑戦しよう。
2023/11/01
話題その1 オセロの探索データの流れを見る
なんかボードの流れが飛んでるように思えたけど、実際飛んでいた。Board2はすでにこちらの一手を打ってるわけだから、その前のBoardも出す必要があったのだった。
33にWが打った後、Bの指し手のリストが出てるわけだな
次にBの43がMoveになって新しい盤面が作られている、と
で、ここが問題だな・・。valに(- minimaxで関数の逆転とかできてないじゃないか・・と。単純にbest-moveの値が‐されてしまってるだけなんだよなぁ。ここは盤面評価関数のcount-differenceの数値が返ってこないといけないのではないか?と。
話題その2 探索のおさらいの為にPaiza ioのSchemeで3目か5目並べ的なものを作るか・・
Chromebook・C200MAを持ち込んでいるバイト先でも書けるという理由でPiazaを使ってオセロと同じ手順で3目か5目並べを作ってみるか・・と思い立って書き始める。GaucheにはList-setが無い?ので書いたり。とりあえず盤面の初期化まで書いた
2023/10/29 探索が理解できた気がするけど実際の動きを見たい
脳内ではなんとなく動きが分かったと思ったけど、実際のデータの流れを見たいと思ってコードの途中にDisplayで数値とかを表示するようにしてみる
たった一手でこんなにデータがはじき出されてたのか・・働くねぇ。
早速読んでみるが・・あれ?なんで43 63 65 66 67なんてのが候補になってるんだ?おかしい・・ということで、このあとLegal-p?やWould-flip?とか元になってる関数をチェックしたり。ちゃんと動いてるはずなのに!?
あ・・そうか、最終的に上がってくるから一手目はラストの(66) 66 46のトコロだったわ(^_^;)
しかしデータだけで読んでいくのは困難・・ツリー形式で実際のBest-moveとかValとかを追いたい・・出来ればその時のボードも見たいということで・・処理が激重になるのを覚悟で更にコードを変えて
おおっ!1ゲーム10分位かかったけどGeekbenchでマルチスコア273のX200が頑張ってくれました。ちょっとこの出力を使ってデータの流れを追ってみようと思います。
2023/10/26 突然探索が理解できた
と言っても自分でも本当のところどうなのかはこれから何らかの自作プログラム(三目並べとかか?)を作ってみないと分からないのだが・・26日の19時10分頃、夜のお仕事に備えてシャワーを浴びて体を拭いてるときに突如
「そうだったのか!」
という感覚がやってきた。まあ、自己分析では「再帰」の理解がちょっと足りてなかったのが原因っぽいんですけどね。
なんとなくずっと頭の片隅にコードがあって、時々思い出して「うーん」とか思ってたら突然来た。かつての本業「オステオパシー」でも内臓マニピュレーションで肝臓の自動運動の動きを捉えるのに毎日1時間、太った友達のお腹に手を当て続けるというのを行った結果、1年後くらいに突然動きが分かるときが来た経験があるが・・身体的なものだけではなくて脳内のイメージ操作だったり論理的な流れの把握なんかでも同じなのだろうか?非常に興味深い!
とりあえずちょっと忙しいのでその後放置になってるけど、オセロのデータ表示部分を追加してデータを追ってみよう!久々に燃えてきたぜ・・・
2023/10/19 オセロの探索をまだ考えている(^_^;)
なんかどうにもちゃんと理解できてないのが気持ち悪いので、まだ探索について取り組んでいる。まあ、このままだと何も進まないので宿直バイトの週2〜3日の夜だけ探索について考えることにした。他の時間帯はプログラミング系の読書とかUdemyのWebデベロッパー講座をやったりしようかな?と。ゲームが作りたいって言っても子供の頃に挑戦できなかったことへのリベンジでしかないので、脳トレとしてやってると思えば探索の理解に年単位かかっても屁でも無いからね。
というわけで昨夜はとうとうアナログ作戦に切り替えた。紙にボードの状態を描いて深度ごとに必要になる値を実際に書き出してみる、と。
続いても実際のありそうな数字を書き出して見る。と・・おお・・なるほど!うまく行かないところが分かってきた気がする。問題はFinal-valueに(多分)あり!全部のコマを打ち終わる前にお互いに打つ手がなくなってしまった場合(無いとは言えないね?)に返るのもFinal-valueだけど、そこで初期値の0が返ってきてたから謎の0エラーが出ていたのだな。
しかし、もともとの仕様がそもそもおかしくないか?例えば先に伸びていく枝よりも確実にお互いの手がなくなっても勝てる選択肢があればそこを選ぶべきでは無いのか?とか、そうでない場合でもFinal-valuesで返す値が極大の整数、極大の負の整数とかってどういう意味があるのだろうか。
そし敵番で敵が勝利するFinal-valueを選ぶ枝は絶対に選んではいけないだろうし・・・
うーん・・こうなったら
1:他の言語でも良いのでオセロのプログラムを探して読む
2:この仕様を元に自分で作ってみる
のどっちかしか無いのでは?
あと-をつけるだけで敵の戦略になるってのもよく分からないな〜・・。返ってくる値がCount-differenceだったらまだ値がマイナスになれば計算ができそうな気もするけど・・
よし、次回からはコードを参考にせずに自分なりのMinimaxを書いてみよう。