// Call for actuall updating the visual aspect of the game private void PlayPiece(GameSquare gameSquare) { // update our boards visualBoard.Find(query => query.isGameSquareEqualByPosition(gameSquare)).piece = new GamePiece(currentTurn); playedOn.Add(gameSquare); GameObject piece = (GameObject)Instantiate(Resources.Load("Model_Piece")); piece.transform.parent = gameObject.transform; piece.transform.localPosition = new Vector3(gameSquare.centerX, PIECE_STARTING_HEIGHT, gameSquare.centerZ); piece.AddComponent <ModelPiece>(); piece.GetComponent <ModelPiece>().setInfo(new GamePiece(currentTurn)); if (currentTurn == Player.white) { Debug.Log("White's move"); piece.transform.Rotate(new Vector3(180, 0, 0)); currentTurn = Player.black; opponent = Player.white; } else { Debug.Log("Black's move"); currentTurn = Player.white; opponent = Player.black; } piece.AddComponent <Rigidbody>(); piece.GetComponent <Rigidbody>().isKinematic = true; bestMoveOn = true; PlayedAI = false; }
private void FlipPieces(List <GameSquare> toFlip) { ModelPiece[] pieces = FindObjectsOfType <ModelPiece>(); foreach (GameSquare square in toFlip) { Debug.Log("need to flip at: " + square.centerX + ", " + square.centerZ); } foreach (ModelPiece piece in pieces) { if (piece.pieceInfo.ownedBy == opponent) { //Debug.Log("Found an opponent piece " + piece.name + " in the field at: " + piece.transform.localPosition.x + ", " + piece.transform.localPosition.z); GameSquare spot = toFlip.Find(square => Math.Abs(square.centerX - piece.transform.localPosition.x) < .0001 && Math.Abs(square.centerZ - piece.transform.localPosition.z) < .0001); if (spot != null) { // flip the piece piece.pieceInfo.ownedBy = currentTurn; piece.flip = true; // update the spot info spot.piece.ownedBy = currentTurn; } } } }
public bool isGameSquareEqualByPosition(GameSquare gameSquare) { if (gameSquare.centerX == this.centerX && gameSquare.centerZ == this.centerZ) { return(true); } return(false); }
public GameSquare(GameSquare square) { this.centerX = square.centerX; this.centerZ = square.centerZ; this.value = square.value; if (square.piece != null) { this.piece = new GamePiece(square.piece.ownedBy); } }
private List <GameSquare> GetToCaptureList(GameSquare clicked, bool realTime, Player currentPlayer, List <GameSquare> board) { // if it is not next to an opponent square, no good Player opposingPlayer = GetOpposingPlayer(currentPlayer); // just get the squares List <GameSquare> surroundingSquaresWithPieces = GetSurroundingSquaresWithPieces(clicked, board); // if no pieces on surrounding squares, no good if (surroundingSquaresWithPieces.Count == 0) { // Debug.Log("no pieces nearby"); return(new List <GameSquare>()); } else { // Debug.Log("surrounding squares with pieces: " + surroundingSquaresWithPieces.Count); } // retrieve surrounding squares with opponent pieces List <GameSquare> surroundingOpponentSquares = GetSurroundingOpponentSquares(clicked, surroundingSquaresWithPieces, currentPlayer, opposingPlayer); // if no surrounding pieces are opponent pieces, nod good if (surroundingOpponentSquares.Count == 0) { // Debug.Log("uh oh, this spot is not next to an opponent location"); return(new List <GameSquare>()); } else { // Debug.Log("surround squares next to opponent: " + surroundingOpponentSquares.Count); } // if oppenent's square would not not enclosed in any direction by another // of your pieces, spot is not a legal move List <GameSquare> toFlip = GetPiecesToFlip(clicked, surroundingOpponentSquares, opposingPlayer, board); if (toFlip.Count > 0) { // Debug.Log("legal move, will capture: " + toFlip.Count); if (realTime) { FlipPieces(toFlip); } return(toFlip); } else { // Debug.Log("not gonna capture anything :("); return(new List <GameSquare>()); } }
public RelativePosition GetRelativePositionTo(GameSquare clicked) { RelativePosition relativePosition = RelativePosition.error; // square up & to the left of clicked if (this.centerX == clicked.centerX - 1 && this.centerZ == clicked.centerZ - 1) { relativePosition = RelativePosition.upAndLeft; } // square above clicked if (this.centerX == clicked.centerX - 1 && this.centerZ == clicked.centerZ) { relativePosition = RelativePosition.up; } // square up & to the right of clicked if (this.centerX == clicked.centerX - 1 && this.centerZ == clicked.centerZ + 1) { relativePosition = RelativePosition.upAndRight; } // square to the left of clicked if (this.centerX == clicked.centerX && this.centerZ == clicked.centerZ - 1) { relativePosition = RelativePosition.left; } // square to the right of clicked if (this.centerX == clicked.centerX && this.centerZ == clicked.centerZ + 1) { relativePosition = RelativePosition.right; } // square below & to the left of clicked if (this.centerX == clicked.centerX + 1 && this.centerZ == clicked.centerZ - 1) { relativePosition = RelativePosition.downAndLeft; } // square below of clicked if (this.centerX == clicked.centerX + 1 && this.centerZ == clicked.centerZ) { relativePosition = RelativePosition.down; } // square below & to the right of clicked if (this.centerX == clicked.centerX + 1 && this.centerZ == clicked.centerZ + 1) { relativePosition = RelativePosition.downAndRight; } return(relativePosition); }
private List <GameSquare> GetSurroundingOpponentSquares(GameSquare clicked, List <GameSquare> surroundingSquaresWithPieces, Player currentPlayer, Player opposingPlayer) { List <GameSquare> surroundingOpponentSquares = new List <GameSquare>(); foreach (GameSquare gameSquare in surroundingSquaresWithPieces) { if (gameSquare.piece.ownedBy == opposingPlayer) { surroundingOpponentSquares.Add(gameSquare); } } return(surroundingOpponentSquares); }
private void PlayUser() { // someone's turn if (Input.GetMouseButtonDown(0) && !anyFlipping) { RaycastHit hit; Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit, 100)) { Debug.Log(hit.point); GameSquare clicked = FindGameSquareClicked(hit.point); if (clicked != null) { if (clicked.piece != null) { // if not null, square already occupied // Debug.Log("Cannot play on an already occupied square"); } else { List <GameSquare> move = GetToCaptureList(clicked, true, currentTurn, visualBoard); // only attempt to play if it's a legal move if (move.Count > 0) { // attempt to play PlayPiece(clicked); // update the score UpdateScoreVisuals(); } } } else { // Debug.Log("Could not find game square, please try to click again"); } if (Input.GetMouseButton(1)) { ConcedeTurn(); } } } }
public GameSquare GetNextSquare(RelativePosition relativePosition) { GameSquare nextToCheck = new GameSquare(); switch (relativePosition) { case RelativePosition.upAndLeft: nextToCheck = new GameSquare(this.centerX - 1, this.centerZ - 1); break; case RelativePosition.up: nextToCheck = new GameSquare(this.centerX - 1, this.centerZ); break; case RelativePosition.upAndRight: nextToCheck = new GameSquare(this.centerX - 1, this.centerZ + 1); break; case RelativePosition.left: nextToCheck = new GameSquare(this.centerX, this.centerZ - 1); break; case RelativePosition.right: nextToCheck = new GameSquare(this.centerX, this.centerZ + 1); break; case RelativePosition.downAndLeft: nextToCheck = new GameSquare(this.centerX + 1, this.centerZ - 1); break; case RelativePosition.down: nextToCheck = new GameSquare(this.centerX + 1, this.centerZ); break; case RelativePosition.downAndRight: nextToCheck = new GameSquare(this.centerX + 1, this.centerZ + 1); break; } return(nextToCheck); }
private List <GameSquare> GetSurroundingSquaresWithPieces(GameSquare clicked, List <GameSquare> board) { // initial positions float current_x = clicked.centerX - 1; float current_z = clicked.centerZ - 1; // intialize surrounding squares List <GameSquare> surroundingSquares = new List <GameSquare>(); // find any squares that are next to this one for (int i = 0; i < 3; i++) { current_z = clicked.centerZ - 1; for (int j = 0; j < 3; j++) { GameSquare toFind = new GameSquare(current_x, current_z); GameSquare currentSquare = board.Find(gameSquare => gameSquare.isGameSquareEqualByPosition(toFind)); if (currentSquare != null) { surroundingSquares.Add(currentSquare); } current_z++; } current_x++; } // find squares surrounding this square with game pieces on them List <GameSquare> surroundingSquaresWithPieces = surroundingSquares.FindAll(gameSquare => gameSquare.piece != null); // if no pieces are surrounding this square, return empty list if (surroundingSquaresWithPieces == null) { return(new List <GameSquare>()); } return(surroundingSquaresWithPieces); }
public Move(GameSquare centerSquare, List <GameSquare> toFlip, float value) { this.centerSquare = centerSquare; this.toFlip = toFlip; valueOfMove = value; }
private GameSquare FindGameSquareClicked(Vector3 point) { GameSquare toReturn = visualBoard.Find(gameSquare => gameSquare.isPointInside(point)); return(toReturn); }
private List <GameSquare> GetPiecesToFlip(GameSquare clicked, List <GameSquare> surroundingOpponentSquares, Player opposingPlayer, List <GameSquare> board) { List <GameSquare> toFlip = new List <GameSquare>(); // check to the left of clicked foreach (GameSquare square in surroundingOpponentSquares) { // next in line is a var for holding the next square in the line (logic done in GameSquare) GameSquare nextInLine = square; // set up a temporary to flip list List <GameSquare> tempFlip = new List <GameSquare>(); // used for checking if the temp flips should actually be added or not bool isLegal = false; // continue until we hit a piece of our own or there are no pieces played at the next space while (nextInLine != null && nextInLine.piece != null) { // logic for deciding what to do with the current piece // we know there is a piece played, therefore it is either ours or their's if (nextInLine.piece.ownedBy == opposingPlayer) { tempFlip.Add(nextInLine); } else { // stop once we hit our own piece isLegal = true; break; } // logic for getting next in line for next iteration // get next relative position GameSquare.RelativePosition relativePosition = square.GetRelativePositionTo(clicked); // if not an error, do logic if (relativePosition != GameSquare.RelativePosition.error) { // retrieve coordinates of the next square GameSquare coordinatesOfNext = nextInLine.GetNextSquare(relativePosition); // actually find it on the board nextInLine = board.Find(gameSquare => gameSquare.isGameSquareEqualByPosition(coordinatesOfNext)); } else { Debug.Log("there was an error in finding relative position"); return(new List <GameSquare>()); } } // only add the temp if we ran into another of our pieces in the search if (isLegal) { toFlip.AddRange(tempFlip); } } return(toFlip); }
// Use this for initialization void Start() { // set current turn currentTurn = Player.black; opponent = Player.white; float x_position = STARTING_X; float z_position = STARTING_Z; for (int i = 0; i < 8; i++) { String vals = ""; z_position = STARTING_Z; for (int j = 0; j < 8; j++) { GameSquare toAdd = new GameSquare(x_position, z_position); vals += " " + toAdd.value; // if an intial game piece, make sure we assign the right player to it // intial white positions if ((x_position == -.5 && z_position == -.5) || (x_position == .5 && z_position == .5)) { toAdd.piece = new GamePiece(Player.white); } // intial black position if ((x_position == .5 && z_position == -.5) || (x_position == -.5 && z_position == .5)) { toAdd.piece = new GamePiece(Player.black); } if (toAdd.piece != null) { playedOn.Add(toAdd); } visualBoard.Add(toAdd); // DEBUG //if (toAdd.piece != null) //{ // Debug.Log(x_position + ", " + z_position + ": " + toAdd.piece.ownedBy); //} //else //{ // Debug.Log(x_position + ", " + z_position); //} z_position++; } // making sure my weights are correct // Debug.Log(vals); x_position++; } UpdateScoreVisuals(); TextMesh[] meshes = FindObjectsOfType <TextMesh>(); foreach (TextMesh mesh in meshes) { if (mesh.name.Equals("GAME OVER")) { GameOverMesh = mesh; } if (mesh.name.Equals("Depth")) { DepthMesh = mesh; } } mySlider = FindObjectOfType <Slider>(); MainCamera = FindObjectOfType <Camera>(); }
private GameState NegaMax(GameState gameState, int depth, int helpNega, Player currentPlayer, Player opposingPlayer, float alpha, float beta) { // do nega max GameState bestGameState = gameState; // UpdateScoreVisuals(); // Debug.Log("post flip score: " + blackScore + ", " + whiteScore); bool endOfGame = CheckForEndGame(gameState.board); if (depth == this.depth && endOfGame) { //Debug.Log("hmmm"); } List <Move> legalMoves = GenerateLegalMoves(currentPlayer, gameState.board); if (depth == 0 || endOfGame) { if (endOfGame) { float thisScore = gameState.board.FindAll(gameSquare => gameSquare.piece != null && gameSquare.piece.ownedBy == currentPlayer).Count; float theirScore = gameState.board.FindAll(gameSquare => gameSquare.piece != null && gameSquare.piece.ownedBy == opposingPlayer).Count; if (thisScore > theirScore) { gameState.valueOfState = 1000000000f; } else { gameState.valueOfState = .1f; } } gameState.valueOfState *= helpNega; return(gameState); } float bestVal = float.MinValue; if (legalMoves.Count == 0) { return(gameState); } IEnumerable <Move> orderedLegalMoves = legalMoves.OrderBy(move => move.valueOfMove); Debug.Log("there are " + legalMoves.Count + " legal moves for " + currentPlayer); foreach (Move move in orderedLegalMoves) { GameState nextGameState = new GameState(); // create next game state from original game state nextGameState.board = new List <GameSquare>(); nextGameState.board = gameState.board.ConvertAll(gameSquare => new GameSquare(gameSquare)); nextGameState.associatedMove = new Move(move); nextGameState.valueOfState = move.centerSquare.value * (move.toFlip.Count); nextGameState.firstMoveToGetHere = new Move(); if (depth == this.depth) { // Debug.Log(move.centerSquare.centerZ + ", " + move.centerSquare.centerX); nextGameState.firstMoveToGetHere = new Move(move); } else { nextGameState.firstMoveToGetHere = new Move(gameState.firstMoveToGetHere); } //// "play" the move on the new game board GameSquare placeToPlay = nextGameState.board.Find(gameSquare => gameSquare.isGameSquareEqualByPosition(move.centerSquare)); placeToPlay.piece = new GamePiece(currentPlayer); List <GameSquare> toCaptureList = GetToCaptureList(placeToPlay, false, currentPlayer, nextGameState.board); foreach (GameSquare square in toCaptureList) { square.piece.ownedBy = currentPlayer; } // update the score on the new game state nextGameState.blackScore = nextGameState.board.FindAll(gameSquare => gameSquare.piece != null && gameSquare.piece.ownedBy == Player.black).Count; nextGameState.whiteScore = nextGameState.board.FindAll(gameSquare => gameSquare.piece != null && gameSquare.piece.ownedBy == Player.white).Count; // send that new game state to the next round of negamax GameState returnedGameState = new GameState(); returnedGameState = NegaMax(nextGameState, depth - 1, -helpNega, opposingPlayer, currentPlayer, -beta, -alpha); // negate the returned value returnedGameState.valueOfState = -returnedGameState.valueOfState; float returnedVal = returnedGameState.valueOfState; Debug.Log("returned val: " + returnedVal); if (returnedVal > bestVal) { bestGameState = returnedGameState; bestVal = returnedVal; } if (returnedVal > alpha) { alpha = returnedVal; } if (alpha > beta) { break; } } return(bestGameState); }
// Update is called once per frame void Update() { depth = (int)mySlider.value; DepthMesh.text = depth.ToString(); if (Input.GetKeyDown("p") && !movingCamera) { if (paused) { Debug.Log("display game"); paused = false; } else { Debug.Log("display menu"); paused = true; } movingCamera = true; } if (movingCamera) { if (currentCameraPosition == .13f) { MainCamera.transform.position -= new Vector3(0, 0, .5f); if (MainCamera.transform.position.z <= -20.14f) { currentCameraPosition = -20.14f; MainCamera.transform.position = new Vector3(MainCamera.transform.position.x, MainCamera.transform.position.y, currentCameraPosition); movingCamera = false; } } else { MainCamera.transform.position += new Vector3(0, 0, .5f); if (MainCamera.transform.position.z >= .13) { currentCameraPosition = .13f; MainCamera.transform.position = new Vector3(MainCamera.transform.position.x, MainCamera.transform.position.y, currentCameraPosition); movingCamera = false; } } } bool endOfGame = false; if (!checkedForEndGame) { endOfGame = CheckForEndGame(visualBoard); checkedForEndGame = true; } // Debug.Log("played on: " + playedOn.Count); // check if the player can move List <Move> currentLegalMoves = GenerateLegalMoves(currentTurn, visualBoard); if (currentLegalMoves.Count == 0) { Debug.Log("Conceding turn"); ConcedeTurn(); } anyFlipping = false; ModelPiece[] pieces = GetComponentsInChildren <ModelPiece>(); foreach (ModelPiece piece in pieces) { if (piece.flip) { anyFlipping = true; break; } } if (!paused && !endOfGame && !anyFlipping) { //Debug.Log(AIOn + " | " + PlayedAI); if (AIOn && currentTurn == Player.white) // { Debug.Log("Playing AI"); Move toPlay = new Move(); toPlay = PlayAI(); if (toPlay != null) { List <GameSquare> toFlip = new List <GameSquare>(); // we want to actually update our board foreach (GameSquare square in toPlay.toFlip) { toFlip.Add(visualBoard.Find(gameSquare => gameSquare.isGameSquareEqualByPosition(square))); } // find the one on our board GameSquare ourMove = visualBoard.Find(gameSquare => gameSquare.isGameSquareEqualByPosition(toPlay.centerSquare)); // update visuals FlipPieces(toFlip); PlayPiece(ourMove); UpdateScoreVisuals(); } else { ConcedeTurn(); } } else { if (bestMoveOn) { DisplaySomeMoves(); bestMoveOn = false; } PlayUser(); } } if (endOfGame) { if (blackScore > whiteScore) { GameOverMesh.text = "YOU WIN!"; GameOverMesh.color = Color.green; } GameOverMesh.transform.localPosition = new Vector3(-1.21f, GameOverMesh.transform.localPosition.y, GameOverMesh.transform.localPosition.z); } checkedForEndGame = false; }