static void set_rbuffer(UNUSED(Param pm), char *x) { ZLE_STRING_T y; int len; if (x && *x != ZWC('\0')) y = stringaszleline(x, 0, &len, NULL, NULL); else y = ZWS(""), len = 0; sizeline(zlell = zlecs + len); ZS_memcpy(zleline + zlecs, y, len); zsfree(x); if (len) free(y); fixsuffix(); menucmp = 0; }
int PVS(const uint64_t P, const uint64_t O, uint64_t& NodeCounter, const int alpha, const int beta, const int selectivity, const int depth, const int empties, CLine* pline) { assert((P & O) == 0); assert(-64 <= alpha); assert(alpha <= 64); assert(-64 <= beta ); assert(beta <= 64); assert(alpha <= beta); assert(0 <= depth); assert(depth <= 60); assert(0 <= empties); assert(empties <= 60); assert(empties == Empties(P, O)); assert(depth <= empties); if (depth <= 2 && depth < empties) { if (depth == 2) return Midgame::PVS_2(P, O, NodeCounter, alpha, beta, pline); if (depth == 1) return Midgame::PVS_1(P, O, NodeCounter, alpha, beta, pline); if (depth == 0) return Midgame::Eval_0(P, O, NodeCounter); } if (empties <= A && depth == empties) return Endgame::PVS_A(P, O, NodeCounter, alpha, beta, empties, pline); int lower = alpha; int score; int bestscore = -65; uint8_t BestMove = 64; uint64_t BitBoardPossible = PossibleMoves(P, O); uint64_t LocalNodeCounter = NodeCounter; CHashTableValueType ttValue; NodeCounter++; if (!BitBoardPossible){ if (HasMoves(O, P)) return -PVS(O, P, NodeCounter, -beta, -alpha, selectivity, depth, empties, pline); else { if (pline) pline->NoMoves(); return EvalGameOver(P, empties); } } if (!pline && StabilityCutoff_PVS(P, O, alpha, score)) return score; if (LookUpTTPV(P, O, ttValue) || LookUpTT(P, O, ttValue)) if (USE_PV_TTCUT && !pline && UseTTValue(ttValue, alpha, beta, depth, selectivity, score)) return score; if (USE_IID && ttValue.PV == 64) // IID { int reduced_depth = (depth == empties) ? depth - A : depth - 2; if (reduced_depth >= 3) { PVS(P, O, NodeCounter, -64, 64, 6, reduced_depth, empties, nullptr); if (LookUpTTPV(P, O, ttValue)) if (USE_PV_TTCUT && !pline && UseTTValue(ttValue, alpha, beta, depth, selectivity, score)) return score; } } CLine * line = nullptr; if (pline && pline->size) line = new CLine(pline->size-1); CMoveList mvList(P, O, NodeCounter, BitBoardPossible, depth, alpha, ttValue, true); for (const auto& mv : mvList) { if (bestscore == -65) score = -PVS(mv.P, mv.O, NodeCounter, -beta, -lower, selectivity, depth-1, empties-1, line); else { score = -ZWS(mv.P, mv.O, NodeCounter, -lower-1, selectivity, depth-1, empties-1); if (score > lower && score < beta) score = -PVS(mv.P, mv.O, NodeCounter, -beta, -lower, selectivity, depth-1, empties-1, line); // OPTIMIZATION: -lower -> -score } if (score > bestscore) { bestscore = score; BestMove = mv.move; if (line) pline->NewPV(mv.move, line); if (score >= beta) break; if (score > lower) lower = score; } } if (empties-1 <= B) { UpdateTTPV(P, O, NodeCounter - LocalNodeCounter, alpha, beta, bestscore, depth, NO_SELECTIVITY, BestMove, mvList.BestMove(), mvList.NextBestMove()); UpdateTT(P, O, NodeCounter - LocalNodeCounter, alpha, beta, bestscore, depth, NO_SELECTIVITY, BestMove, mvList.BestMove(), mvList.NextBestMove()); } else { UpdateTTPV(P, O, NodeCounter - LocalNodeCounter, alpha, beta, bestscore, depth, selectivity, BestMove, mvList.BestMove(), mvList.NextBestMove()); UpdateTT(P, O, NodeCounter - LocalNodeCounter, alpha, beta, bestscore, depth, selectivity, BestMove, mvList.BestMove(), mvList.NextBestMove()); } delete line; return bestscore; }
int ZWS(const uint64_t P, const uint64_t O, uint64_t& NodeCounter, const int alpha, const int selectivity, const int depth, const int empties) { assert((P & O) == 0); assert(-64 <= alpha); assert(alpha <= 64); assert(0 <= depth); assert(depth <= 60); assert(0 <= empties); assert(empties <= 60); assert(empties == Empties(P, O)); assert(depth <= empties); if (depth <= 3 && depth < empties) { if (depth == 3) return Midgame::ZWS_3(P, O, NodeCounter, alpha); if (depth == 2) return Midgame::ZWS_2(P, O, NodeCounter, alpha); if (depth == 1) return Midgame::ZWS_1(P, O, NodeCounter, alpha); if (depth == 0) return Midgame::Eval_0(P, O, NodeCounter); } if (empties <= B && depth == empties) return Endgame::ZWS_B(P, O, NodeCounter, alpha, empties); int score; int bestscore = -64; uint8_t BestMove = 64; uint64_t BitBoardPossible = PossibleMoves(P, O); uint64_t LocalNodeCounter = NodeCounter; CHashTableValueType ttValue; NodeCounter++; if (!BitBoardPossible){ if (HasMoves(O, P)) return -ZWS(O, P, NodeCounter, -alpha - 1, selectivity, depth, empties); else return EvalGameOver(P, empties); } if (StabilityCutoff_ZWS(P, O, alpha, score)) return score; if (LookUpTT(P, O, ttValue) && UseTTValue(ttValue, alpha, alpha+1, depth, selectivity, score)) return score; if (MPC(P, O, NodeCounter, alpha, selectivity, depth, empties, score)) return score; CMoveList mvList(P, O, NodeCounter, BitBoardPossible, depth, alpha, ttValue, false); for (const auto& mv : mvList) // ETC { if (StabilityCutoff_ZWS(mv.P, mv.O, -alpha - 1, score)) { UpdateTT(P, O, 0, alpha, alpha + 1, -score, depth, NO_SELECTIVITY, mv.move, mvList.BestMove(), mvList.NextBestMove()); return -score; } if (LookUpTT(mv.P, mv.O, ttValue) && UseTTValue(ttValue, -alpha - 1, -alpha, depth - 1, selectivity, score) && (-score > alpha)) { UpdateTT(P, O, 0, alpha, alpha+1, -score, depth, selectivity, mv.move, mvList.BestMove(), mvList.NextBestMove()); return -score; } } for (const auto& mv : mvList) { score = -ZWS(mv.P, mv.O, NodeCounter, -alpha-1, selectivity, depth-1, empties-1); if (score > bestscore) { bestscore = score; BestMove = mv.move; if (score > alpha) break; } } if (empties-1 <= B) UpdateTT(P, O, NodeCounter-LocalNodeCounter, alpha, alpha+1, bestscore, depth, NO_SELECTIVITY, BestMove, mvList.BestMove(), mvList.NextBestMove()); else UpdateTT(P, O, NodeCounter-LocalNodeCounter, alpha, alpha+1, bestscore, depth, selectivity, BestMove, mvList.BestMove(), mvList.NextBestMove()); return bestscore; }
bool MPC(uint64_t P, uint64_t O, uint64_t& NodeCounter, int alpha, int selectivity, int depth, int empties, int& value) { assert((P & O) == 0); assert(-64 <= alpha); assert(alpha <= 64); assert(0 <= depth); assert(depth <= 60); assert(0 <= empties); assert(empties <= 60); assert(empties == Empties(P, O)); assert(depth <= empties); if (selectivity) { const int beta = alpha + 1; const double t = SelectivityTable[selectivity].T; const int zero_eval = Midgame::Eval_0(P, O, NodeCounter); double probcut_sigma = sigma(depth, 0, empties); int probcut_beta = beta + t * probcut_sigma; int probcut_alpha = probcut_beta - 1; if (empties <= 21) { if (zero_eval >= beta + t * probcut_sigma) { value = beta; return true; } if (zero_eval < alpha - t * probcut_sigma) { value = alpha; return true; } } probcut_sigma = sigma(depth, (depth % 2 == 0 ? 2 : 1), empties); if (zero_eval >= beta + t * probcut_sigma) { for (int probcut_depth = (depth % 2 == 0 ? 2 : 1)+2; probcut_depth <= depth / 2; probcut_depth += 2) { double probcut_sigma = sigma(depth, probcut_depth, empties); int probcut_beta = beta + t * probcut_sigma; int probcut_alpha = probcut_beta - 1; if (probcut_beta <= 64) { int score = ZWS(P, O, NodeCounter, probcut_alpha, NO_SELECTIVITY, probcut_depth, empties); if (score >= probcut_beta) { value = beta; return true; } } } } if (zero_eval < alpha - t * probcut_sigma) { for (int probcut_depth = (depth % 2 == 0 ? 2 : 1)+2; probcut_depth <= depth / 2; probcut_depth += 2) { int probcut_sigma = sigma(depth, probcut_depth, empties); int probcut_alpha = alpha - t * probcut_sigma; if (probcut_alpha >= -64) { int score = ZWS(P, O, NodeCounter, probcut_alpha, NO_SELECTIVITY, probcut_depth, empties); if (score <= probcut_alpha) { value = alpha; return true; } } } } //for (int probcut_depth = depth % 2 ? 1 : 2; probcut_depth <= depth / 2; probcut_depth++) //{ // double probcut_sigma = sigma(depth, probcut_depth, empties); // int probcut_beta = RoundInt(beta + t * probcut_sigma); // int probcut_alpha = probcut_beta - 1; // int score; // if (zero_eval >= beta && probcut_beta <= 64) // { // score = ZWS(P, O, NodeCounter, probcut_alpha, NO_SELECTIVITY, probcut_depth, empties); // if (score >= probcut_beta) { value = beta; return true; } // } // probcut_alpha = RoundInt(alpha - t * probcut_sigma); // if (zero_eval < alpha && probcut_alpha >= -64) // { // score = ZWS(P, O, NodeCounter, probcut_alpha, NO_SELECTIVITY, probcut_depth, empties); // if (score <= probcut_alpha) { value = alpha; return true; } // } //} } return false; }