public void UseBadMoveEngine() { IEngine badMoveEngine = this.GetEngine("Quixo.Engine.Tests.BadMoveTestEngine"); Board board = new Board(); Assert.AreEqual(Player.X, board.CurrentPlayer, "The starting player is invalid."); board.MovePiece(new Point(0, 0), new Point(0, 4)); Assert.AreEqual(Player.O, board.CurrentPlayer, "The player before the generated move is invalid."); Move engineMove = badMoveEngine.GenerateMove(board, new ManualResetEvent(false)); board.MovePiece(engineMove.Source, engineMove.Destination); }
public override Move GenerateMove(Board board, ManualResetEvent cancel) { var random = new Random(); var sources = board.GetValidSourcePieces(); var sourceIndex = random.Next(sources.Count); var source = sources[sourceIndex]; var destinations = board.GetValidDestinationPieces(source); var destinationIndex = random.Next(destinations.Count); var destination = destinations[destinationIndex]; return new Move(board.CurrentPlayer, source, destination); }
public void UseGoodEngine() { IEngine goodEngine = this.GetEngine("Quixo.Engine.RandomEngine"); Board board = new Board(); Assert.AreEqual(Player.X, board.CurrentPlayer, "The starting player is invalid."); board.MovePiece(new Point(0, 0), new Point(0, 4)); Assert.AreEqual(Player.O, board.CurrentPlayer, "The player before the generated move is invalid."); Move engineMove = goodEngine.GenerateMove(board, new ManualResetEvent(false)); Assert.AreEqual(Player.O, engineMove.Player, "The player after the generated move is invalid."); board.MovePiece(engineMove.Source, engineMove.Destination); Assert.AreEqual(Player.X, board.CurrentPlayer, "The player after the generated move was performed is invalid."); }
private void InitializeBoard(QF.Board board, IEngine playerX, IEngine playerO) { int x = 0, y = 0; if (this.pieces != null) { for (x = 0; x < QF.Board.Dimension; x++) { for (y = 0; y < QF.Board.Dimension; y++) { if (this.pieces[x, y] != null) { this.Controls.Remove(this.pieces[x, y]); } } } } this.source = null; this.playerX = playerX; this.playerO = playerO; if (board == null) { this.board = new QF.Board(); } else { this.board = board; } this.pieces = new Piece[QF.Board.Dimension, QF.Board.Dimension]; for (x = 0; x < QF.Board.Dimension; x++) { for (y = 0; y < QF.Board.Dimension; y++) { var point = new Point(x, y); var newPiece = new Piece(new QF.Piece(point, this.board.GetPiece(point))); newPiece.Selected += this.OnPieceSelected; this.pieces[x, y] = newPiece; this.Controls.Add(newPiece); } } this.UpdatePieceStates(); }
private void InitializeBoard(QF.Board board, IEngine playerX, IEngine playerO) { int x = 0, y = 0; if (this.pieces != null) { for (x = 0; x < QF.Board.Dimension; x++) { for (y = 0; y < QF.Board.Dimension; y++) { if (this.pieces[x, y] != null) { this.Controls.Remove(this.pieces[x, y]); } } } } this.source = null; this.playerX = playerX; this.playerO = playerO; if (board == null) { this.board = new QF.Board(); } else { this.board = board; } this.pieces = new Piece[QF.Board.Dimension, QF.Board.Dimension]; for (x = 0; x < QF.Board.Dimension; x++) { for (y = 0; y < QF.Board.Dimension; y++) { Point point = new Point(x, y); Piece newPiece = new Piece(new QF.Piece(point, this.board.GetPiece(point))); newPiece.Selected += this.OnPieceSelected; this.pieces[x, y] = newPiece; this.Controls.Add(newPiece); } } this.UpdatePieceStates(); }
/// <summary> /// Returns a <see cref="Board"/> object based on the /// serialized data. /// </summary> /// <param name="serializationStream">A serialized version of a <see cref="Board"/> in the simplified format</param> /// <returns>A new <see cref="Board"/> object.</returns> /// <exception cref="ArgumentNullException">Thrown if <paramref name="serializationStream"/> is <code>null</code>.</exception> /// <exception cref="SerializationException">Thrown if an error occurred during deserialization.</exception> public object Deserialize(Stream serializationStream) { if (serializationStream == null) { throw new ArgumentNullException("serializationStream"); } var board = new Board(); string moves = null; using (var reader = new StreamReader(serializationStream)) { moves = reader.ReadToEnd(); } try { foreach (string move in moves.Split('|')) { var moveParts = move.Split(':'); var sourceMove = moveParts[0].Split(',')[0]; var destinationMove = moveParts[1].Split(',')[1]; board.MovePiece( new Point(int.Parse(moveParts[0].Split(',')[0]), int.Parse(moveParts[0].Split(',')[1])), new Point(int.Parse(moveParts[1].Split(',')[0]), int.Parse(moveParts[1].Split(',')[1]))); } } catch (FormatException formatEx) { throw new SerializationException(string.Empty, formatEx); } catch (IndexOutOfRangeException indexEx) { throw new SerializationException(string.Empty, indexEx); } return board; }
public int Evaluate(Board board) { int evaluation = 0; if(board.WinningPlayer != Player.None) { if(board.Moves.Count > 0) { Move lastMove = board.Moves[board.Moves.Count - 1]; if(lastMove.Player == board.WinningPlayer) { evaluation = WinningLine; } else { evaluation = LosingLine; } } } else { evaluation = this.EvaluateHorizontalLines(board, evaluation); if(evaluation != LosingLine && evaluation != WinningLine) { evaluation = this.EvaluateVerticalLines(board, evaluation); } if(evaluation != LosingLine && evaluation != WinningLine) { evaluation = this.EvaluateDiagonalLines(board, evaluation); } } return evaluation; }
private int Evaluate(Board board, Player currentPlayer) { int evaluation = 0; if(board.WinningPlayer != Player.None) { if(board.WinningPlayer == currentPlayer) { evaluation = int.MaxValue; } else { evaluation = int.MinValue; } } else { evaluation = this.Evaluate(board); } return evaluation; }
public WinningLines(Board board) : this() { this.board = board; this.CalculateWinningCounts(); }
public object Clone() { var newBoard = new Board(); newBoard.currentPlayer = this.currentPlayer; newBoard.winningPlayer = this.winningPlayer; newBoard.moveHistory = this.moveHistory.Clone() as MoveCollection; newBoard.pieces = this.pieces; return newBoard; }
private int EvaluateDiagonalLines(Board board, int evaluation) { int diagonalEvaluation = evaluation; Player lineState = board.GetPiece(0, 0); if(lineState == board.CurrentPlayer) { diagonalEvaluation++; } else if(lineState != Player.None) { diagonalEvaluation--; } int continuationFactor = 1; for(int x = 1; x < Board.Dimension; x++) { Player currentPiece = board.GetPiece(x, x); if(currentPiece == board.CurrentPlayer) { diagonalEvaluation++; } else if(currentPiece != Player.None) { diagonalEvaluation--; } if(currentPiece == board.GetPiece(x - 1, x - 1)) { continuationFactor = this.UpdateContinuation(continuationFactor); if(currentPiece == board.CurrentPlayer) { diagonalEvaluation += continuationFactor; } else if(currentPiece != Player.None) { diagonalEvaluation -= continuationFactor; } } else { lineState = Player.None; continuationFactor = 1; } } if(lineState != Player.None && lineState != board.CurrentPlayer) { diagonalEvaluation = LosingLine; } else { if(lineState == board.CurrentPlayer) { diagonalEvaluation = WinningLine; } else { lineState = board.GetPiece(0, Board.Dimension - 1); if(lineState == board.CurrentPlayer) { diagonalEvaluation++; } else if(lineState != Player.None) { diagonalEvaluation--; } for(int x = 1; x < Board.Dimension; x++) { Player currentPiece = board.GetPiece(x, Board.Dimension - 1 - x); if(currentPiece == board.CurrentPlayer) { diagonalEvaluation++; } else if(currentPiece != Player.None) { diagonalEvaluation--; } if(currentPiece == board.GetPiece(x - 1, Board.Dimension - x)) { continuationFactor = this.UpdateContinuation(continuationFactor); if(currentPiece == board.CurrentPlayer) { diagonalEvaluation += continuationFactor; } else if(currentPiece != Player.None) { diagonalEvaluation -= continuationFactor; } } else { lineState = Player.None; continuationFactor = 1; } } if(lineState == board.CurrentPlayer) { diagonalEvaluation = WinningLine; } else if(lineState != Player.None) { diagonalEvaluation = LosingLine; } } } return diagonalEvaluation; }
public override Move GenerateMove(Board board, ManualResetEvent cancel) { return null; }
public override Move GenerateMove(Board board, ManualResetEvent cancel) { return new Move(board.CurrentPlayer, new Point(0, 0), new Point(0, 0)); }
public override Move GenerateMove(Board board, ManualResetEvent cancel) { XmlDocument moveDocument = null; XmlNode movesNode = null, moveNode = null; XmlAttribute movePlayerNode = null, moveSourceNode = null, moveDestinationNode = null, moveValue = null; moveDocument = new XmlDocument(); movesNode = moveDocument.CreateElement("PotentialMoves"); moveDocument.AppendChild(movesNode); int bestValue = int.MinValue; int possibleBestValue = int.MinValue; Move generatedMove = null; foreach(Point source in board.GetValidSourcePieces()) { foreach(Point destination in board.GetValidDestinationPieces(source)) { moveNode = moveDocument.CreateElement("Move"); movesNode.AppendChild(moveNode); movePlayerNode = moveDocument.CreateAttribute("Player"); moveNode.Attributes.Append(movePlayerNode); movePlayerNode.Value = board.CurrentPlayer.ToString(); moveSourceNode = moveDocument.CreateAttribute("Source"); moveNode.Attributes.Append(moveSourceNode); moveSourceNode.Value = source.ToString(); moveDestinationNode = moveDocument.CreateAttribute("Destination"); moveNode.Attributes.Append(moveDestinationNode); moveDestinationNode.Value = destination.ToString(); Board nextMoveBoard = ((Board)board.Clone()); nextMoveBoard.MovePiece(source, destination); possibleBestValue = this.MinimaxAB(nextMoveBoard, board.CurrentPlayer, false, 1, int.MinValue, int.MaxValue, moveNode); moveValue = moveDocument.CreateAttribute("Value"); moveNode.Attributes.Append(moveValue); moveValue.Value = possibleBestValue.ToString(); if(possibleBestValue > bestValue || (possibleBestValue >= bestValue && generatedMove == null)) { bestValue = possibleBestValue; generatedMove = new Move(board.CurrentPlayer, source, destination); } } } string moveFileName = Guid.NewGuid().ToString("n") + ".xml"; moveDocument.Save(moveFileName); if(this.debugWriter != null) { this.debugWriter.WriteLine( string.Format("Best value for move {0}: {1} ", generatedMove.Print(), bestValue)); Board nextMoveBoard = (Board)board.Clone(); nextMoveBoard.MovePiece(generatedMove.Source, generatedMove.Destination); this.debugWriter.WriteLine( string.Format("Evaluation of board for move {0}: {1} ", generatedMove.Print(), this.Evaluate(nextMoveBoard, board.CurrentPlayer) * -1)); } return generatedMove; }
public abstract Move GenerateMove(Board board, ManualResetEvent cancel);
private int EvaluateVerticalLines(Board board, int evaluation) { int verticalEvaluation = evaluation; bool hasWinningLine = false, hasLosingLine = false; for(int x = 0; x < Board.Dimension; x++) { Player lineState = board.GetPiece(x, 0); if(lineState == board.CurrentPlayer) { verticalEvaluation++; } else if(lineState != Player.None) { verticalEvaluation--; } int continuationFactor = 1; for(int y = 1; y < Board.Dimension; y++) { Player currentPiece = board.GetPiece(x, y); if(currentPiece == board.CurrentPlayer) { verticalEvaluation++; } else if(currentPiece != Player.None) { verticalEvaluation--; } if(currentPiece == board.GetPiece(x, y - 1)) { continuationFactor = this.UpdateContinuation(continuationFactor); if(currentPiece == board.CurrentPlayer) { verticalEvaluation += continuationFactor; } else if(currentPiece != Player.None) { verticalEvaluation -= continuationFactor; } } else { lineState = Player.None; continuationFactor = 1; } } if(lineState == board.CurrentPlayer) { hasWinningLine = true; break; } else if(lineState != Player.None) { hasLosingLine = true; break; } } if(hasWinningLine == true && hasLosingLine == false) { verticalEvaluation = WinningLine; } else if(hasLosingLine == true) { verticalEvaluation = LosingLine; } return verticalEvaluation; }
public void Reset(QF.Board board, IEngine playerX, IEngine playerO) { this.InitializeBoard(board, playerX, playerO); this.CheckForMoveGeneration(); this.RedrawBoard(); }
private int MinimaxAB(Board board, Player currentPlayer, bool isMax, int depth, int alpha, int beta, XmlNode parentMoveNode) { XmlNode moveNode = null; XmlAttribute movePlayerNode = null, moveSourceNode = null, moveDestinationNode = null, moveValue = null; int evaluation = 0; if(depth >= DepthLimit || board.WinningPlayer != Player.None) { evaluation = this.Evaluate(board, currentPlayer); if(board.CurrentPlayer != Player.None && board.CurrentPlayer != currentPlayer) { evaluation *= -1; } else if(board.CurrentPlayer == Player.None && board.WinningPlayer != currentPlayer) { evaluation *= -1; } } else { int nextEvaluation = 0; foreach(Point source in board.GetValidSourcePieces()) { foreach(Point destination in board.GetValidDestinationPieces(source)) { moveNode = parentMoveNode.OwnerDocument.CreateElement("Move"); parentMoveNode.AppendChild(moveNode); movePlayerNode = parentMoveNode.OwnerDocument.CreateAttribute("Player"); moveNode.Attributes.Append(movePlayerNode); movePlayerNode.Value = board.CurrentPlayer.ToString(); moveSourceNode = parentMoveNode.OwnerDocument.CreateAttribute("Source"); moveNode.Attributes.Append(moveSourceNode); moveSourceNode.Value = source.ToString(); moveDestinationNode = parentMoveNode.OwnerDocument.CreateAttribute("Destination"); moveNode.Attributes.Append(moveDestinationNode); moveDestinationNode.Value = destination.ToString(); Board nextMoveBoard = (Board)board.Clone(); nextMoveBoard.MovePiece(source, destination); int newDepth = depth; nextEvaluation = this.MinimaxAB(nextMoveBoard, currentPlayer, !isMax, ++newDepth, alpha, beta, moveNode); moveValue = parentMoveNode.OwnerDocument.CreateAttribute("Value"); moveNode.Attributes.Append(moveValue); moveValue.Value = nextEvaluation.ToString(); if(alpha > beta) { break; } else if(isMax == false && nextEvaluation < beta) { beta = nextEvaluation; } else if(isMax == true && nextEvaluation > alpha) { alpha = nextEvaluation; } } if(alpha > beta) { break; } } if(isMax == true) { evaluation = alpha; } else { evaluation = beta; } } return evaluation; }
public void GetEvaluationValueForInProgressGameAboutToBeLost() { Board board = new Board(); AlphaBetaPruningEngine engine = new AlphaBetaPruningEngine(); Move nextMove = engine.GenerateMove(board.Clone() as Board, new ManualResetEvent(false)); // The problem is that ABP was doing 0,3 to 4,3 in 0.2.0.0, which causes a loss. Assert.IsFalse((nextMove.Source == new Point(0, 3) && nextMove.Destination == new Point(4, 3)), "The next move is invalid."); }