public double EvaluatePosition(MoveTreeNode moveTree, PieceDict myPieces, PieceDict theirPieces, int moveNumber) { double myPoints = EvaluatePieces(myPieces); double theirPoints = EvaluatePieces(theirPieces); return(myPoints - theirPoints); }
public void InitializePlayer(Board board, PieceColor color) { if (moveTree == null) { moveTree = BuildInitialMoveTree(board, color); } }
public override Move SelectMove(Board board, MoveTreeNode moveTree, PieceColor color) { var allMoves = moveTree.CounterMoves.Values; foreach (var move in allMoves) { move.Score = ScoreMove(move, 0); } var sortedDescending = (from m in allMoves orderby m.Score descending select m); var topMove = sortedDescending.First(); var candidates = new List <Move>(); foreach (var move in sortedDescending) { if (move.Score == topMove.Score) { candidates.Add(topMove.Move); } else { break; } } var finalChoice = candidates[rnd.Next(0, candidates.Count)]; moveTree = moveTree.CounterMoves[finalChoice]; return(finalChoice); }
public override Move SelectMove(Board board, MoveTreeNode moveTree, PieceColor color) { var allMoves = moveTree.CounterMoves.Values.ToList(); var randomMove = allMoves[_rnd.Next(0, allMoves.Count)]; return(randomMove.Move); }
public static BoardNode ApplyMoveToBoard(BoardNode board, Move moveToApply) { var postMoveBoard = board.Board.ApplyMoveToBoard(moveToApply); var san = moveToSan.Translate(moveToApply, board.Board, postMoveBoard); var postMoveState = new PostMoveState(postMoveBoard, moveToApply, san); var node = new MoveTreeNode <PostMoveState>(postMoveState, board.Node); return(new BoardNode(postMoveBoard, node)); }
private double EvaluatePiece(MoveTreeNode moveTree, ChessPiece piece, int moveNumber) { int maxMoves = 40; int normalizedMoveCount = Math.Min(moveNumber, maxMoves); double moveBonus = CalculateBonusForMoves(piece, moveTree); return(QUEEN_VALUE + moveBonus); }
/// <summary> /// Writes move section in PGN form. /// </summary> /// <param name="node">The starting node.</param> /// <param name="pgnWriter">The writer used to write the information.</param> public void Serialize(MoveTreeNode <PostMoveState> node, PgnWriter pgnWriter) { var enumerator = new GameToPgnEnumerator(node); while (enumerator.MoveNext()) { var move = enumerator.Current; pgnWriter.WriteMove(move); } }
public double EvaluatePosition(MoveTreeNode moveTree, PieceDict myPieces, PieceDict theirPieces, int moveCount) { double pawnValue = 0; // pawnEvaluator.EvaluatePosition(myPieces, theirPieces, moveCount); double rookValue = rookEvaluator.EvaluatePosition(moveTree, myPieces, theirPieces, moveCount); double bishopValue = bishopEvaluator.EvaluatePosition(moveTree, myPieces, theirPieces, moveCount); double knightValue = knightEvaluator.EvaluatePosition(moveTree, myPieces, theirPieces, moveCount); double queenValue = queenEvaluator.EvaluatePosition(moveTree, myPieces, theirPieces, moveCount); return(pawnValue + rookValue + bishopValue + knightValue + queenValue); }
public double EvaluatePosition(MoveTreeNode moveTree, PieceDict myPieces, PieceDict theirPieces, int moveNumber) { var myQueens = myPieces[PieceType.Queen]; double queenValue = 0.0; foreach (var r in myQueens) { queenValue += EvaluatePiece(moveTree, r, moveNumber); } return(queenValue); }
private MoveTreeNode BuildInitialMoveTree(Board board, PieceColor color) { var node = new MoveTreeNode(); node.Move = null; node.Score = 0.0; node.Board = board; node.ColorToPlay = color; FillNodeWithMoves(node, MaximumRecurseDepth, MaximumRecurseDepth - 1); return(node); }
private double EvaluatePiece(MoveTreeNode moveTree, ChessPiece piece, int moveNumber) { int maxMoves = 40; int normalizedMoveCount = Math.Min(moveNumber, maxMoves); double startingValue = ROOK_STARTGAME_VALUE + (ROOK_ENDGAME_VALUE - ROOK_STARTGAME_VALUE) * ((double)normalizedMoveCount / (double)maxMoves); double moveBonus = CalculateBonusForMoves(piece, moveTree); return(startingValue + moveBonus); }
private void ExpandMoveTree(Board board, PieceColor color) { if (board.MoveHistory.Count > 0) { var lastMove = board.MoveHistory.Last(); if (moveTree.CounterMoves.ContainsKey(lastMove)) { moveTree = moveTree.CounterMoves[lastMove]; } } FillNodeWithMoves(moveTree, MaximumRecurseDepth, 0); }
public GameToPgnEnumerator(MoveTreeNode <PostMoveState> initial) : base(initial) { var startingNode = (MoveTreeNode <PostMoveState>)initial.Clone(); if (startingNode.Value.MoveValue == Move.NullMove && startingNode.Continuations.Any()) { startingNode = startingNode.Next; } Initial = (MoveTreeNode <PostMoveState>)startingNode.Clone(); Reset(); }
protected double EvaluateBoardFor(MoveTreeNode currentMoveTree, PieceColor color) { var board = currentMoveTree.Board; var myPieces = color == PieceColor.White ? board.WhitePieces : board.BlackPieces; var theirPieces = color == PieceColor.Black ? board.WhitePieces : board.BlackPieces; var myPieceDict = ConvertPieceListToDict(board, myPieces); var theirPieceDict = ConvertPieceListToDict(board, myPieces); double myScore = PositionEvaluator.EvaluatePosition(currentMoveTree, myPieceDict, theirPieceDict, board.MoveHistory.Count); return(myScore); }
public double EvaluatePosition(MoveTreeNode moveTree, PieceDict myPieces, PieceDict theirPieces, int moveNumber) { var myRooks = myPieces[PieceType.Rook]; double rookValue = 0.0; foreach (var r in myRooks) { rookValue += EvaluatePiece(moveTree, r, moveNumber); } if (myRooks.Count >= 2) { rookValue += DOUBLE_ROOK_BONUS; } return(rookValue); }
public double EvaluatePosition(MoveTreeNode moveTree, PieceDict myPieces, PieceDict theirPieces, int moveNumber) { var myPawns = myPieces[PieceType.Pawn].ToList(); var theirPawns = theirPieces[PieceType.Pawn].ToList(); double pawnScore = 0.0; foreach (var p in myPawns) { var pawnEval = EvaluatePawn(p, myPawns, theirPawns); pawnScore += pawnEval.TotalValue; } return(pawnScore); }
public double EvaluatePosition(MoveTreeNode moveTree, PieceDict myPieces, PieceDict theirPieces, int moveNumber) { var myBishops = myPieces[PieceType.Bishop]; double bishopValue = 0.0; foreach (var r in myBishops) { bishopValue += EvaluatePiece(r, moveTree, moveNumber); } if (myBishops.Count >= 2) { bishopValue += DOUBLE_BISHOP_BONUS; } return(bishopValue); }
public double EvaluatePosition(MoveTreeNode moveTree, PieceDict myPieces, PieceDict theirPieces, int moveNumber) { var myKnights = myPieces[PieceType.Knight]; double knightValue = 0.0; foreach (var r in myKnights) { knightValue += EvaluatePiece(moveTree, r, moveNumber); } if (myKnights.Count >= 2) { knightValue += DOUBLE_KNIGHT_BONUS; } return(knightValue); }
public IEnumerable <MovePair> GetMovePairs() { var pair = new MovePair(null); var flattenedTreeNodes = FlattenToPgnOrder(); var nodeQueue = new Queue <MoveTreeNode <PostMoveState> >(flattenedTreeNodes); var lastLevel = 0; MoveTreeNode <PostMoveState> previous = null; while (nodeQueue.TryDequeue(out var moveNode)) { var currentDepth = moveNode.VariationDepth; var hasNextNode = nodeQueue.TryPeek(out var nextNodeInQueue); var depthDifferencePrevious = GetPreviousDepthDifference(moveNode, previous, lastLevel); var depthDifferenceNext = GetNextDepthDifference(moveNode, nextNodeInQueue, currentDepth); var node = new PgnMoveInformation(moveNode.ColorMakingMove, moveNode.Value.San, moveNode.MoveNumber, moveNode.IsFirstMoveInGame, !hasNextNode, depthDifferencePrevious, depthDifferenceNext, moveNode.Comment, moveNode.Annotation); lastLevel = currentDepth; previous = moveNode; if (node.ColorMakingMove == Color.White) { if (!pair.IsEmpty) { yield return(pair); } pair = new MovePair(node); } else { pair.BlackNode = node; yield return(pair); pair = new MovePair(null); } if ((node.VariationDepthFromNext != 0 || node.VariationDepthFromPrevious != 0 || node.IsLastMove) && !pair.IsEmpty) { yield return(pair); pair = new MovePair(null); } } }
public PgnNode(MoveTreeNode <PostMoveState> treeNode) { Debug.Assert(treeNode != null); var node = (MoveTreeNode <PostMoveState>)treeNode.Clone(); VariationDepth = treeNode.VariationDepth; Value = node; if (!node.IsFirstMoveOfVariation) { SiblingNodes = node.GetSiblingVariations().Select(x => new PgnNode(x)).ToArray(); } Next = node.Continuations.Any() ? new PgnNode((MoveTreeNode <PostMoveState>)node.Continuations.First()) : null; }
public Move DecideMove(Board board, PieceColor color) { telemetry = new HighSpeedTelemetry(); var now = DateTime.Now; ExpandMoveTree(board, color); var duration = (DateTime.Now - now).TotalSeconds; Console.Title = "Tree Generation took: " + duration; var selectedMove = SelectMove(board, moveTree, color); moveTree = moveTree.CounterMoves[selectedMove]; return(selectedMove); }
protected double CalculateBonusForMoves(ChessPiece piece, MoveTreeNode moveTree) { var possibleMoves = (from m in moveTree.CounterMoves select m.Value.Move); var myPossibleMoves = (from move in possibleMoves where move.Type == Moves.MoveType.NormalPiece && move.NormalPieceMove.Piece == piece select move.NormalPieceMove); int totalMoves = myPossibleMoves.Count(); int takingMoves = (from move in myPossibleMoves where move.PieceCaptured select move).Count(); int nonTakingMoves = totalMoves - takingMoves; return(takingMoves * TAKING_MOVES_BONUS + nonTakingMoves * NON_TAKING_MOVES_BONUS); }
private static int GetNextDepthDifference(MoveTreeNode <PostMoveState> currentNode, MoveTreeNode <PostMoveState> nextNodeInQueue, int currentDepth) { if (nextNodeInQueue == null) { return(-currentDepth); } var diff = nextNodeInQueue.VariationDepth - currentDepth; if (diff == 0 && nextNodeInQueue.ColorMakingMove == currentNode.ColorMakingMove && currentNode.IsLastMoveOfContinuation) { return(-1); } return(diff); }
private static int GetPreviousDepthDifference(MoveTreeNode <PostMoveState> currentNode, MoveTreeNode <PostMoveState> previousNode, int currentDepth) { if (previousNode == null) { return(0); } var depthDiff = currentNode.VariationDepth - currentDepth; if (depthDiff == 0 && previousNode.ColorMakingMove == currentNode.ColorMakingMove && currentNode.IsFirstMoveOfVariation) { return(1); } return(depthDiff); }
private double ScoreMove(MoveTreeNode moveTree, int recurseDepth) { if (recurseDepth == 2) { double colorToPlay = EvaluateBoardFor(moveTree, moveTree.ColorToPlay); double colorAgainst = EvaluateBoardFor(moveTree, moveTree.ColorToPlay.Opposite()); return(colorToPlay - colorAgainst); } else { Parallel.ForEach(moveTree.CounterMoves, (mkvp) => { mkvp.Value.Score = ScoreMove(mkvp.Value, recurseDepth + 1); }); var movesFromBestToWorst = (from kvp in moveTree.CounterMoves orderby kvp.Value.Score descending select kvp); var bestMove = (recurseDepth % 2 == 0 ? movesFromBestToWorst.First() : movesFromBestToWorst.Last()); return(bestMove.Value.Score.Value); } }
private Move ChooseBestMove(MoveTreeNode moveTree, PieceColor color, int recurseDepth = 0) { if (recurseDepth == MaximumRecurseDepth) { moveTree.Score = EvaluateBoardFor(moveTree, color); return(moveTree.Move); } else { double scoreRightNow = EvaluateBoardFor(moveTree, color); foreach (var tree in moveTree.CounterMoves) { var move = tree.Value.Move; if (move.ToString() == "be8 h5") { } if (tree.Value.Score == MoveTreeNode.CHECKMATE_SCORE) { return(tree.Value.Move); } if (tree.Value.Score == null) { ChooseBestMove(tree.Value, color, recurseDepth + 1); } } if (moveTree.CounterMoves.Count == 0) { throw new CheckmateException(); } var sortedMoves = (from m in moveTree.CounterMoves orderby m.Value.Score descending select m.Value).ToList(); var bestMove = sortedMoves[0]; moveTree.Score = bestMove.Score; return(bestMove.Move); } }
public void Add(MoveTreeNode n) { throw new System.NotSupportedException(); }
public bool LastContinuationMove_ShouldReturnCorrectValue(MoveTreeNode <PostMoveState> node) { return(node.IsLastMoveOfContinuation); }
public BoardNode(BoardNode boardNode) { Node = (MoveTreeNode <PostMoveState>)boardNode.Node.Clone(); Board = (Board)boardNode.Board.Clone(); }
/// <summary> /// Create a BoardNode, which consists of the board along with the postmove state. /// </summary> /// <param name="board"></param> /// <param name="postMoveStateNode"></param> public BoardNode(Board board, INode <PostMoveState> postMoveStateNode) { Board = (Board)board.Clone(); Node = (MoveTreeNode <PostMoveState>)postMoveStateNode; }