static void shutdown(Ether *ether) { int i; Ctlr *ctlr = ether->ctlr; Gbereg *reg = ctlr->reg; ilock(ctlr); quiesce(reg); reg->euc |= Portreset; coherence(); iunlock(ctlr); delay(100); ilock(ctlr); reg->euc &= ~Portreset; coherence(); delay(20); reg->psc0 = 0; /* no PSC0porton */ reg->psc1 |= PSC1portreset; coherence(); delay(50); reg->psc1 &= ~PSC1portreset; coherence(); for (i = 0; i < nelem(reg->tcqdp); i++) reg->tcqdp[i] = 0; for (i = 0; i < nelem(reg->crdp); i++) reg->crdp[i].r = 0; coherence(); iunlock(ctlr); }
int quiesce(int alpha,int beta) { int i, j, x; ++nodes; /* do some housekeeping every 1024 nodes */ if ((nodes & 1023) == 0) checkup(); pv_length[ply] = ply; /* are we too deep? */ if (ply >= MAX_PLY - 1) return eval(); if (hply >= HIST_STACK - 1) return eval(); /* check with the evaluation function */ x = eval(); if (x >= beta) return beta; if (x > alpha) alpha = x; gen_caps(); if (follow_pv) /* are we following the PV? */ sort_pv(); /* loop through the moves */ for (i = first_move[ply]; i < first_move[ply + 1]; ++i) { sort(i); if (!makemove(gen_dat[i].m.b)) continue; x = -quiesce(-beta, -alpha); takeback(); if (x > alpha) { if (x >= beta) return beta; alpha = x; /* update the PV */ pv[ply][ply] = gen_dat[i].m; for (j = ply + 1; j < pv_length[ply + 1]; ++j) pv[ply][j] = pv[ply + 1][j]; pv_length[ply] = pv_length[ply + 1]; } } return alpha; }
/*Genera le mosse della Root e le ordina*/ void root(){ int d,next; RMOVEL m; unsigned int c; /*siamo sotto scacco?*/ check_condition(); /*generiamo le mosse della root*/ gen_all(); /*validiamo, inseriamo nella lista e attribuiamo un valore*/ tree.last_root_move=0; for (c=0;c<tree.first_move[1];c++) { if(!makemove(tree.move_list[c].move,0))continue; tree.root_move_list[tree.last_root_move].move=tree.move_list[c].move; tree.root_move_list[c].scorec=-quiesce(-INF,+INF,0); tree.root_move_list[c].scoren=0; tree.last_root_move++; unmakemove(); } /*ordiniamo*/ d=1; do { next=0; for (c=0;c<((tree.last_root_move)-d);c++) { if (tree.root_move_list[c].scorec<tree.root_move_list[c+1].scorec) { m=tree.root_move_list[c]; tree.root_move_list[c]=tree.root_move_list[c+1]; tree.root_move_list[c+1]=m; next=1; } } d++; } while (next); }
int search(int alpha, int beta, int depth) { int i, j, x; BOOL c, f; /* we're as deep as we want to be; call quiesce() to get a reasonable score and return it. */ if (!depth) return quiesce(alpha,beta); ++nodes; /* do some housekeeping every 1024 nodes */ if ((nodes & 1023) == 0) checkup(); pv_length[ply] = ply; /* if this isn't the root of the search tree (where we have to pick a move and can't simply return 0) then check to see if the position is a repeat. if so, we can assume that this line is a draw and return 0. */ if (ply && reps()) return 0; /* are we too deep? */ if (ply >= MAX_PLY - 1) return eval(); if (hply >= HIST_STACK - 1) return eval(); /* are we in check? if so, we want to search deeper */ c = in_check(side); if (c) ++depth; gen(); if (follow_pv) /* are we following the PV? */ sort_pv(); f = FALSE; /* loop through the moves */ for (i = first_move[ply]; i < first_move[ply + 1]; ++i) { sort(i); if (!makemove(gen_dat[i].m.b)) continue; f = TRUE; x = -search(-beta, -alpha, depth - 1); takeback(); if (x > alpha) { /* this move caused a cutoff, so increase the history value so it gets ordered high next time we can search it */ history[(int)gen_dat[i].m.b.from][(int)gen_dat[i].m.b.to] += depth; if (x >= beta) return beta; alpha = x; /* update the PV */ pv[ply][ply] = gen_dat[i].m; for (j = ply + 1; j < pv_length[ply + 1]; ++j) pv[ply][j] = pv[ply + 1][j]; pv_length[ply] = pv_length[ply + 1]; } } /* no legal moves? then we're in checkmate or stalemate */ if (!f) { if (c) return -10000 + ply; else return 0; } /* fifty move draw rule */ if (fifty >= 100) return 0; return alpha; }
int Game::quiesce(ChessBoard *board, const int depth, int alpha, const int beta) { // before any evaluation, first check if time is up if(m_evalCount % 1000 == 0) { if(timeUp()) m_bInterrupted = true; } if(m_bInterrupted){ #if DEBUG_LEVEL & 1 DEBUG_PRINT("\nQ interrupted @%d\n", depth); #endif return alpha; // } #if DEBUG_LEVEL & 1 DEBUG_PRINT(" %d{", depth); #endif // administer evaluation count and get the board value m_evalCount++; const int boardValue = board->boardValueExtension(); int value; // at this point there can be a beta cutt-off unless we're in check if(!Move_isCheck(board->getMyMove())){ if(boardValue >= beta){ #if DEBUG_LEVEL & 1 DEBUG_PRINT("X%d,%d ", depth, value, beta); #endif return beta; } } if(depth == 0) // ok, max quiesce depth is reached; return this value { #if DEBUG_LEVEL & 1 //DEBUG_PRINT(".%d", boardValue); #endif // get the value of this node return boardValue; } if(boardValue >= beta) return beta; // futility pruning here? i.e. can alpha be improved // update lower bound if(boardValue > alpha) { alpha = boardValue; } int move; //int best = (-ChessBoard::VALUATION_MATE)-1; ChessBoard *nextBoard = m_boardFactory[MAX_DEPTH - depth]; board->scoreMoves(); while (board->hasMoreMoves()) { move = board->getNextScoredMove(); board->makeMove(move, nextBoard); // self check is illegal! if(nextBoard->checkInSelfCheck()){ // not valid, remove this move and continue board->removeMoveElementAt(); continue; } // generate the moves for this next board in order to validate the board // todo, reset this if attackedMoveSquares are working //nextBoard->genMoves(); if(nextBoard->checkInCheck()){ #if DEBUG_LEVEL & 1 DEBUG_PRINT("!", 0); #endif nextBoard->setMyMoveCheck(); move = Move_setCheck(move); } #if DEBUG_LEVEL & 1 char buf[20]; Move::toDbgString(move, buf); DEBUG_PRINT(" %s ", buf); #endif // quiescent search if(Move_isHIT(move) || Move_isCheck(move) || Move_isPromotionMove(move)){ // a valid and active move, so continue quiescent search // optimization; only generate when needed // todo back to before checkInCheck? nextBoard->genMoves(); value = -quiesce(nextBoard, depth-1,-beta,-alpha); if(value > alpha) { alpha = value; if(value >= beta){ #if DEBUG_LEVEL & 1 DEBUG_PRINT("B", 0); #endif return beta; //break; } } } } // no valid moves, so mate or stalemate if(board->getNumMoves() == 0){ //DEBUG_PRINT("@", 0); if(Move_isCheck(board->getMyMove())){ #if DEBUG_LEVEL & 1 DEBUG_PRINT("Q.#\n", 0); #endif return (-ChessBoard::VALUATION_MATE); } #if DEBUG_LEVEL & 1 DEBUG_PRINT("Q.$\n", 0); #endif return ChessBoard::VALUATION_DRAW; } #if DEBUG_LEVEL & 1 DEBUG_PRINT("|%d} %d @%d\n", board->getNumMoves(), alpha, depth); #endif return alpha; }
//////////////////////////////////////////////////////////////////////////////// // alphaBeta //////////////////////////////////////////////////////////////////////////////// int Game::alphaBeta(ChessBoard *board, const int depth, int alpha, const int beta) { if(m_evalCount % 1000 == 0) { if(timeUp()) m_bInterrupted = true; } if(m_bInterrupted){ return alpha; // } int value = 0; // 50 move rule and repetition check if(board->checkEnded()){ return ChessBoard::VALUATION_DRAW; } board->scoreMovesPV(m_arrPVMoves[m_searchDepth - depth]); int best = (-ChessBoard::VALUATION_MATE)-1; int move = 0; ChessBoard *nextBoard = m_boardFactory[depth]; while (board->hasMoreMoves()) { move = board->getNextScoredMove(); board->makeMove(move, nextBoard); // self check is illegal! if(nextBoard->checkInSelfCheck()){ // not valid, remove this move and continue //DEBUG_PRINT("#", 0); board->removeMoveElementAt(); continue; } // generate the moves for this next board in order to validate the board nextBoard->genMoves(); if(nextBoard->checkInCheck()){ //DEBUG_PRINT("+", 0); nextBoard->setMyMoveCheck(); move = Move_setCheck(move); } // ok valid move #if DEBUG_LEVEL & 1 char buf[20]; Move::toDbgString(move, buf); DEBUG_PRINT("\n%d %s > ", depth, buf); #endif // at depth one is at the leaves, so call quiescent search if(depth == 1) { value = -quiesce(nextBoard, QUIESCE_DEPTH, -beta, -alpha); } else { value = -alphaBeta(nextBoard, depth-1,-beta,-alpha); } if(value > best) { best = value; m_arrPVMoves[m_searchDepth - depth] = move; } if(best > alpha) { #if DEBUG_LEVEL & 1 DEBUG_PRINT("$ best > alpha %d > %d ", best, alpha); #endif alpha = best; } if(best >= beta){ #if DEBUG_LEVEL & 1 DEBUG_PRINT("$ best >= beta break, %d > %d\n", best, beta); #endif break; } } // no valid moves, so mate or stalemate if(board->getNumMoves() == 0){ //DEBUG_PRINT("@", 0); if(Move_isCheck(board->getMyMove())){ #if DEBUG_LEVEL & 1 DEBUG_PRINT("\nMate #\n", 0); #endif return (-ChessBoard::VALUATION_MATE); } #if DEBUG_LEVEL & 1 DEBUG_PRINT("\nStalemate\n", 0); #endif return ChessBoard::VALUATION_DRAW; } #if DEBUG_LEVEL & 4 DEBUG_PRINT("\n==> alphaBeta #moves: %d\n", board->getNumMoves()); #endif return best; }
boolean Game::alphaBetaRoot(const int depth, int alpha, const int beta) { if(m_bInterrupted){ return false; // } int value = 0; m_board->scoreMovesPV(m_arrPVMoves[m_searchDepth - depth]); int best = (-ChessBoard::VALUATION_MATE)-1; int move = 0, bestMove = 0; ChessBoard *nextBoard = m_boardFactory[depth]; while (m_board->hasMoreMoves()) { move = m_board->getNextScoredMove(); m_board->makeMove(move, nextBoard); // self check is illegal! if(nextBoard->checkInSelfCheck()){ // not valid, remove this move and continue //DEBUG_PRINT("#", 0); m_board->removeMoveElementAt(); continue; } // generate the moves for this next board in order to validate the board nextBoard->genMoves(); #if DEBUG_LEVEL & 1 //char bbuf[2048]; //nextBoard->printB(bbuf); //DEBUG_PRINT("\n%s\n", bbuf); #endif if(nextBoard->checkInCheck()){ #if DEBUG_LEVEL & 1 DEBUG_PRINT("!", 0); #endif nextBoard->setMyMoveCheck(); move = Move_setCheck(move); } // ok valid move #if DEBUG_LEVEL & 1 char buf[20]; Move::toDbgString(move, buf); DEBUG_PRINT("\n====== %s [ > ", buf); #endif // at depth one is at the leaves, so call quiescent search if(depth == 1) { value = -quiesce(nextBoard, QUIESCE_DEPTH, -beta, -alpha); } else { // if not PV then narrow search window value = -alphaBeta(nextBoard, depth-1,-beta,-alpha); } #if DEBUG_LEVEL & 1 DEBUG_PRINT(":: %d ", value); #endif if(value > best) { best = value; bestMove = move; m_arrPVMoves[m_searchDepth - depth] = move; } if(best > alpha) { //co.pl(" a= " + best); alpha = best; } if(best >= beta){ #if DEBUG_LEVEL & 1 DEBUG_PRINT("\nBreak out main loop %d\n", best); #endif break; } } #if DEBUG_LEVEL & 1 DEBUG_PRINT("]",0); #endif // we're interrupted, no move and no value! if(m_bInterrupted) return false; m_bestMove = bestMove; m_bestValue = best; if(m_board->getNumMoves() <= 1){ if(m_board->getNumMoves() == 0){ DEBUG_PRINT("NO moves in aphaBetaRoot!", 0); } #if DEBUG_LEVEL & 1 DEBUG_PRINT("\n==> alphaBetaRoot NO continuation %d\n", m_board->getNumMoves()); #endif // do not contine, so return false return false; } #if DEBUG_LEVEL & 1 DEBUG_PRINT("\n==> alphaBetaRoot continue %d\n", m_board->getNumMoves()); #endif return true; }