/// <summary> /// Enumerates all possible moves that could be made for the given board. /// </summary> private List <SquareTypes[, ]> getAllPossibleNextBoards(SquareTypes[,] board, SquareTypes squareType) { List <SquareTypes[, ]> possibleBoards = new List <SquareTypes[, ]>(); for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { // Skip squares that are taken. if (board[i, j] != SquareTypes.N) { continue; } // Create the new board. SquareTypes[,] possibleBoard = new SquareTypes[3, 3]; Array.Copy(board, possibleBoard, 9); // Set the possible move. possibleBoard[i, j] = squareType; // Add the possible board to the list of boards. possibleBoards.Add(possibleBoard); } } return(possibleBoards); }
public GameForm() { InitializeComponent(); _randomPlayer = new RandomPlayer(); _optimalPlayer = new OptimalPlayer(SquareTypes.O); _neatPlayer = new NeatPlayer(null, SquareTypes.O); _aiSquareType = SquareTypes.O; _humanSquareType = SquareTypes.X; _game = new TicTacToeGame(); // Set the AI to the random player by default. _ai = _randomPlayer; // Experiment classes encapsulate much of the nuts and bolts of setting up a NEAT search. _experiment = new TicTacToeExperiment(); _hyperNeatExperiment = new TicTacToeHyperNeatExperiment(); // Load config XML for the NEAT experiment. XmlDocument xmlConfig = new XmlDocument(); xmlConfig.Load("tictactoe.config.xml"); _experiment.Initialize("TicTacToe", xmlConfig.DocumentElement); // Load config XML for the HyperNEAT experiment. xmlConfig = new XmlDocument(); xmlConfig.Load("hyperneat.config.xml"); _hyperNeatExperiment.Initialize("TicTacToe", xmlConfig.DocumentElement); }
public static SquareTypes[,] GetBoardFromString(string boardString) { var lineTokens = boardString.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); Debug.Assert(lineTokens.Length == 3, "Invalid board string:\n" + boardString + "\n"); var tokens = new string[9]; var line = lineTokens[0].Trim().Split('|'); Debug.Assert(line.Length == 3); line.CopyTo(tokens, 0); line = lineTokens[1].Trim().Split('|'); Debug.Assert(line.Length == 3); line.CopyTo(tokens, 3); line = lineTokens[2].Trim().Split('|'); Debug.Assert(line.Length == 3); line.CopyTo(tokens, 6); Debug.Assert(tokens.Length == 9, "Invalid board string:\n" + boardString + "\n"); SquareTypes[,] board = new SquareTypes[3, 3]; board[0, 0] = getSquareType(tokens[0]); board[1, 0] = getSquareType(tokens[1]); board[2, 0] = getSquareType(tokens[2]); board[0, 1] = getSquareType(tokens[3]); board[1, 1] = getSquareType(tokens[4]); board[2, 1] = getSquareType(tokens[5]); board[0, 2] = getSquareType(tokens[6]); board[1, 2] = getSquareType(tokens[7]); board[2, 2] = getSquareType(tokens[8]); return board; }
public RiverMaker(IBrickRepo brick_repo, IBrickRiverPartSelector part_selector) { _brick_repo = brick_repo; _part_selector = part_selector; _water_config = MapConfig.GetSquareConfigurations().First(x => x.Type == SquareTypes.Water); _sea_type = SquareTypes.Sea; }
private bool DoesBrickFitOnMap(SquareTypes current_type, MapSquare[,] map, int start_x, int start_z, int size_x, int size_z) { if (map.GetLength(0) < (start_x + size_x)) { return(false); } if (map.GetLength(1) < (start_z + size_z)) { return(false); } for (int z = start_z; z < (start_z + size_z); z++) { for (int x = start_x; x < (start_x + size_x); x++) { if (map[x, z].Type != current_type) { return(false); } } } return(true); }
public void GetBoardFromStringTest() { string boardString = @" | | | | | | "; SquareTypes[,] expected = new SquareTypes[3, 3]; SquareTypes[,] actual; actual = TicTacToeGame.GetBoardFromString(boardString); AssertEqualBoards(expected, actual); boardString = @"X| |O |O| X| |X"; expected[0, 0] = SquareTypes.X; expected[1, 0] = SquareTypes.N; expected[2, 0] = SquareTypes.O; expected[0, 1] = SquareTypes.N; expected[1, 1] = SquareTypes.O; expected[2, 1] = SquareTypes.N; expected[0, 2] = SquareTypes.X; expected[1, 2] = SquareTypes.N; expected[2, 2] = SquareTypes.X; actual = TicTacToeGame.GetBoardFromString(boardString); AssertEqualBoards(expected, actual); }
/// <summary> /// create obstacle on the square /// </summary> /// <param name="obstacleType"></param> /// <param name="obLayer"></param> public void CreateObstacle(SquareTypes obstacleType, int obLayer) { if (obstacleType == SquareTypes.SpiralBlock) { GenSpiral(); return; } var prefabs = GetBlockPrefab(obstacleType); for (var i = 0; i < obLayer; i++) { var prefab = prefabs[i]; var b = Instantiate(prefab); b.transform.SetParent(transform); Square square = b.GetComponent <Square>(); square.field = field; b.transform.localPosition = new Vector3(0, 0, -0.5f); b.transform.localScale = Vector2.one; LevelManager.THIS.levelData.SetSquareTarget(b, obstacleType, prefab); // if (prefab != null && obstacleType == SquareTypes.ThrivingBlock) // Destroy(prefab.gameObject); if (obstacleType != SquareTypes.JellyBlock) { subSquares.Add(b.GetComponent <Square>()); } else { subSquares.Insert(0, b.GetComponent <Square>()); } type = GetSubSquare().type; undestroyable = square.undestroyable; } }
public Item GenItem(bool falling = true) { if (type == SquareTypes.STATIC_COLOR && colorToGen == 0) { type = SquareTypes.EMPTY; return(null); } if (IsNone() && !CanGoInto()) { return(null); } GameObject item = Instantiate(LevelManager.THIS.itemPrefab) as GameObject; item.transform.localScale = Vector2.one * 0.6f; item.GetComponent <Item>().square = this; //if (!falling) // item.GetComponent<Item>().anim.SetTrigger("reAppear"); item.transform.SetParent(transform.parent); if (falling) { item.transform.position = transform.position + Vector3.back * 0.2f + Vector3.up * 3f; item.GetComponent <Item>().justCreatedItem = true; } else { item.transform.position = transform.position + Vector3.back * 0.2f; } this.item = item.GetComponent <Item>(); return(this.item); }
public Square(Canvas canvas, SquareTypes st, int row, int col) { this.canvas = canvas; Row = row; Col = col; NewSquare(st); DrawSquare(); }
/// <summary> /// Sets the human's square type to O and the AI's square type to X. /// </summary> private void oToolStripMenuItem_Click(object sender, EventArgs e) { _humanSquareType = SquareTypes.O; _optimalPlayer.SquareType = SquareTypes.X; _neatPlayer.SquareType = SquareTypes.X; _aiSquareType = SquareTypes.X; xToolStripMenuItem.Checked = false; oToolStripMenuItem.Checked = true; }
private double getInputForSquareType(SquareTypes squareTypes) { if (squareTypes == SquareTypes.N) { return(0); } if (squareTypes == SquareType) { return(1); } return(-1); }
/// <summary> /// Returns the score for a game. Scoring is 10 for a win, 1 for a draw /// and 0 for a loss. Note that scores cannot be smaller than 0 because /// NEAT requires the fitness score to be positive. /// </summary> private int getScore(SquareTypes winner, SquareTypes neatSquareType) { if (winner == neatSquareType) { return(10); } if (winner == SquareTypes.N) { return(1); } return(0); }
public Move GetMove(SquareTypes[,] board) { int x = random.Next(3); int y = random.Next(3); while (board[x, y] != SquareTypes.N) { x = random.Next(3); y = random.Next(3); } return new Move(x, y); }
public static int GetLayersCount(SquareTypes sqType) { var layers = 1; var item1 = Resources.Load("Blocks/" + sqType) as GameObject; layers = item1?.GetComponent <LayeredBlock>()?.layers?.Length ?? 0; if (layers == 0) { layers = 1; } return(layers); }
/// <summary> /// Returns the score for a game. Scoring is 10 for a win, 1 for a draw /// and 0 for a loss. Note that scores cannot be smaller than 0 because /// NEAT requires the fitness score to be positive. /// </summary> private double getScore(SquareTypes winner, SquareTypes neatSquareType) { if (winner == neatSquareType) { return(neatSquareType == SquareTypes.X ? 2 : 10); } if (winner == SquareTypes.N) { return(neatSquareType == SquareTypes.X ? 1 : 2); } return(0); }
public void SetSquareTarget(GameObject gameObject, SquareTypes _sqType, GameObject prefabLink) { if (_sqType.ToString().Contains(target.name)) { var subTargetContainer = subTargetsContainers.FirstOrDefault(i => _sqType.ToString().Contains(i.targetPrefab.name)); if (subTargetContainer == null) { Debug.LogError("Check Target Editor for " + _sqType); } subTargetContainer.changeCount(1); gameObject.AddComponent <TargetComponent>(); } }
private void NewSquare(SquareTypes st) { switch (st) { case SquareTypes.Maroon: this.fill = new SolidColorBrush(Colors.Maroon); this.border = new SolidColorBrush(Colors.LightGray); break; case SquareTypes.Silver: this.fill = new SolidColorBrush(Colors.Silver); this.border = new SolidColorBrush(Colors.DarkGray); break; case SquareTypes.Purple: this.fill = new SolidColorBrush(Colors.Purple); this.border = new SolidColorBrush(Colors.LightGray); break; case SquareTypes.Blue: this.fill = new SolidColorBrush(Colors.DarkBlue); this.border = new SolidColorBrush(Colors.LightGray); break; case SquareTypes.Green: this.fill = new SolidColorBrush(Colors.Green); this.border = new SolidColorBrush(Colors.DarkGray); break; case SquareTypes.Brown: this.fill = new SolidColorBrush(Colors.Brown); this.border = new SolidColorBrush(Colors.White); break; case SquareTypes.Teal: this.fill = new SolidColorBrush(Colors.Teal); this.border = new SolidColorBrush(Colors.White); break; default: throw new InvalidOperationException(); } this.rect = new Rectangle { Fill = this.fill, Stroke = this.border, Width = 20, Height = 20 }; }
// Converts the square type into an integer value. // We use 1 for our squares, -1 for opponent squares, // and 0 for empty squares. private int squareToInt(SquareTypes square) { if (square == SquareType) { return(1); } if (square == SquareTypes.N) { return(0); } return(-1); }
private static void PlayVSHuman() { int inputCount = 9; int outputCount = 9; int depth = 3; int hiddenNeuronsPerLayer = 5; TicTacToeGame game = new TicTacToeGame(); NeuralPlayer champion = MakeNeuralPlayer(inputCount, outputCount, depth, hiddenNeuronsPerLayer, new DNA(bestDNA)); champion.SquareType = SquareTypes.X; SquareTypes winner = SquareTypes.N; for (int moveNum = 0; moveNum < 9 && winner == SquareTypes.N; moveNum++) { Console.WriteLine($"+- Turn {moveNum + 1} -+"); TicTacToeGame.DisplayBoard(game.Board); SquareTypes curSquareType; Move move; if (moveNum % 2 == 1) { curSquareType = SquareTypes.O; move = AskHumanForMove(); } else { curSquareType = SquareTypes.X; move = champion.GetMove(game.Board); } if (game.IsEmpty(move.X, move.Y)) { game.Board[move.X, move.Y] = curSquareType; } else { Console.WriteLine($"Player {curSquareType.ToString()} tried to use non-empty space [{move.X}, {move.Y}]"); } if (moveNum > 3) { winner = game.GetWinner(); } } Console.WriteLine($"The winner is {winner.ToString()}"); }
/// <summary> /// Methods for the editor /// </summary> /// <param name="sqType"></param> /// <returns></returns> public static GameObject[] GetBlockPrefab(SquareTypes sqType) { var list = new List <GameObject>(); var item1 = Resources.Load("Blocks/" + sqType) as GameObject; if (item1?.GetComponent <LayeredBlock>() != null) { list.AddRange(item1.GetComponent <LayeredBlock>().layers.Select(i => i.gameObject)); } if (list.Count() == 0 && item1 != null) { list.Add(item1); } return(list.ToArray()); }
/// <summary> /// Gets the next move as dictated by the neural network. /// </summary> public Move GetMove(SquareTypes[,] board) { // Clear the network Brain.ResetState(); // Convert the game board into an input array for the network setInputSignalArray(Brain.InputSignalArray, board); // Activate the network Brain.Activate(); // Find the highest-scoring available move Move move = null; double max = double.MinValue; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { // If the square is taken, skip it. if (board[i, j] != SquareTypes.N) continue; // Set the score for this square. double score = Brain.OutputSignalArray[i * 3 + j]; // If this is the first available move we've found, // set it to the current best. if (move == null) { move = new Move(i, j); max = score; } // If this square has a higher score than any we've // found, set it to the current best. else if (max < score) { move.X = i; move.Y = j; max = score; } } return move; }
/// <summary> /// A helper method for competing two players against each other. /// </summary> /// <param name="xPlayer">The player to act first.</param> /// <param name="oPlayer">The player to act second.</param> /// <returns> /// The square type of the winner, or SquareTypes.N if the game /// was a draw. /// </returns> public static SquareTypes PlayGameToEnd(IPlayer xPlayer, IPlayer oPlayer) { TicTacToeGame game = new TicTacToeGame(); SquareTypes winner = SquareTypes.N; // Play until we have a winner or the game board is full. for (int moveNum = 0; moveNum < 9 && winner == SquareTypes.N; moveNum++) { IPlayer curPlayer; SquareTypes curSquareType; // Determine if it's X's or O's turn to act. if (moveNum % 2 == 0) { curPlayer = xPlayer; curSquareType = SquareTypes.X; } else { curPlayer = oPlayer; curSquareType = SquareTypes.O; } // Get the next move from the current player. var move = curPlayer.GetMove(game.Board); // Check to make sure the player's move is legal. Debug.Assert(game.IsEmpty(move.X, move.Y), "Player tried to make an illegal move!"); // Set the board to the player's move. game.Board[move.X, move.Y] = curSquareType; // Start checking if we have a winner once xPlayer has made // at least 3 moves. if (moveNum > 3) { winner = game.GetWinner(); } } // Return the square type of the winner, or SquareTypes.N if it was a draw. return(winner); }
private static Square GetSquare(char type) { SquareTypes squareType = (SquareTypes)type; switch (squareType) { case SquareTypes.PermanentObstacle: return(new Obstacle(false)); case SquareTypes.DestructableObstacle: return(new Obstacle(true)); case SquareTypes.Goal: return(new Goal()); case SquareTypes.North: return(new Directional(Compass.North)); case SquareTypes.South: return(new Directional(Compass.South)); case SquareTypes.East: return(new Directional(Compass.East)); case SquareTypes.West: return(new Directional(Compass.West)); case SquareTypes.Beer: return(new Beer()); case SquareTypes.Inverter: return(new Inverter()); case SquareTypes.Teleporter: return(new Teleport()); case SquareTypes.Blunder: default: return(new Square()); } }
/// <summary> /// Gets a random game board played for a specified /// number of moves. /// </summary> public static SquareTypes[,] GetRandomBoard(int moves) { Debug.Assert(moves < 10); SquareTypes[,] board = new SquareTypes[3, 3]; Random random = new Random(); for (int i = 0; i < moves; i++) { int next = random.Next(9); while (board[next / 3, next % 3] != SquareTypes.N) { next = random.Next(9); } board[next / 3, next % 3] = i % 2 == 0 ? SquareTypes.X : SquareTypes.O; } return(board); }
public static Tuple<SquareTypes, int> PlayGameToEnd(IPlayer xPlayer, IPlayer oPlayer) { TicTacToeGame game = new TicTacToeGame(); SquareTypes winner = SquareTypes.N; int moveNum; for (moveNum = 0; moveNum < 9 && winner == SquareTypes.N; moveNum++) { //Console.WriteLine($"+- Turn {moveNum+1} -+"); IPlayer curPlayer; SquareTypes curSquareType; if (moveNum % 2 == 0) { curPlayer = xPlayer; curSquareType = SquareTypes.X; } else { curPlayer = oPlayer; curSquareType = SquareTypes.O; } var move = curPlayer.GetMove(game.Board); if (game.IsEmpty(move.X, move.Y)) game.Board[move.X, move.Y] = curSquareType; //else //return new Tuple<SquareTypes, int>(curSquareType == SquareTypes.X ? SquareTypes.O : SquareTypes.X, moveNum); if (moveNum > 3) winner = game.GetWinner(); //DisplayBoard(game.Board); } return new Tuple<SquareTypes, int>(winner, moveNum); }
public void SetType(SquareTypes _type, int sqLayer, SquareTypes obstacleType, int obLayer) { var prefabs = GetBlockPrefab(_type); if (type != _type && !IsTypeExist(_type)) { for (var i = 0; i < sqLayer; i++) { var prefab = prefabs[i]; if (prefab != null && _type != SquareTypes.EmptySquare && _type != SquareTypes.NONE) { var b = Instantiate(prefab); LevelManager.THIS.levelData.SetSquareTarget(b, _type, prefab); b.transform.SetParent(transform); b.GetComponent <Square>().field = field; b.transform.localScale = Vector2.one; b.transform.localPosition = new Vector3(0, 0, -0.01f); b.GetComponent <SpriteRenderer>().sortingOrder = 0 + i + GetComponent <SpriteRenderer>().sortingOrder; if (_type != SquareTypes.JellyBlock) { subSquares.Add(b.GetComponent <Square>()); } else { subSquares.Insert(0, b.GetComponent <Square>()); } type = GetSubSquare().type; } } } if (obstacleType != SquareTypes.NONE) { CreateObstacle(obstacleType, obLayer); } }
/// <summary> /// destroy block (obstacle or jelly) /// </summary> public void DestroyBlock() { if (destroyIteration == 0) { destroyIteration = LevelManager.THIS.destLoopIterations; LeanTween.delayedCall(1, () => { destroyIteration = 0; }); } else { return; } if (GetSubSquare().undestroyable) { return; } if (LevelManager.THIS.DebugSettings.DestroyLog) { DebugLogKeeper.Log("DestroyBlock " + " " + type + " " + GetInstanceID(), DebugLogKeeper.LogType.Destroying); } if (GetSubSquare().CanGoInto()) { var sqList = GetAllNeghborsCross(); foreach (var sq in sqList) { if (!sq.GetSubSquare().CanGoInto() || (sq.Item?.currentType == ItemsTypes.SPIRAL && Item?.currentType != ItemsTypes.SPIRAL)) { sq.DestroyBlock(); } } } if (Item?.currentType == ItemsTypes.SPIRAL) { Item.DestroyItem(); } if (subSquares.Count > 0) { var subSquare = GetSubSquare(); if (type == SquareTypes.JellyBlock) { return; } if (subSquare.GetComponent <TargetComponent>() == null) { SoundBase.Instance.PlayOneShot(SoundBase.Instance.block_destroy); var itemAnim = new GameObject(); var animComp = itemAnim.AddComponent <AnimateItems>(); animComp.InitAnimation(subSquare.gameObject, new Vector2(transform.position.x, -5), subSquare.transform.localScale, null); } LevelManager.THIS.levelData.GetTargetObject().CheckSquare(new[] { this }); LevelManager.THIS.ShowPopupScore(subSquare.score, transform.position, 0); subSquares.Remove(subSquare); Destroy(subSquare.gameObject); subSquare = GetSubSquare(); if (subSquares.Count > 0) { type = subSquare.type; } if (subSquares.Count == 0) { type = SquareTypes.EmptySquare; } } if (IsFree() && Item == null) { Item = null; } }
public TicTacToeGame() { Board = new SquareTypes[3, 3]; }
/// <summary> /// Is type exist among sub-squares /// </summary> /// <param name="_type"></param> /// <returns></returns> private bool IsTypeExist(SquareTypes _type) { return(subSquares.Count(i => i.type == _type) > 0); }
/// <summary> /// Takes a string description of a game board and returns the board array. /// A valid board example is: /// X|O|X /// |X| /// O|X|O /// /// Note that there should be a space in blank squares. /// </summary> public static SquareTypes[,] GetBoardFromString(string boardString) { var lineTokens = boardString.Split(new [] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); Debug.Assert(lineTokens.Length == 3, "Invalid board string:\n" + boardString + "\n"); var tokens = new string[9]; var line = lineTokens[0].Trim().Split('|'); Debug.Assert(line.Length == 3); line.CopyTo(tokens, 0); line = lineTokens[1].Trim().Split('|'); Debug.Assert(line.Length == 3); line.CopyTo(tokens, 3); line = lineTokens[2].Trim().Split('|'); Debug.Assert(line.Length == 3); line.CopyTo(tokens, 6); Debug.Assert(tokens.Length == 9, "Invalid board string:\n" + boardString + "\n"); SquareTypes[,] board = new SquareTypes[3, 3]; board[0, 0] = getSquareType(tokens[0]); board[1, 0] = getSquareType(tokens[1]); board[2, 0] = getSquareType(tokens[2]); board[0, 1] = getSquareType(tokens[3]); board[1, 1] = getSquareType(tokens[4]); board[2, 1] = getSquareType(tokens[5]); board[0, 2] = getSquareType(tokens[6]); board[1, 2] = getSquareType(tokens[7]); board[2, 2] = getSquareType(tokens[8]); return board; }
public static Texture2D GetSquareTexture(SquareTypes sqType) { return(GetBlockPrefab(sqType)?.First().GetComponent <SpriteRenderer>()?.sprite?.texture); }
/// <summary> /// Creates a new NEAT player with the specified brain. /// </summary> public NeatPlayer(IBlackBox brain, SquareTypes squareType) { Brain = brain; SquareType =squareType; }
/// <summary> /// Sets the human's square type to X and the AI's square type to O. /// </summary> private void xToolStripMenuItem_Click(object sender, EventArgs e) { _humanSquareType = SquareTypes.X; _optimalPlayer.SquareType = SquareTypes.O; _neatPlayer.SquareType = SquareTypes.O; _aiSquareType = SquareTypes.O; xToolStripMenuItem.Checked = true; oToolStripMenuItem.Checked = false; }
public Move GetMove(SquareTypes[,] board) { TicTacToeGame.GetWinner(board); int moveNum = 0; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) if (board[i, j] != SquareTypes.N) moveNum++; //first move is always a corner if (moveNum == 0) return new Move(0, 0); //second move should be the center if free, else a corner if (moveNum == 1) { if (board[1, 1] == SquareTypes.N) return new Move(1, 1); return new Move(0, 0); } //make a winning move if possible for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { if (board[i, j] != SquareTypes.N) continue; board[i, j] = SquareType; var winner = TicTacToeGame.GetWinner(board); board[i, j] = SquareTypes.N; if (winner == SquareType) return new Move(i, j); } //if we can't win, check if there are any moves that we have to make //to prevent ourselves from losing for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { if (board[i, j] != SquareTypes.N) continue; //set the move to the opponent's type board[i, j] = SquareType == SquareTypes.X ? SquareTypes.O : SquareTypes.X; var winner = TicTacToeGame.GetWinner(board); board[i, j] = SquareTypes.N; //if the opponent will win by moving here, move here to block them if (winner != SquareTypes.N) return new Move(i, j); } //if we're here, that means we have made at least 1 move already and can't win //nor lose in 1 move, so just make the optimal play which would be to a free //corner that isn't blocked Move move = null; int max = -1; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { if (board[i, j] != SquareTypes.N) continue; board[i, j] = SquareType; int count = 0; for (int m = 0; m < 3; m++) for (int n = 0; n < 3; n++) { if (board[m, n] != SquareTypes.N) continue; board[m, n] = SquareType; var winner = TicTacToeGame.GetWinner(board); board[m, n] = SquareTypes.N; if (winner == SquareType) count++; } board[i, j] = SquareTypes.N; if (count > max) { move = new Move(i, j); max = count; } } return move; }
public OptimalPlayer(SquareTypes type) { SquareType = type; }
/// <summary> /// Gets the winner based on the specified board. /// </summary> /// <param name="Board"></param> /// <returns> /// The SquareType of the winner, or SquareTypes.N /// if no one has won yet or there's a draw. /// </returns> public static SquareTypes GetWinner(SquareTypes[,] Board) { if (Board[0, 0] != SquareTypes.N) { var type = Board[0, 0]; //top left to bottom left if (type == Board[0, 1] && type == Board[0, 2]) return type; //top left to top right if (type == Board[1, 0] && type == Board[2, 0]) return type; //top left to bottom right if (type == Board[1, 1] && type == Board[2, 2]) return type; } if (Board[0, 2] != SquareTypes.N) { var type = Board[0, 2]; //bottom left to top right if (type == Board[1, 1] && type == Board[2, 0]) return type; //bottom left to bottom right if (type == Board[1, 2] && type == Board[2, 2]) return type; } if (Board[0, 1] != SquareTypes.N) { var type = Board[0, 1]; //middle left to middle right if (type == Board[1, 1] && type == Board[2, 1]) return type; } if (Board[1, 0] != SquareTypes.N) { var type = Board[1, 0]; //middle top to middle bottom if (type == Board[1, 1] && type == Board[1, 2]) return type; } if (Board[2, 0] != SquareTypes.N) { var type = Board[2, 0]; //top right to bottom right if (type == Board[2, 1] && type == Board[2, 2]) return type; } return SquareTypes.N; }
// Converts the square type into an integer value. // We use 1 for our squares, -1 for opponent squares, // and 0 for empty squares. private int squareToInt(SquareTypes square) { if (square == SquareType) return 1; if (square == SquareTypes.N) return 0; return -1; }
public void DestroyBlock() { if (type == SquareTypes.UNDESTROYABLE) { return; } if (type != SquareTypes.SOLIDBLOCK && type != SquareTypes.THRIVING) { List <Square> sqList = GetAllNeghbors(); foreach (Square sq in sqList) { if (sq.type == SquareTypes.SOLIDBLOCK || sq.type == SquareTypes.THRIVING) { sq.DestroyBlock(); } } } if (block.Count > 0) { if (type == SquareTypes.BLOCK) { LevelManager.THIS.CheckCollectedTarget(gameObject.transform.Find("Block(Clone)").gameObject); LevelManager.THIS.PopupScore(LevelManager.THIS.scoreForBlock, transform.position, 0); LevelManager.THIS.TargetBlocks--; block[block.Count - 1].GetComponent <SpriteRenderer>().enabled = false; } if (type == SquareTypes.WIREBLOCK) { LevelManager.THIS.PopupScore(LevelManager.THIS.scoreForWireBlock, transform.position, 0); } if (type == SquareTypes.SOLIDBLOCK) { LevelManager.THIS.PopupScore(LevelManager.THIS.scoreForSolidBlock, transform.position, 0); } if (type == SquareTypes.THRIVING) { LevelManager.THIS.PopupScore(LevelManager.THIS.scoreForThrivingBlock, transform.position, 0); LevelManager.Instance.thrivingBlockDestroyed = true; } //Destroy( block[block.Count-1]); if (type != SquareTypes.BLOCK) { SoundBase.Instance.GetComponent <AudioSource>().PlayOneShot(SoundBase.Instance.block_destroy); block[block.Count - 1].GetComponent <Animation>().Play("BrickRotate"); block[block.Count - 1].GetComponent <SpriteRenderer>().sortingOrder = 4; block[block.Count - 1].AddComponent <Rigidbody2D>(); block[block.Count - 1].GetComponent <Rigidbody2D>().AddRelativeForce(new Vector2(Random.insideUnitCircle.x * Random.Range(30, 200), Random.Range(100, 150)), ForceMode2D.Force); } GameObject.Destroy(block[block.Count - 1], 1.5f); if (block.Count > 1) { type = SquareTypes.BLOCK; } block.Remove(block[block.Count - 1]); if (block.Count == 0) { type = SquareTypes.EMPTY; } } }
// Loads the board into the input signal array. // This just flattens the 2d board into a 1d array. private void setInputSignalArray(ISignalArray inputArr, SquareTypes[,] board) { inputArr[0] = squareToInt(board[0, 0]); inputArr[1] = squareToInt(board[1, 0]); inputArr[2] = squareToInt(board[2, 0]); inputArr[3] = squareToInt(board[0, 1]); inputArr[4] = squareToInt(board[1, 1]); inputArr[5] = squareToInt(board[2, 1]); inputArr[6] = squareToInt(board[0, 2]); inputArr[7] = squareToInt(board[1, 2]); inputArr[8] = squareToInt(board[2, 2]); }
private void AssertEqualBoards(SquareTypes[,] expected, SquareTypes[,] actual) { Assert.AreEqual(expected[0, 0], actual[0, 0]); Assert.AreEqual(expected[1, 0], actual[1, 0]); Assert.AreEqual(expected[2, 0], actual[2, 0]); Assert.AreEqual(expected[0, 1], actual[0, 1]); Assert.AreEqual(expected[1, 1], actual[1, 1]); Assert.AreEqual(expected[2, 1], actual[2, 1]); Assert.AreEqual(expected[0, 2], actual[0, 2]); Assert.AreEqual(expected[1, 2], actual[1, 2]); Assert.AreEqual(expected[2, 2], actual[2, 2]); }
/// <summary> /// Gets a random game board played for a specified /// number of moves. /// </summary> public static SquareTypes[,] GetRandomBoard(int moves) { Debug.Assert(moves < 10); SquareTypes[,] board = new SquareTypes[3, 3]; Random random = new Random(); for (int i = 0; i < moves; i++) { int next = random.Next(9); while (board[next / 3, next % 3] != SquareTypes.N) next = random.Next(9); board[next / 3, next % 3] = i % 2 == 0 ? SquareTypes.X : SquareTypes.O; } return board; }
static private bool isWater(SquareTypes intype) { return(intype == SquareTypes.Water || intype == SquareTypes.Sea); }
public void GetBoardFromStringTest() { string boardString = @" | | | | | | "; SquareTypes[,] expected = new SquareTypes[3,3]; SquareTypes[,] actual; actual = TicTacToeGame.GetBoardFromString(boardString); AssertEqualBoards(expected, actual); boardString = @"X| |O |O| X| |X"; expected[0, 0] = SquareTypes.X; expected[1, 0] = SquareTypes.N; expected[2, 0] = SquareTypes.O; expected[0, 1] = SquareTypes.N; expected[1, 1] = SquareTypes.O; expected[2, 1] = SquareTypes.N; expected[0, 2] = SquareTypes.X; expected[1, 2] = SquareTypes.N; expected[2, 2] = SquareTypes.X; actual = TicTacToeGame.GetBoardFromString(boardString); AssertEqualBoards(expected, actual); }