/// <summary> /// gets a list of available moves for a color /// </summary> public static List <ChessMove> getmovesofcolor(StudentAI ai, ChessColor color, ChessBoard board) { List <ChessMove> colormoves = new List <ChessMove>(); for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { if (color == ChessColor.Black) { switch (board[x, y]) { case ChessPiece.BlackPawn: case ChessPiece.BlackKnight: case ChessPiece.BlackBishop: case ChessPiece.BlackQueen: case ChessPiece.BlackRook: case ChessPiece.BlackKing: colormoves.AddRange(getmovesofpiece(ai, color, board, new ChessLocation(x, y))); break; default: break; } } if (color == ChessColor.White) { switch (board[x, y]) { case ChessPiece.WhitePawn: case ChessPiece.WhiteKnight: case ChessPiece.WhiteBishop: case ChessPiece.WhiteQueen: case ChessPiece.WhiteRook: case ChessPiece.WhiteKing: colormoves.AddRange(getmovesofpiece(ai, color, board, new ChessLocation(x, y))); break; default: break; } } } } return(colormoves); }
/// <summary> /// gets a list of available moves for a color /// </summary> public static List<ChessMove> getmovesofcolor(StudentAI ai, ChessColor color, ChessBoard board) { List<ChessMove> colormoves = new List<ChessMove>(); for (int y = 0; y < 8; y++) { for (int x = 0; x < 8; x++) { if (color == ChessColor.Black) { switch (board[x, y]) { case ChessPiece.BlackPawn: case ChessPiece.BlackKnight: case ChessPiece.BlackBishop: case ChessPiece.BlackQueen: case ChessPiece.BlackRook: case ChessPiece.BlackKing: colormoves.AddRange(getmovesofpiece(ai, color, board, new ChessLocation(x, y))); break; default: break; } } if (color == ChessColor.White) { switch (board[x, y]) { case ChessPiece.WhitePawn: case ChessPiece.WhiteKnight: case ChessPiece.WhiteBishop: case ChessPiece.WhiteQueen: case ChessPiece.WhiteRook: case ChessPiece.WhiteKing: colormoves.AddRange(getmovesofpiece(ai, color, board, new ChessLocation(x, y))); break; default: break; } } } } return colormoves; }
/// <summary> /// gets move for a specfic piece /// </summary> public static List<ChessMove> getmovesofpiece(StudentAI ai,ChessColor color, ChessBoard board,ChessLocation location) { List<ChessMove> piecemoves = new List<ChessMove>(); ChessMove move = new ChessMove(location,location); switch (board[location]) { case ChessPiece.BlackPawn: ChessMove bdiag1 = new ChessMove(location,new ChessLocation((location.X)-1,(location.Y)+1)); ChessMove bdown = new ChessMove(location,new ChessLocation((location.X),(location.Y)+1)); ChessMove bdown2 = new ChessMove(location, new ChessLocation((location.X), (location.Y) + 2)); ChessMove bdiag2 = new ChessMove(location,new ChessLocation((location.X)+1,(location.Y)+1)); if (ai.IsValidMove(board, bdiag1, color)) piecemoves.Add(bdiag1); if (ai.IsValidMove(board, bdown, color)) piecemoves.Add(bdown); if (ai.IsValidMove(board, bdiag2, color)) piecemoves.Add(bdiag2); if (ai.IsValidMove(board, bdown2, color)) piecemoves.Add(bdown2); break; case ChessPiece.WhitePawn: ChessMove wdiag1 = new ChessMove(location,new ChessLocation((location.X)-1,(location.Y)-1)); ChessMove wup = new ChessMove(location,new ChessLocation((location.X),(location.Y)-1)); ChessMove wup2 = new ChessMove(location, new ChessLocation((location.X), (location.Y) - 2)); ChessMove wdiag2 = new ChessMove(location,new ChessLocation((location.X)+1,(location.Y)-1)); if (ai.IsValidMove(board, wdiag1, color)) piecemoves.Add(wdiag1); if (ai.IsValidMove(board, wup, color)) piecemoves.Add(wup); if (ai.IsValidMove(board, wdiag2, color)) piecemoves.Add(wdiag2); if (ai.IsValidMove(board, wup2, color)) piecemoves.Add(wup2); break; case ChessPiece.BlackKing: for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { move = new ChessMove(location, new ChessLocation(location.X + i, location.Y + j)); if(ai.IsValidMove(board,move,color)) piecemoves.Add(move); } } break; case ChessPiece.WhiteKing: for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { move = new ChessMove(location, new ChessLocation(location.X + i, location.Y + j)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); } } break; case ChessPiece.BlackKnight: move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + 1)); if(ai.IsValidMove(board,move,color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + -1)); if(ai.IsValidMove(board,move,color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + 2)); if(ai.IsValidMove(board,move,color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + -2)); if(ai.IsValidMove(board,move,color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + 1)); if(ai.IsValidMove(board,move,color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + -1)); if(ai.IsValidMove(board,move,color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + 2)); if(ai.IsValidMove(board,move,color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + -2)); if(ai.IsValidMove(board,move,color)) piecemoves.Add(move); break; case ChessPiece.WhiteKnight: move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + 1)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + -1)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + 2)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + -2)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + 1)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + -1)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + 2)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + -2)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); break; case ChessPiece.BlackBishop: case ChessPiece.WhiteBishop: bool flag = true; int x = 1; while(flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y + x)); if(ai.IsValidMove(board,move,color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y - x)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y - x)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y + x)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } break; case ChessPiece.BlackRook: case ChessPiece.WhiteRook: flag = true; x = 1; while(flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while(flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while(flag) { move = new ChessMove(location, new ChessLocation(location.X, location.Y+x)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while(flag) { move = new ChessMove(location, new ChessLocation(location.X, location.Y-x)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } break; case ChessPiece.BlackQueen: case ChessPiece.WhiteQueen: flag = true; x = 1; while (flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y + x)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y - x)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y - x)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y + x)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X, location.Y + x)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X, location.Y - x)); if (ai.IsValidMove(board, move, color)) piecemoves.Add(move); else flag = false; x++; } break; default: return piecemoves; } return piecemoves; }
/// <summary> /// gets move for a specfic piece /// </summary> public static List <ChessMove> getmovesofpiece(StudentAI ai, ChessColor color, ChessBoard board, ChessLocation location) { List <ChessMove> piecemoves = new List <ChessMove>(); ChessMove move = new ChessMove(location, location); switch (board[location]) { case ChessPiece.BlackPawn: ChessMove bdiag1 = new ChessMove(location, new ChessLocation((location.X) - 1, (location.Y) + 1)); ChessMove bdown = new ChessMove(location, new ChessLocation((location.X), (location.Y) + 1)); ChessMove bdown2 = new ChessMove(location, new ChessLocation((location.X), (location.Y) + 2)); ChessMove bdiag2 = new ChessMove(location, new ChessLocation((location.X) + 1, (location.Y) + 1)); if (ai.IsValidMove(board, bdiag1, color)) { piecemoves.Add(bdiag1); } if (ai.IsValidMove(board, bdown, color)) { piecemoves.Add(bdown); } if (ai.IsValidMove(board, bdiag2, color)) { piecemoves.Add(bdiag2); } if (ai.IsValidMove(board, bdown2, color)) { piecemoves.Add(bdown2); } break; case ChessPiece.WhitePawn: ChessMove wdiag1 = new ChessMove(location, new ChessLocation((location.X) - 1, (location.Y) - 1)); ChessMove wup = new ChessMove(location, new ChessLocation((location.X), (location.Y) - 1)); ChessMove wup2 = new ChessMove(location, new ChessLocation((location.X), (location.Y) - 2)); ChessMove wdiag2 = new ChessMove(location, new ChessLocation((location.X) + 1, (location.Y) - 1)); if (ai.IsValidMove(board, wdiag1, color)) { piecemoves.Add(wdiag1); } if (ai.IsValidMove(board, wup, color)) { piecemoves.Add(wup); } if (ai.IsValidMove(board, wdiag2, color)) { piecemoves.Add(wdiag2); } if (ai.IsValidMove(board, wup2, color)) { piecemoves.Add(wup2); } break; case ChessPiece.BlackKing: for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { move = new ChessMove(location, new ChessLocation(location.X + i, location.Y + j)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } } } break; case ChessPiece.WhiteKing: for (int i = -1; i < 2; i++) { for (int j = -1; j < 2; j++) { move = new ChessMove(location, new ChessLocation(location.X + i, location.Y + j)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } } } break; case ChessPiece.BlackKnight: move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + 1)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + -1)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + 2)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + -2)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + 1)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + -1)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + 2)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + -2)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } break; case ChessPiece.WhiteKnight: move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + 1)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + 2, location.Y + -1)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + 2)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + 1, location.Y + -2)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + 1)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + -2, location.Y + -1)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + 2)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } move = new ChessMove(location, new ChessLocation(location.X + -1, location.Y + -2)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } break; case ChessPiece.BlackBishop: case ChessPiece.WhiteBishop: bool flag = true; int x = 1; while (flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y + x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y - x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y - x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y + x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } break; case ChessPiece.BlackRook: case ChessPiece.WhiteRook: flag = true; x = 1; while (flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X, location.Y + x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X, location.Y - x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } break; case ChessPiece.BlackQueen: case ChessPiece.WhiteQueen: flag = true; x = 1; while (flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y + x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y - x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y - x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y + x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X + x, location.Y)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X - x, location.Y)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X, location.Y + x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } x = 1; flag = true; while (flag) { move = new ChessMove(location, new ChessLocation(location.X, location.Y - x)); if (ai.IsValidMove(board, move, color)) { piecemoves.Add(move); } else { flag = false; } x++; } break; default: return(piecemoves); } return(piecemoves); }
private void SetMoveFlagAndValue(ChessMoveData moveData) { var myMoves = StudentAI.GetMyMoves(moveData.NewBoard, moveData.Color); //see if checking other player bool any = false; foreach (var move in myMoves) { var oldToTile = move.OldBoard[move.Move.To.X, move.Move.To.Y]; if ((moveData.Color == ChessColor.Black && oldToTile == ChessPiece.WhiteKing) || (moveData.Color == ChessColor.White && oldToTile == ChessPiece.BlackKing)) { any = true; break; } } moveData.Move.Flag = any ? ChessFlag.Check : ChessFlag.NoFlag; //see if in checkmate if (moveData.Move.Flag == ChessFlag.Check) { if (InCheckmate(moveData)) { moveData.Move.Flag = ChessFlag.Checkmate; } } moveData.Move.ValueOfMove = GetBoardValue(moveData.NewBoard, moveData.Color); var otherMoves = StudentAI.GetMyMoves(moveData.NewBoard, EnemyColor(moveData.Color)); foreach (var otherMove in otherMoves) { if (otherMove.Move.To.X != moveData.Move.To.X || otherMove.Move.To.Y != moveData.Move.To.Y) { continue; } var currentPiece = moveData.NewBoard[moveData.Move.To.X, moveData.Move.To.Y]; if (currentPiece == ChessPiece.Empty) { continue; } var colorMulti = (GetChessPieceColor(currentPiece) == moveData.Color) ? 1 : -1; var value = 0; switch (currentPiece) { case ChessPiece.BlackPawn: value += colorMulti * pawnValue; value += colorMulti * (pawnValue / PawnRankModifier) * (moveData.Move.To.Y - 1); break; case ChessPiece.WhitePawn: value += colorMulti * pawnValue; value += colorMulti * (pawnValue / PawnRankModifier) * (6 - moveData.Move.To.Y); break; case ChessPiece.BlackRook: case ChessPiece.WhiteRook: value += colorMulti * rookValue; break; case ChessPiece.BlackKnight: case ChessPiece.WhiteKnight: value += colorMulti * knightValue; break; case ChessPiece.BlackBishop: case ChessPiece.WhiteBishop: value += colorMulti * bishopValue; break; case ChessPiece.BlackQueen: case ChessPiece.WhiteQueen: value += colorMulti * queenValue; break; case ChessPiece.BlackKing: case ChessPiece.WhiteKing: break; default: throw new Exception("Somehow not catching a specific piece? Empty?"); break; } value = (int)(value * 1.5f); moveData.Move.ValueOfMove -= value; break; } var random = new Random(); moveData.Move.ValueOfMove += random.Next(randomValue * 2) - randomValue; if (moveData.Move.Flag == ChessFlag.Check) { moveData.Move.ValueOfMove += checkValue; } if (moveData.Move.Flag == ChessFlag.Checkmate) { moveData.Move.ValueOfMove += checkmateValue; } }
public Hueristic getMinimax(StudentAI AI, ChessBoard board, ChessColor color, int depth, ChessColor maxColor, int alpha = -999999, int beta = 999999) { //TODO update to return heuristic instead of move and update get next move to return move of heuristic. if (depth > maxdepth) { return new Hueristic(board,new ChessMove(null, null),color); } List<ChessMove> allmoves = new List<ChessMove>(); allmoves.AddRange(PieceMoves.getmovesofcolor(AI, color, board)); List<Hueristic> HueristicMoves = new List<Hueristic>(); //DecisionTree descisions = new DecisionTree(board); //descisions. ChessColor oppositeColor = color == ChessColor.Black ? ChessColor.White : ChessColor.Black; //set check/checkmate flag and calculate hueristic on each move foreach (var move in allmoves) { var tempBoard = board.Clone(); tempBoard.MakeMove(move); if (StudentAI.IsKingInCheck(tempBoard, oppositeColor)) { move.Flag = ChessFlag.Check; //check for checkmate if (PieceMoves.getmovesofcolor(AI, oppositeColor, tempBoard).Count == 0) { move.Flag = ChessFlag.Checkmate; return new Hueristic(board,move,color); } } HueristicMoves.Add(new Hueristic(board, move, color)); if (color == maxColor && move.Flag == ChessFlag.Check) HueristicMoves[HueristicMoves.Count - 1].HValue += 2; if (color == maxColor && move.Flag == ChessFlag.Checkmate) { HueristicMoves[HueristicMoves.Count - 1].HValue = 10000; return HueristicMoves[HueristicMoves.Count -1]; } } HueristicMoves.Sort((x, y) => y.HValue.CompareTo(x.HValue)); if (AI.IsMyTurnOver() && HueristicMoves.Count > 0) return HueristicMoves[0]; //if (depth == maxdepth && HueristicMoves.Count>0) // return HueristicMoves[0]; List<Hueristic> updatedhueristic = new List<Hueristic>(); //minimax and alpha beta pruning bool defined = false; var temp = new List<Hueristic>(); do { //TODO, store previous move and if we ran out of time use that one since we don't know if optimal on the next one temp = new List<Hueristic>(); foreach (var hmove in HueristicMoves) { var tempBoard = board.Clone(); if (hmove.TheMove != null) { tempBoard.MakeMove(hmove.TheMove); if (depth != maxdepth) { var oppositemove = getMinimax(AI, tempBoard, oppositeColor, depth + 1, maxColor, alpha, beta); //get best move of the other color if (oppositemove.TheMove.To != null && oppositemove.TheMove.From != null) { hmove.HValue -= oppositemove.HValue; // update our moves score based on return of projected other move } } temp.Add(hmove); // add new scored hueristic to new list if (AI.IsMyTurnOver()) break; //a=max(a,hueristic) if (maxColor == color) { alpha = alpha > hmove.HValue ? alpha : hmove.HValue; if (beta <= alpha) break; } else { beta = beta < hmove.HValue ? beta : hmove.HValue; if (beta <= alpha) break; } } } if (!AI.IsMyTurnOver()) { if (depth == 0) { maxdepth += 1; defined = true; updatedhueristic = temp; } } } while (!AI.IsMyTurnOver() && depth == 0); if (!defined) updatedhueristic = temp; updatedhueristic.Sort((x, y) => y.HValue.CompareTo(x.HValue)); // sort the new list if (color == maxColor) { if (updatedhueristic.Count == 0) { var game_over = new ChessMove(null, null); game_over.Flag = ChessFlag.Stalemate; var game_overhueristic = new Hueristic(board, game_over, color); return game_overhueristic; } int tiecount = -1; foreach (var x in updatedhueristic) if (x.HValue == updatedhueristic[0].HValue) tiecount++; if (tiecount > 0) return updatedhueristic[rand.Next(0, tiecount)]; } if (updatedhueristic.Count == 0) return new Hueristic(board,new ChessMove(null, null),color); return updatedhueristic[0]; //return the best value from the new list }
public Hueristic getMinimax(StudentAI AI, ChessBoard board, ChessColor color, int depth, ChessColor maxColor, int alpha = -999999, int beta = 999999) { //TODO update to return heuristic instead of move and update get next move to return move of heuristic. if (depth > maxdepth) { return(new Hueristic(board, new ChessMove(null, null), color)); } List <ChessMove> allmoves = new List <ChessMove>(); allmoves.AddRange(PieceMoves.getmovesofcolor(AI, color, board)); List <Hueristic> HueristicMoves = new List <Hueristic>(); //DecisionTree descisions = new DecisionTree(board); //descisions. ChessColor oppositeColor = color == ChessColor.Black ? ChessColor.White : ChessColor.Black; //set check/checkmate flag and calculate hueristic on each move foreach (var move in allmoves) { var tempBoard = board.Clone(); tempBoard.MakeMove(move); if (StudentAI.IsKingInCheck(tempBoard, oppositeColor)) { move.Flag = ChessFlag.Check; //check for checkmate if (PieceMoves.getmovesofcolor(AI, oppositeColor, tempBoard).Count == 0) { move.Flag = ChessFlag.Checkmate; return(new Hueristic(board, move, color)); } } HueristicMoves.Add(new Hueristic(board, move, color)); if (color == maxColor && move.Flag == ChessFlag.Check) { HueristicMoves[HueristicMoves.Count - 1].HValue += 2; } if (color == maxColor && move.Flag == ChessFlag.Checkmate) { HueristicMoves[HueristicMoves.Count - 1].HValue = 10000; return(HueristicMoves[HueristicMoves.Count - 1]); } } HueristicMoves.Sort((x, y) => y.HValue.CompareTo(x.HValue)); if (AI.IsMyTurnOver() && HueristicMoves.Count > 0) { return(HueristicMoves[0]); } //if (depth == maxdepth && HueristicMoves.Count>0) // return HueristicMoves[0]; List <Hueristic> updatedhueristic = new List <Hueristic>(); //minimax and alpha beta pruning bool defined = false; var temp = new List <Hueristic>(); do { //TODO, store previous move and if we ran out of time use that one since we don't know if optimal on the next one temp = new List <Hueristic>(); foreach (var hmove in HueristicMoves) { var tempBoard = board.Clone(); if (hmove.TheMove != null) { tempBoard.MakeMove(hmove.TheMove); if (depth != maxdepth) { var oppositemove = getMinimax(AI, tempBoard, oppositeColor, depth + 1, maxColor, alpha, beta); //get best move of the other color if (oppositemove.TheMove.To != null && oppositemove.TheMove.From != null) { hmove.HValue -= oppositemove.HValue; // update our moves score based on return of projected other move } } temp.Add(hmove); // add new scored hueristic to new list if (AI.IsMyTurnOver()) { break; } //a=max(a,hueristic) if (maxColor == color) { alpha = alpha > hmove.HValue ? alpha : hmove.HValue; if (beta <= alpha) { break; } } else { beta = beta < hmove.HValue ? beta : hmove.HValue; if (beta <= alpha) { break; } } } } if (!AI.IsMyTurnOver()) { if (depth == 0) { maxdepth += 1; defined = true; updatedhueristic = temp; } } } while (!AI.IsMyTurnOver() && depth == 0); if (!defined) { updatedhueristic = temp; } updatedhueristic.Sort((x, y) => y.HValue.CompareTo(x.HValue)); // sort the new list if (color == maxColor) { if (updatedhueristic.Count == 0) { var game_over = new ChessMove(null, null); game_over.Flag = ChessFlag.Stalemate; var game_overhueristic = new Hueristic(board, game_over, color); return(game_overhueristic); } int tiecount = -1; foreach (var x in updatedhueristic) { if (x.HValue == updatedhueristic[0].HValue) { tiecount++; } } if (tiecount > 0) { return(updatedhueristic[rand.Next(0, tiecount)]); } } if (updatedhueristic.Count == 0) { return(new Hueristic(board, new ChessMove(null, null), color)); } return(updatedhueristic[0]); //return the best value from the new list }