Пример #1
0
		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);
		}
Пример #2
0
		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);
		}
Пример #3
0
		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.");
		}
Пример #4
0
        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();
        }
Пример #5
0
		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();
		}
Пример #6
0
		/// <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;
		}
Пример #7
0
		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;
		}
Пример #8
0
		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;
		}
Пример #9
0
			public WinningLines(Board board)
				: this()
			{
				this.board = board;
				this.CalculateWinningCounts();
			}
Пример #10
0
		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;
		}
Пример #11
0
		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;
		}
Пример #12
0
		public override Move GenerateMove(Board board, ManualResetEvent cancel)
		{
			return null;
		}
Пример #13
0
		public override Move GenerateMove(Board board, ManualResetEvent cancel)
		{
			return new Move(board.CurrentPlayer, new Point(0, 0), new Point(0, 0));
		}
Пример #14
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;
		}
Пример #15
0
		public abstract Move GenerateMove(Board board, ManualResetEvent cancel);
Пример #16
0
		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;
		}
Пример #17
0
 public void Reset(QF.Board board, IEngine playerX, IEngine playerO)
 {
     this.InitializeBoard(board, playerX, playerO);
     this.CheckForMoveGeneration();
     this.RedrawBoard();
 }
Пример #18
0
		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;
		}
Пример #19
0
		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.");
		}