using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class BoardManager : MonoBehaviour { // Global reference to the canvas' width and height. private float canvaswidth; private float canvasheight; // Variable to change spacing of the board from the edges of the canvas. private float canvasspacing = 80f; public Image board; // Board size references. private float boardwidth; private float boardheight; // Might want to make this part modular in the future. private int numberofspaces = 11; // Spaces for the board need to be spawned and resized based on canvas. private float spacespacing; public Button blackspaceasset; public Transform blackspacetransform; public Image whitespaceasset; public Transform whitespacetransform; // Image assets for the board spaces. public Sprite angelsprite; public Sprite demonsprite; public Sprite emptysprite; // Should later be defined in a separate namespace. public struct WhiteSpace { public Image img; public int spriteindex; }; // Keep references of all the space GameObjects. private Button[] blackspaces = new Button[61]; private WhiteSpace[] whitespaces = new WhiteSpace[60]; // Keep references for when MakeMove() is called. private int[] spaces = new int[4]; // Indexes relative to whitespaces[] of the spaces being changed. private int[] sprites = new int[4]; // Which sprite to change the space to. public bool movemade = false; // Fix to keep ChangeSpaces() from being called every frame. // Use this for initialization void Start () { canvasheight = this.GetComponentInParent().rect.height; canvaswidth = this.GetComponentInParent().rect.width; boardheight = board.GetComponent().rect.height; boardwidth = board.GetComponent().rect.width; spacespacing = ((canvaswidth - canvasspacing)/11f); SpawnInitialBoard(); ResetSpaces(); ResetSprites(); } // Grab the current canvas dimentions, used for dynamic resizing checks. private Vector2 GetCurrentCanvas() { Vector2 output; output.x = this.GetComponentInParent().rect.height; output.y = this.GetComponentInParent().rect.width; return output; } // 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. private void ResetSpaces() { for(int i = 0; i < spaces.Length; ++i) { spaces[i] = -1; } } // See above, but for the sprites array. private void ResetSprites() { for(int i = 0; i < sprites.Length; ++i) { sprites[i] = -1; } } // Function call to return one Instantiated Button object. // Should be changed along with SpawnWhiteSpace to instead spawn the object and attach them // to a defined struct that can also hold the index of the spawned object. This will allow // for easier indexing of these prefabs in the future without the need for parsing. private Button SpawnBlackSpace(int i) { Button bsbutton; bsbutton = Instantiate(blackspaceasset, blackspacetransform); bsbutton.name += "" + i; bsbutton.onClick.AddListener(delegate{ButtonAction(bsbutton);}); return bsbutton; } // Function call to return one Instantiated Image object. private Image SpawnWhiteSpace() { Image wsimage; wsimage = Instantiate(whitespaceasset, whitespacetransform); return wsimage; } // Set up an empty board, sized to the current canvas. private void SpawnInitialBoard() { for(int i = 0; i < blackspaces.Length; ++i) { Button temp; temp = SpawnBlackSpace(i); temp.GetComponent().sizeDelta = new Vector2(spacespacing, spacespacing); float x = (spacespacing*i*2 + (temp.GetComponent().rect.width / 2f)) % (boardwidth) - ((boardwidth) / 2f); float y = (boardheight / 2f) - ((temp.GetComponent().rect.height / 2f) + spacespacing*(Mathf.Floor(i/(11f/2f)))); temp.transform.localPosition = new Vector3(x, y, 0); blackspaces[i] = temp; if(i < blackspaces.Length - 1) { WhiteSpace tempws; Image tempimage; tempimage = SpawnWhiteSpace(); tempimage.GetComponent().sizeDelta = new Vector2(spacespacing, spacespacing); tempimage.sprite = emptysprite; x = (spacespacing*i*2 + (tempimage.GetComponent().rect.width / 2f)*3) % (boardwidth) - ((boardwidth) / 2f); y = (boardheight / 2f) - ((tempimage.GetComponent().rect.height / 2f) + spacespacing*(Mathf.Floor((i + 1)/(11.01f/2f)))); tempimage.transform.localPosition = new Vector3(x, y, 0); tempws.img = tempimage; tempws.spriteindex = 2; whitespaces[i] = tempws; } } } // Update the board's scale according to the current canvas size, call UpdatePieceScale(). private void UpdateBoardScale() { canvasheight = this.GetComponentInParent().rect.height; canvaswidth = this.GetComponentInParent().rect.width; if(canvaswidth > canvasheight) { board.rectTransform.sizeDelta = new Vector2(canvasheight - canvasspacing, canvasheight - canvasspacing); } else { board.rectTransform.sizeDelta = new Vector2(canvaswidth - canvasspacing, canvaswidth - canvasspacing); } boardheight = board.GetComponent().rect.height; boardwidth = board.GetComponent().rect.width; spacespacing = ((boardwidth)/11f); UpdatePieceScale(); } // Update the pieces' scales according to the current canvas size. private void UpdatePieceScale() { for(int i = 0; i < blackspaces.Length; ++i) { Button temp = blackspaces[i]; temp.GetComponent().sizeDelta = new Vector2(spacespacing, spacespacing); float x = (spacespacing*i*2 + (temp.GetComponent().rect.width / 2f)) % (boardwidth) - ((boardwidth) / 2f); float y = (boardheight / 2f) - ((temp.GetComponent().rect.height / 2f) + spacespacing*(Mathf.Floor(i/(11f/2f)))); temp.transform.localPosition = new Vector3(x, y, 0); blackspaces[i] = temp; if(i < blackspaces.Length - 1) { Image tempimage = whitespaces[i].img; tempimage.GetComponent().sizeDelta = new Vector2(spacespacing, spacespacing); x = (spacespacing*i*2 + (tempimage.GetComponent().rect.width / 2f)*3) % (boardwidth) - ((boardwidth) / 2f); y = (boardheight / 2f) - ((tempimage.GetComponent().rect.height / 2f) + spacespacing*(Mathf.Floor((i + 1)/(11.01f/2f)))); tempimage.transform.localPosition = new Vector3(x, y, 0); whitespaces[i].img = tempimage; } } } // Change the passed in space indexes' sprites to the specified sprites. private void ChangeSpaces(int[] spaces, int[] sprites) { for(int i = 0; i < spaces.Length; ++i) { if(spaces[i] >= 0 && spaces[i] < whitespaces.Length) { switch(sprites[i]) { case 0: whitespaces[spaces[i]].img.sprite = angelsprite; whitespaces[spaces[i]].spriteindex = 0; break; case 1: whitespaces[spaces[i]].img.sprite = demonsprite; whitespaces[spaces[i]].spriteindex = 1; break; case 2: whitespaces[spaces[i]].img.sprite = emptysprite; whitespaces[spaces[i]].spriteindex = 2; break; default: break; } } } // After a move has been made, since right now spaces are checked every frame, // change all spaces[] values to -1 to avoid sprites being updated every frame. ResetSpaces(); ResetSprites(); movemade = false; } /* Update is called once per frame * Here we check if the current canvas has changed and if so, call UpdateBoardScale(), * then we also check if a move has been made, and call ChangeSpaces with the necessary parameters. */ void Update () { Vector2 currentcanvas = GetCurrentCanvas(); if(currentcanvas.x != canvaswidth || currentcanvas.y != canvasheight) { UpdateBoardScale(); } if(movemade) { ChangeSpaces(spaces, sprites); } } // Function definition to specify what the buttons should do when pressed, which is to call // the GameManager.MakeMove() function with the necessary parameters. public void ButtonAction(Button b) { int buttonindex = 0; int.TryParse(b.name.Replace("Move Selection(Clone)", ""), out buttonindex); Vector2 boardcoords = ConvertButtonIndex(buttonindex); // This is completely incorrect and will most likely need a switch case of some kind in the future. //Debug.Log("Board coordinates: " + boardcoords.x + " " + boardcoords.y); // Temporarily hardcoded. Should later be changed to a GameManager function call that determines // what to change spaces to. GameManager.MakeMove(boardcoords, numberofspaces, whitespaces, spaces, sprites, ref movemade); } // 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; } }