//Constructor for making a new board public TTTBoard(int lengthOfBoard, int winAmnt) { amountForWin = winAmnt; boardLength = lengthOfBoard; board = new TTTSquare[boardLength][]; //List of random priorities to distribute to the board squares List <int> randomPriorities = new List <int>(); for (int i = 0; i < boardLength * boardLength; ++i) { randomPriorities.Add(i); } //initializing an array of arrays for (int i = 0; i < boardLength; ++i) { board[i] = new TTTSquare[boardLength]; for (int j = 0; j < boardLength; ++j) { //Priorities are randomly given to allow for greater board diversity //Each priority is a unique number from 0-8 int priority = randomPriorities[Random.Range(0, randomPriorities.Count)]; board[i][j] = new TTTSquare(priority); randomPriorities.Remove(priority); } } availableMoves = lengthOfBoard * lengthOfBoard; SetWinConditions(); SetSymmetries(); }
//for creating duplicates public TTTSquare(TTTSquare duplicateSquare) { state = duplicateSquare.state; priority = duplicateSquare.priority; affectedConditions = new List <TTTWinCondition>(); symmetries = new List <TTTIndividualSymmetry>(); }
//Add a physical playing piece to the board. Also checks if a piece already existed there. public void PlaceOnSquare(AbstractPlayer ap) { if (MainGame.currentPlayer != ap) { ap.lastValidity = MoveValidity.NOT_YOUR_TURN; return; } //Size of board - to account for modularity. int bSize = MainGame.gameBoard.boardLength; TTT.TTTSquare selectedSquare = MainGame.gameBoard.board[MySquareNumber / bSize][MySquareNumber % bSize]; //Determines legality of move. //Ordinarily you'd deny the player to move illegally, but I found it more fun to let it happen //The game halts if you attempt an illegal move, and the AI throws a table bool legal = (selectedSquare.state == TTT.SquareState.Empty); //Uses the clickable square's number to find its location on the abstract game board, and set its state to X or O MainGame.gameBoard.SetSquareState(new Vector2Int(MySquareNumber / bSize, MySquareNumber % bSize), ap.playingAs); //Instantiate piece on the board square you click on. y value adjusts according to if a piece already exists, to avoid Z fighting. //Pieces are offset slightly on the X and Z axes, to add better feel to the game GamePiece newPiece = Instantiate(ap.piece, transform.position + new Vector3(Random.Range(-moveSpread, moveSpread), myPieces.Count * 0.03f, Random.Range(-moveSpread, moveSpread)), transform.rotation); FlippableSymbol flippable = newPiece.GetComponent <FlippableSymbol>(); newPiece.SetPlaced(); //Set the flippable object as 'placed' on the board, so it can be flipped later if (flippable != null) { flippable.placed = true; } myPieces.Add(newPiece); //inform player of legality if (legal) { ap.lastValidity = MoveValidity.LEGAL; } else { ap.lastValidity = MoveValidity.SQUARE_ALREADY_OCCUPIED; } }
//Constructor to duplicate boards, such that the AI does not modify the existing board public TTTBoard(TTTBoard toDuplicate) { amountForWin = toDuplicate.amountForWin; boardLength = toDuplicate.boardLength; board = new TTTSquare[toDuplicate.board.Length][]; //Sets the board squares to be the same as the previous board for (int i = 0; i < boardLength; ++i) { board[i] = new TTTSquare[boardLength]; for (int j = 0; j < boardLength; ++j) { board[i][j] = new TTTSquare(toDuplicate.board[i][j]); } } availableMoves = toDuplicate.availableMoves; SetWinConditions(); SetSymmetries(); }
//Upon adding a square to check, it also tells the square to add itself to that square's affectedConditions list public void AddCheck(TTTSquare square) { checks.Add(square); square.affectedConditions.Add(this); amountPer[square.state] += 1; }