public bool isValid(Pair to, Pair from, PegBoard pegBoard, Player.Color currentPlayerColor) { int moveUpDown = from.row - to.row; int moveLeftRight = from.col - to.col; if (pegBoard.checkColor(from) != currentPlayerColor || // correct color pegBoard.isEmpty(from) || // selected empty peg slot !pegBoard.isEmpty(to)) // dropped on occupied slot { // conditions for immediate failure return(false); } else if (Math.Abs(moveUpDown) == 1 || Math.Abs(moveLeftRight) == 1) { // jump OR move 1 return(true); } else if (Math.Abs(moveUpDown) == 2 ^ Math.Abs(moveLeftRight) == 2) // xor jump (2) { // Jumps A color and Jumps OTHER color return(!pegBoard.isEmpty(from.row - moveUpDown / 2, from.col - moveLeftRight / 2) && pegBoard.checkColor(from.row - moveUpDown / 2, from.col - moveLeftRight / 2) != currentPlayerColor); } else { // Don't jump the rainbow! return(false); } }
public Game(Game.TypeOfGame type) // AI v AI { diskBoard = new DiskBoard(boardSize); pegBoard = new PegBoard(boardSize + 1); player1 = new Player("AI1", Player.Color.White, Player.TypeOfPlayer.AI); player2 = new Player("AI2", Player.Color.Black, Player.TypeOfPlayer.AI); currentPlayer = player1; }
public Game(Player me, GameOptions gameOptions) // Campaign, Quickgame, TimeAttack { diskBoard = new DiskBoard(boardSize); pegBoard = new PegBoard(boardSize + 1); player1 = me; player2 = new Player(gameOptions.player2Name, Player.Color.Black, Player.TypeOfPlayer.AI); currentPlayer = player1; }
public Game(string p1Name, string p2Name) // Local { diskBoard = new DiskBoard(boardSize); pegBoard = new PegBoard(boardSize + 1); player1 = new Player(p1Name, Player.Color.White, Player.TypeOfPlayer.Human); player2 = new Player(p2Name, Player.Color.Black, Player.TypeOfPlayer.Human); currentPlayer = player1; }
/// <summary> /// Populates each child node pushing every possible move /// </summary> /// <param name="parent"></param> /// <returns></returns> private List <TreeNode> PopulateTree(TreeNode parent) { List <TreeNode> children = new List <TreeNode>(); //loop through each peg //foreach (Peg peg in parent._pegBoard.pegList) ParallelOptions op = new ParallelOptions(); op.MaxDegreeOfParallelism = 40; Parallel.ForEach(parent._pegBoard.pegList, op, peg => { //if the peg is the same color as this node if (peg.color == parent._currentColor) { //loop through all possible moves foreach (Pair pair in _moveSet) { //if the move keeps us on the board, and it is a valid move if (peg.pos.row + pair.row >= 0 && peg.pos.row + pair.row < _pegBoard.size && peg.pos.col + pair.col >= 0 && peg.pos.col + pair.col < _pegBoard.size && isValid(new Pair(peg.pos.row + pair.row, peg.pos.col + pair.col), peg.pos, parent._pegBoard, parent._currentColor)) { //create a new pegBoard and make the move on the new board PegBoard pegBoard = new PegBoard(parent._pegBoard); DiskBoard diskBoard = new DiskBoard(parent._diskBoard); PieceMove pm = new PieceMove(new Pair(peg.pos.row + pair.row, peg.pos.col + pair.col), peg.pos); pegBoard.movePeg(parent._currentColor, pm.to, pm.from); if ((Math.Abs(pair.row) == 1 && Math.Abs(pair.col) == 1)) { diskBoard.placeDisk(parent._currentColor, pm.to, pm.from); } // change the diskBoard //add this new node as a child node lock (this) { children.Add(new TreeNode(parent._currentColor, pegBoard, diskBoard, parent._minimaxValue, new Pair(peg.pos.row + pair.row, peg.pos.col + pair.col), peg.pos, parent._levelInTree + 1, parent._aiColor, parent._movesFromWin, parent._maxTreeDepth, parent._middlePegHeuristic)); } } } } }); return(children); }
private bool isValid(Pair to, Pair from, PegBoard pegBoard, Player.Color currentPlayerColor) { int moveUpDown = from.row - to.row; int moveLeftRight = from.col - to.col; if (to.row < 0 || to.col < 0 || from.row < 0 || from.col < 0 || to.row > boardSize || to.col > boardSize || from.row > boardSize || from.col > boardSize) { return(false); } else if (pegBoard.checkColor(from) != currentPlayerColor || // correct color pegBoard.isEmpty(from) || // selected empty peg slot !pegBoard.isEmpty(to)) // dropped on occupied slot { // Conditions for immediate failure return(false); } else if (Math.Abs(moveUpDown) == 1 && Math.Abs(moveLeftRight) == 1) { // Jump return(true); } else if (Math.Abs(moveUpDown) + Math.Abs(moveLeftRight) == 1) { // Move peg over 1 return(true); } else if (Math.Abs(moveUpDown) + Math.Abs(moveLeftRight) == 2) { // jump (2,0) or (0,2) --> the (1,1) case has already been tested return(!pegBoard.isEmpty(from.row - moveUpDown / 2, from.col - moveLeftRight / 2) && pegBoard.checkColor(from.row - moveUpDown / 2, from.col - moveLeftRight / 2) != currentPlayerColor); // Jumps A color and Jumps OTHER color } else { // Don't jump the rainbow! return(false); } }
/// <summary> /// Private Constructor used to initialize child node /// </summary> /// <param name="currentColor"></param> ---> will switch color /// <param name="pegBoard"></param> /// <param name="diskBoard"></param> /// <param name="minimaxValue"></param> ---> will switch min/max /// <param name="to"></param> /// <param name="from"></param> /// <param name="levelInTree"></param> /// <param name="aiColor"></param> private TreeNode(Player.Color currentColor, PegBoard pegBoard, DiskBoard diskBoard, MiniMax minimaxValue, Pair to, Pair from, int levelInTree, Player.Color aiColor, int movesFromWin, int maxTreeDepth, double middlePegHeuristic) { this._pegBoard = pegBoard; this._diskBoard = diskBoard; this._moveMade = new PieceMove(); this._moveMade.to = to; this._moveMade.from = from; this._levelInTree = levelInTree; this._aiColor = aiColor; this._movesFromWin = movesFromWin - 1; this._maxTreeDepth = maxTreeDepth; this._middlePegHeuristic = middlePegHeuristic; if (maxTreeDepth == 1) { this._difficultyLevel = Difficulty.Easy; } else if (maxTreeDepth == 3) { this._difficultyLevel = Difficulty.Medium; } else { this._difficultyLevel = Difficulty.Hard; } // Switch colors if (currentColor == Player.Color.White) { this._currentColor = Player.Color.Black; } else { this._currentColor = Player.Color.White; } // Switch minimaxValue if (minimaxValue == MiniMax.Max) { this._minimaxValue = MiniMax.Min; } else { this._minimaxValue = MiniMax.Max; } }
public Game(string p1Name, string p2Name, int whichOneIsPlayer1) // Network { diskBoard = new DiskBoard(boardSize); pegBoard = new PegBoard(boardSize + 1); if (whichOneIsPlayer1 == 1) { player1 = new Player(p1Name, Player.Color.White, Player.TypeOfPlayer.Human); player2 = new Player(p2Name, Player.Color.Black, Player.TypeOfPlayer.Network); } else { player1 = new Player(p1Name, Player.Color.White, Player.TypeOfPlayer.Network); player2 = new Player(p2Name, Player.Color.Black, Player.TypeOfPlayer.Human); } currentPlayer = player1; }
public PieceMove getAIMove(Player currentPlayer, PegBoard pegBoard, DiskBoard diskBoard, int treeDepth) { PieceMove move = null; TreeNode root = new TreeNode(currentPlayer, pegBoard, diskBoard, TreeNode.MiniMax.Min, treeDepth); int selectedMove = root.AlphaBeta(root, int.MinValue, int.MaxValue); foreach (TreeNode node in root.children) { if (node.heuristicValue < selectedMove) { selectedMove = node.heuristicValue; move = node.moveMade; } } if (move == null) { move = root.children.ElementAt(0).moveMade; } return(move); }
/// <summary> /// Public Constructor /// </summary> /// <param name="player"></param> /// <param name="pegBoard"></param> /// <param name="diskBoard"></param> /// <param name="minimaxValue"></param> public TreeNode(Player player, PegBoard pegBoard, DiskBoard diskBoard, MiniMax minimaxValue, int treeDepth) { this._minimaxValue = minimaxValue; this._pegBoard = pegBoard; this._currentColor = this._aiColor = player.color; this._diskBoard = diskBoard; this._movesFromWin = diskBoard.movesFromWin(); this._maxTreeDepth = treeDepth; if (treeDepth == 1) { this._difficultyLevel = Difficulty.Easy; } else if (treeDepth == 3) { this._difficultyLevel = Difficulty.Medium; } else { this._difficultyLevel = Difficulty.Hard; } }
/// <summary> /// Copy Constructor /// </summary> /// <param name="oldPegBoard"></param> public PegBoard(PegBoard oldPegBoard) { this.pegList = new List <Peg>(oldPegBoard.pegList); this._whitePegCount = oldPegBoard._whitePegCount; this._blackPegCount = oldPegBoard._blackPegCount; }