//public Dictionary<Point, CheckerPiece> CheckerPieceMap { get; set; } //copy constructor public CheckerBoard(CheckerBoard other) { Board = other.Board; MustJump = new[] { other.MustJump[0], other.MustJump[1] }; SelectedPiece = null; JumpMade = null; AllPieces = new List<CheckerPiece>(other.AllPieces.Count()); for (var i = 0; i < other.AllPieces.Count(); i++) { AllPieces.Add(new CheckerPiece(other.AllPieces[i].Row, other.AllPieces[i].Col, other.AllPieces[i].Color, other.AllPieces[i].Status)); if (other.JumpMade == null) continue; if (other.AllPieces[i] == other.JumpMade) { JumpMade = AllPieces[i]; } } }
public List<MoveSet> CheckJumpMove(CheckerBoard currentBoard, CheckerPiece piece) { var row = piece.Row; var col = piece.Col; var jumpMoves = new List<MoveSet>(); var possibleLocation = new List<Point>{new Point(1, -1), new Point(1, 1), new Point(-1, -1), new Point(-1, 1)}; //Goes to each adjacent tile foreach(var location in possibleLocation) { //Get the adjacent piece that will be jumped var targetPiece = currentBoard.GetCheckerPiece(row + location.X, col + location.Y); //if the piece exists and the color is the opposite color if (targetPiece != null && targetPiece.Color != piece.Color) { //Check if there is a empty space after that piece and there is no piece at the location if (Board.CheckValidTile(row + 2 * location.X, col + 2 * location.Y) && currentBoard.GetCheckerPiece(row + 2 * location.X, col + 2 * location.Y) == null) { var jump = new MoveSet(row + 2 * location.X, col + 2 * location.Y); //Check continuous jumps //Generate a copy of the board var nextBoard = new CheckerBoard(currentBoard); nextBoard.SelectedPiece = nextBoard.GetCheckerPiece(piece.Row, piece.Col); nextBoard.MustJump[piece.Color] = true; //Move nextBoard.HandleMove(row + 2 * location.X, col + 2 * location.Y); //Keep checking for jump moves var nextJumps = CheckJumpMove(nextBoard, nextBoard.SelectedPiece); if (nextJumps.Any()) { foreach (var nextJump in nextJumps) { var branch = new MoveSet(jump); branch.MoveList.AddRange(nextJump.MoveList); jumpMoves.Add(branch); } } else { jumpMoves.Add(jump); } } } } return jumpMoves; }
int MinValue(CheckerBoard currentBoard, int depth, int alpha, int beta, int currentPlayer) { if (_nodeGeneration % 10000 == 0 && _nodeGeneration != 0) { Console.WriteLine("Max Depth: {0}", _maxDepth); Console.WriteLine("# of Pruning in Max: {0}", _maxPruning); Console.WriteLine("# of Pruning in Min: {0}", _minPruning); Console.WriteLine("# of Node Generated: {0}", _nodeGeneration); Console.WriteLine("Time Elapsed: {0}", TimeElapsed); } CheckerStatus status = currentBoard.GetStatus(_currentTurn); if (status != CheckerStatus.Continue) { return (int) status; } _maxDepth = Math.Max(_maxDepth, depth); if (depth == Difficulty ) return currentBoard.EvaluateBoard(_currentTurn); int v = 999; //For each movable piece for (var i = 0; i < currentBoard.MovablePieces[currentPlayer].Count(); i++) { //for each possible positions that the piece can go for (var j = 0; j < currentBoard.MoveDict[currentBoard.MovablePieces[currentPlayer][i]].Count(); j++) { _nodeGeneration++; //For each possible move make a new checkerboard and move it var newCheckerBoard = new CheckerBoard(currentBoard); var selectedPiece = newCheckerBoard.GetCheckerPiece(currentBoard.MovablePieces[currentPlayer][i].Row, currentBoard.MovablePieces[currentPlayer][i].Col); newCheckerBoard.SelectedPiece = selectedPiece; newCheckerBoard.HandleMove(currentBoard.MoveDict[currentBoard.MovablePieces[currentPlayer][i]][j]); newCheckerBoard.CheckAllAvailableMoves(); int nextTurn = newCheckerBoard.AINextTurn(currentPlayer); v = Math.Min(v, MaxValue(newCheckerBoard, depth + 1, alpha, beta, nextTurn)); //pruning if (v <= alpha) { _minPruning++; return v; } if (v < beta) { beta = v; if (currentBoard == _checkerBoard) { _bestMoveSet = currentBoard.MoveDict[currentBoard.MovablePieces[currentPlayer][i]][j]; _bestPiece = currentBoard.MovablePieces[currentPlayer][i]; } } } } return v; }
//Gets the Max Value int MaxValue(CheckerBoard currentBoard, int depth, int alpha, int beta, int currentPlayer) { if (_nodeGeneration % 10000 == 0 && _nodeGeneration !=0) { Console.WriteLine("Max Depth: {0}", _maxDepth); Console.WriteLine("# of Pruning in Max: {0}", _maxPruning); Console.WriteLine("# of Pruning in Min: {0}", _minPruning); Console.WriteLine("# of Node Generated: {0}", _nodeGeneration); Console.WriteLine("Time Elapsed: {0}", TimeElapsed); } //Checks to see if it is a utility value CheckerStatus status = currentBoard.GetStatus(_currentTurn); //If it is return the value if (status != CheckerStatus.Continue) { return (int) status; } _maxDepth = Math.Max(_maxDepth, depth); //Depth Limiter if (depth == Difficulty ) return currentBoard.EvaluateBoard(_currentTurn); var v = -999; //Iterate through every movable pieces for (var i = 0; i < currentBoard.MovablePieces[currentPlayer].Count(); i++) { //Iterate through every possible move for the selected piece for (var j = 0; j < currentBoard.MoveDict[currentBoard.MovablePieces[currentPlayer][i]].Count(); j++) { //Increment node counter _nodeGeneration++; //For each possible move make a new checkerboard and move it var newCheckerBoard = new CheckerBoard(currentBoard); //Select the piece that will be moved var selectedPiece = newCheckerBoard.GetCheckerPiece(currentBoard.MovablePieces[currentPlayer][i].Row, currentBoard.MovablePieces[currentPlayer][i].Col); newCheckerBoard.SelectedPiece = selectedPiece; //Move the piece to a piece location newCheckerBoard.HandleMove(currentBoard.MoveDict[currentBoard.MovablePieces[currentPlayer][i]][j]); newCheckerBoard.CheckAllAvailableMoves(); var nextTurn = newCheckerBoard.AINextTurn(currentPlayer); v = Math.Max(v, MinValue(newCheckerBoard, depth + 1, alpha, beta, nextTurn)); if (v >= beta) { _maxPruning++; return v; } if (v > alpha) { alpha = v; if (currentBoard == _checkerBoard) { _bestMoveSet = currentBoard.MoveDict[currentBoard.MovablePieces[currentPlayer][i]][j]; _bestPiece = currentBoard.MovablePieces[currentPlayer][i]; } } } } return v; }
void AlphaBetaSearch(CheckerBoard currentBoard, int playerColor) { _maxPruning = 0; _minPruning = 0; _maxDepth = 0; TimeElapsed = 0; MaxValue(currentBoard, 0, -999, 999, playerColor); }
/// <summary> /// Allows the game to perform any initialization it needs to before starting to run. /// This is where it can query for any required services and load any non-graphic /// related content. Calling base.Initialize will enumerate through any components /// and initialize them as well. /// </summary> protected override void Initialize() { _maxPruning = 0; _minPruning = 0; _maxDepth = 0; _timer = 0; _nodeGeneration = 0; _checkerBoard = new CheckerBoard(Rows, Cols); _cam = new Camera {Pos = new Vector2(0, 0)}; _particleManager = new ParticleManager(); _screenManager = new UIScreenManager(); _setupForm = new SetupForm(this); _drawDriver = new DrawDriver(); base.Initialize(); }