public void ResolveMove(StoneMove _move) { if (state[_move.startPos] == TileState.WhitePiece && _move.endPos < 4) { state[_move.startPos] = TileState.WhiteKing; } else if (state[_move.startPos] == TileState.BlackPiece && _move.endPos > 30) { state[_move.startPos] = TileState.BlackKing; } else if (_move.endState != TileState.Empty) { state[_move.startPos] = _move.endState; } state[_move.endPos] = state[_move.startPos]; state[_move.startPos] = TileState.Empty; if (_move.stoneCaptured) { foreach (int pos in _move.capturedStones) { state[pos] = TileState.Empty; } } }
public void AttemptMove(StoneMove _move) { if (validMoves.Contains(_move)) { bool captureFound = false; bool furtherCaps = true; List <StoneMove> moveCheck = new List <StoneMove>(); boardState.ResolveMove(_move); if (_move.stoneCaptured) { foreach (int pos in _move.capturedStones) { AI.FindValidMoves(boardState, _move.endPos, ref captureFound, ref furtherCaps, moveCheck, false); } int blackRemaining = 0, whiteRemaining = 0; for (int i = 0; i < 35; i++) { TileState s = boardState.state[i]; if (s == TileState.BlackKing || s == TileState.BlackPiece) { blackRemaining++; } else if (s == TileState.WhiteKing || s == TileState.WhitePiece) { whiteRemaining++; } } if (blackRemaining == 0) { winner = 2; EventManager.TriggerEvent("gameOver"); } else if (whiteRemaining == 0) { winner = 1; EventManager.TriggerEvent("gameOver"); } } if (captureFound) { validMoves = moveCheck; } else { turnComplete = true; } EventManager.TriggerEvent("boardUpdated"); } }
public BoardNode(Board _boardState, int _activePlayer, StoneMove _moveMade) { boardState = _boardState.Clone(); activePlayer = _activePlayer; childNodes = new List <BoardNode>(); validMoves = AI.FindAllValidMoves(boardState, activePlayer, true); endNode = true; moveMade = _moveMade; valueCalculated = false; }
public EstimateMoveNode AddChild(StoneMove move) { var child = new EstimateMoveNode(this, move); lock (_lock) { this._Children.Add(child); } return(child); }
public BoardNode(Board _boardState, int _activePlayer, bool _shuffleMoves) { boardState = _boardState.Clone(); activePlayer = _activePlayer; childNodes = new List <BoardNode>(); validMoves = AI.FindAllValidMoves(boardState, activePlayer, true); System.Random rnd = new System.Random(); validMoves = validMoves.OrderBy(item => rnd.Next()).ToList(); endNode = true; moveMade = null; valueCalculated = false; }
private EstimateMoveNode(EstimateMoveNode parent, StoneMove move) { if (null == parent) { throw new ArgumentNullException("parent is null."); } if (null == move) { throw new ArgumentNullException("move is null."); } this.Parent = parent; this.Depth = Parent.Depth + 1; this.Move = move; this._Children = new List <EstimateMoveNode>(); InitializeState(); }
public void AttemptMove(StoneMove _move) { model.AttemptMove(_move); }
public override bool PerformTurn(Board _currentBoard, int _aiPlayer, PlayerType otherPlayer, bool _firstTurn, out StoneMove _move, int presetFirstMove) { ADRASMoveList.Clear(); if (boardNodes == null) { boardNodes = new List <BoardNode>(); } _move = new StoneMove(); List <StoneMove> possibleMoves = FindAllValidMoves(_currentBoard, _aiPlayer, true); System.Random rnd = new System.Random(); List <StoneMove> shuffledList = possibleMoves.OrderBy(item => rnd.Next()).ToList(); if (shuffledList.Count > 0) { StoneMove selectedMove = possibleMoves[0]; float selectedMoveValue = -Mathf.Infinity; if (_firstTurn) { FFData temp; float boardVal = GetBoardRating(_currentBoard, _aiPlayer, out temp); InitBoardVal[_aiPlayer - 1] = boardVal; if (_aiPlayer == 1) { if (presetFirstMove >= 0 && presetFirstMove < possibleMoves.Count && !GameManager.DEMO) { _move = possibleMoves[presetFirstMove]; } else { _move = shuffledList.First(); } return(true); } } else { bool existingNodeFound = false; BoardNode baseNode = new BoardNode(_currentBoard, _aiPlayer); if (boardNodes.Count > 0) { for (int i = 0; i < boardNodes.Count; i++) { if (boardNodes[i].boardState == _currentBoard) { existingNodeFound = true; baseNode = boardNodes[i]; break; } } } boardNodes = new List <BoardNode>(); if (existingNodeFound && !baseNode.IsEndNode()) { boardNodes.AddRange(baseNode.GetChildren()); } else { foreach (StoneMove m in shuffledList) { Board testBoard = _currentBoard.Clone(); testBoard.ResolveMove(m); BoardNode bn = new BoardNode(testBoard, 3 - _aiPlayer, m); boardNodes.Add(bn); } } foreach (BoardNode bn in boardNodes) { bool prevStateFound = false; foreach (Board b in CheckersMain.prevStates) { if (b == bn.boardState) { prevStateFound = true; } } float moveValue = Mathf.NegativeInfinity; if (!prevStateFound) { moveValue = Search.TraverseNodeList(bn, searchDepth - 1, Mathf.NegativeInfinity, Mathf.Infinity, _aiPlayer, false, this, 0); } if (moveValue >= 1 - accuracyMod) { ADRASMoveList.Add(bn); } if (moveValue > selectedMoveValue) { selectedMove = bn.GetMoveMade(); selectedMoveValue = moveValue; } } if (otherPlayer == PlayerType.Human) { List <BoardNode> newNodeList = new List <BoardNode>(0); foreach (BoardNode bn in boardNodes) { if (!bn.IsEndNode()) { newNodeList.AddRange(bn.GetChildren()); } } boardNodes = newNodeList; } } if (selectedMoveValue > 1 - accuracyMod) { selectedMove = ADRASMoveList.OrderBy(item => rnd.Next()).First().GetMoveMade(); } _move = selectedMove; return(true); } else { FFData data; GetBoardRating(_currentBoard, _aiPlayer, out data); return(false); } }
public virtual bool PerformTurn(Board _currentBoard, int _aiPlayer, PlayerType otherPlayer, bool _firstTurn, out StoneMove _move, int _presetFirstMove) { //initialize board node list if it isn't already if (boardNodes == null) { boardNodes = new List <BoardNode>(); } //Placeholder move in case no valid moves are found _move = new StoneMove(); //Generate list of possible moves for board state List <StoneMove> possibleMoves = FindAllValidMoves(_currentBoard, _aiPlayer, true); //Shuffle the list System.Random rnd = new System.Random(); List <StoneMove> shuffledList = possibleMoves.OrderBy(item => rnd.Next()).ToList(); if (shuffledList.Count > 0) { //set selected move to first move in the list & the value to infinity, this will likely be overwritten immediately. StoneMove selectedMove = possibleMoves[0]; float selectedMoveValue = -Mathf.Infinity; //If its the first turn, run some extra processing if (_firstTurn) { FFData temp; //Find the initial board value for the player. This is used for dynamic difficulty AI's float boardVal = GetBoardRating(_currentBoard, _aiPlayer, out temp); InitBoardVal[_aiPlayer - 1] = boardVal; //If player is black, select the preset first move from the list and exit. if (_aiPlayer == 1) { if (_presetFirstMove >= 0 && _presetFirstMove < possibleMoves.Count && !GameManager.DEMO) { _move = possibleMoves[_presetFirstMove]; } else { _move = shuffledList.First(); } return(true); } } //Main body else { bool existingNodeFound = false; BoardNode baseNode = new BoardNode(_currentBoard, _aiPlayer); //If we already have a list of board nodes to use the attempt to locate the current board in the list. if (boardNodes.Count > 0) { for (int i = 0; i < boardNodes.Count; i++) { if (boardNodes[i].boardState == _currentBoard) { existingNodeFound = true; baseNode = boardNodes[i]; break; } } } //Refresh board node list boardNodes = new List <BoardNode>(); //If we found a node, add the nodes children to the board node list if (existingNodeFound && !baseNode.IsEndNode()) { boardNodes.AddRange(baseNode.GetChildren()); } //otherwise, generate a new node from this board and add that nodes children to the list else { foreach (StoneMove m in shuffledList) { Board testBoard = _currentBoard.Clone(); testBoard.ResolveMove(m); BoardNode bn = new BoardNode(testBoard, 3 - _aiPlayer, m); boardNodes.Add(bn); } } //Go through the board nodes and begin search foreach (BoardNode bn in boardNodes) { bool prevStateFound = false; foreach (Board b in CheckersMain.prevStates) { if (b == bn.boardState) { prevStateFound = true; } } float moveValue = Mathf.NegativeInfinity; if (!prevStateFound) { moveValue = Search.TraverseNodeList(bn, searchDepth - 1, Mathf.NegativeInfinity, Mathf.Infinity, _aiPlayer, false, this, 0); } if (moveValue > selectedMoveValue) { selectedMove = bn.GetMoveMade(); selectedMoveValue = moveValue; } } //If the other player is human. Then the next board state will be skipped, so next board node list has to be 2 ply away. if (otherPlayer == PlayerType.Human) { List <BoardNode> newNodeList = new List <BoardNode>(0); foreach (BoardNode bn in boardNodes) { if (!bn.IsEndNode()) { newNodeList.AddRange(bn.GetChildren()); } } boardNodes = newNodeList; } } _move = selectedMove; return(true); } else { FFData data; GetBoardRating(_currentBoard, _aiPlayer, out data); return(false); } }
//Tests for any further captures that are possible and returns list of all further necessary captures. static private bool TestFurtherMoves(Board _board, int _activePlayer, StoneMove _initialMove, ref List <StoneMove> _foundMoves) { Board tempBoard = _board.Clone(); tempBoard.ResolveMove(_initialMove); int newPos = _initialMove.endPos; TileState state = tempBoard.state[newPos]; int enemyPlayer = 3 - _activePlayer; List <int> tempCaps = new List <int>(); bool moveFound = false; int enemyPos, nextPos; for (int i = 4; i <= 5; i++) { if (state == TileState.BlackKing || state == TileState.BlackPiece || state == TileState.WhiteKing) { enemyPos = newPos + i; nextPos = enemyPos + i; if (tempBoard.GetOwner(enemyPos) == enemyPlayer && tempBoard.GetOwner(nextPos) == 0) { moveFound = true; tempCaps.Clear(); tempCaps.AddRange(_initialMove.capturedStones); tempCaps.Add(enemyPos); StoneMove newMove = new StoneMove(_initialMove.startPos, nextPos, true, tempCaps, state); if (!TestFurtherMoves(_board, _activePlayer, newMove, ref _foundMoves)) { _foundMoves.Add(newMove); } } } if (state == TileState.BlackKing || state == TileState.WhitePiece || state == TileState.WhiteKing) { enemyPos = newPos - i; nextPos = enemyPos - i; if (tempBoard.GetOwner(enemyPos) == enemyPlayer && tempBoard.GetOwner(nextPos) == 0) { moveFound = true; tempCaps.Clear(); tempCaps.AddRange(_initialMove.capturedStones); tempCaps.Add(enemyPos); StoneMove newMove = new StoneMove(_initialMove.startPos, nextPos, true, tempCaps, state); if (!TestFurtherMoves(_board, _activePlayer, newMove, ref _foundMoves)) { _foundMoves.Add(newMove); } } } } if (!moveFound) { return(false); } else { return(true); } }
protected static bool TestMove(Board _board, int _owner, int _startPos, int _movePos, ref bool _captureFound, ref bool _firstCap, List <StoneMove> _moves, bool _capChains) { //First ensure target position is within the bounds of the board. if (_movePos > 34 || _movePos < 0 || _movePos == 8 || _movePos == 17 || _movePos == 26) { return(false); } TileState targetState = _board.state[_movePos]; //If target tile is occupied by a stone owned by the same player, move is not valid. if (_owner == 1 && (targetState == TileState.BlackKing || targetState == TileState.BlackPiece) || _owner == 2 && (targetState == TileState.WhiteKing || targetState == TileState.WhitePiece)) { return(false); } //If target tile is empty then move is allowed. if (targetState == TileState.Empty) { if (_captureFound) { return(false); } _moves.Add(new StoneMove(_startPos, _movePos, false, 0)); return(true); } //If we have gotten this far then the tile must be occupied by an enemy! Now we test if there is an unoccupied tile behind them int endPos = _movePos + (_movePos - _startPos); //Double check we're still within the board bounds. if (endPos > 34 || endPos < 0 || endPos == 8 || endPos == 17 || endPos == 26) { return(false); } //Final check, if the tile beyond the enemy is empty then they are capturable! But we have to check for further captures that are possible if (_board.state[endPos] == TileState.Empty) { _captureFound = true; if (_firstCap) { _moves.Clear(); _firstCap = false; } StoneMove _move = new StoneMove(_startPos, endPos, true, _movePos); if (!_capChains) { _moves.Add(_move); } else if (!TestFurtherMoves(_board, _owner, _move, ref _moves)) { _moves.Add(_move); } return(true); } //If we get this far then there are no more checks to do. It is not a valid move. return(false); }
// Use this for initialization void Start() { objectalpha = stoneRef.GetComponent <StoneMove>(); this.GetComponent <Image>().color = new Color(1.0f, 1.0f, 1.0f, 0.0f); }