using UnityEngine; using UnityEngine.UI; namespace AngelsDemons { /* Specific struct used to keep track of information on each of the * board's white spaces. */ public struct WhiteSpace { public Image img; public int spriteindex; }; /* Static functions that help when manipulating or obtaining information * from the board outside of BoardManager. */ public class Board { private static bool gameover = false; // Keep references for when MakeMove() is called. private static int[] spaces = new int[4]; // Indexes relative to whitespaces[] of the spaces being changed. private static int[] sprites = new int[4]; // Which sprite to change the space to. private static bool movemade = false; // Fix to keep ChangeSpaces() from being called every frame. // Reset the spaces array to all -1 values. This means they will be ignored if they somehow // get passed to a function that tries to change spaces. public static void ResetSpaces() { for(int i = 0; i < spaces.Length; ++i) { spaces[i] = -1; } } // See above, but for the sprites array. public static void ResetSprites() { for(int i = 0; i < sprites.Length; ++i) { sprites[i] = -1; } } public static void SetSpaces(int i, int v) { spaces[i] = v; } public static int GetSpaces(int i) { return spaces[i]; } public static void SetSprites(int i, int v) { sprites[i] = v; } public static int GetSprites(int i) { return sprites[i]; } public static void SetMoveMade(bool b) { movemade = b; } public static int GetSpacesLength() { return spaces.Length; } public static int GetSpritesLength() { return sprites.Length; } public static bool GetMoveMade() { return movemade; } public static void EndGame() { gameover = true; } public static void StartGame() { gameover = false; } public static bool IsGameOver() { return gameover; } // Convert a given button index in the blackspaces[] array to board coordinates. // These need to made more modular in the future to support // different board sizes. public static Vector2 ConvertButtonIndex(int i) { Vector2 temp; temp.x = (i*2)%11; temp.y = 0; switch(i) { case 0: case 1: case 2: case 3: case 4: case 5: return temp; case 6: case 7: case 8: case 9: case 10: temp.y = 1; return temp; case 11: case 12: case 13: case 14: case 15: case 16: temp.y = 2; return temp; case 17: case 18: case 19: case 20: case 21: temp.y = 3; return temp; case 22: case 23: case 24: case 25: case 26: case 27: temp.y = 4; return temp; case 28: case 29: case 30: case 31: case 32: temp.y = 5; return temp; case 33: case 34: case 35: case 36: case 37: case 38: temp.y = 6; return temp; case 39: case 40: case 41: case 42: case 43: temp.y = 7; return temp; case 44: case 45: case 46: case 47: case 48: case 49: temp.y = 8; return temp; case 50: case 51: case 52: case 53: case 54: temp.y = 9; return temp; case 55: case 56: case 57: case 58: case 59: case 60: temp.y = 10; return temp; default: return temp; } } // Convert a given set of board coordinates to the corresponding whitespaces[] array index. public static int ConvertImageIndex(Vector2 bc) { int i = 0; switch(Mathf.RoundToInt(bc.y)) { case 0: i = (Mathf.RoundToInt(bc.x) - 1)/2; break; case 1: i = (Mathf.RoundToInt(bc.x))/2; i += 5; break; case 2: i = (Mathf.RoundToInt(bc.x) - 1)/2; i += 11; break; case 3: i = (Mathf.RoundToInt(bc.x))/2; i += 16; break; case 4: i = (Mathf.RoundToInt(bc.x) - 1)/2; i += 22; break; case 5: i = (Mathf.RoundToInt(bc.x))/2; i += 27; break; case 6: i = (Mathf.RoundToInt(bc.x) - 1)/2; i += 33; break; case 7: i = (Mathf.RoundToInt(bc.x))/2; i += 38; break; case 8: i = (Mathf.RoundToInt(bc.x) - 1)/2; i += 44; break; case 9: i = (Mathf.RoundToInt(bc.x))/2; i += 49; break; case 10: i = (Mathf.RoundToInt(bc.x) - 1)/2; i += 55; break; default: break; } return i; } } // UNFINISHED // Functions and structs to help keep track of player info. public class Player { // Private players variable, used to keep track of which player has which spaces. // Should later be defined as a struct in a separate namespace. private static int[] players = new int[2]; // Function call to return what the indexed player's space choice is. public static int getPlayer(int n) { return players[n]; } /* Function called at the beginning of a game to set the player spaces * and reset the turn counter. * * This function should later be called by a manager script of some * kind that handles menu navigation/logistics between games and other * activity outside of the main game. */ public static void StartGame(int playerchoice) { players[0] = playerchoice; switch(playerchoice) { case 1: players[1] = 2; break; case 2: players[1] = 1; break; default: Debug.Log("Invalid Player Choice!"); return; } GameLogic.ResetTurn(); } } /* Class defined to detail functions that determine how the game is played, * in essence, this class defines the fundamental rules of the game, * and the functions inside help determine how to handle situations * that arise throughout the game. */ public class GameLogic { // Private static turn limit value. private static int turnlimit = 10; public static int GetTurnLimit() { return turnlimit; } public static void SetTurnLimit(int l) { turnlimit = l; } // Private static turn counter. private static int turn = 1; // UNUSED // Static function that returns the current turn count. public static int GetTurn() { return turn; } /* Used to reset the turn counter at the beginning of every game. * Needs to be at the beginning because I want to continue displaying * or having the turn counter saved until I can be sure there is a new * game starting. */ public static void ResetTurn() { turn = 1; } /* This function is directly called by the BoardManager when a move is attempted, * and determines what spaces will be changed to what based on the game's rules. * This is goverened by the following: * - Which player's turn it is (which sprite to change to) * - What the space's sprite already is * - Whether the move is legal based on the game's rules */ public static void MakeMove(Vector2 bc, int numberofspaces, WhiteSpace[] whitespaces) { // Function call to determine which spaces will be changed, see definition below. DetermineSpacesChanged(bc, numberofspaces); // Function call to determine which sprites the spaces will change to, see definition below. DetermineSpritesChanged(whitespaces); // Increment the turn counter. EndTurn(); // Tell BoardManager that the move is finished. Board.SetMoveMade(true); } /* This function determines which spaces *can* be changed based on the board's * limitations. */ private static void DetermineSpacesChanged(Vector2 bc, int numberofspaces) { // Used to check adjacent spaces without changing the bc reference passed in. Vector2 tempbc = bc; // "White Space Index", holder variable to save the return of converting from // board coordinates to the equivalent index in the whitespaces array. int wsi = 0; /* Intricate set of if/elseif statements to determine which moves are * legate according to the board's size values. */ if(bc.x > 0 && bc.x < (numberofspaces - 1)) { if(bc.y > 0) { /* Debug.Log( "changing space:" + (bc.x) + " " + (bc.y - 1) ); */ tempbc = bc; tempbc.y -= 1; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(3, wsi); } if(bc.y < (numberofspaces - 1)) { /* Debug.Log( "changing space:" + (bc.x) + " " + (bc.y + 1) ); */ tempbc = bc; tempbc.y += 1; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(1, wsi); } /* Debug.Log( "changing spaces:" + (bc.x - 1) + " " + (bc.y) + "\t" + (bc.x + 1) + " " + (bc.y) ); */ tempbc = bc; tempbc.x -= 1; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(0, wsi); tempbc.x += 2; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(2, wsi); } else if(bc.y > 0 && bc.y < (numberofspaces - 1)) { if(bc.x == 0) { /* Debug.Log( "changing space:" + (bc.x + 1) + " " + (bc.y) ); */ tempbc = bc; tempbc.x += 1; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(2, wsi); } if(bc.x == (numberofspaces - 1)) { /* Debug.Log( "changing space:" + (bc.x - 1) + " " + (bc.y) ); */ tempbc = bc; tempbc.x -= 1; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(0, wsi); } /* Debug.Log( "changing spaces:" + (bc.x) + " " + (bc.y - 1) + "\t" + (bc.x) + " " + (bc.y + 1) ); */ tempbc = bc; tempbc.y -= 1; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(3, wsi); tempbc.y += 2; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(1, wsi); } else { if(bc.x == 0) { /* Debug.Log( "changing space:" + (bc.x + 1) + " " + (bc.y) ); */ tempbc = bc; tempbc.x += 1; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(2, wsi); } if(bc.x == (numberofspaces - 1)) { /* Debug.Log( "changing space:" + (bc.x - 1) + " " + (bc.y) ); */ tempbc = bc; tempbc.x -= 1; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(0, wsi); } if(bc.y > 0) { /* Debug.Log( "changing space:" + (bc.x) + " " + (bc.y - 1) ); */ tempbc = bc; tempbc.y -= 1; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(3, wsi); } if(bc.y < (numberofspaces - 1)) { /* Debug.Log( "changing space:" + (bc.x) + " " + (bc.y + 1) ); */ tempbc = bc; tempbc.y += 1; wsi = Board.ConvertImageIndex(tempbc); Board.SetSpaces(1, wsi); } } } /* After determining which spaces are legal to change based on the board's limitations, * this function is called to determine what sprites those spaces will change to, given * current state of the game and the game's rule set. */ private static void DetermineSpritesChanged(WhiteSpace[] whitespaces) { int currentplayerturn = (turn -1) % 2; for(int i = 0; i < Board.GetSpacesLength(); ++i) { // If this is a legal move. No need for an else statement, since if it's not, // it will already be ignored by the BoardManager. if(Board.GetSpaces(i) >= 0 && Board.GetSpaces(i) < whitespaces.Length) { // Check what space's sprite is currently set to, then set sprites[i] // to the sprite to be changed to, according to the game's rules. switch(whitespaces[Board.GetSpaces(i)].spriteindex) { case 0: if(currentplayerturn != 0) { Board.SetSprites(i, 2); } break; case 1: if(currentplayerturn != 1) { Board.SetSprites(i, 2); } break; case 2: Board.SetSprites(i, currentplayerturn); break; default: Debug.Log("Illegal sprite index!"); return; } } } } /* This should be called to increment the turn counter at the end of every turn. * This is at the end because if an illegal move is made or some other rule is * broken, it will keep the turn counter from being incremented unnecessarily. * E.g. don't increment if the turn isn't actually over. */ private static void EndTurn() { ++turn; } } /* Class that will be used to define functions and needed static * variables that determine how the enemy AI will play. * Most likely going to be a simple min-max a/b pruning function * with multiple options for difficulty. */ public class BotLogic { // TODO } /* Class that will be used to handle various menu navigations, * UI displays, setting up games, ending games, keeping track * of scores, and other UI and navigation functionality. */ public class MenuNav { // TODO } }