public CheckerState(int rows, int cols) { MustJump = new[]{false, false}; bool black = true; AllPieces = new List<CheckerPiece>(); CheckerPieceMap = new Dictionary<int, CheckerPiece>(); for (int row = 0; row < rows; row++) //top to down { for (int col = cols - 1; col >= 0; col--) // right to left { CheckerPieceMap[row*cols + col] = null; if (black) { var numPieceRows = (rows - 2); if (row < numPieceRows) { var tempPiece = new CheckerPiece(row, col, 0); AllPieces.Add(tempPiece); CheckerPieceMap[row * cols + col] = tempPiece; } else if (row >= rows - numPieceRows) { var tempPiece = new CheckerPiece(row, col, 1); AllPieces.Add(tempPiece); CheckerPieceMap[row * cols + col] = tempPiece; } } black = !black; if (col == 0) black = !black; } } }
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); }
public CheckerPieces(int rows, int cols) { var black = true; Rows = rows; Cols = cols; AllPieces = new List<CheckerPiece>(); PieceLocation = new CheckerPiece[Rows, Cols]; for (var row = 0; row < Rows; row++) //top to down { for (var col = Cols - 1; col >= 0; col--) // right to left { if (black) { var numPieceRows = Math.Floor((Rows - 2) / 2.0); if (row < numPieceRows) { var tempPiece = new CheckerPiece(row, col, 0); AllPieces.Add(tempPiece); PieceLocation[row, col] = tempPiece; } else if (row >= Rows - numPieceRows) { var tempPiece = new CheckerPiece(row, col, 1); AllPieces.Add(tempPiece); PieceLocation[row, col] = tempPiece; } } if (col != 0 || Cols % 2 != 0) black = !black; } } }
//Alpha Beta void Ai() { _bestMoveSet = null; _bestPiece = null; _nodeGeneration = 0; _maxPruning = 0; _minPruning = 0; _maxDepth = 0; AlphaBetaSearch(_checkerBoard, _currentTurn); //If it never found something b/c it was limited in depth if (_bestMoveSet == null && _bestPiece == null) { var randomPiece = Rand.Next(0, _checkerBoard.MovablePieces[_currentTurn].Count - 1); var randomMove = Rand.Next(0, _checkerBoard.MoveDict[_checkerBoard.MovablePieces[_currentTurn][randomPiece]].Count - 1); _bestMoveSet = _checkerBoard.MoveDict[_checkerBoard.MovablePieces[_currentTurn][randomPiece]][randomMove]; _bestPiece = _checkerBoard.MovablePieces[_currentTurn][randomPiece]; } _checkerBoard.SelectedPiece = _bestPiece; if (_bestPiece != null) { Console.WriteLine("Moving Piece at Row: {0}, Col: {1}", _bestPiece.Row, _bestPiece.Col); } if (_bestMoveSet != null) { Console.WriteLine("{0}", _bestMoveSet.MoveList.ToList()); } 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 Nodes Generated: {0}", _nodeGeneration); Console.WriteLine("Time Elapsed: {0}", TimeElapsed); if (_selectedParticle != null) { _selectedParticle.status = ParticleStatus.Dead; _selectedParticle = null; } if (_bestPiece != null) { _selectedParticle = _particleManager.Spawn(_particleManager.particleSystemInfoDict["fireSmall"], _checkerBoard.GetCenterOfTile(_bestPiece.Row, _bestPiece.Col)); } Thread.Sleep(TimeDelay); //Handle the move to that location Debug.Assert(_bestMoveSet != null, "bestMove != null"); _checkerBoard.HandleMove(_bestMoveSet, TimeDelay); if (_selectedParticle != null) { _selectedParticle.status = ParticleStatus.Dead; _selectedParticle = null; } }
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); }
public void CheckAllAvailableMoves() { MovablePieces = new List <CheckerPiece> [2]; MovablePieces[0] = new List <CheckerPiece>(); MovablePieces[1] = new List <CheckerPiece>(); MoveDict = new Dictionary <CheckerPiece, List <MoveSet> >(); SelectedPiece = null; foreach (var t in AllPieces.Where(piece => piece.Status == CheckerPieceStatus.Alive)) { CheckAvailableMoves(t); } }
public int AINextTurn(int currentTurn) { //There was a jump move made, need to see if there is possible after jumps MustJump[0] = false; MustJump[1] = false; JumpMade = null; int nextTurn = (currentTurn + 1) % 2; CheckAllAvailableMoves(); SelectedPiece = null; return(nextTurn); }
public void DrawPieces(SpriteBatch spriteBatch, Camera cam, List <CheckerPiece> allPieces, int tileScale) { spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, cam.get_transformation(_device)); for (int i = 0; i < allPieces.Count(); i++) { CheckerPiece currentPiece = allPieces[i]; if (currentPiece != null) { spriteBatch.Draw(_checkerTileTexture, new Vector2((currentPiece.Col * tileScale + tileScale * .5f), currentPiece.Row * tileScale + tileScale * .5f), new Rectangle(currentPiece.Color * tileScale, (int)currentPiece.Status * tileScale, tileScale, tileScale), Color.White, 0, new Vector2(tileScale / 2.0f, tileScale / 2.0f), 1, SpriteEffects.None, 0); } } spriteBatch.End(); }
//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 int NextTurn(int currentTurn) { int nextTurn = currentTurn; //There was a jump move made, need to see if there is possible after jumps if (JumpMade != null) { CheckAllAvailableMoves(); } if (JumpMade == null || !MovablePieces[JumpMade.Color].Contains(GetCheckerPiece(JumpMade.Row, JumpMade.Col))) { MustJump[0] = false; MustJump[1] = false; JumpMade = null; nextTurn = (currentTurn + 1) % 2; } CheckAllAvailableMoves(); SelectedPiece = null; return(nextTurn); }
public void DrawCheckerBoard(CheckerTile[,] tileBoard, List<CheckerPiece> allPieces, CheckerPiece selectedPiece, List<CheckerPiece>[] movablePieces, Dictionary<CheckerPiece, List<MoveSet>> MoveDict, int TILE_SCALE, SpriteBatch spriteBatch, Camera cam) { if (!_contentLoaded) return; spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, cam.get_transformation(_device)); //Checker Tiles for (var row = 0; row < tileBoard.GetLength(0); row++) { for (int col = 0; col < tileBoard.GetLength(1); col++) { spriteBatch.Draw(_blankTexture, new Rectangle(col * TILE_SCALE, row * TILE_SCALE, TILE_SCALE, TILE_SCALE), null, (tileBoard[row, col].Color == 1)?Color.Gray:Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); } } //Lines for (var row = 0; row <= tileBoard.GetLength(0); row++) { spriteBatch.Draw(_blankTexture, new Rectangle(0, row * TILE_SCALE, tileBoard.GetLength(1) * TILE_SCALE, 1), null, Color.Black, 0, Vector2.Zero, SpriteEffects.None, 0); } for (var col = 0; col <= tileBoard.GetLength(1); col++) { spriteBatch.Draw(_blankTexture, new Rectangle(col * TILE_SCALE, 0, 1, tileBoard.GetLength(0) * TILE_SCALE), null, Color.Black, 0, Vector2.Zero, SpriteEffects.None, 0); } spriteBatch.End(); //Draw Pieces DrawPieces(spriteBatch, cam, allPieces, TILE_SCALE); //Draw the possible moves if (selectedPiece != null && movablePieces != null && movablePieces[selectedPiece.Color].Contains(selectedPiece) && MoveDict.ContainsKey(selectedPiece)) { DrawPossibleMoves(spriteBatch, cam, MoveDict[selectedPiece], TILE_SCALE, selectedPiece); } }
public void Reset(int rows, int cols) { Rows = rows; Cols = cols; //Place the pieces bool black = true; Board = new Board(rows, cols, TileScale); AllPieces = new List <CheckerPiece>(); for (int row = 0; row < Rows; row++) //top to down { for (int col = Cols - 1; col >= 0; col--) // right to left { if (black) { var numPieceRows = Math.Floor((Rows - 2) / 2.0); if (row < numPieceRows) { var tempPiece = new CheckerPiece(row, col, 0); AllPieces.Add(tempPiece); } else if (row >= Rows - numPieceRows) { var tempPiece = new CheckerPiece(row, col, 1); AllPieces.Add(tempPiece); } } if (col != 0 || Cols % 2 != 0) { black = !black; } } } MustJump = new[] { false, false }; CheckAllAvailableMoves(); }
public CheckerState(int rows, int cols) { MustJump = new[] { false, false }; bool black = true; AllPieces = new List <CheckerPiece>(); CheckerPieceMap = new Dictionary <int, CheckerPiece>(); for (int row = 0; row < rows; row++) //top to down { for (int col = cols - 1; col >= 0; col--) // right to left { CheckerPieceMap[row * cols + col] = null; if (black) { var numPieceRows = (rows - 2); if (row < numPieceRows) { var tempPiece = new CheckerPiece(row, col, 0); AllPieces.Add(tempPiece); CheckerPieceMap[row * cols + col] = tempPiece; } else if (row >= rows - numPieceRows) { var tempPiece = new CheckerPiece(row, col, 1); AllPieces.Add(tempPiece); CheckerPieceMap[row * cols + col] = tempPiece; } } black = !black; if (col == 0) { black = !black; } } } }
public CheckerPieces(int rows, int cols) { var black = true; Rows = rows; Cols = cols; AllPieces = new List <CheckerPiece>(); PieceLocation = new CheckerPiece[Rows, Cols]; for (var row = 0; row < Rows; row++) //top to down { for (var col = Cols - 1; col >= 0; col--) // right to left { if (black) { var numPieceRows = Math.Floor((Rows - 2) / 2.0); if (row < numPieceRows) { var tempPiece = new CheckerPiece(row, col, 0); AllPieces.Add(tempPiece); PieceLocation[row, col] = tempPiece; } else if (row >= Rows - numPieceRows) { var tempPiece = new CheckerPiece(row, col, 1); AllPieces.Add(tempPiece); PieceLocation[row, col] = tempPiece; } } if (col != 0 || Cols % 2 != 0) { black = !black; } } } }
public void Reset(int rows, int cols) { Rows = rows; Cols = cols; //Place the pieces bool black = true; Board = new Board(rows, cols, TileScale); AllPieces = new List<CheckerPiece>(); for (int row = 0; row < Rows; row++) //top to down { for (int col = Cols - 1; col >= 0; col--) // right to left { if (black) { var numPieceRows = Math.Floor((Rows - 2) / 2.0); if (row < numPieceRows) { var tempPiece = new CheckerPiece(row, col, 0); AllPieces.Add(tempPiece); } else if (row >= Rows - numPieceRows) { var tempPiece = new CheckerPiece(row, col, 1); AllPieces.Add(tempPiece); } } if (col != 0 || Cols % 2 != 0) black = !black; } } MustJump = new[]{false,false}; CheckAllAvailableMoves(); }
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; }
public void CheckAvailableMoves(CheckerPiece piece) { var row = piece.Row; var col = piece.Col; var tempPossibleMoves = CheckJumpMove(this, piece); //regular move //Check for regular move if there is no jump moves if (!tempPossibleMoves.Any()) { if (!MustJump[piece.Color]) { //If the current turn is white if (piece.Color == 0) { //At most there are two regular moves left or right diagonal //Check if the tile is valid and has no piece on it if (Board.CheckValidTile(row + 1, col - 1) && GetCheckerPiece(row + 1, col - 1) == null) { tempPossibleMoves.Add(new MoveSet(row + 1, col - 1)); } if (Board.CheckValidTile(row + 1, col + 1) && GetCheckerPiece(row + 1, col + 1) == null) { tempPossibleMoves.Add(new MoveSet(row + 1, col + 1)); } } //current turn is black else { //At most there are two regular moves left or right diagonal //Check if the tile is valid and has no piece on it if (Board.CheckValidTile(row - 1, col - 1) && GetCheckerPiece(row - 1, col - 1) == null) { tempPossibleMoves.Add(new MoveSet(row - 1, col - 1)); } if (Board.CheckValidTile(row - 1, col + 1) && GetCheckerPiece(row - 1, col + 1) == null) { tempPossibleMoves.Add(new MoveSet(row - 1, col + 1)); } } } } //A jump can be made else { //A previous jump was made if (JumpMade != null) { if (JumpMade == piece) { MovablePieces[piece.Color].Add(piece); MustJump[piece.Color] = true; } } //If there was no previous jump made else { //If this is the first jump if (MustJump[piece.Color] == false) { //Clear the movable piece set MovablePieces[piece.Color].Clear(); MustJump[piece.Color] = true; } //if this piece is a jump piece add it if (MustJump[piece.Color]) { MovablePieces[piece.Color].Add(piece); } } } //Add this to the dictionary if there is actual moves if (tempPossibleMoves.Count != 0) { MoveDict[piece] = tempPossibleMoves; //if there is no jump add it if (!MustJump[piece.Color]) MovablePieces[piece.Color].Add(piece); } }
public void DrawPossibleMoves(SpriteBatch spriteBatch, Camera cam, List <MoveSet> allTile, int TILE_SCALE, CheckerPiece SelectedPiece) { spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, cam.get_transformation(_device)); for (int i = 0; i < allTile.Count(); i++) { for (int j = 0; j < allTile[i].MoveList.Count(); j++) { Color color = (j == 0) ? new Color(255, 255, 255, 127) : new Color(255, 255, 255, 50); spriteBatch.Draw(_checkerTileTexture, new Vector2((allTile[i].MoveList[j].Col * TILE_SCALE + TILE_SCALE * .5f), allTile[i].MoveList[j].Row * TILE_SCALE + TILE_SCALE * .5f), new Rectangle(SelectedPiece.Color * TILE_SCALE, 0, TILE_SCALE, TILE_SCALE), color, 0, new Vector2(TILE_SCALE * .5f, TILE_SCALE * .5f), 1, SpriteEffects.None, 0); } } spriteBatch.End(); }
//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); }
public void DrawCheckerBoard(CheckerTile[,] tileBoard, List <CheckerPiece> allPieces, CheckerPiece selectedPiece, List <CheckerPiece>[] movablePieces, Dictionary <CheckerPiece, List <MoveSet> > MoveDict, int TILE_SCALE, SpriteBatch spriteBatch, Camera cam) { if (!_contentLoaded) { return; } spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, cam.get_transformation(_device)); //Checker Tiles for (var row = 0; row < tileBoard.GetLength(0); row++) { for (int col = 0; col < tileBoard.GetLength(1); col++) { spriteBatch.Draw(_blankTexture, new Rectangle(col * TILE_SCALE, row * TILE_SCALE, TILE_SCALE, TILE_SCALE), null, (tileBoard[row, col].Color == 1)?Color.Gray:Color.White, 0, Vector2.Zero, SpriteEffects.None, 1); } } //Lines for (var row = 0; row <= tileBoard.GetLength(0); row++) { spriteBatch.Draw(_blankTexture, new Rectangle(0, row * TILE_SCALE, tileBoard.GetLength(1) * TILE_SCALE, 1), null, Color.Black, 0, Vector2.Zero, SpriteEffects.None, 0); } for (var col = 0; col <= tileBoard.GetLength(1); col++) { spriteBatch.Draw(_blankTexture, new Rectangle(col * TILE_SCALE, 0, 1, tileBoard.GetLength(0) * TILE_SCALE), null, Color.Black, 0, Vector2.Zero, SpriteEffects.None, 0); } spriteBatch.End(); //Draw Pieces DrawPieces(spriteBatch, cam, allPieces, TILE_SCALE); //Draw the possible moves if (selectedPiece != null && movablePieces != null && movablePieces[selectedPiece.Color].Contains(selectedPiece) && MoveDict.ContainsKey(selectedPiece)) { DrawPossibleMoves(spriteBatch, cam, MoveDict[selectedPiece], TILE_SCALE, selectedPiece); } }
//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; }
//Alpha Beta void Ai() { _bestMoveSet = null; _bestPiece = null; _nodeGeneration = 0; _maxPruning = 0; _minPruning = 0; _maxDepth = 0; AlphaBetaSearch(_checkerBoard, _currentTurn); //If it never found something b/c it was limited in depth if (_bestMoveSet == null && _bestPiece == null){ var randomPiece = Rand.Next(0, _checkerBoard.MovablePieces[_currentTurn].Count - 1); var randomMove = Rand.Next(0, _checkerBoard.MoveDict[_checkerBoard.MovablePieces[_currentTurn][randomPiece]].Count - 1); _bestMoveSet = _checkerBoard.MoveDict[_checkerBoard.MovablePieces[_currentTurn][randomPiece]][randomMove]; _bestPiece = _checkerBoard.MovablePieces[_currentTurn][randomPiece]; } _checkerBoard.SelectedPiece = _bestPiece; if (_bestPiece != null) Console.WriteLine("Moving Piece at Row: {0}, Col: {1}", _bestPiece.Row, _bestPiece.Col); if (_bestMoveSet != null) Console.WriteLine("{0}", _bestMoveSet.MoveList.ToList()); 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 Nodes Generated: {0}", _nodeGeneration); Console.WriteLine("Time Elapsed: {0}", TimeElapsed); if (_selectedParticle != null) { _selectedParticle.status = ParticleStatus.Dead; _selectedParticle = null; } if (_bestPiece != null) _selectedParticle = _particleManager.Spawn(_particleManager.particleSystemInfoDict["fireSmall"], _checkerBoard.GetCenterOfTile(_bestPiece.Row, _bestPiece.Col)); Thread.Sleep(TimeDelay); //Handle the move to that location Debug.Assert(_bestMoveSet != null, "bestMove != null"); _checkerBoard.HandleMove(_bestMoveSet, TimeDelay); if (_selectedParticle != null) { _selectedParticle.status = ParticleStatus.Dead; _selectedParticle = null; } }
public void DrawPossibleMoves(SpriteBatch spriteBatch, Camera cam, List<MoveSet> allTile, int TILE_SCALE, CheckerPiece SelectedPiece) { spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, cam.get_transformation(_device)); for (int i = 0; i < allTile.Count(); i++) { for (int j = 0; j < allTile[i].MoveList.Count(); j++) { Color color = (j == 0) ? new Color(255, 255, 255, 127) : new Color(255, 255, 255, 50); spriteBatch.Draw(_checkerTileTexture, new Vector2((allTile[i].MoveList[j].Col * TILE_SCALE + TILE_SCALE * .5f), allTile[i].MoveList[j].Row * TILE_SCALE + TILE_SCALE * .5f), new Rectangle(SelectedPiece.Color*TILE_SCALE, 0, TILE_SCALE, TILE_SCALE), color, 0, new Vector2(TILE_SCALE * .5f, TILE_SCALE * .5f), 1, SpriteEffects.None, 0); } } spriteBatch.End(); }
public void Move(CheckerPiece piece, int row, int col) { PieceLocation[row, col] = piece; PieceLocation[row, col] = null; }
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; }
public void Move(CheckerPiece piece, int row, int col) { PieceLocation[row, col] = piece; PieceLocation[row, col] = null; }
public void CheckAvailableMoves(CheckerPiece piece) { var row = piece.Row; var col = piece.Col; var tempPossibleMoves = CheckJumpMove(this, piece); //regular move //Check for regular move if there is no jump moves if (!tempPossibleMoves.Any()) { if (!MustJump[piece.Color]) { //If the current turn is white if (piece.Color == 0) { //At most there are two regular moves left or right diagonal //Check if the tile is valid and has no piece on it if (Board.CheckValidTile(row + 1, col - 1) && GetCheckerPiece(row + 1, col - 1) == null) { tempPossibleMoves.Add(new MoveSet(row + 1, col - 1)); } if (Board.CheckValidTile(row + 1, col + 1) && GetCheckerPiece(row + 1, col + 1) == null) { tempPossibleMoves.Add(new MoveSet(row + 1, col + 1)); } } //current turn is black else { //At most there are two regular moves left or right diagonal //Check if the tile is valid and has no piece on it if (Board.CheckValidTile(row - 1, col - 1) && GetCheckerPiece(row - 1, col - 1) == null) { tempPossibleMoves.Add(new MoveSet(row - 1, col - 1)); } if (Board.CheckValidTile(row - 1, col + 1) && GetCheckerPiece(row - 1, col + 1) == null) { tempPossibleMoves.Add(new MoveSet(row - 1, col + 1)); } } } } //A jump can be made else { //A previous jump was made if (JumpMade != null) { if (JumpMade == piece) { MovablePieces[piece.Color].Add(piece); MustJump[piece.Color] = true; } } //If there was no previous jump made else { //If this is the first jump if (MustJump[piece.Color] == false) { //Clear the movable piece set MovablePieces[piece.Color].Clear(); MustJump[piece.Color] = true; } //if this piece is a jump piece add it if (MustJump[piece.Color]) { MovablePieces[piece.Color].Add(piece); } } } //Add this to the dictionary if there is actual moves if (tempPossibleMoves.Count != 0) { MoveDict[piece] = tempPossibleMoves; //if there is no jump add it if (!MustJump[piece.Color]) { MovablePieces[piece.Color].Add(piece); } } }