private void HintThreadFunc(object args) { object[] argsarray = (object[])args; BoardClass board = (BoardClass)argsarray[1]; CpuClass cpuClass = (CpuClass)argsarray[2]; Form1 formobj = (Form1)argsarray[3]; uint level = (uint)argsarray[4]; int ret = 0; CppWrapper cpw = new CppWrapper(); // 着手可能リスト取得 ulong moves = cpw.GetEnumMove(board); // 現在のCPUの設定を取得 CpuConfig cpuConfig = SetCpuConfig(cpuClass); // BOOK禁止 cpuConfig.bookFlag = false; ulong bk = board.GetBlack(); ulong wh = board.GetWhite(); HintClass hintData = new HintClass(); // 空きマス数 int empty = cpw.CountBit(~(bk | wh)); // CPU設定 cpuConfig.color = board.GetColor(); cpuConfig.winLossDepth = dcTable[level - 1]; cpuConfig.exactDepth = dcTable[level - 1] - 2; if (cpuConfig.exactDepth >= empty) { // WLDとEXACTの前にある程度の探索を行うため0で初期化 cpuConfig.exactDepth = 0; cpuConfig.winLossDepth = 0; hintData.SetAttr(HintClass.SOLVE_MIDDLE); // 反復深化探索(level - 8) for (int i = 0; i < level / 2; i++) { cpuConfig.searchDepth = (uint)i * 2 + 2; // 着手可能マスに対してそれぞれ評価値を計算 ret = doSearch(bk, wh, cpuConfig, moves, formobj, hintData); if (ret == -1) break; // UIに反復x回目終了を通知 hintData.SetPos(64); ((Form1)formobj).Invoke(((Form1)formobj).hintDelegate, new object[] { hintData }); } if (ret == 0) { hintData.SetAttr(HintClass.SOLVE_EXCAT); cpuConfig.exactDepth = dcTable[level - 1] - 2; // 着手可能マスに対してそれぞれ評価値を計算 ret = doSearch(bk, wh, cpuConfig, moves, formobj, hintData); } } else if (cpuConfig.winLossDepth >= empty) { cpuConfig.exactDepth = 0; cpuConfig.winLossDepth = 0; hintData.SetAttr(HintClass.SOLVE_MIDDLE); // 反復深化探索(level - 8) for (int i = 0; i < level / 2; i++) { cpuConfig.searchDepth = (uint)i * 2 + 2; // 着手可能マスに対してそれぞれ評価値を計算 ret = doSearch(bk, wh, cpuConfig, moves, formobj, hintData); if (ret == -1) break; // UIに反復x回目終了を通知 hintData.SetPos(64); ((Form1)formobj).Invoke(((Form1)formobj).hintDelegate, new object[] { hintData }); } if (ret == 0) { hintData.SetAttr(HintClass.SOLVE_WLD); cpuConfig.winLossDepth = dcTable[level - 1]; // 着手可能マスに対してそれぞれ評価値を計算 ret = doSearch(bk, wh, cpuConfig, moves, formobj, hintData); } } else { hintData.SetAttr(HintClass.SOLVE_MIDDLE); // 反復深化探索 for (int i = 0; i < level && i <= empty; i++) { cpuConfig.searchDepth = (uint)i * 2 + 2; // 着手可能マスに対してそれぞれ評価値を計算 ret = doSearch(bk, wh, cpuConfig, moves, formobj, hintData); if (ret == -1) break; // UIに反復x回目終了を通知 hintData.SetPos(64); ((Form1)formobj).Invoke(((Form1)formobj).hintDelegate, new object[] { hintData }); } } // UIに探索終了を通知 ((Form1)formobj).Invoke(((Form1)formobj).hintDelegate, new object[] { null }); }
private int doSearch(ulong bk, ulong wh, CpuConfig cpuConfig, ulong moves, Form1 formobj, HintClass hintData) { int pos; int ret = 0; ulong move_bk, move_wh, rev; for (ulong m = moves; m != 0; m ^= 1UL << pos) { pos = cpw.CountBit((~m) & (m - 1)); if (cpuConfig.color == BoardClass.WHITE) { rev = cpw.GetBoardChangeInfo(bk, wh, pos); move_bk = bk ^ ((1UL << pos) | rev); move_wh = wh ^ rev; } else { rev = cpw.GetBoardChangeInfo(wh, bk, pos); move_wh = wh ^ ((1UL << pos) | rev); move_bk = bk ^ rev; } cpw.GetCpuMove(move_bk, move_wh, cpuConfig); hintData.SetPos(pos); hintData.SetEval(-cpw.GetLastEvaluation()); // UIに評価値を通知 ((Form1)formobj).Invoke(((Form1)formobj).hintDelegate, new object[] { hintData }); // 中断処理 if (m_abort == true) { m_abort = false; ret = -1; break; } } return ret; }
private void doHintProcess(HintClass hintData) { if (hintData != null) { if (hintData.GetPos() == 64) { // 最大評価値を初期化 m_hintEvalMax = -INFINITY_SCORE; } else { // ヒントデータ更新 int attr = hintData.GetAttr(); int position = hintData.GetPos(); int index = findIndexFromPosition(position); if (index == -1) { // 新規データ m_hintList.Add(new int[] { attr, position, hintData.GetEval() }); } else { // 更新 m_hintList[index] = new int[] { attr, position, hintData.GetEval() }; } // ソート処理 m_hintList.Sort(CompareEval); } } else { // 終了通知 m_hintEvalMax = -INFINITY_SCORE; m_hintFlagProperty = false; SetControlEnable(true); this.Cursor = Cursors.Default; } // 画面再描画 panel1.Invalidate(false); panel1.Update(); }