▶ 実 行
▶ 実行
クリア
リバーシ(マルチスレッド版)
by てぃふと@うぇいく
# エディタ上で実行する場合は描画先の設定は不要 # 『#nako3_canvas_1』へ描画開始。 「全て」を実行速度優先する。 画面横は描画中キャンバス["width"] 画面縦は描画中キャンバス["height"] 定数の無は0 定数のメインスレッドマーカーは空 盤サイズは8 人数は2 探索深度は3 完全読手数は5 人間番は1 CPU思考時間は5 AB法ワーカー利用はオフ 完全読法ワーカー利用はオフ ABワーカー数は6 定数のカラーセットは{ "黒": {色:"黒", 駒:黒色, 枠:白色 }, "白": {色:"白", 駒:白色, 枠:黒色 }, "赤": {色:"赤", 駒:赤色, 枠:青色 }, "青": {色:"青", 駒:青色, 枠:赤色 } } 共通汎用部品は["盤スコア", "勝利スコア", "盤評価", "駒カウント", "手候補取得", "仮打", "着手判定", "方向位置", "人数", "盤サイズ", "無", "ABワーカー数", "ステータス表示"] AB法ワーカー化親部品は["AB法ワーカー依頼", "AB法ワーカー親ハンドラ", "AB法ワーカー準備", "AB法ワーカー初回準備", "AB法ワーカーリセット", "AB法ID", "AB法コールバック", "AB法ワーカー利用"] AB法ワーカー化子部品は["AB法ワーカー初期化", "AB法ワーカー子ハンドラ", "AB法ワーカー応答"] ABワーカー化親部品は["ABワーカー依頼", "ABワーカー処理受付", "ABワーカー親ハンドラ", "ABワーカー準備", "ABワーカー初回準備", "ABワーカーリセット", "ABワーカー後始末", "ワーカー状態調査", "ワーカー状態報告", "ABワーカー", "ABワーカー状態", "ABID", "ABコールバック", "ABワーカー依頼キュー", "共通汎用部品", "ABワーカー化子部品", "AB子部品", "ワーカーベースURL"] ABワーカー化子部品は["ABワーカー初期化", "ABワーカー子ハンドラ", "ABワーカー応答"] AB法親部品は["AB法"] AB法子部品は["非同期AB法"] AB親部品は["非同期AB時"] AB子部品は["AB"] 完読子部品は["完読"] # 仮打ちから参照 定数の方向位置は[ _ [-1,-1],[-1,0],[-1,1], _ [0,-1],[0,1], _ [1,-1],[1,0],[1,1] _ ] PLは[] 到達探索深度は0 到達行動は0 到達手は0 探索タイムアウトはオフ 探索コールバックは空 探索タイマIDは0 手番は0 連続パス人数は0 盤状態は、[] ステータス内容は[] 代打思考中はオフ ワーカー状態退避は[0,0] CPUエラー発生はオフ 中止要求はオフ AB法ワーカーは空 ABワーカーは[] マウスボタンハンドラは空 AB法コールバックは{} AB法IDは0 ABワーカー状態は[] ABコールバックは{} ABIDは0 ABワーカー依頼キューは[] ワーカーベースURLは空 ワーカー状態退避は[0,0] オプション選択ダイアグは空 ターン番号は0 最終考察深度は0 最終考察行動は空 最終考察手は[0, 0] 手探索コールバックは空 手探索タイムアウトはオフ # 0:なし/1:新手途中/2:新手置いた/3:返り途中/4:返り置いた(=0) 描画状態ステータスは0 新手セルは[] 新手色は無 返セルリストは[] # ミリ秒 描画遷移時間間隔は100 盤縦横は200 盤位置は[20,20] セル縦横は盤縦横÷盤サイズの整数部分 盤縦横はセル縦横×盤サイズ ステータス表示行数は12 ステータス行高さは16 ステータス位置は[盤位置[0]+盤縦横+8, 盤位置[1]+盤縦横-(ステータス表示行数×(ステータス行高さ+1))] 手番位置は[盤位置[0]+盤縦横÷2, 盤位置[1]+盤縦横+1] ワーカー状態位置は[画面横-1, 1] 中止サイズは[40,20] 中止位置は[盤位置[0]+盤縦横-中止サイズ[0], 0] パスサイズは[40,20] パス位置は[中止位置[0]-パスサイズ[0], 0] 代打サイズは[40,20] 代打位置は[パス位置[0]-代打サイズ[0], 0] # 盤スコアから参照 盤スコアは、[] 定数の勝利スコアは500 sは『<form method="dialog"> <table> <tbody> <tr> <th>サイズ・人数</th> <td> <label><input type="radio" name="size" value="6">6x6(2人)</label> <label><input type="radio" name="size" value="8" checked="checked">8x8(2人)</label> <label><input type="radio" name="size" value="12">12x12(4人)</label> </td> </tr> <tr> <th>人間の順番</th> <td> <label><input type="radio" name="nin" value="0">CPU観戦</label> <label><input type="radio" name="nin" value="1" checked="checked">先手</label> <label><input type="radio" name="nin" value="2">後手</label> </td> </tr> <tr> <th>初期配置</th> <td> <label><input type="radio" name="init" value="cross" checked="checked">クロス</label> </td> </tr> <tr> <th>賢さ(開始探索深度)</th> <td> <label><input type="radio" name="depth" value="1">1</label> <label><input type="radio" name="depth" value="2">2</label> <label><input type="radio" name="depth" value="3">3</label> <label><input type="radio" name="depth" value="4">4</label> <label><input type="radio" name="depth" value="5">5</label> <label><input type="radio" name="depth" value="6" checked="checked">6</label> <label><input type="radio" name="depth" value="7">7</label> <label><input type="radio" name="depth" value="8">8</label> <label><input type="radio" name="depth" value="9">9</label> <label><input type="radio" name="depth" value="10">10</label> </td> </tr> <tr> <th>賢さ(完全読み手数)</th> <td> <label><input type="radio" name="comp" value="0">0</label> <label><input type="radio" name="comp" value="1">1</label> <label><input type="radio" name="comp" value="2">2</label> <label><input type="radio" name="comp" value="3">3</label> <label><input type="radio" name="comp" value="4">4</label> <label><input type="radio" name="comp" value="5" checked="checked">5</label> <label><input type="radio" name="comp" value="8">8</label> <label><input type="radio" name="comp" value="10">10</label> <label><input type="radio" name="comp" value="12">12</label> <label><input type="radio" name="comp" value="15">15</label> </td> </tr> <tr> <th>賢さ(継続思考時間)</th> <td> <label><input type="radio" name="cputime" value="0">なし</label> <label><input type="radio" name="cputime" value="1">1秒</label> <label><input type="radio" name="cputime" value="3">3秒</label> <label><input type="radio" name="cputime" value="5" checked="checked">5秒</label> <label><input type="radio" name="cputime" value="10">10秒</label> <label><input type="radio" name="cputime" value="15">15秒</label> <label><input type="radio" name="cputime" value="30">30秒</label> <label><input type="radio" name="cputime" value="60">1分</label> <label><input type="radio" name="cputime" value="180">3分</label> <label><input type="radio" name="cputime" value="300">5分</label> </td> </tr> <tr> <th>AIスレッド数</th> <td> <label><input type="radio" name="worker" value="1">1</label> <label><input type="radio" name="worker" value="2">2</label> <label><input type="radio" name="worker" value="3">3</label> <label><input type="radio" name="worker" value="4">4</label> <label><input type="radio" name="worker" value="5">5</label> <label><input type="radio" name="worker" value="6" checked="checked">6</label> <label><input type="radio" name="worker" value="8">8</label> <label><input type="radio" name="worker" value="10">10</label> </td> </tr> </tbody> </table> <div style="text-align: center"> <button value="cancel">Cancel</button> <button value="start">開始</button> </div> </form>』 ●オプション選択画面表示とは もし、ダイアログ使用可能でなければ、 「ダイアログ要素が使用できないため、既定の設定で開始します」を表示する 初期化する AB法ワーカー初回準備する 開始する 戻る ここまで オプション選択ダイアグはsでダイアログ作成する。 オプション選択ダイアグを"body"にDOM子要素追加する オプション選択ダイアグの"close"に「DIALOG_CLOSE」をDOMイベント追加 対象テーブルはオプション選択ダイアグの"querySelector"を["table"]でJSメソッド実行 対象テーブルに初期選択色設定 対象テーブルの"change"に「RADIO_CLICK」をDOMイベント追加 オプション選択ダイアグのダイアログモーダル開く ここまで ●DIALOG_CLOSEとは 全要素はオプション選択ダイアグの"querySelectorAll"を["input:checked"]でJSメソッド実行 全要素数は全要素の配列要素数 全要素数回、 要素は全要素[回数-1] 要素名は要素["name"]の大文字変換 値は(要素["value"]-0) 要素名で条件分岐 「SIZE」ならば、 盤サイズは値 もし、盤サイズが12ならば、 人数は4 違えば 人数は2 ここまで ここまで 「NIN」ならば、 人間番は値 ここまで 「DEPTH」ならば、 探索深度は値 ここまで 「COMP」ならば、 完全読手数は値 ここまで 「CPUTIME」ならば、 CPU思考時間は値 ここまで 「WORKER」ならば、 ワーカー数は値 もし、ワーカー数が0ならば、 AB法ワーカー利用はオフ ABワーカー数は0 違えば、 AB法ワーカー利用はオフ ABワーカー数はワーカー数 ここまで ここまで ここまで ここまで 結果はオプション選択ダイアグ["returnValue"] オプション選択ダイアグの"close"から「DIALOG_CLOSE」をDOMイベント削除 対象テーブルはオプション選択ダイアグの"querySelector"を["table"]でJSメソッド実行 対象テーブルの"change"から「RADIO_CLICK」をDOMイベント削除 オプション選択ダイアグを"body"からDOM子要素削除する もし、結果が「start」ならば、 初期化する AB法ワーカー初回準備する 開始する 違えば、 「キャンセルされました。」を表示する。 ここまで ここまで ●(対象テーブルに)初期選択色設定とは LABELSは対象テーブルの"querySelectorAll"を["label"]でJSメソッド実行 ラベル数はLABELSの配列要素数 ラベル数回、 LはLABELS[回数-1] IはLの"querySelector"を["input"]でJSメソッド実行 もし、I["checked"]ならば、 Lの"背景色"に"#48f"をDOMスタイル設定 違えば、 Lの"背景色"に"#fff"をDOMスタイル設定 ここまで ここまで ここまで ●RADIO_CLICKとは EVTはWINDOW["event"] 対象はEVT["target"] もし、(対象["tagName"]を大文字変換)="INPUT"&&(対象["type"]を大文字変換)="RADIO"ならば、 LABELは対象 LABELの間、 もし、(LABEL["tagName"]を大文字変換)="LABEL"ならば、 抜ける ここまで LABELはLABEL["parentNode"] ここまで もし、LABELでなければ、 戻る ここまで TDはLABEL TDの間、 もし、(TD["tagName"]を大文字変換)="TD"ならば、 抜ける ここまで TDはTD["parentNode"] ここまで もし、TDでなければ、 戻る ここまで LABELSはTDの"querySelectorAll"を["label"]でJSメソッド実行 ラベル数はLABELSの配列要素数 ラベル数回、 LはLABELS[回数-1] Lの"背景色"に"#fff"をDOMスタイル設定 ここまで LABELの"背景色"に"#48f"をDOMスタイル設定 ここまで ここまで ●初期化とは もし、盤サイズ=8&&人数=2ならば、 盤スコアは、[ _ [ 120, -20, 20, 5, 5, 20, -20, 120], _ [ -20, -40, -5, -5, -5, -5, -40, -20], _ [ 20, -5, 15, 3, 3, 15, -5, 20], _ [ 5, -5, 3, 3, 3, 3, -5, 5], _ [ 5, -5, 3, 3, 3, 3, -5, 5], _ [ 20, -5, 15, 3, 3, 15, -5, 20], _ [ -20, -40, -5, -5, -5, -5, -40, -20], _ [ 120, -20, 20, 5, 5, 20, -20, 120] _ ] 盤状態は、[ _ [0,0,0,0,0,0,0,0], _ [0,0,0,0,0,0,0,0], _ [0,0,0,0,0,0,0,0], _ [0,0,0,2,1,0,0,0], _ [0,0,0,1,2,0,0,0], _ [0,0,0,0,0,0,0,0], _ [0,0,0,0,0,0,0,0], _ [0,0,0,0,0,0,0,0] _ ] PL[1]はカラーセット["黒"] PL[2]はカラーセット["白"] 違えばもし、盤サイズ=6&&人数=2ならば、 盤スコアは、[ _ [ 120, -20, 5, 5, -20, 120], _ [ -20, -40, -5, -5, -40, -20], _ [ 5, -5, 3, 3, -5, 5], _ [ 5, -5, 3, 3, -5, 5], _ [ -20, -40, -5, -5, -40, -20], _ [ 120, -20, 5, 5, -20, 120] _ ] 盤状態は、[ _ [0,0,0,0,0,0], _ [0,0,0,0,0,0], _ [0,0,2,1,0,0], _ [0,0,1,2,0,0], _ [0,0,0,0,0,0], _ [0,0,0,0,0,0] _ ] PL[1]はカラーセット["黒"] PL[2]はカラーセット["白"] 違えばもし、盤サイズ=12&&人数=4ならば、 盤スコアは、[ _ [ 120, -20, 20, 5, 5, 5, 5, 5, 5, 20, -20, 120], _ [ -20, -40, -5, -5, -5, -5, -5, -5, -5, -5, -40, -20], _ [ 20, -5, 15, 3, 3, 3, 3, 3, 3, 15, -5, 20], _ [ 5, -5, 3, 3, 3, 3, 3, 3, 3, 3, -5, 5], _ [ 5, -5, 3, 3, 3, 3, 3, 3, 3, 3, -5, 5], _ [ 5, -5, 3, 3, 3, 3, 3, 3, 3, 3, -5, 5], _ [ 5, -5, 3, 3, 3, 3, 3, 3, 3, 3, -5, 5], _ [ 5, -5, 3, 3, 3, 3, 3, 3, 3, 3, -5, 5], _ [ 5, -5, 3, 3, 3, 3, 3, 3, 3, 3, -5, 5], _ [ 20, -5, 15, 3, 3, 3, 3, 3, 3, 15, -5, 20], _ [ -20, -40, -5, -5, -5, -5, -5, -5, -5, -5, -40, -20], _ [ 120, -20, 20, 5, 5, 5, 5, 5, 5, 20, -20, 120], _ ] 盤状態は、[ _ [0,0,0,0,0,0,0,0,0,0,0,0], _ [0,0,0,0,0,0,0,0,0,0,0,0], _ [0,0,0,0,0,0,0,0,0,0,0,0], _ [0,0,0,2,1,0,0,2,3,0,0,0], _ [0,0,0,1,2,0,0,3,2,0,0,0], _ [0,0,0,0,0,0,0,0,0,0,0,0], _ [0,0,0,0,0,0,0,0,0,0,0,0], _ [0,0,0,4,1,0,0,4,3,0,0,0], _ [0,0,0,1,4,0,0,3,4,0,0,0], _ [0,0,0,0,0,0,0,0,0,0,0,0], _ [0,0,0,0,0,0,0,0,0,0,0,0], _ [0,0,0,0,0,0,0,0,0,0,0,0] _ ] PL[1]はカラーセット["黒"] PL[2]はカラーセット["白"] PL[3]はカラーセット["赤"] PL[4]はカラーセット["青"] 違えば、 「初期の盤面が解りません。サイズを8か6にして、人数を2人にしてください」を言う 戻る ここまで 手番は0 連続パス人数は0 CPUエラー発生はオフ 中止要求はオフ セル縦横は盤縦横÷盤サイズの整数部分 盤縦横はセル縦横×盤サイズ ステータス位置は[盤位置[0]+盤縦横+8, 盤位置[1]+盤縦横-(ステータス表示行数×(ステータス行高さ+1))] 手番位置は[盤位置[0]+盤縦横÷2, 盤位置[1]+盤縦横+1] 中止位置は[盤位置[0]+盤縦横-中止サイズ[0], 0] パス位置は[中止位置[0]-パスサイズ[0], 0] 代打位置は[パス位置[0]-代打サイズ[0], 0] 描画中キャンバスの「mousedown」に「マウスボタン処理」をDOMイベント追加 ここまで ●マウスボタン処理とは EVTはWINDOW["event"] 要素位置はEVT["target"]の"getBoundingClientRect"を[]でJSメソッド実行 XはEVT["clientX"]-要素位置["left"] YはEVT["clientY"]-要素位置["top"] もし、マウスボタンハンドラが空でなければ、 マウスボタンハンドラ(X,Y) ここまで ここまで ●(XYで位置とサイズに)ボタンヒットとは もし、(XY[0]≧位置[0])&&(XY[0]≦位置[0]+サイズ[0])ならば、 もし、(XY[1]≧位置[1])&&(XY[1]≦位置[1]+サイズ[1])ならば、 オンで戻る ここまで ここまで オフで戻る ここまで ●(XとYで)ゲーム中マウスボタン処理とは 位置は[X, Y] もし、(位置でパス位置とパスサイズにボタンヒット)ならば、 パスクリック ここまで もし、(位置で中止位置と中止サイズにボタンヒット)ならば、 中止クリック ここまで もし、(位置で代打位置と代打サイズにボタンヒット)ならば、 代打クリック ここまで もし、(X≧盤位置[0])&&(X≦盤位置[0]+盤縦横)ならば、 もし、(Y≧盤位置[1])&&(Y≦盤位置[1]+盤縦横)ならば、 セルXは(X-盤位置[0])/セル縦横+1の整数部分 セルYは(Y-盤位置[1])/セル縦横+1の整数部分 [セルX,セルY]をセルクリック ここまで ここまで ここまで ●開始とは マウスボタンハンドラは「ゲーム中マウスボタン処理」のJSオブジェクト取得 画面表示する 手番進む ここまで ●終了処理とは マウスボタンハンドラは空 ターン番号は0 最終考察深度は0 描画中キャンバスの「mousedown」から「マウスボタン処理」をDOMイベント削除 もし、CPUエラー発生ならば、 「CPUのエラーにより終了しました。」をステータス表示 違えばもし、中止要求ならば 「中止ボタンにより終了しました。」をステータス表示 違えば、 カウントは盤状態を駒カウント 勝利者は1 同率一位は[] 人数回、 Iは回数 もし、I≠勝利者&&カウント[I]>カウント[勝利者]ならば 勝利者はI 同率一位は[] ここまで もし、カウント[I]=カウント[勝利者]ならば 同率一位にPL[I]["色"]を配列追加 ここまで ここまで もし、(同率一位の配列要素数)=人数ならば、 「引き分けに終わりました。」をステータス表示 ここまで もし、(同率一位の配列要素数)>1ならば、 勝利者名は同率一位を"と"で配列結合する 勝利者名+「が同数で勝ちです。」をステータス表示 違えば、 同率一位[0]+「の勝ちです。」をステータス表示 ここまで ここまで 「お疲れさまでした」をステータス表示 AB法ワーカー後始末する ABワーカー後始末する ここまで ●画面表示とは [0, 0, 画面横, 画面縦]に描画クリア 盤状態を盤表示 各ボタン表示 ステータス内容をステータス描画 ワーカー状態退避をワーカー状態表示 手番表示 ここまで ●手番表示とは 左上は[手番位置[0]-盤縦横÷2, 手番位置[1]] [左上[0], 左上[1], 画面横-左上[0], 画面縦-左上[1]]に描画クリア もし、手番が無ならば、 情報は「まだ始まっていません」 違えばもし、手番が人間番ならば、 情報は「今はあなた(」+PL[手番]["色"]+「)の番です」 違えば、 情報は「今はわたし(」+PL[手番]["色"]+「)の番です」 ここまで キャンバス状態保存 黒色に塗り色設定 黒色に線色設定 描画中コンテキスト["textAlign"]は"center" 描画中コンテキスト["textBaseline"]は"top" [手番位置[0], 手番位置[1]]に情報を文字描画 キャンバス状態復元 ここまで ●(ステータスを)ステータス描画とは [ステータス位置[0], ステータス位置[1], 画面横-ステータス位置[0], 画面縦-ステータス位置[1]]に描画クリア もし、(ステータスの配列要素数)が0ならば、 戻る ここまで 黒色に塗り色設定 黒色に線色設定 (ステータスの配列要素数)回、 Iは回数 内容はステータス[I-1] [ステータス位置[0], ステータス位置[1]+I*ステータス行高さ]に内容を文字描画 ここまで ここまで ●(矩形にオプションで文字を)二文字ボタン表示とは キャンバス状態保存 オプション["背景色"]に塗り色設定 オプション["枠色"]に線色設定 1に線太さ設定 [矩形[0], 矩形[1], 矩形[2], 矩形[3]]へ四角描画 オプション["文字色"]に塗り色設定 「16px bold sans-serif」に描画フォント設定 描画中コンテキスト["textAlign"]は"center" 描画中コンテキスト["textBaseline"]は"middle" [矩形[0]+矩形[2]÷2, 矩形[1]+矩形[3]÷2]に文字を文字描画 キャンバス状態復元 ここまで ●各ボタン表示とは 矩形は[中止位置[0], 中止位置[1], 中止サイズ[0], 中止サイズ[1]] オプションは{背景色:赤色 ,枠色:黄色, 文字色:黒色} 矩形にオプションで「中止」を二文字ボタン表示 矩形は[パス位置[0], パス位置[1], パスサイズ[0], パスサイズ[1]] オプションは{背景色:黄色 ,枠色:青色, 文字色:赤色} 矩形にオプションで「パス」を二文字ボタン表示 矩形は[代打位置[0], 代打位置[1], 代打サイズ[0], 代打サイズ[1]] オプションは{背景色:水色 ,枠色:青色, 文字色:黒色} 矩形にオプションで「代打」を二文字ボタン表示 ここまで ●ワーカー状態調査とは 総数はABワーカーの配列要素数 稼働数は0 総数回、 Iは回数-1 もし、ABワーカー状態[I]でなければ、 稼働数は稼働数+1 ここまで ここまで [稼働数, 総数]で戻る ここまで ●(状態を)ワーカー状態表示とは [ワーカー状態位置[0]-60, ワーカー状態位置[1], 画面横-(ワーカー状態位置[0]-60), 14]に描画クリア 総数は状態[1] 稼働数は状態[0] もし、総数が0ならば、 戻る ここまで ワーカー状態退避は状態 キャンバス状態保存 黒色に塗り色設定 「12px sans-serif」に描画フォント設定 描画中コンテキスト["textAlign"]は"right" 描画中コンテキスト["textBaseline"]は"top" 表示文字列は「(」+稼働数+「/」+総数+「)」 [ワーカー状態位置[0], ワーカー状態位置[1]]に表示文字列を文字描画 キャンバス状態復元 ここまで ●(盤状態を)盤表示とは [盤位置[0], 盤位置[1], 盤縦横, 盤縦横]に描画クリア 緑色に塗り色設定 黒色に線色設定 1に線太さ設定 [盤位置[0], 盤位置[1], 盤縦横, 盤縦横]へ四角描画 白色に線色設定 (盤サイズ-1)回、 Iは回数 [盤位置[0]+I*セル縦横, 盤位置[1]]から[盤位置[0]+I*セル縦横, 盤位置[1]+盤縦横]へ線描画 [盤位置[0], 盤位置[1]+I*セル縦横]から[盤位置[0]+盤縦横, 盤位置[1]+I*セル縦横]へ線描画 ここまで 盤サイズ回、 Yは回数 盤サイズ回、 Xは回数 駒は盤状態[Y-1][X-1] もし、駒が無でなければ、 PL[駒]["駒"]に塗り色設定 PL[駒]["枠"]に線色設定 [盤位置[0]+X*セル縦横-セル縦横/2, 盤位置[1]+Y*セル縦横-セル縦横/2]にセル縦横/2-2の円描画 ここまで ここまで ここまで 描画状態ステータスで条件分岐 1ならば、 もし、(描画中コンテキスト["ellipse"]の変数型確認)≠"undefined"ならば、 駒は新手色 Xは新手セル[0] Yは新手セル[1] PL[駒]["駒"]に塗り色設定 PL[駒]["枠"]に線色設定 描画中コンテキストの"beginPath"を[]でJSメソッド実行 描画中コンテキストの"ellipse"を[盤位置[0]+X*セル縦横-セル縦横/2, 盤位置[1]+Y*セル縦横-(セル縦横/8*5)-2, セル縦横/2-2, (セル縦横/4-4)*1.8, 0, 0, 2*JS実行("Math.PI")]でJSメソッド実行 描画中コンテキストの"fill"を[]でJSメソッド実行 描画中コンテキストの"stroke"を[]でJSメソッド実行 描画中コンテキストの"beginPath"を[]でJSメソッド実行 描画中コンテキストの"ellipse"を[盤位置[0]+X*セル縦横-セル縦横/2, 盤位置[1]+Y*セル縦横-(セル縦横/8*5)-2, セル縦横/2-2, (セル縦横/4-4)*1.8, 0, JS実行("Math.PI"),0 , 1]でJSメソッド実行 描画中コンテキストの"lineTo"を[盤位置[0]+X*セル縦横-2, 盤位置[1]+Y*セル縦横-(セル縦横/8*5)-2]でJSメソッド実行 描画中コンテキストの"ellipse"を[盤位置[0]+X*セル縦横-セル縦横/2, 盤位置[1]+Y*セル縦横-(セル縦横/8*5)-2+2, セル縦横/2-2, (セル縦横/4-4)*1.8, 0, 0, JS実行("Math.PI")]でJSメソッド実行 描画中コンテキストの"lineTo"を[盤位置[0]+X*セル縦横-セル縦横+1, 盤位置[1]+Y*セル縦横-(セル縦横/8*5)-2]でJSメソッド実行 描画中コンテキストの"fill"を[]でJSメソッド実行 描画中コンテキストの"stroke"を[]でJSメソッド実行 PL[駒]["枠"]に塗り色設定 PL[駒]["駒"]に線色設定 描画中コンテキストの"beginPath"を[]でJSメソッド実行 描画中コンテキストの"ellipse"を[盤位置[0]+X*セル縦横-セル縦横/2, 盤位置[1]+Y*セル縦横-(セル縦横/8*5)-2+2, セル縦横/2-2, (セル縦横/4-4)*1.8, 0, JS実行("Math.PI"),0 , 1]でJSメソッド実行 描画中コンテキストの"lineTo"を[盤位置[0]+X*セル縦横-2, 盤位置[1]+Y*セル縦横-(セル縦横/8*5)-2+2]でJSメソッド実行 描画中コンテキストの"ellipse"を[盤位置[0]+X*セル縦横-セル縦横/2, 盤位置[1]+Y*セル縦横-(セル縦横/8*5)-2+4, セル縦横/2-2, (セル縦横/4-4)*1.8, 0, 0, JS実行("Math.PI")]でJSメソッド実行 描画中コンテキストの"lineTo"を[盤位置[0]+X*セル縦横-セル縦横+1, 盤位置[1]+Y*セル縦横-(セル縦横/8*5)-2]でJSメソッド実行 描画中コンテキストの"fill"を[]でJSメソッド実行 描画中コンテキストの"stroke"を[]でJSメソッド実行 ここまで ここまで 3ならば、 (返セルリストの配列要素数)回、 Iは回数-1 セルは返セルリスト[I] Xはセル["セル"][0] Yはセル["セル"][1] 駒はセル["駒色"] PL[駒]["駒"]に塗り色設定 PL[駒]["枠"]に線色設定 [盤位置[0]+X*セル縦横-セル縦横/2-3, 盤位置[1]+(Y-1)*セル縦横+2, 3, セル縦横-4]へ四角描画 駒は新手色 PL[駒]["駒"]に塗り色設定 PL[駒]["枠"]に線色設定 [盤位置[0]+X*セル縦横-セル縦横/2+0, 盤位置[1]+(Y-1)*セル縦横+2, 3, セル縦横-4]へ四角描画 ここまで ここまで ここまで ここまで ●(MSGを)ステータス表示とは もし、(メインスレッドマーカーの変数型確認)="undefined"ならば、 { TYPE: "表示", DATA: MSG }をNAKOワーカーデータ送信する 戻る ここまで もし、(ステータス内容の配列要素数)がステータス表示行数ならば、 ステータス内容の0を配列切取する ここまで ステータス内容にMSGを配列追加する ステータス内容をステータス描画 ここまで ●(盤を)駒カウントとは カウントは[0,0,0,0,0] 盤サイズ回、 Yは回数-1 盤サイズ回、 Xは回数-1 駒は盤[Y][X] カウント[駒]はカウント[駒]+1 ここまで ここまで カウントで戻る ここまで ●(仮盤状態を)終局判定とは もし、連続パス人数≧人数ならば、 「全員がパスしたので終わりです。」をステータス表示 0秒後には 終了処理 ここまで オンで戻る ここまで カウントは仮盤状態を駒カウント 生存は0 人数回、 Iは回数 もし、カウント[I]>0ならば 生存は生存+1 ここまで ここまで もし、カウント[無]=0||生存=1ならば、 もし、カウント[無]=0ならば、 「空いている升がありません。」をステータス表示 違えば 人数回、 Iは回数 もし、カウント[I]>0ならば、 PL[I]["色"]+「以外が盤から一掃されました。」をステータス表示 抜ける ここまで ここまで ここまで 0秒後には 終了処理 ここまで オンで戻る ここまで オフで戻る ここまで ●中止処理とは 「中止が押されました。」をステータス表示 中止要求はオン 0秒後には 終了処理 ここまで ここまで # 着手判定を利用 ●(盤状態に自色が)パス判定とは セル位置は[0, 0] 盤サイズ回、 Yは回数 盤サイズ回、 Xは回数 セル位置[0]はX セル位置[1]はY 打可は盤状態にセル位置を自色で着手判定 もし、打可ならば オフで戻る ここまで ここまで ここまで オンで戻る ここまで # 方向位置を参照 ●(仮盤状態にセル位置を自色で)仮打ちとは ゲットは0 OXはセル位置[0]-1 OYはセル位置[1]-1 (方向位置の配列要素数)回、 Iは回数-1 方向は方向位置[I] XはOX YはOY オンの間、 X=X+方向[0] Y=Y+方向[1] もし、X<0||X≧盤サイズ||Y<0||Y≧盤サイズならば、 抜ける ここまで 駒は仮盤状態[Y][X] もし、駒が無ならば、 抜ける ここまで もし、駒が自色ならば、 オンの間、 X=X-方向[0] Y=Y-方向[1] もし、X=OX&&Y=OYならば、 抜ける ここまで ゲットはゲット+1 仮盤状態[Y][X]は自色 ここまで 抜ける ここまで ここまで ここまで もし、ゲット>0ならば 仮盤状態[OY][OX]は自色 ここまで ゲットを戻す ここまで ●(セル位置に手番を)駒置くとは OXはセル位置[0]-1 OYはセル位置[1]-1 もし、盤状態[OY][OX]=無でなければ、 「駒のある所には置けません」をステータス表示 オフで戻る ここまで もし、(盤状態にセル位置を手番で着手判定)でなければ、 「駒を取れないところには置けません」をステータス表示 オフで戻る ここまで 返セルリストは[] (方向位置の配列要素数)回、 Iは回数-1 方向は方向位置[I] XはOX YはOY オンの間、 X=X+方向[0] Y=Y+方向[1] もし、X<0||X≧盤サイズ||Y<0||Y≧盤サイズならば、 抜ける ここまで 駒は盤状態[Y][X] もし、駒が無ならば、 抜ける ここまで もし、駒が手番ならば、 オンの間、 X=X-方向[0] Y=Y-方向[1] もし、X=OX&&Y=OYならば、 抜ける ここまで 返セルリストに{ セル:[X+1, Y+1], 駒色: 盤状態[Y][X] }を配列追加 ここまで 抜ける ここまで ここまで ここまで 新手セルは[OX+1, OY+1] 新手色は手番 オンで戻る ここまで ●描画状態進行とは 描画状態ステータスで条件分岐 0ならば、 描画状態ステータスは1 盤状態を盤表示 ここまで 1ならば、 描画状態ステータスは2 盤状態[新手セル[1]-1][新手セル[0]-1]は新手色 盤状態を盤表示 ここまで 2ならば、 描画状態ステータスは3 (返セルリストの配列要素数)回、 Iは回数-1 セルは返セルリスト[I]["セル"] 盤状態[セル[1]-1][セル[0]-1]は無 ここまで 盤状態を盤表示 ここまで 3ならば、 描画状態ステータスは0 (返セルリストの配列要素数)回、 Iは回数-1 セルは返セルリスト[I]["セル"] 盤状態[セル[1]-1][セル[0]-1]は新手色 ここまで 盤状態を盤表示 0秒後には 手番進む ここまで ここまで ここまで もし、描画状態ステータス>0ならば、 (描画遷移時間間隔÷1000)秒後には 描画状態進行する ここまで ここまで ここまで ●手番進むとは 画面表示する もし、盤状態を終局判定ならば、 戻る ここまで 手番は手番+1 もし、手番>人数ならば 手番=1 ここまで 手番表示 0秒後には もし、手番が人間番ならば、 人間思考実行 違えば、 CPU思考実行 ここまで ここまで ここまで ●パス処理とは 連続パス人数は連続パス人数+1 0秒後には、 手番進む ここまで ここまで ●パス選択とは 「パスします。」をステータス表示 もし、盤状態に手番がパス判定でなければ、 「が、置けるのにパスはできません」をステータス表示 いいえで戻る ここまで 0秒後には、 パス処理 ここまで はいで戻る ここまで ●(次手で)手番実行とは もし、次手[0]=0ならば、 「手がおかしいです」をステータス表示 次手をステータス表示 いいえで戻る ここまで 結果は次手に手番を駒置く もし、結果でなければ、 いいえで戻る ここまで 連続パス人数は0 描画状態ステータスは0 0秒後には、 描画状態進行する ここまで はいで戻る ここまで ##### 人間/CPU固有処置 ●人間思考実行とは # 人間の操作待ち ここまで ●CPU思考実行とは 0秒後には、 盤状態に手番で次手探索には(行動, 手) 行動で条件分岐 「パス」ならば、 CPUパス選択 ここまで 「手」ならば、 手でCPU手番実行 ここまで 違えば 「CPUのAIが変な応答(」+行動+「)を返しました」を表示 ここまで ここまで ここまで ここまで ここまで ##### 補助処理 # 方向位置を参照 ●(盤状態にセル位置を自色で)着手判定とは OXはセル位置[0]-1 OYはセル位置[1]-1 もし、盤状態[OY][OX]が無でなければ、 オフで戻る ここまで (方向位置の配列要素数)回、 Iは回数-1 方向は方向位置[I] XはOX YはOY Cは0 オンの間、 X=X+方向[0] Y=Y+方向[1] C=C+1 もし、X<0||X≧盤サイズ||Y<0||Y≧盤サイズならば、 抜ける ここまで 駒は盤状態[Y][X] もし、駒が無ならば、 抜ける ここまで もし、駒が自色ならば、 もし、C>1ならば、 オンで戻る ここまで 抜ける ここまで ここまで ここまで オフで戻る ここまで # 着手判定を利用 ●(盤状態を)着手数カウントとは カウントは[0,0,0,0,0] セル位置は[0, 0] 盤サイズ回、 Yは回数 盤サイズ回、 Xは回数 セル位置[0]はX セル位置[1]はY 駒は盤状態[Y-1][X-1] もし、駒が無ならば、 人数回、 駒色は回数 もし、盤状態にセル位置を駒色で着手判定ならば、 カウント[駒色]はカウント[駒色]+1 ここまで ここまで ここまで ここまで ここまで カウントで戻る ここまで # 盤スコアを参照 # 勝利スコアを参照 # 着手判定を利用 ●(盤から手番の)盤評価とは スコアは0 カウントは[0,0,0,0,0] 手カウントは[0,0,0,0,0] セル位置は[0, 0] 総手カウントは0 盤サイズ回、 Yは回数-1 盤サイズ回、 Xは回数-1 駒は盤[Y][X] カウント[駒]はカウント[駒]+1 もし、駒が無ならば 人数回、 駒色は回数 セル位置[0]はX+1 セル位置[1]はY+1 もし、盤にセル位置を駒色で着手判定ならば、 手カウント[駒色]は手カウント[駒色]+1 総手カウントは総手カウント+1 ここまで ここまで 違えば、 もし、駒が手番ならば スコア=スコア+盤スコア[Y][X] 違えば、 スコア=スコア-盤スコア[Y][X] ここまで ここまで ここまで ここまで 生存は0 勝利はオフ 終局はオフ もし、総手カウント=0ならば、 勝利はオン 人数回、 Iは回数 もし、I≠手番&&カウント[I]≧カウント[手番]ならば 勝利はオフ 抜ける ここまで ここまで 終局はオン ここまで もし、勝利ならば、 スコア=スコア+勝利スコア ここまで { SCORE:スコア, WIN: 勝利, END: 終局, COUNT: カウント[手番] }を戻す ここまで ●(仮盤状態に自色で)手候補取得とは 手候補リストは[] 一時盤状態は仮盤状態を配列複製 セル位置は[0, 0] 盤サイズ回、 Yは回数 盤サイズ回、 Xは回数 駒は仮盤状態[Y-1][X-1] セル位置[0]はX セル位置[1]はY もし、駒が無ならば、 仮ゲット数は一時盤状態にセル位置を自色で仮打ち もし、仮ゲット数>0ならば 手候補は{} 手候補["手"]はセル位置 手候補["事後"]は一時盤状態 手候補リストに手候補を配列追加 一時盤状態は仮盤状態を配列複製 セル位置は[0, 0] ここまで ここまで ここまで ここまで 手候補リストで戻る ここまで ●(CALLBACKへ仮盤状態に仮手番で)次手探索とは カウンタは仮盤状態を駒カウント ターン番号はカウンタ[無] 手探索コールバックはCALLBACK 手探索タイムアウトはオフ 最終考察深度は0 最終考察行動は「パス」 最終考察手は[0,0] 状態は{ 深度: 探索深度, ターン: ターン番号, 盤: 仮盤状態, 手番: 仮手番 } もし、ターン番号≦完全読手数ならば、 「完全読み開始(」+PL[仮手番]["色"]+「)」をステータス表示 状態が状態["盤"]に状態["手番"]で完全読み法には(行動, 手, 終局, 状態) ターン番号は0 「完全読み(」+状態["ターン"]+「):」+行動+「(」+手+「)」をステータス表示 AB法ワーカーリセット 手探索コールバック(行動, 手) ここまで 違えば、 もし、CPU思考時間>0ならば、 (CPU思考時間)秒後には、 手探索タイムアウトはオン もし、最終考察深度>0ならば、 ターン番号は0 「」+CPU思考時間+「秒:(探索深度:」+最終考察深度+「):」+最終考察行動+「(」+最終考察手+「)」をステータス表示 AB法ワーカーリセット 手探索コールバック(最終考察行動, 最終考察手) ここまで ここまで 違えば、 手探索タイムアウトはオン ここまで 「探索開始(」+PL[仮手番]["色"]+「:探索深度:」+状態["深度"]+「)」をステータス表示 「次手継続探索」のJSオブジェクト取得へ状態が状態["盤"]に状態["手番"]で状態["深度"]までAB法 ここまで ここまで ●次手継続探索(行動, 手, 終局, 状態)とは もし、状態["ターン"]≠ターン番号ならば、 戻る ここまで もし、手探索タイムアウトならば、 ターン番号は0 「時間超過(探索深度:」+状態["深度"]+「):」+行動+「(」+手+「)」をステータス表示 AB法ワーカーリセット 手探索コールバック(行動, 手) 違えばもし、終局ならば、 ターン番号は0 最終考察深度は状態["深度"] 最終考察行動は行動 最終考察手は手 「探索終局(探索深度:」+状態["深度"]+「):」+行動+「(」+手+「)」をステータス表示 AB法ワーカーリセット # 手探索コールバック(行動, 手) # タイマリセットができないので、タイムアウトを待つ 違えばもし、行動=「パス」ならば、 ターン番号は0 最終考察深度は状態["深度"] 最終考察行動は行動 最終考察手は手 「探索パス(探索深度:」+状態["深度"]+「):」+行動+「」をステータス表示 AB法ワーカーリセット # 手探索コールバック(行動, 手) # タイマリセットができないので、タイムアウトを待つ 違えば、、 最終考察深度は状態["深度"] 最終考察行動は行動 最終考察手は手 「探索継続(探索深度:」+状態["深度"]+「):」+行動+「(」+手+「)」をステータス表示 状態["深度"]は状態["深度"]+1 「次手継続探索」のJSオブジェクト取得へ状態が状態["盤"]に状態["手番"]で状態["深度"]までAB法 ここまで ここまで ##### 完全読みによる思考ルーチン ●(CALLBACKへ状態が盤に手番で)完全読み法とは もし、完全読法ワーカー利用ならば、 #未実装 違えば、 CALLBACKへ状態が盤に手番で非同期完全読み法 ここまで ここまで ●(CALLBACKへ状態が仮盤状態に仮手番で)非同期完全読み法とは 自手番は仮手番 次手は[0,0] 手候補リストは仮盤状態に自手番で手候補取得 手候補数は手候補リストの配列要素数 もし、手候補数=0ならば、 評価は仮盤状態から自手番の盤評価 CALLBACK("パス", [],評価["END"], 状態) 戻る ここまで 次手番は仮手番+1 もし、次手番>人数ならば、 次手番は1 ここまで マスターキーは"Date.now()"をJS実行 下限は-99999 上限は99999 完全読法状態は{ 手候補数: 手候補数, 応答数: 0, マスターキー: マスターキー, 依頼側状態: 状態, 手: [0,0], 勝利: オフ, コマ数: -1, スコア: 下限, コールバック: CALLBACK } 手候補数回、 Nは回数 依頼キーは「」+マスターキー+「-」+N+「」 手候補は手候補リスト[N-1] 自状態は{ キー: 依頼キー, 手:手候補["手"], 共通: 完全読法状態 } 自状態が手候補["事後"]に次手番で自手番を上限と完全読法状態["スコア"]まで非同期完全読み解いた時には(評価, 状態) 完全読法状態は状態["共通"] キー要素は状態["キー"]を「-」で区切る マスターキーはキー要素[0] 枝番はキー要素[1] もし、マスターキーが完全読法状態["マスターキー"]でなければ、 戻る ここまで 完全読法状態["応答数"]は完全読法状態["応答数"]+1 もし、評価["SCORE"]>完全読法状態["スコア"]ならば 完全読法状態["スコア"]は評価["SCORE"] 完全読法状態["勝利"]は評価["WIN"] 完全読法状態["コマ数"]は評価["COUNT"] 完全読法状態["手"]は状態["手"] ここまで もし、完全読法状態["応答数"]=完全読法状態["手候補数"]ならば、 CALLBACKは完全読法状態["コールバック"] 依頼側状態は完全読法状態["依頼側状態"] もし、完全読法状態["手"][0]が0ならば、 CALLBACK(「パス」, 「」, オン, 依頼側状態) 違えば、 CALLBACK(「手」, 完全読法状態["手"], オン, 依頼側状態) ここまで ここまで ここまで ここまで ここまで ●(CALLBACKへ状態が仮盤状態に仮手番で自手番を上限と下限まで)非同期完全読解時とは 自状態は{ コールバック: CALLBACK, 依頼側状態: 状態 } もし、ABワーカー数>0ならば、 自状態が仮盤状態に仮手番で自手番を上限と下限まで完読ワーカー依頼には(評価, 自状態) CALLBACKは自状態["コールバック"] 状態は自状態["依頼側状態"] CALLBACK(評価, 状態) ここまで 違えば、 評価は仮盤状態に仮手番で自手番を上限と下限まで完読 CALLBACK(評価, 状態) ここまで ここまで ●(仮盤状態に仮手番で自手番を上限と下限まで)完読とは 手候補リストは仮盤状態に仮手番で手候補取得 もし、(手候補リストの配列要素数)が0ならば、 評価は仮盤状態から自手番の盤評価 もし、評価["END"]ならば、 スコアは評価["COUNT"] もし、 評価["WIN"]ならば、 スコアはスコア+200 ここまで { WIN: 評価["WIN"], COUNT: 評価["COUNT"], SCORE: スコア }で戻る ここまで 手候補リストに{ 手: [0,0], 事後: 仮盤状態}を配列追加 ここまで カウントは仮盤状態を駒カウント 次手番は仮手番+1 もし、次手番>人数ならば、 次手番は1 ここまで コマ数は0 勝利はオフ スコアは0 もし、仮手番が自手番ならば、 (手候補リストの配列要素数)回、 Nは回数 手候補は手候補リスト[N-1] 評価は手候補["事後"]に次手番で自手番を上限と下限まで完読 もし、評価["SCORE"]>下限ならば 下限は評価["SCORE"] コマ数は評価["COUNT"] 勝利は評価["WIN"] ここまで もし、下限≧上限ならば、 抜ける ここまで ここまで スコアは下限 違えば、 閾値は9999 (手候補リストの配列要素数)回、 Nは回数 手候補は手候補リスト[N-1] 評価は手候補["事後"]に次手番で自手番を上限と下限まで完読 もし、評価["SCORE"]<上限ならば 上限は評価["SCORE"] コマ数は評価["COUNT"] 勝利は評価["WIN"] ここまで もし、下限≧上限ならば、 抜ける ここまで ここまで スコアは上限 ここまで { WIN: 勝利, COUNT: コマ数, SCORE: スコア }で戻る ここまで ##### αβ法による思考ルーチン ●(CALLBACKへ状態が盤に手番で探索深度まで)AB法とは もし、AB法ワーカー利用ならば、 CALLBACKへ状態が盤に手番で探索深度までAB法ワーカー依頼 違えば、 CALLBACKへ状態が盤に手番で探索深度まで非同期AB法 ここまで ここまで ●(CALLBACKへ状態が仮盤状態に仮手番で探索深度まで)非同期AB法とは 自手番は仮手番 次手は[0,0] 手候補リストは仮盤状態に自手番で手候補取得 手候補数は手候補リストの配列要素数 もし、手候補数=0ならば、 評価は仮盤状態から自手番の盤評価 CALLBACK("パス", [],評価["END"], 状態) 戻る ここまで 次手番は仮手番+1 もし、次手番>人数ならば、 次手番は1 ここまで マスターキーは"Date.now()"をJS実行 下限は-99999 上限は99999 AB法状態は{ 手候補数: 手候補数, 応答数: 0, マスターキー: マスターキー, 依頼側状態: 状態, 下限: 下限, 終局: オフ, 勝利: オフ, 手: [0,0], コールバック: CALLBACK } 手候補数回、 Nは回数 依頼キーは「」+マスターキー+「-」+N+「」 手候補は手候補リスト[N-1] 自状態は{ キー: 依頼キー, 手:手候補["手"], 共通: AB法状態 } 自状態が手候補["事後"]に次手番で探索深度の自手番を上限とAB法状態["下限"]まで非同期ABした時には(評価, 状態) AB法状態は状態["共通"] キー要素は状態["キー"]を「-」で区切る マスターキーはキー要素[0] 枝番はキー要素[1] もし、マスターキーがAB法状態["マスターキー"]でなければ、 戻る ここまで AB法状態["応答数"]はAB法状態["応答数"]+1 もし、評価["SCORE"]>AB法状態["下限"]ならば AB法状態["下限"]は評価["SCORE"] AB法状態["終局"]は評価["END"] AB法状態["勝利"]は評価["WIN"] AB法状態["手"]は状態["手"] ここまで もし、AB法状態["応答数"]=AB法状態["手候補数"]ならば、 CALLBACKはAB法状態["コールバック"] 依頼側状態はAB法状態["依頼側状態"] もし、AB法状態["手"][0]が0ならば、 CALLBACK(「パス」, 「」, AB法状態["終局"], 依頼側状態) 違えば、 CALLBACK(「手」, AB法状態["手"], AB法状態["終局"], 依頼側状態) ここまで ここまで ここまで ここまで ここまで ●(CALLBACKへ状態が仮盤状態に仮手番で現深度の自手番を上限と下限まで)非同期AB時とは 自状態は{ コールバック: CALLBACK, 依頼側状態: 状態 } もし、ABワーカー数>0ならば、 自状態が仮盤状態に仮手番で現深度の自手番を上限と下限までABワーカー依頼には(評価, 自状態) CALLBACKは自状態["コールバック"] 状態は自状態["依頼側状態"] CALLBACK(評価, 状態) ここまで 違えば、 評価は仮盤状態に仮手番で現深度の自手番を上限と下限までAB CALLBACK(評価, 状態) ここまで ここまで ●(仮盤状態に仮手番で現深度の自手番を上限と下限まで)ABとは もし、現深度が0ならば、 仮盤状態から自手番の盤評価で戻る ここまで 手候補リストは仮盤状態に仮手番で手候補取得 もし、(手候補リストの配列要素数)が0ならば、 仮盤状態から自手番の盤評価で戻る ここまで 次手番は仮手番+1 もし、次手番>人数ならば、 次手番は1 ここまで 次深度は現深度-1 終局はオフ 勝利はオフ スコアは0 もし、仮手番が自手番ならば、 (手候補リストの配列要素数)回、 Nは回数 手候補は手候補リスト[N-1] 評価は手候補["事後"]に次手番で次深度の自手番を上限と下限までAB もし、評価["SCORE"]>下限ならば 下限は評価["SCORE"] 終局は評価["END"] 勝利は評価["WIN"] ここまで もし、下限≧上限ならば、 抜ける ここまで ここまで スコアは下限 違えば、 (手候補リストの配列要素数)回、 Nは回数 手候補は手候補リスト[N-1] 評価は手候補["事後"]に次手番で次深度の自手番を上限と下限までAB もし、評価["SCORE"]<上限ならば 上限は評価["SCORE"] 終局は評価["END"] 勝利は評価["WIN"] ここまで もし、下限≧上限ならば、 抜ける ここまで ここまで スコアは上限 ここまで { SCORE: スコア, WIN: 勝利, END: 終局}で戻る ここまで ##### 人間の操作受付処理 ●パスクリックとは もし、描画状態ステータス>0ならば、 戻る 違えばもし、代打思考中ならば、 「代打にてCPUが試行中です」をステータス表示する 違えばもし、手番が人間番ならば、 パス選択 ここまで ここまで ●中止クリックとは 中止処理 ここまで ●代打クリックとは もし、描画状態ステータス>0ならば、 戻る 違えばもし、代打思考中ならば、 「代打にてCPUが試行中です」をステータス表示する 違えばもし、手番が人間番ならば、 代打思考中はオン CPU思考実行 違えば、 「あなたの順番ではありません」をステータス表示 ここまで ここまで ●(セル位置を)セルクリックとは もし、描画状態ステータス>0ならば、 戻る 違えばもし、手番が人間番ならば、 セル位置で手番実行 違えば、 「あなたの順番ではありません」をステータス表示 ここまで ここまで ##### CPUの操作受付処理 ●(手で)CPU手番実行とは もし、代打思考中ならば、 代打思考中はオフ ここまで 結果は手で手番実行 もし、結果がいいえならば 「内部エラーで続行できません。」をステータス表示 CPUエラー発生はオン 0秒後には、 終了処理 ここまで ここまで ここまで ●CPUパス選択とは もし、代打思考中ならば、 代打思考中はオフ ここまで 結果はパス選択 もし、結果がいいえならば 「内部エラーで続行できません。」をステータス表示 CPUエラー発生はオン 0秒後には、 終了処理 ここまで ここまで ここまで ##### AB法ワーカー利用関連の処理 ●(CALLBACKへ状態が盤に手番で探索深度まで)AB法ワーカー依頼とは IDはAB法ID AB法IDはAB法ID+1 AB法コールバック[ID]は{ 依頼側状態: 状態, コールバック: CALLBACK } 依頼内容は{ KEY:ID, TYPE:"AB法", DATA: { BOARD:盤, SIDE:手番, BASEDEPTH:探索深度 } } AB法ワーカーに依頼内容をNAKOワーカーデータ送信 ここまで ●(データで)AB法ワーカー親ハンドラとは 種類はデータ["TYPE"] もし、種類="手"||種類="パス"ならば、 キーはデータ["KEY"] OBJはAB法コールバック[キー] もし、OBJならば、 CALLBACKはOBJ["コールバック"] 状態はOBJ["依頼側状態"] CALLBACK(データ["TYPE"], データ["DATA"]["TE"], データ["END"], 状態) AB法コールバック[キー]はundefined 違えば、 #「なんか、予定外のキー(」+キー+「)を持つAB法ワーカーからの応答がありました」を表示 ここまで 違えばもし、種類="表示"ならば、 データ["DATA"]をステータス表示 違えばもし、種類="ワーカー様態"ならば、 データ["DATA"]をワーカー状態表示 違えば、 「なんか、予定外の種類(」+種類+「)を持つAB法ワーカーからの応答がありました」を表示 ここまで ここまで ●AB法ワーカー初回準備とは もし、AB法ワーカー利用でなければ、 「AB法ワーカーは未使用」をステータス表示 ABワーカー初回準備 戻る ここまで AB法ワーカー準備 もし、ABワーカー数>0ならば、 AB法ワーカーで「ABワーカー初回準備」をNAKOワーカープログラム起動 ここまで 「AB法ワーカー準備完了」をステータス表示 ここまで ●AB法ワーカーリセットとは もし、AB法ワーカー利用でなければ、 ABワーカーリセット 戻る ここまで AB法ワーカー後始末 AB法ワーカー準備 もし、ABワーカー数>0ならば、 AB法ワーカーで「ABワーカーリセット」をNAKOワーカープログラム起動 ここまで ここまで ●AB法ワーカー準備とは 追加プラグインは[] 転送対象は共通汎用部品 転送対象は転送対象にAB法ワーカー化子部品を配列足す 転送対象は転送対象にAB法子部品を配列足す 転送対象は転送対象にAB親部品を配列足す 転送対象は転送対象にAB子部品を配列足す もし、ABワーカー数>0ならば、 転送対象は転送対象にABワーカー化親部品を配列足す 転送対象は転送対象にABワーカー化子部品を配列足す 転送対象は転送対象に完読子部品を配列足す "plugin_webworker.js"を追加プラグインに配列追加 ワーカーベースURLはワーカーURL ここまで AB法ワーカーは追加プラグインでNAKOワーカー起動 AB法ワーカーへ転送対象をNAKOワーカー転送 AB法ワーカーで「AB法ワーカー初期化」をNAKOワーカープログラム起動 AB法ワーカーからNAKOワーカーデータ受信した時には 受信データでAB法ワーカー親ハンドラ ここまで AB法ワーカーからNAKOワーカー表示した時には 受信データを表示する ここまで ここまで ●AB法ワーカー初期化とは NAKOワーカーデータ受信した時には 受信データでAB法ワーカー子ハンドラ ここまで ここまで ●(データで)AB法ワーカー子ハンドラとは キーはデータ["KEY"] タイプはデータ["TYPE"] 内容はデータ["DATA"] タイプで条件分岐 「AB法」ならば 状態は{ キー: キー } 状態が内容["BOARD"]に内容["SIDE"]で内容["BASEDEPTH"]まで非同期AB法には(行動, 手, 終局, 状態) 状態["キー"]が行動を手で終局のAB法ワーカー応答 ここまで ここまで ここまで ここまで ●(キーが行動を手で終局の)AB法ワーカー応答とは 依頼内容は{} もし、行動が「パス」ならば、 依頼内容は{ KEY: キー, TYPE:"パス", END: 終局, DATA: {} } 違えば、 依頼内容は{ KEY: キー, TYPE:"手", END: 終局, DATA: { TE:手 } } ここまで 依頼内容をNAKOワーカーデータ送信 ここまで ●AB法ワーカー後始末とは AB法コールバックは{} もし、AB法ワーカー利用ならば、 AB法ワーカーをワーカー終了 AB法ワーカーは空 ここまで もし、ABワーカー数>0ならば、 ABワーカー後始末 ここまで ここまで ##### AB法にてABワーカー利用関連の処理 ●(CALLBACKへ状態が盤に手番で深度の自手番を上限と下限まで)ABワーカー依頼とは IDはABID ABIDはABID+1 ABコールバック[ID]は{ 依頼側状態: 状態, コールバック: CALLBACK } 依頼内容は{ KEY: ID, TYPE:"AB", DATA: { BOARD:盤, SIDE:手番, DEPTH:深度, OWNSIDE:自手番, WINDOW_UPPER:上限, WINDOW_LOWER:下限 } } ABワーカー依頼キューに依頼内容を配列追加する ABワーカー処理受付する ここまで ●(CALLBACKへ状態が盤に手番で自手番を上限と下限まで)完読ワーカー依頼とは IDはABID ABIDはABID+1 ABコールバック[ID]は{ 依頼側状態: 状態, コールバック: CALLBACK } 依頼内容は{ KEY: ID, TYPE:"完読", DATA: { BOARD:盤, SIDE:手番, OWNSIDE:自手番, WINDOW_UPPER:上限, WINDOW_LOWER:下限 } } ABワーカー依頼キューに依頼内容を配列追加する ABワーカー処理受付する ここまで ●ABワーカー処理受付とは 依頼数はABワーカー依頼キューの配列要素数 もし、依頼数=0ならば、 ワーカー状態報告する 戻る ここまで ワーカー数はABワーカー状態の配列要素数 ワーカー数回、 Iは回数-1 もし、ABワーカー状態[I]ならば、 ABワーカー状態[I]はオフ ((ABワーカー依頼キューの配列要素数)>0)の間、 依頼内容はABワーカー依頼キューの0を配列切り取る IDは依頼内容["KEY"] もし、(ABコールバック[ID]の変数型確認)≠"undefined"ならば、 抜ける ここまで ここまで もし、(ABコールバック[ID]の変数型確認)≠"undefined"ならば、 ABコールバック[ID]["INDEX"]はI ABワーカー[I]に依頼内容をNAKOワーカーデータ送信 ここまで もし、(ABワーカー依頼キューの配列要素数)=0ならば、 抜ける ここまで ここまで ここまで ワーカー状態報告する ここまで ●ワーカー状態報告とは 状態はワーカー状態調査 もし、(メインスレッドマーカーの変数型確認)="undefined"でなければ、 状態をワーカー状態表示 違えば、 依頼内容は{ TYPE:"ワーカー状態", DATA: 状態 } 依頼内容をNAKOワーカーデータ送信 ここまで ここまで ●(データで)ABワーカー親ハンドラとは 種類はデータ["TYPE"] もし、種類="応答"ならば、 キーはデータ["KEY"] OBJはABコールバック[キー] もし、OBJならば、 CALLBACKはOBJ["コールバック"] 状態はOBJ["依頼側状態"] IはOBJ["INDEX"] ABワーカー状態[I]はオン ABコールバック[キー]はundefined ABワーカー処理受付する CALLBACK(データ["DATA"], 状態) 違えば、 #「なんか、予定外のキー(」+キー+「)を持つABワーカーからの応答がありました」を表示 ここまで 違えばもし、種類="表示"ならば、 データ["DATA"]をステータス表示 違えば、 「なんか、予定外の種類(」+種類+「)を持つABワーカーからの応答がありました」を表示 ここまで ここまで ●ABワーカー初回準備とは もし、ABワーカー数が0ならば、 「ABワーカーは未使用」をステータス表示 戻る ここまで ABワーカー準備 ワーカー状態報告する (「ABワーカー準備完了(」+ABワーカー数+「個)」)をステータス表示 ここまで ●ABワーカーリセットとは もし、ABワーカー数が0ならば、 戻る ここまで ABワーカー後始末 ABワーカー準備 ワーカー状態報告する ここまで ●ABワーカー準備とは もし、ワーカーURLが空ならば、 ワーカーベースURLにワーカーURL設定 ここまで 転送対象は共通汎用部品 転送対象は転送対象にABワーカー化子部品を配列足す 転送対象は転送対象にAB子部品を配列足す 転送対象は転送対象に完読子部品を配列足す ABワーカー数回、 ワーカーはNAKOワーカー起動 ワーカーへ転送対象をNAKOワーカー転送 ワーカーで「ABワーカー初期化」をNAKOワーカープログラム起動 ワーカーからNAKOワーカーデータ受信した時には 受信データでABワーカー親ハンドラ ここまで ワーカーからNAKOワーカー表示した時には 受信データを表示する ここまで ワーカーをABワーカーに配列追加する はいをABワーカー状態に配列追加する ここまで ここまで ●ABワーカー初期化とは NAKOワーカーデータ受信した時には 受信データでABワーカー子ハンドラ ここまで ここまで ●(データで)ABワーカー子ハンドラとは タイプはデータ["TYPE"] 内容はデータ["DATA"] タイプで条件分岐 「AB」ならば 評価は内容["BOARD"]に内容["SIDE"]で内容["DEPTH"]の内容["OWNSIDE"]を内容["WINDOW_UPPER"]と内容["WINDOW_LOWER"]までABする データ["KEY"]に評価でABワーカー応答する ここまで 「完読」ならば 評価は内容["BOARD"]に内容["SIDE"]で内容["OWNSIDE"]を内容["WINDOW_UPPER"]と内容["WINDOW_LOWER"]まで完読する データ["KEY"]に評価でABワーカー応答する ここまで ここまで ここまで ●(キーに評価で)ABワーカー応答とは 依頼内容は{ KEY: キー, TYPE: "応答", DATA: 評価 } 依頼内容をNAKOワーカーデータ送信 ここまで ●ABワーカー後始末とは ABコールバックは{} ワーカー数はABワーカーの配列要素数 (ワーカー数)回、 Iは回数-1 WはABワーカー[I] Wをワーカー終了 ここまで ABワーカーは[] ABワーカー状態は[] ここまで ##### ダイアログ利用補助機能 ●ダイアログ使用可能とは DLGは"dialog"のDOM要素作成 (『(function (DLG) {return typeof DLG.open})』を[DLG]でJS関数実行)≠"undefined"で戻る。 ここまで ●(SRCで)ダイアログ作成とは eは"dialog"のDOM要素作成 eにSRCをDOM_HTML設定 eで戻る ここまで ●(DLGの)ダイアログ開くとは もし、(『(function (DLG) {return typeof DLG.open})』を[DLG]でJS関数実行)="undefined"ならば、 「ダイアログ機能は使えません」を表示する。 戻る。 ここまで DLGの"open"を[]でJSメソッド実行する。 ここまで ●(DLGの)ダイアログモーダル開くとは もし、(『(function (DLG) {return typeof DLG.showModal})』を[DLG]でJS関数実行)="undefined"ならば、 「ダイアログ機能は使えません」を表示する。 戻る。 ここまで DLGの"showModal"を[]でJSメソッド実行する。 ここまで ##### 実際の処理実行 オプション選択画面表示 ここまで