public override Tuple <Point2D, Point2D> GetMove() { Stopwatch.Start(); var pieces = Board.GetAllColored(Color); var possibleMoves = Board.GetAllPossibleMoves(); possibleMoves = possibleMoves.FindAll(tuple => tuple.Item1.Color == Color); //var newGameMoves = game.ugly_moves(); var bestMove = _randomAi.GetMove(); //use any negative large number var bestValue = BoardEvalMethod.GetEvalFunc(_boardEval).Invoke(Board, Color); for (var i = 0; i < possibleMoves.Count; i++) { var newGameMove = possibleMoves[i]; var tmpBoard = Board.Clone(); tmpBoard.Move(newGameMove.Item1, newGameMove.Item2); tmpBoard.Move(new RandomAI(tmpBoard, Util.ConverToOpposite(Color)).GetMove()); //take the negative as AI plays as black var boardValue = BoardEvalMethod.GetEvalFunc(_boardEval).Invoke(tmpBoard, Color); if (boardValue > bestValue) { bestValue = boardValue; bestMove = new Tuple <Point2D, Point2D>(newGameMove.Item1.PositionPoint2D, newGameMove.Item2); } } _stopwatch.Stop(); return(bestMove); }
/* * function alphabeta(node, depth, α, β, maximizingPlayer) * 02 if depth = 0 or node is a terminal node * 03 return the heuristic value of node * 04 if maximizingPlayer * 05 v := -∞ * 06 for each child of node * 07 v := max(v, alphabeta(child, depth – 1, α, β, FALSE)) * 08 α := max(α, v) * 09 if β ≤ α * 10 break (* β cut-off *) * 11 return v * 12 else * 13 v := +∞ * 14 for each child of node * 15 v := min(v, alphabeta(child, depth – 1, α, β, TRUE)) * 16 β := min(β, v) * 17 if β ≤ α * 18 break (* α cut-off *) * 19 return v * * alphabeta(origin, depth, -∞, +∞, TRUE) * */ private float AlpaBetaMinimax(Node node, float alpha, float beta, int depth, Color color) { if (depth == 0 || Rules.GameFinished(node.Board)) { if (Rules.CheckCheckMate(node.Board)) { node.Score = color == Color ? 1000 : -1000; } else { node.Score = BoardEvalMethod.GetEvalFunc(_boardEval).Invoke(node.Board, Color); } return(node.Score); } if (color == Color) { var v = -float.MaxValue; foreach (var childNode in node.GenerateChildNodes()) { v = Math.Max(v, AlpaBetaMinimax(childNode, alpha, beta, depth - 1, Util.ConverToOpposite(color))); alpha = Math.Max(v, alpha); node.Score = alpha; if (beta <= alpha) { break; } } return(v); } else { var v = float.MaxValue; foreach (var childNode in node.GenerateChildNodes()) { v = Math.Min(v, AlpaBetaMinimax(childNode, alpha, beta, depth - 1, Util.ConverToOpposite(color))); beta = Math.Min(v, beta); node.Score = beta; if (beta <= alpha) { ; break; } } return(v); } }
public Node[] GenerateChildNodes() { var list = new List <Node>(); foreach (var allPossibleMove in Organize(Board.GetAllPossibleMoves(Color), BoardEvalMethod.GetEvalFunc(BoardEval))) { var newBoard = Board.Clone(); newBoard.Move(allPossibleMove); list.Add(new Node(this, new Pair <Point2D, Point2D>(allPossibleMove.Item1.PositionPoint2D, allPossibleMove.Item2), newBoard, Depth - 1, BoardEval)); } childerNodes = list; return(list.ToArray()); }