using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; public static class MineSweeperConstants { private static Texture2D Cell_Button; private static Texture2D Cell_Clicked; private static GUIStyle Button_Style; private static GUIStyle Clicked_Style; /// /// Height and Width of a Cell in Pixels /// public static int CELL_SIZE { get { return 20; } } /// /// Texture of Cell when it hasn't been clicked /// public static Texture2D CELL_BUTTON { get { if (Cell_Button == null) { Cell_Button = CreateButtonTexture(Color.white, new Color(0.75f, 0.75f, 0.75f), Color.black); Debug.Log("Generating CELL_BUTTON"); } return Cell_Button; } } /// /// Texture of Cell when it has been clicked /// public static Texture2D CELL_CLICKED { get { if (Cell_Clicked == null) { Cell_Clicked = CreateButtonTexture(new Color(0.2f, 0.2f, 0.2f), new Color(0.75f, 0.75f, 0.75f), new Color(0.8f, 0.8f, 0.8f)); Debug.Log("Generating CELL_CLicked"); } return Cell_Clicked; } } /// /// Style to use with a Cell_Button /// public static GUIStyle STYLE_CELL_BUTTON { get { if (Button_Style == null) { Debug.Log("Creating Cell Style"); Button_Style = new GUIStyle(); Button_Style.alignment = TextAnchor.MiddleCenter; Button_Style.normal.background = CELL_BUTTON; } return Button_Style; } } /// /// Style to use with a Cell_Button /// public static GUIStyle STYLE_CELL_CLICKED { get { if (Clicked_Style == null) { Debug.Log("Creating Cell Style Clicked"); Clicked_Style = new GUIStyle(); Clicked_Style.alignment = TextAnchor.MiddleCenter; Clicked_Style.normal.background = CELL_CLICKED; } return Clicked_Style; } } private static Texture2D CreateButtonTexture(Color highLight, Color mainColor, Color lowLight) { Texture2D retval = new Texture2D(CELL_SIZE, CELL_SIZE); for (int i = 0; i < CELL_SIZE; i++) { for (int j = 0; j < CELL_SIZE; j++) { if (i == 0 || j == CELL_SIZE - 1) { retval.SetPixel(i, j, highLight); } else if (i == CELL_SIZE - 1 || j == 0) { retval.SetPixel(i, j, lowLight); } else retval.SetPixel(i, j, mainColor); } } retval.Apply(); return retval; } } public class Board { private Cell[,] Cells; private int MineCount = 10; public Board(Vector2Int Size) { Cells = new Cell[Size.x, Size.y]; for (int i = 0; i < Size.x; i++) for (int j = 0; j < Size.y; j++) Cells[i, j] = new Cell(this, new Vector2Int(i, j)); PlaceMines(new Vector2Int(0, 0)); } public void OnGUI() { foreach (Cell cell in Cells) cell.DrawCell(); } public void OnClick() { Event e = Event.current; if (e.type == EventType.MouseUp) { foreach (Cell cell in Cells) cell.OnClick(e.button, e.mousePosition); } } public Cell[] AdjacentCells(Vector2Int coords) { List retVal = new List(); for (int i = -1; i <= 1; i++) { if (coords.x + i < 0 || coords.x + i >= Cells.GetLength(0)) continue; for (int j = -1; j <= 1; j++) { if (coords.y + j < 0 || coords.y + j >= Cells.GetLength(0)) continue; if (i == 0 && j == 0) continue; retVal.Add(Cells[coords.x + i, coords.y + j]); } } return retVal.ToArray(); } public void PlaceMines(Vector2Int startPos) { int placedMines = 0; while (placedMines < MineCount) { int x = Random.Range(0, Cells.GetLength(0) - 1); int y = Random.Range(0, Cells.GetLength(1) - 1); if (!Cells[x, y].containsMine || startPos != new Vector2Int(x,y)) { Cells[x, y].containsMine = true; Debug.Log("Mine at: (" + x + ", " + y + ")"); placedMines++; } } } } public class Cell { public enum Mark { None,Flag,Question} public bool isClicked = false; public bool containsMine = false; public int adjacentMines = 0; public Board board; private Rect rect; Vector2Int coords; public bool isMarked = false; public Cell(Board board, Vector2Int coords) { this.board = board; this.coords = coords; rect = new Rect(coords.x * MineSweeperConstants.CELL_SIZE + 1, coords.y * MineSweeperConstants.CELL_SIZE + 1, MineSweeperConstants.CELL_SIZE, MineSweeperConstants.CELL_SIZE); } public void DrawCell() { if (!isClicked) { if (isMarked) GUI.Label(rect, "!", MineSweeperConstants.STYLE_CELL_BUTTON); else { GUI.Label(rect, "", MineSweeperConstants.STYLE_CELL_BUTTON); } } else { if (containsMine) GUI.Label(rect, "X", MineSweeperConstants.STYLE_CELL_CLICKED); else { MineSweeperConstants.STYLE_CELL_CLICKED.normal.textColor = MineSweeperEditor.getColor(adjacentMines); GUI.Label(rect, adjacentMines.ToString(), MineSweeperConstants.STYLE_CELL_CLICKED); MineSweeperConstants.STYLE_CELL_CLICKED.normal.textColor = Color.black; } } } public void OnClick(int button, Vector2 mousePos) { if (rect.Contains(mousePos)) { if (button == 0) DoLeftClick(); else if (button == 1) DoRightClick(); } } private void DoLeftClick() { if (isClicked) return; isClicked = true; Cell[] adjacentCells = board.AdjacentCells(coords); foreach (Cell cell in adjacentCells) { if (cell.containsMine) adjacentMines++; } if (adjacentMines == 0 && !containsMine) foreach (Cell cell in adjacentCells) if (!cell.isClicked) cell.DoLeftClick(); } private void DoRightClick() { isMarked = !isMarked; } } public struct Vector2Int { public int x; public int y; public Vector2Int(int x, int y) { this.x = x; this.y = y; } public override bool Equals(System.Object obj) { return obj is Vector2Int && this == (Vector2Int)obj; } public override int GetHashCode() { return x.GetHashCode() ^ y.GetHashCode(); } public static bool operator ==(Vector2Int x, Vector2Int y) { return x.x == y.x && x.y == y.y; } public static bool operator !=(Vector2Int x, Vector2Int y) { return !(x == y); } }