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;
		}
		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;
		}
Exemple #3
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.");
		}