/// <summary> /// Gets all the possible nodes for a given position /// </summary> /// <param name="position">Positional node</param> public List <PositionNode> GetNodes(Position position, sbyte team) { List <PositionNode> nodes = new List <PositionNode>(); sbyte winner = -1; if (position.IsWon(out winner)) { return(nodes); } DiceRoll[] rolls = GetRollsQueue(position, team); for (int r = 0; r < rolls.Length; r++) { MoveCollection collection = GetMoves(position, rolls[r], team); if (collection != null) { PositionNode[] pnodes = new PositionNode[collection.Count]; for (int i = 0; i < collection.Count; i++) { Position node = position.Clone(); PerformMove(node, collection[i]); pnodes[i] = new PositionNode(node, collection[i], rolls[r]); } nodes.AddRange(pnodes); } } return(nodes); }
/// <summary> /// Gets the next target search /// </summary> /// <param name="current">Next Node</param> public PlySearch Next(PositionNode current) { sbyte nextPlayer = board.NextPlayer(CurrentPlayer); PlySearch next = new PlySearch(board, current, RootPlayer, nextPlayer, CurrentPlyDepth - 1); next.NextDepth = next.CurrentPlyDepth - 1; if (current.RolledDoubles) { next.NextPlayer = next.CurrentPlayer; next.NextDepth = next.CurrentPlyDepth; next.DoublesCount = DoublesCount + 1; if (next.DoublesCount >= 3) { current.Value.RemoveFrontMarble(next.CurrentPlayer); next.DoublesCount = 0; next.NextPlayer = board.NextPlayer(next.CurrentPlayer); next.NextDepth = next.CurrentPlyDepth - 1; } } else { next.DoublesCount = 0; } return(next); }
/// <summary> /// Gets the next target search for a minimax algorithm /// </summary> /// <param name="current">Next node</param> public PlySearch NextMiniMax(PositionNode current) { //Flipped maximizing because this is normally after we invert the bool sbyte nextPlayer = (!Maximizing) ? board.NextPlayer(CurrentPlayer) : CurrentPlayer; PlySearch next = new PlySearch(board, current, RootPlayer, nextPlayer, CurrentPlyDepth - 1); next.Maximizing = !Maximizing; next.NextDepth = next.CurrentPlyDepth - 1; if (current.RolledDoubles) { next.NextPlayer = next.CurrentPlayer; next.NextDepth = next.CurrentPlyDepth; next.DoublesCount = DoublesCount + 1; if (next.DoublesCount >= 3) { current.Value.RemoveFrontMarble(next.CurrentPlayer); next.DoublesCount = 0; next.NextPlayer = board.NextPlayer(next.CurrentPlayer); next.NextDepth = next.CurrentPlyDepth - 1; } } else { next.DoublesCount = 0; } return(next); }
/// <summary> /// Thinks about the current position given the dice roll and calculates the best move /// </summary> /// <param name="algorithm">Evaluation algorithm to use</param> /// <param name="roll">Roll</param> /// <param name="team">Team to think for</param> /// <param name="depth">Depth to think</param> public Move ThinkBest(Algorithm algorithm, DiceRoll roll, sbyte team, int ms) { MoveCollection collection = GetMoves(roll, team); if (collection.Count == 0) { return(null); } else if (collection.Count == 1) { return(collection[0]); } else if (ms < 0) { return(collection[random.Next(collection.Count)]); } PositionNode[] nodes = new PositionNode[collection.Count]; for (int i = 0; i < collection.Count; i++) { Position node = new Position(this.quadrants); PerformMove(node, collection[i]); nodes[i] = new PositionNode(node, collection[i], roll); } algorithm.Player = team; Vector4[] evaluations = new Vector4[nodes.Length]; for (int j = 0; j < nodes.Length; j++) { PositionNode currentRootMoveNode = nodes[j]; algorithm.Root = currentRootMoveNode; Vector4 moveEval = algorithm.Go(ms / collection.Count); evaluations[j] = moveEval; } int highIndex = 0; double high = evaluations[0].GetMagnitude(team); for (int i = 1; i < evaluations.Length; i++) { double curMag = evaluations[i].GetMagnitude(team); if (curMag > high) { high = curMag; highIndex = i; } } return(collection[highIndex]); }
public MoveCollection ThinkAll(Algorithm algorithm, DiceRoll roll, sbyte team, int ms, out Vector4[] scores) { MoveCollection collection = GetMoves(roll, team); if (collection.Count == 0) { scores = null; return(null); } else if (collection.Count == 1) { scores = new Vector4[1] { algorithm.Eval(this.GetPosition(), roll.IsDoubles() ? team : Board.NO_PLAYER) }; return(collection); } if (ms < 0) { throw new ArgumentException(); } PositionNode[] nodes = new PositionNode[collection.Count]; for (int i = 0; i < collection.Count; i++) { Position node = new Position(this.quadrants); PerformMove(node, collection[i]); nodes[i] = new PositionNode(node, collection[i], roll); } algorithm.Player = team; Vector4[] evaluations = new Vector4[nodes.Length]; for (int j = 0; j < nodes.Length; j++) { PositionNode currentRootMoveNode = nodes[j]; algorithm.Root = currentRootMoveNode; Vector4 moveEval = algorithm.Go(ms / collection.Count); evaluations[j] = moveEval; } SortDecreasing(evaluations, collection, team); scores = evaluations; return(collection); }
/// <summary> /// Creates a new ply search /// </summary> /// <param name="board">Board</param> /// <param name="node">Current node</param> /// <param name="rootPlayer">Root player</param> /// <param name="currentPlayer">Current player</param> /// <param name="startPlyDepth">Current depth</param> public PlySearch(Board board, PositionNode node, sbyte rootPlayer, sbyte currentPlayer, int startPlyDepth) : base(board, node, rootPlayer, currentPlayer) { CurrentPlyDepth = startPlyDepth; }