public void TestSmallAmountOfMoves() { Point[][] pos = new Point[2][]; pos[0] = new Point[8]; pos[1] = new Point[8]; pos[0][0] = new Point(0, 7); pos[0][1] = new Point(1, 2); pos[0][2] = new Point(2, 2); pos[0][3] = new Point(3, 7); pos[0][4] = new Point(1, 4); pos[0][5] = new Point(5, 1); pos[0][6] = new Point(6, 1); pos[0][7] = new Point(7, 7); pos[1][0] = new Point(7, 4); pos[1][1] = new Point(6, 0); pos[1][2] = new Point(4, 1); pos[1][3] = new Point(4, 5); pos[1][4] = new Point(3, 5); pos[1][5] = new Point(2, 0); pos[1][6] = new Point(1, 0); pos[1][7] = new Point(0, 3); Point tomove = new Point(1, 4); GameState gs = new GameState(pos, tomove, false); Assert.AreEqual(3, gs.NextStates.Count); }
public SumoDazedMove(GameState state, Piece piece) { _state = state; _piece = piece; _end = _piece.Position; _start = _piece.Position; }
public MoveInfo GetMove(GameState currentState) { while (!GotMove) ; GotMove = false; return new MoveInfo(ChosenMove, 0, 0); }
public Move(GameState state, Piece piece, Point end) { _state = state; _piece = piece; _end = end; _start = _piece.Position; }
public GameEngine(IPlayer player1, IPlayer player2, GameState startState) { Player1 = player1; Player2 = player2; ActivePlayer = Player1; CurrentState = startState; _roundInfo = new RoundInfo(startState.Copy()); }
static void Main(string[] args) { List<Piece> pieces = new List<Piece>(); pieces.Add(new Piece(false, new System.Drawing.Point(0, 7), PieceColor.Blue, 1)); pieces.Add(new Piece(false, new System.Drawing.Point(1, 7), PieceColor.Yellow, 0)); pieces.Add(new Piece(false, new System.Drawing.Point(2, 7), PieceColor.Brown, 1)); pieces.Add(new Piece(false, new System.Drawing.Point(3, 7), PieceColor.Pink, 0)); pieces.Add(new Piece(false, new System.Drawing.Point(4, 7), PieceColor.Green, 1)); pieces.Add(new Piece(false, new System.Drawing.Point(5, 7), PieceColor.Red, 0)); pieces.Add(new Piece(false, new System.Drawing.Point(6, 7), PieceColor.Orange, 1)); pieces.Add(new Piece(false, new System.Drawing.Point(7, 7), PieceColor.Purple, 3)); pieces.Add(new Piece(true, new System.Drawing.Point(0, 0), PieceColor.Yellow, 0)); pieces.Add(new Piece(true, new System.Drawing.Point(1, 0), PieceColor.Purple, 2)); pieces.Add(new Piece(true, new System.Drawing.Point(2, 0), PieceColor.Green, 1)); pieces.Add(new Piece(true, new System.Drawing.Point(3, 0), PieceColor.Orange, 0)); pieces.Add(new Piece(true, new System.Drawing.Point(4, 0), PieceColor.Red, 1)); pieces.Add(new Piece(true, new System.Drawing.Point(5, 0), PieceColor.Blue, 0)); pieces.Add(new Piece(true, new System.Drawing.Point(6, 0), PieceColor.Pink, 0)); pieces.Add(new Piece(true, new System.Drawing.Point(7, 0), PieceColor.Brown, 2)); GameState startState = new GameState(pieces, null); List<IMove> possibleMoves = startState.PossibleMoves; possibleMoves.Sort(new Comparison<IMove>((IMove m1, IMove m2) => { return m1.End.Y - m2.End.Y; })); foreach (IMove move in possibleMoves) { System.IO.File.AppendAllText(@"C:\Users\Dan\Documents\Visual Studio 2012\Projects\Kamisado\IterativeDeepening\bin\Debug\Output.txt", "Starting move " + move + Environment.NewLine); Console.WriteLine("Starting move " + move); for (int depth = 1; depth <= 20; depth++) { GameState smallState = new GameState(pieces, null); smallState.PossibleMoves = new List<IMove>(); smallState.PossibleMoves.Add(new Move(smallState, smallState.PiecePositions[move.Piece.BelongsToPlayerTwo ? 1 : 0][(int)move.Piece.Color], new Point(move.End.X, move.End.Y))); Bot bot = new Bot(depth, (GameState g, bool imPlayerTwo) => { return 0; }); MoveInfo info = bot.GetMove(smallState); System.IO.File.AppendAllText(@"C:\Users\Dan\Documents\Visual Studio 2012\Projects\Kamisado\IterativeDeepening\bin\Debug\Output.txt", move + " at depth " + depth + " had value " + info.Value + Environment.NewLine); Console.WriteLine(move + " at depth " + depth + " had value " + info.Value); if (info.Value != 0) { break; } } System.IO.File.AppendAllText(@"C:\Users\Dan\Documents\Visual Studio 2012\Projects\Kamisado\IterativeDeepening\bin\Debug\Output.txt", Environment.NewLine); Console.WriteLine(""); } }
private static double NumPossibleMoves(GameState currentState, bool imPlayerTwo) { int numPossible = 0; for (int i = 0; i < 8; i++) { numPossible += currentState.PiecePositions[imPlayerTwo ? 1 : 0][i].GetPossibleMoves(currentState).Count; } return ((double)numPossible) / 102.0; }
private static double MoveFar(GameState currentState, bool imPlayerTwo) { int score = 0; for (int i = 0; i < 8; i++) { if (imPlayerTwo) { score += currentState.PiecePositions[1][i].Position.Y; } else { score += 7 - currentState.PiecePositions[0][i].Position.Y; } } return ((double)score) / 48; }
public List<IMove> GetPossibleMoves(GameState state) { List<IMove> res = new List<IMove>(); int ystep = -1; if (BelongsToPlayerTwo) { ystep = 1; } res.AddRange(GenerateMovesOnLine(state, MaxMoveLength, -1, ystep)); res.AddRange(GenerateStraightMoves(state, MaxMoveLength, ystep)); res.AddRange(GenerateMovesOnLine(state, MaxMoveLength, 1, ystep)); if (res.Count == 0) { res.Add(new Move(state, this, Position)); } return res; }
private static double PiecesInStriking(GameState currentState, bool imPlayerTwo) { int numStriking = 0; foreach (Piece myPiece in currentState.PiecePositions[Convert.ToInt32(imPlayerTwo)]) { List<IMove> possibleMoves = myPiece.GetPossibleMoves(currentState); foreach (IMove m in possibleMoves) { if (imPlayerTwo && m.End.Y == 7) { numStriking += 1; break; } else if (!imPlayerTwo && m.End.Y == 0) { numStriking += 1; break; } } } return ((double)numStriking) / 24.0; }
public void TestMove() { Point[][] pos = new Point[2][]; pos[0] = new Point[8]; pos[1] = new Point[8]; pos[0][0] = new Point(0, 7); pos[0][1] = new Point(1, 2); pos[0][2] = new Point(2, 2); pos[0][3] = new Point(3, 7); pos[0][4] = new Point(1, 4); pos[0][5] = new Point(5, 1); pos[0][6] = new Point(6, 1); pos[0][7] = new Point(7, 7); pos[1][0] = new Point(7, 4); pos[1][1] = new Point(6, 0); pos[1][2] = new Point(4, 1); pos[1][3] = new Point(4, 5); pos[1][4] = new Point(3, 5); pos[1][5] = new Point(2, 0); pos[1][6] = new Point(1, 0); pos[1][7] = new Point(0, 3); Point tomove = new Point(1, 4); GameState gs = new GameState(pos, tomove, false); Assert.IsFalse(gs.IsPlayerTwo); GameState gs2 = new GameState(gs, new Move(new Point(1, 4), new Point(3, 2))); Assert.IsTrue(gs2.IsPlayerTwo); Assert.AreEqual(5, gs2.NextStates.Count); GameState gs3 = new GameState(gs2, new Move(new Point(4, 1), new Point(5, 2))); Assert.IsFalse(gs3.IsPlayerTwo); Assert.AreEqual(7, gs3.NextStates.Count); }
protected virtual List<IMove> GenerateStraightMoves(GameState state, int maxLength, int ystep) { if (0 <= Position.Y + ystep && Position.Y + ystep < 8 && state.BoardPositions[Position.Y + ystep][Position.X] != null) { return GenerateSumoPushMoves(state, ystep); } else { return GenerateMovesOnLine(state, MaxMoveLength, 0, ystep); } }
public double[] GetMoveValues(GameState currentState) { _imPlayerTwo = currentState.IsPlayerTwo; List<IMove> possibleMoves = currentState.PossibleMoves; IMove[] moves = new IMove[possibleMoves.Count]; possibleMoves.CopyTo(moves, 0); double[] moveValues = new double[moves.Length]; for (int move = 0; move < moves.Length; move++) { moves[move].Execute(); moveValues[move] = Min(currentState, 1, Double.MinValue, Double.MaxValue); moves[move].Reverse(); } return moveValues; }
public SumoPushMove(GameState state, Piece piece, Point end) { _state = state; _piece = piece; _end = end; }
private List<IMove> GenerateSumoPushMoves(GameState state, int ystep) { if (Sumoness == 0) { return new List<IMove>(); } int currentX = Position.X; int currentY = Position.Y; bool goodGuys = true; bool foundNull = false; for (int i = 0; i <= Sumoness; i++) { currentY += ystep; if (currentY < 0 || currentY >= 8) { break; } if (state.BoardPositions[currentY][currentX] == null) { foundNull = true; break; } if (Sumoness <= state.BoardPositions[currentY][currentX].Sumoness || state.BoardPositions[currentY][currentX].BelongsToPlayerTwo == BelongsToPlayerTwo) { goodGuys = false; break; } } if (foundNull && goodGuys) { List<IMove> res = new List<IMove>(); res.Add(new SumoPushMove(state, this, new Point(Position.X, Position.Y + ystep))); return res; } else { return new List<IMove>(); } }
private double EvaluateGameState(GameState gs) { if (gs.PlayerTwoWinning.HasValue && ((gs.PlayerTwoWinning.Value && _imPlayerTwo) || (!gs.PlayerTwoWinning.Value && !_imPlayerTwo))) { return Double.MaxValue / (Math.Pow(10, 3 - gs.WinningPiece.Sumoness)); } else if (gs.PlayerTwoWinning.HasValue) { return Double.MinValue / (Math.Pow(10, 3 - gs.WinningPiece.Sumoness)); } return _evaluate(gs, _imPlayerTwo); }
public RoundInfo(GameState startState) { StartState = startState; MadeMoves = new LinkedList<MoveInfo>(); }
public double[] GetMoveValues(GameState currentState, int maxDepth) { int cachedMaxDepth = _maxDepth; _maxDepth = maxDepth; double[] res = GetMoveValues(currentState); _maxDepth = cachedMaxDepth; return res; }
public MoveInfo GetMove(GameState currentState) { _imPlayerTwo = currentState.IsPlayerTwo; List<IMove> possibleMoves = currentState.PossibleMoves; if (_cutWidth > 0) { List<MoveInfo> moveInfos = new List<MoveInfo>(); for (int i = 0; i < possibleMoves.Count; i++) { IMove move = possibleMoves[i]; move.Execute(); moveInfos.Add(new MoveInfo(move, EvaluateGameState(currentState), -1)); move.Reverse(); } moveInfos.Sort((MoveInfo m1, MoveInfo m2) => { return Math.Sign(m2.Value - m1.Value); }); List<IMove> foundMoves = new List<IMove>(); double largestMoveValue = Double.MinValue; foreach (MoveInfo moveInfo in moveInfos) { IMove move = moveInfo.Move; move.Execute(); double moveValue = ABMin(currentState, 1, Double.MinValue, Double.MaxValue); largestMoveValue = Math.Max(largestMoveValue, moveValue); if (moveValue > Double.MinValue / 10000) { foundMoves.Add(move); } move.Reverse(); if (foundMoves.Count >= _cutWidth) { break; } } if (foundMoves.Count <= 0) { return new MoveInfo(currentState.PossibleMoves[0], largestMoveValue, -1); } possibleMoves = foundMoves; } else { possibleMoves.Reverse(); } IMove[] moves = new IMove[possibleMoves.Count]; possibleMoves.CopyTo(moves, 0); double[] moveValues = new double[moves.Length]; for (int move = 0; move < moves.Length; move++) { moves[move].Execute(); moveValues[move] = Min(currentState, 1, Double.MinValue, Double.MaxValue); moves[move].Reverse(); //Debug.WriteLine("Move " + moves[move] + " had value " + moveValues[move]); } double bestValue = moveValues[0]; for (int i = 0; i < moves.Length; i++) { if (moveValues[i] > bestValue) { bestValue = moveValues[i]; } } List<IMove> bestMoves = new List<IMove>(); for (int i = 0; i < moves.Length; i++) { if (moveValues[i] == bestValue) { bestMoves.Add(moves[i]); } } /* MoveInfo[] moveInfos = new MoveInfo[moves.Length]; for (int i = 0; i < moves.Length; i++) { moveInfos[i] = new MoveInfo(moves[i], moveValues[i], -1); } Array.Sort(moveInfos, (MoveInfo mi1, MoveInfo mi2) => { return Math.Sign(mi1.Value - mi2.Value); });*/ /*Debug.WriteLine("Sorterad: "); for (int i = 0; i < moveInfos.Length; i++) { MoveInfo mi = moveInfos[i]; Debug.WriteLine("Move " + mi.Move + " had value " + mi.Value); }*/ bestMoves.Shuffle(); Debug.WriteLine("Längden är " + bestMoves.Count); return new MoveInfo(bestMoves[0], bestValue, -1); }
private double ABMin(GameState gs, int depth, double alpha, double beta) { if (depth >= 4 || gs.PlayerTwoWinning.HasValue) { return ABEvaluateGameState(gs); } double v = Double.MaxValue; List<IMove> possibleMoves = gs.PossibleMoves; foreach (IMove move in possibleMoves) { move.Execute(); double current = ABMax(gs, depth + 1, alpha, beta); if (current < v) { v = current; } move.Reverse(); if (v <= alpha) { return v; } beta = Math.Min(beta, v); } return v; }
public MoveInfo GetMove(GameState currentState, int maxDepth) { List<IMove> possibleMoves = currentState.PossibleMoves; IMove[] moves = new IMove[possibleMoves.Count]; possibleMoves.CopyTo(moves, 0); // For every bot, find the value of the moves MoveInfo[][] moveInfos = new MoveInfo[_bots.Length][]; for (int i = 0; i < _bots.Length; i++) { double[] moveValues; if (maxDepth < 0) { moveValues = _bots[i].GetMoveValues(currentState); } else { moveValues = _bots[i].GetMoveValues(currentState, maxDepth); } moveInfos[i] = new MoveInfo[moveValues.Length]; for (int j = 0; j < moveValues.Length; j++) { moveInfos[i][j] = new MoveInfo(moves[j], moveValues[j], -1); } } // Find each bots highest value double[] highestValues = new double[_bots.Length]; for (int i = 0; i < _bots.Length; i++) { highestValues[i] = Double.MinValue; for (int j = 0; j < moveInfos[i].Length; j++) { if (moveInfos[i][j].Value > highestValues[i]) { highestValues[i] = moveInfos[i][j].Value; } } } // Check if there is a winning move for (int i = 0; i < highestValues.Length; i++) { if (highestValues[i] > Double.MaxValue / 10000) { for (int j = 0; j < moveInfos[i].Length; j++) { if (moveInfos[i][j].Value == highestValues[i]) { return moveInfos[i][j]; } } } } double[] lowestNonLosingValues = new double[_bots.Length]; for (int i = 0; i < _bots.Length; i++) { lowestNonLosingValues[i] = Double.MaxValue; for (int j = 0; j < moveInfos[i].Length; j++) { if (moveInfos[i][j].Value > Double.MinValue / 10000 && moveInfos[i][j].Value < lowestNonLosingValues[i]) { lowestNonLosingValues[i] = moveInfos[i][j].Value; } } } // Check if all moves are losing for (int i = 0; i < lowestNonLosingValues.Length; i++) { if (lowestNonLosingValues[i] == Double.MaxValue) { // All moves are losing return moveInfos[0][0]; } } for (int i = 0; i < _bots.Length; i++) { List<int> indices = Enumerable.Range(0, moveInfos[i].Length).ToList(); indices.Sort((int ind1, int ind2) => { if (moveInfos[i][ind1].Value < moveInfos[i][ind2].Value) { return -1; } else if (moveInfos[i][ind1].Value > moveInfos[i][ind2].Value) { return 1; } else { return 0; } }); int strength = 1; for (int j = 0; j < indices.Count; j++) { double tmp = moveInfos[i][indices[j]].Value; moveInfos[i][indices[j]].Value = strength; if (j + 1 < indices.Count && moveInfos[i][indices[j + 1]].Value != tmp) { strength++; } } } // Combine values List<int> highestCombinedIndeces = new List<int>(); double highestCombined = Double.MinValue; double[] combinedMoveValues = new double[moves.Length]; for (int i = 0; i < combinedMoveValues.Length; i++) { for (int j = 0; j < _bots.Length; j++) { combinedMoveValues[i] += _weights[j] * moveInfos[j][i].Value; } if (combinedMoveValues[i] > highestCombined) { highestCombined = combinedMoveValues[i]; highestCombinedIndeces = new List<int>(); highestCombinedIndeces.Add(i); } else if (combinedMoveValues[i] == highestCombined) { highestCombinedIndeces.Add(i); } } highestCombinedIndeces.Shuffle(); return new MoveInfo(moves[highestCombinedIndeces[0]], highestCombined, -1); }
public MoveInfo GetMove(GameState currentState, int maxDepth) { return GetMove(currentState); }
/*public MoveInfo GetMove(GameState currentState) { _imPlayerTwo = currentState.IsPlayerTwo; IMove[] moves = new IMove[currentState.PossibleMoves.Count]; currentState.PossibleMoves.CopyTo(moves, 0); double[][] moveValues = new double[_maxDepth][]; for (int i = 0; i < _maxDepth; i++) { moveValues[i] = new double[moves.Length]; } int cachedMaxDepth = _maxDepth; for (int depth = 1; depth <= cachedMaxDepth; depth++) { _maxDepth = depth; for (int move = 0; move < moves.Length; move++) { moves[move].Execute(); moveValues[depth - 1][move] = Min(currentState, 1, Double.MinValue, Double.MaxValue); moves[move].Reverse(); } Debug.WriteLine("Hello, im done with depth " + depth); } _maxDepth = cachedMaxDepth; Debug.WriteLine("Last row is: "); for (int move = 0; move < moves.Length; move++) { Debug.WriteLine(moves[move] + " had value " + moveValues[_maxDepth - 1][move]); } double lastRowHighestValue = Double.MinValue; IList<Int32> lastRowHighestValueIndices = new List<Int32>(); for (int move = 0; move < moves.Length; move++) { if (moveValues[_maxDepth - 1][move] > lastRowHighestValue) { lastRowHighestValueIndices = new List<Int32>(); lastRowHighestValue = moveValues[_maxDepth - 1][move]; lastRowHighestValueIndices.Add(move); } else if (moveValues[_maxDepth - 1][move] == lastRowHighestValue) { lastRowHighestValueIndices.Add(move); } } if (lastRowHighestValue >= Double.MaxValue / 4) { int shortestIndex = -1; int shortestDepth = Int32.MaxValue; foreach (int index in lastRowHighestValueIndices) { int currentSwitchIndex = _maxDepth - 1; while (moveValues[currentSwitchIndex][index] == lastRowHighestValue) { currentSwitchIndex--; if (currentSwitchIndex < 0) { break; } } if (currentSwitchIndex + 2 < shortestDepth) { shortestDepth = currentSwitchIndex + 2; shortestIndex = index; } } return new MoveInfo(moves[shortestIndex], lastRowHighestValue, shortestDepth); } else if (lastRowHighestValue <= Double.MinValue / 4) { for (int depth = _maxDepth; depth > 0; depth--) { foreach (int index in lastRowHighestValueIndices) { if (moveValues[depth - 1][index] > Double.MinValue / 4) { return new MoveInfo(moves[index], lastRowHighestValue, depth + 1); } } } return new MoveInfo(moves[lastRowHighestValueIndices[0]], lastRowHighestValue, 1); } else { lastRowHighestValueIndices.Shuffle(); Debug.WriteLine("Detta är längden " + lastRowHighestValueIndices.Count); return new MoveInfo(moves[lastRowHighestValueIndices[0]], lastRowHighestValue, _maxDepth); } }*/ private double Max(GameState gs, int depth, double alpha, double beta) { if (depth >= _maxDepth || gs.PlayerTwoWinning.HasValue) { return EvaluateGameState(gs); } double v = Double.MinValue; List<IMove> possibleMoves = gs.PossibleMoves; if (_cutWidth > 0) { List<MoveInfo> moveInfos = new List<MoveInfo>(); for (int i = 0; i < possibleMoves.Count; i++) { IMove move = possibleMoves[i]; move.Execute(); moveInfos.Add(new MoveInfo(move, EvaluateGameState(gs), -1)); move.Reverse(); } moveInfos.Sort((MoveInfo m1, MoveInfo m2) => { return Math.Sign(m2.Value - m1.Value); }); List<IMove> foundMoves = new List<IMove>(); double largestMoveValue = Double.MinValue; foreach (MoveInfo moveInfo in moveInfos) { IMove move = moveInfo.Move; move.Execute(); double moveValue = ABMin(gs, 1, Double.MinValue, Double.MaxValue); largestMoveValue = Math.Max(largestMoveValue, moveValue); if (moveValue > Double.MinValue / 10000) { foundMoves.Add(move); } move.Reverse(); if (foundMoves.Count >= _cutWidth) { break; } } if (foundMoves.Count <= 0) { return largestMoveValue; } possibleMoves = foundMoves; } else { possibleMoves.Reverse(); } /*for (int i = 0; i < moveInfos.Count; i++) { Debug.WriteLine("Max Move " + moveInfos[i].Move + " with value " + moveInfos[i].Value); }*/ foreach (IMove move in possibleMoves) { move.Execute(); double current = Min(gs, depth + 1, alpha, beta); if (current > v) { v = current; } move.Reverse(); if (v >= beta) { return v; } alpha = Math.Max(alpha, v); } return v; }
protected List<IMove> GenerateMovesOnLine(GameState state, int maxLength, int xstep, int ystep) { List<IMove> res = new List<IMove>(); int col = Position.X + xstep; int row = Position.Y + ystep; int count = 0; while (count < maxLength && 0 <= col && col < 8 && 0 <= row && row < 8 && state.BoardPositions[row][col] == null) { Move move = new Move(state, this, new Point(col, row)); res.Add(move); col += xstep; row += ystep; count++; } return res; }
public static GameState GenerateNextRound(GameState endState, bool left) { List<Piece> oldPieces = new List<Piece>(); oldPieces.AddRange(endState.PiecePositions[0]); oldPieces.AddRange(endState.PiecePositions[1]); List<Piece> newPiecesOne = new List<Piece>(); List<Piece> newPiecesTwo = new List<Piece>(); Piece winningPiece = endState.WinningPiece; oldPieces.Remove(winningPiece); foreach (Piece oldPiece in oldPieces) { if (oldPiece.BelongsToPlayerTwo) { newPiecesTwo.Add(oldPiece.Copy()); } else { newPiecesOne.Add(oldPiece.Copy()); } } if (winningPiece.BelongsToPlayerTwo) { Piece p = winningPiece.Copy(); p.Sumoness += 1; newPiecesTwo.Add(p); } else { Piece p = winningPiece.Copy(); p.Sumoness += 1; newPiecesOne.Add(p); } Comparison<Piece> comp = new Comparison<Piece>((Piece p1, Piece p2) => { if (p1.Position.Y == p2.Position.Y) { return (left ? 1 : -1) * (p1.Position.X - p2.Position.X); } else { return p2.Position.Y - p1.Position.Y; } }); newPiecesOne.Sort(comp); newPiecesTwo.Sort(comp); if (endState.PlayerTwoWinning.Value) { if (!left) { newPiecesOne.Reverse(); newPiecesTwo.Reverse(); } for (int i = 0; i < 8; i++) { newPiecesOne[i].Position = new Point(i, 7); newPiecesTwo[i].Position = new Point(i, 0); } } else { if (left) { newPiecesOne.Reverse(); newPiecesTwo.Reverse(); } for (int i = 0; i < 8; i++) { newPiecesOne[i].BelongsToPlayerTwo = true; newPiecesOne[i].Position = new Point(i, 0); newPiecesTwo[i].BelongsToPlayerTwo = false; newPiecesTwo[i].Position = new Point(i, 7); } } List<Piece> newPieces = new List<Piece>(); newPieces.AddRange(newPiecesOne); newPieces.AddRange(newPiecesTwo); return new GameState(newPieces, null); }
public void TestShouldHave102OpeningMoves() { GameState gs = new GameState(); Assert.AreEqual(102, gs.NextStates.Count); }
public MoveInfo GetMove(GameState currentState) { return GetMove(currentState, -1); }
private double Min(GameState gs, int depth, double alpha, double beta) { if (depth >= _maxDepth || gs.PlayerTwoWinning.HasValue) { return EvaluateGameState(gs); } double v = Double.MaxValue; List<IMove> possibleMoves = gs.PossibleMoves; if (_cutWidth > 0) { List<MoveInfo> moveInfos = new List<MoveInfo>(); for (int i = 0; i < possibleMoves.Count; i++) { IMove move = possibleMoves[i]; move.Execute(); moveInfos.Add(new MoveInfo(move, EvaluateGameState(gs), -1)); move.Reverse(); } moveInfos.Sort((MoveInfo m1, MoveInfo m2) => { return Math.Sign(m1.Value - m2.Value); }); List<IMove> foundMoves = new List<IMove>(); double smallestMoveValue = Double.MaxValue; foreach (MoveInfo moveInfo in moveInfos) { IMove move = moveInfo.Move; move.Execute(); double moveValue = ABMax(gs, 1, Double.MinValue, Double.MaxValue); smallestMoveValue = Math.Min(smallestMoveValue, moveValue); if (moveValue < Double.MaxValue / 10000) { foundMoves.Add(move); } move.Reverse(); if (foundMoves.Count >= _cutWidth) { break; } } if (foundMoves.Count <= 0) { return smallestMoveValue; } possibleMoves = foundMoves; } else { possibleMoves.Reverse(); } foreach (IMove move in possibleMoves) { move.Execute(); double current = Max(gs, depth + 1, alpha, beta); if (current < v) { v = current; } move.Reverse(); if (v <= alpha) { return v; } beta = Math.Min(beta, v); } return v; }
private void UpdateDisplayState() { _displayState = _engine.CurrentState.Copy(); }
public MoveInfo GetMove(GameState currentState, int maxDepth) { int cachedMaxDepth = _maxDepth; _maxDepth = maxDepth; MoveInfo res = GetMove(currentState); _maxDepth = cachedMaxDepth; return res; }