int main(void) { static unsigned x; initprg(); initgame(); clrscr(); printf("Alpha test AR-Chess V 1.0\n" "Copyright November 30, 1992\n" "\nMr. Carey Bloodworth\n" "\nThis program may be freely\n" "copied and modified as long\n" "as my name is present as the\n" "original author.\n" "Sharp 7xx port: A.R. Pruss"); ozdelay64hz(200); /* ozsendscreen(); */ while (! quit) { if ( /* (breakpress) || */ (draw) || (mate) || ((tomove==human) && (!bothsides)) ) inputcommand(); printboard(); /* if (pvsflag) { currow=7; atright(); printf(pvsmsg); } */ if (status[0]) { currow=8; atright(); printf(status); } currow=6; atright(); printf(msg); if (! (quit || mate || draw)) selectmove(tomove); /* if (! breakpress) */ tomove=chngcolor(tomove); }; endprg(); return 0; }
int Board::alphabetapvs(int ply, int depth, int alpha, int beta) { // PV search int i, j, movesfound, pvmovesfound, val; triangularLength[ply] = ply; if (depth == 0) { followpv = false; return qsearch(ply, alpha, beta); } // repetition check: if (repetitionCount() >= 3) return DRAWSCORE; movesfound = 0; pvmovesfound = 0; moveBufLen[ply+1] = movegen(moveBufLen[ply]); for (i = moveBufLen[ply]; i < moveBufLen[ply+1]; i++) { selectmove(ply, i, depth, followpv); makeMove(moveBuffer[i]); { if (!isOtherKingAttacked()) { inodes++; movesfound++; if (!ply) displaySearchStats(3, ply, i); if (pvmovesfound) { val = -alphabetapvs(ply+1, depth-1, -alpha-1, -alpha); if ((val > alpha) && (val < beta)) { // in case of failure, proceed with normal alphabeta val = -alphabetapvs(ply+1, depth - 1, -beta, -alpha); } } // normal alphabeta else val = -alphabetapvs(ply+1, depth-1, -beta, -alpha); unmakeMove(moveBuffer[i]); if (val >= beta) { // update the history heuristic if (nextMove) blackHeuristics[moveBuffer[i].getFrom()][moveBuffer[i].getTosq()] += depth*depth; else whiteHeuristics[moveBuffer[i].getFrom()][moveBuffer[i].getTosq()] += depth*depth; return beta; } if (val > alpha) { alpha = val; // both sides want to maximize from *their* perspective pvmovesfound++; triangularArray[ply][ply] = moveBuffer[i]; // save this move for (j = ply + 1; j < triangularLength[ply+1]; j++) { triangularArray[ply][j] = triangularArray[ply+1][j]; // and append the latest best PV from deeper plies } triangularLength[ply] = triangularLength[ply+1]; if (!ply) { msStop = timer.getms(); displaySearchStats(2, depth, val); } } } else unmakeMove(moveBuffer[i]); } } // update the history heuristic if (pvmovesfound) { if (nextMove) blackHeuristics[triangularArray[ply][ply].getFrom()][triangularArray[ply][ply].getTosq()] += depth*depth; else whiteHeuristics[triangularArray[ply][ply].getFrom()][triangularArray[ply][ply].getTosq()] += depth*depth; } // 50-move rule: if (fiftyMove >= 100) return DRAWSCORE; // Checkmate/stalemate detection: if (!movesfound) { if (isOwnKingAttacked()) return (-CHECKMATESCORE+ply-1); else return (STALEMATESCORE); } return alpha; }
int Board::alphabetapvs(int ply, int depth, int alpha, int beta) { // PV search int i, j, movesfound, pvmovesfound, val; triangularLength[ply] = ply; if (depth <= 0) { followpv = false; return qsearch(ply, alpha, beta); } // repetition check: if (repetitionCount() >= 3) return DRAWSCORE; // now try a null move to get an early beta cut-off: if (!followpv && allownull) { if ((nextMove && (board.totalBlackPieces > NULLMOVE_LIMIT)) || (!nextMove && (board.totalWhitePieces > NULLMOVE_LIMIT))) { if (!isOwnKingAttacked()) { allownull = false; inodes++; if (--countdown <=0) readClockAndInput(); nextMove = !nextMove; hashkey ^= KEY.side; val = -alphabetapvs(ply, depth - NULLMOVE_REDUCTION, -beta, -beta+1); nextMove = !nextMove; hashkey ^= KEY.side; if (timedout) return 0; allownull = true; if (val >= beta) return val; } } } allownull = true; movesfound = 0; pvmovesfound = 0; moveBufLen[ply+1] = movegen(moveBufLen[ply]); for (i = moveBufLen[ply]; i < moveBufLen[ply+1]; i++) { selectmove(ply, i, depth, followpv); makeMove(moveBuffer[i]); { if (!isOtherKingAttacked()) { inodes++; if (--countdown <=0) readClockAndInput(); movesfound++; if (!ply) displaySearchStats(3, ply, i); if (pvmovesfound) { val = -alphabetapvs(ply+1, depth-1, -alpha-1, -alpha); if ((val > alpha) && (val < beta)) { // in case of failure, proceed with normal alphabeta val = -alphabetapvs(ply+1, depth - 1, -beta, -alpha); } } // normal alphabeta else val = -alphabetapvs(ply+1, depth-1, -beta, -alpha); unmakeMove(moveBuffer[i]); if (timedout) return 0; if (val >= beta) { // update the history heuristic if (nextMove) blackHeuristics[moveBuffer[i].getFrom()][moveBuffer[i].getTosq()] += depth*depth; else whiteHeuristics[moveBuffer[i].getFrom()][moveBuffer[i].getTosq()] += depth*depth; return beta; } if (val > alpha) { alpha = val; // both sides want to maximize from *their* perspective pvmovesfound++; triangularArray[ply][ply] = moveBuffer[i]; // save this move for (j = ply + 1; j < triangularLength[ply+1]; j++) { triangularArray[ply][j] = triangularArray[ply+1][j]; // and append the latest best PV from deeper plies } triangularLength[ply] = triangularLength[ply+1]; if (!ply) displaySearchStats(2, depth, val); } } else unmakeMove(moveBuffer[i]); } } // update the history heuristic if (pvmovesfound) { if (nextMove) blackHeuristics[triangularArray[ply][ply].getFrom()][triangularArray[ply][ply].getTosq()] += depth*depth; else whiteHeuristics[triangularArray[ply][ply].getFrom()][triangularArray[ply][ply].getTosq()] += depth*depth; } // 50-move rule: if (fiftyMove >= 100) return DRAWSCORE; // Checkmate/stalemate detection: if (!movesfound) { if (isOwnKingAttacked()) return (-CHECKMATESCORE+ply-1); else return (STALEMATESCORE); } return alpha; }