public List <Move> AllPosiblePiecePlays(Board board, BoardLogic boardLogic, PieceBase piece, List <Move> AllMoves, double actualValue) { board = boardLogic.GoTo(board.TurnNumber, board); int x = piece.Position.PositionX; int y = piece.Position.PositionY; foreach (Position position in piece.ValidMoves(board)) { if (boardLogic.FinallyMove(x, y, position.x1, position.y1, board, boardLogic, false)) { // solo lo guardo si no empeora la situacion (cuanto ams negativo mejor para la pc double Eval = EvaluateBoard(board); if (Eval <= actualValue) { //actualValue = EvaluateBoard(board); AllMoves.Add(new Move { x1 = x, y1 = y, x2 = position.x1, y2 = position.y1 }); } // back to previous board board = boardLogic.GoTo(board.TurnNumber - 1, board); boardLogic.futureMoves.Clear(); } //} } return(AllMoves); }
/// <summary> /// devuelve la mejor jugada que debe hacer la compu tras probar 4 movidas hacia adelante. Metodo minimax de los rústicos /// </summary> /// <param name="board"></param> /// <returns></returns> public Move BestComputerMoveDepth4(Board board, BoardLogic boardLogic) { bool Turno = board.Turn; board = boardLogic.GoTo(board.TurnNumber, board); double value = EvaluateBoard(board); Console.WriteLine("calculó EvaluateBoard"); Move BestComputerMove = null; List <Move> allMove1 = AllPosiblePlays(board, boardLogic); Console.WriteLine("calculó las AllPosiblePlays"); foreach (Move move1 in allMove1) { if (boardLogic.FinallyMove(move1.x1, move1.y1, move1.x2, move1.y2, board, boardLogic, false)) { Move moveResponse = BestResponse(board, boardLogic); boardLogic.FinallyMove(moveResponse.x1, moveResponse.y1, moveResponse.x2, moveResponse.y2, board, boardLogic, false); Console.WriteLine("movio y calculo la Best Response"); List <Move> allMove3 = AllPosiblePlays(board, boardLogic); Console.WriteLine("calculó las AllPosiblePlays luego de mover y repsonder"); foreach (Move move3 in allMove3) { if (boardLogic.FinallyMove(move3.x1, move3.y1, move3.x2, move3.y2, board, boardLogic, false)) { Move moveResponse2 = BestResponse(board, boardLogic); boardLogic.FinallyMove(moveResponse2.x1, moveResponse2.y1, moveResponse2.x2, moveResponse2.y2, board, boardLogic, false); double Eval = EvaluateBoard(board); if (Eval <= value) { value = EvaluateBoard(board); BestComputerMove = move1; //me quedo con la move1 que produce la menor bestresponse } // back to previous board board = boardLogic.GoTo(board.TurnNumber - 2, board); boardLogic.futureMoves.Clear(); } } board = boardLogic.GoTo(board.TurnNumber - 2, board); boardLogic.futureMoves.Clear(); } } if (BestComputerMove != null) { return(BestComputerMove); } Console.WriteLine("Algo raro, falla BestComputerMoveDepth4"); return(BestResponse(board, boardLogic)); }
// devuelve una movida que minimiza el score y el score public double[] Minimize(Board board, BoardLogic boardLogic, int depth) { double minScore = 10000; double[] result = new double[] { 0, 0, 0, 0, EvaluateBoard(board) }; if (Math.Abs(EvaluateBoard(board)) > 500 || depth > Constants.depthLimit) { result = new double[] { 0, 0, 0, 0, EvaluateBoard(board) }; return(result); } HashSet <PieceBase> BackupWhitePiecesAPP = board.CloneWhitePieces(); HashSet <PieceBase> BackupBlackPiecesAPP = board.CloneBlackPieces(); var hashSet = board.Turn ? BackupWhitePiecesAPP : BackupBlackPiecesAPP; foreach (PieceBase piece in hashSet) { board = boardLogic.GoTo(board.TurnNumber, board); int x = piece.Position.PositionX; int y = piece.Position.PositionY; foreach (Position position in piece.ValidMoves(board)) { if (boardLogic.FinallyMove(x, y, position.x1, position.y1, board, boardLogic, false)) { double[] maximized = Maximize(board, boardLogic, depth + 1); double Eval = maximized[4]; if (Eval <= minScore) { minScore = Eval; result[0] = x; result[1] = y; result[2] = position.x1; result[3] = position.y1; result[4] = minScore; } // back to previous board board = boardLogic.GoTo(board.TurnNumber - 1, board); boardLogic.futureMoves.Clear(); } } } return(result); }
/// <summary> /// devuelve la movida que mas aumenta el puntaje de un estado del tablero (o si es negativo que lo hace menos negativo) Es un metodo para simular la movida del humano /// </summary> /// <param name="board"></param> /// <returns></returns> public Move BestResponse(Board board, BoardLogic boardLogic) { bool Turno = board.Turn; board = boardLogic.GoTo(board.TurnNumber, board); double actualValue = EvaluateBoard(board); Move response = new Move(); Move responseNotNull = new Move(); HashSet <PieceBase> BackupWhitePieces = board.CloneWhitePieces(); HashSet <PieceBase> BackupBlackPieces = board.CloneBlackPieces(); var hashSet = board.Turn ? BackupWhitePieces : BackupBlackPieces; foreach (PieceBase piece in hashSet) { int i = piece.Position.PositionX; int j = piece.Position.PositionY; foreach (Position position in piece.ValidMoves(board)) { var removedPiece = board.GetPiece(position.x1, position.y1); if (boardLogic.FinallyMove(i, j, position.x1, position.y1, board, boardLogic, false)) { responseNotNull.x1 = i; responseNotNull.y1 = j; responseNotNull.x2 = position.x1; responseNotNull.y2 = position.y1; // si movió el de abajo if (board.player1 != board.Turn) // va != porque el finally me lo acaba de cambiar a turn { // guardo la mejor movida double Eval = EvaluateBoard(board); if (Eval >= actualValue) { actualValue = Eval; response.x1 = i; response.y1 = j; response.x2 = position.x1; response.y2 = position.y1; } } else { // mueve el de arriba if (EvaluateBoard(board) <= actualValue) { actualValue = EvaluateBoard(board); response.x1 = i; response.y1 = j; response.x2 = position.x1; response.y2 = position.y1; } } // back to previous board board = boardLogic.GoTo(board.TurnNumber - 1, board); boardLogic.futureMoves.Clear(); } } } if (response != null) { return(response); } Console.WriteLine("Algo raro, falla bestResponse"); return(responseNotNull); }