bool ChessAI::nextMove() { Square s, e; if (!isSetUp) { err << "nextMove() called when ChessAI not yet set up" << err; return false; } copyInData(game); if (gameOver) { err << "nextMove() caalled after game is over" << err; return false; } if (colorToMove!=myColor) { err << "called chessAI with wrong color to move" << err; return false; } err << "\n\n" << err; bool success=findBestMove(true, settings.checkDepth); return success; }
void AIPlayer::getMove(Grid& grid) { bool shouldAttack = true; //Check if we are in risk of losing and block the opponent. int riskX, riskY; Risk risk = checkRisk(grid, getOtherPlayerColor(), riskX, riskY); //Before this, have to check if the risk of losing is smaller than the risk of wining. //Use heuristics later we may take more risk. switch(risk) { case Risk_Medium: case Risk_High: case Risk_WinTheGame: { playPosition.x = riskX; playPosition.y = riskY; //shouldAttack = false; //we gotta defend! } break; } //Else try playing using the minimax algorithm. if (shouldAttack) { AIMove move = findBestMove(grid); playPosition = move.position; } }
void Chess::update() { if (_controls._mouseLeft && _draggedPiece == nullptr && mouseOnTile() != nullptr && mouseOnTile()->holding() != nullptr) { if (&(mouseOnTile()->holding()->owner()) == &_player) { _draggedPiece = mouseOnTile()->holding(); } } if (!_controls._mouseLeft && _draggedPiece != nullptr) { if (_draggedPiece->move(mouseOnTile(), _board.tiles())) { _lastMovedPlayer = &_draggedPiece->owner(); _computer._bestScore = -10000; _computer._moves.clear(); _player._bestScore = -10000; _player._moves.clear(); findBestMove(&_computer, 4); _computer._bestMove.fromTile->_currPiece->move(_computer._bestMove.toTile, _board.tiles()); } _draggedPiece = nullptr; } if (_draggedPiece != nullptr) { _draggedPiece->setPosition(_controls._mousePos.x - _draggedPiece->sprite().getGlobalBounds().width / 2 + _draggedPiece->sprite().getSize().x / 2, _controls._mousePos.y - _draggedPiece->sprite().getGlobalBounds().height / 2 + _draggedPiece->sprite().getSize().y / 2); } }
int Chess::findBestMove(Player* player, int depth) { Player* otherPlayer = player; if (player == &_computer) { otherPlayer = &_player; } else { otherPlayer = &_computer; } if (depth == 0) { return (player->score(_board.tiles()) - otherPlayer->score(_board.tiles())); } for (auto cp : player->activeChessPieces(_board.tiles())) { for (auto pm : cp->possibleMoves(_board.tiles())) { // Make move ChessPiece* endPosPiece = pm.toTile->_currPiece; cp->move(pm.toTile, _board.tiles()); player->_moves.push_back(Move(pm.fromTile, pm.toTile)); int score = findBestMove(otherPlayer, depth - 1); if (score > player->_bestScore){ player->_bestScore = score; player->_bestMove = player->_moves[0]; } // Restore piece cp->_currTile = pm.fromTile; pm.fromTile->_currPiece = cp; pm.toTile->_currPiece = endPosPiece; if (endPosPiece != nullptr) { endPosPiece->setActive(true); } player->_moves.pop_back(); // TODO: Change the way we update position of chesspieces everywhere. cp->setPosition(pm.fromTile->_pos.x + pm.fromTile->_size.x / 2, pm.fromTile->_pos.y + pm.fromTile->_size.y / 2); } } return (player->score(_board.tiles()) - otherPlayer->score(_board.tiles())); }
char findBestComputerMove(Hole originalBoard[]) { printFlag = 0; int i, j, k; // make a copy of the originalBoard Hole newBoard[BOARDSIZE]; copyBoard(newBoard, originalBoard); // construct the searching tree Node root; initSearchTree(newBoard, &root); // construct first level. Root is at level 0 int depth = 3; expandTree(&root, depth, 1); Node* bestNode; bestNode = findBest(&root, depth); char computerMove = findBestMove(bestNode, &root); deleteTree(&root, &root); printFlag = 1; return computerMove; }
int main(int argc, char** argv) { char b[BS]; int r, c; Communicator comm(argc, argv); int validHMoves[BS]; int validCMoves[BS]; int scoreHMoves[BS]; validCMoves[0] = 0; char buf[100]; ofstream outputFile; if (comm.rank == 0) { sprintf(buf,"\n\nP = %d", comm.nprocs); logIt(buf); int hMove = 0; int depth = atoi(argv[1]); srand((int) time(NULL)); setupBoard(b); do { validMoves(b,H,validHMoves,scoreHMoves); displayBoard(b); if (validHMoves[0]) { hMove = moveHuman(b,validHMoves); // to get a manually entered move if (hMove == 0) { break; } cout << "After your move the board is:\n"; displayBoard(b,C); } else { cout << "You Don't have any valid moves.\n"; } cout << "Computer is plotting your demise.\n"; int best = findBestMove(comm, b, C, depth); if (best != 0) { squareScore(b,best,C,true); aiToBs(best, r, c); cout << "Computer moves to [" << r << "," << c << "]\n"; } else { cout << "Computer does not have a valid move\n"; } } while ((validCMoves[0] || validHMoves[0]) && (hMove != 0)); WorkRequest* wReq = new WorkRequest(); wReq->b[0] = 'T'; for(int i = 1; i < comm.nprocs; i++) comm.send(i, (char *) wReq, 1, TAG_DO_THIS_WORK); cout << "\n\nGame over\n\n"; } else { // not comm.rank 0 worker(comm); } comm.finalize(); return (EXIT_SUCCESS); }
double ChessAI::findBestMove(bool playIt, int iter) { PieceColor color=colorToMove; Square s, e; MoveHolder moves(settings.checkWidth); if (checkForBoringTie()) { //err << "\n\n\n BORING TIE FOUND\n\n\n" << err; return 0.5; } for (int i=((color==WHITE)?0:16); i<((color==WHITE)?16:32); ++i) { if (pieces[i].alive) { s=pieces[i].square; for (e.y=0; e.y<8; ++e.y) { for (e.x=0; e.x<8; ++e.x) { bool path=checkMovePath(s, e); bool check=checkCheck(colorToMove, s, e); if (path && check) { forceMove(s, e); moves.add(MoveData(s, e, eval(color))); undo(); checkBoard(); } } } } } if (moves.size()<1) { if (checkCheck(color, kings[color]->square, kings[color]->square)) return 0.5; else return 0.0; } MoveData bestMove; bestMove.score=-1; for (auto i=moves.begin(); i!=moves.end(); ++i) { for (int j=settings.checkDepth; j>iter; --j) err << " "; err << pieceColor2Name(color) << " " << pieceType2Name(board((*i).s)->type) << " from " << (*i).s.str() << " to " << (*i).e.str() << err; forceMove((*i).s, (*i).e); double score=0; if (iter<=0) { score=eval(color); } else { score=1-findBestMove(false, iter-1); } undo(); for (int j=settings.checkDepth+1; j>iter; --j) err << " "; err << "best score for " << pieceColor2Name(myColor) << ": " << ((myColor==color)?score:1-score) << err; if (score>bestMove.score) { bestMove.s=(*i).s; bestMove.e=(*i).e; bestMove.score=score; } } if (playIt) { return game->playMove(bestMove.s, bestMove.e); } else { return bestMove.score; } }