public Move MinMaxRoot(int depth, Game g, bool IsMaximizingPlayer) { MoveGenerationResult result = g.GetMoves(); count += result.Moves.Count; if (result.Endgame == EndgameType.Checkmate) { throw new CheckmateException(); } else if (result.Endgame == EndgameType.Stalemate) { throw new StalemateException(); } double bestMove = -999999 * (g.WhiteToMove ? 1 : -1); Random r = new Random(); Move bestMoveFound = result.Moves[r.Next(result.Moves.Count - 1)]; string FENFEN = g.ToFENString(); var exceptions = new ConcurrentQueue <Exception>(); ConcurrentBag <Tuple <Move, double> > resultVal = new ConcurrentBag <Tuple <Models.Move, double> >(); Parallel.ForEach(result.Moves, (move) => { Game g2 = new Game(FENFEN); move = g2.Move(move); try { double value = MiniMax(depth - 1, g2, -1000000, 1000000, !IsMaximizingPlayer, move.To); resultVal.Add(new Tuple <Move, double>(move, value)); } catch (Exception w) { exceptions.Enqueue(w); } g2.Undo(); }); if (exceptions.Count > 0 && resultVal.Count == 0) { Exception ex; exceptions.TryDequeue(out ex); throw ex; } foreach (Tuple <Move, double> moveTuple in resultVal) { if ((g.WhiteToMove && (moveTuple.Item1.MaterialScore >= bestMove)) || (!g.WhiteToMove && (moveTuple.Item1.MaterialScore <= bestMove))) { bestMove = moveTuple.Item2; bestMoveFound = moveTuple.Item1; } } return(bestMoveFound); }
public double MiniMax(int depth, Game g, double alpha, double beta, bool IsMaximizingPlayer, int thisMove) { if (depth == 0) { return(g.BoardValue()); } MoveGenerationResult result = g.GetMoves(); if (result.Endgame == EndgameType.Checkmate) { if (g.WhiteToMove) { return(-10000000); } else { return(10000000); } } if (result.Endgame == EndgameType.Stalemate) { if (g.WhiteToMove) { return(10000000); } else { return(-10000000); } } count += result.Moves.Count; if (g.WhiteToMove) { double bestMove = -999999; foreach (Move move in result.Moves) { g.Move(move); bestMove = Math.Max(bestMove, MiniMax(depth - 1, g, alpha, beta, !IsMaximizingPlayer, move.To)); g.Undo(); alpha = Math.Max(alpha, bestMove); if (beta <= alpha) { return(bestMove); } } return(bestMove); } else { double bestMove = 999999; foreach (Move move in result.Moves) { g.Move(move); bestMove = Math.Min(bestMove, MiniMax(depth - 1, g, alpha, beta, !IsMaximizingPlayer, move.To)); g.Undo(); beta = Math.Min(beta, bestMove); if (beta <= alpha) { return(bestMove); } } return(bestMove); } }