You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

303 lines
7.5 KiB

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor;
  5. public static class MineSweeperConstants
  6. {
  7. private static Texture2D Cell_Button;
  8. private static Texture2D Cell_Clicked;
  9. private static GUIStyle Button_Style;
  10. private static GUIStyle Clicked_Style;
  11. /// <summary>
  12. /// Height and Width of a Cell in Pixels
  13. /// </summary>
  14. public static int CELL_SIZE { get { return 20; } }
  15. /// <summary>
  16. /// Texture of Cell when it hasn't been clicked
  17. /// </summary>
  18. public static Texture2D CELL_BUTTON
  19. {
  20. get
  21. {
  22. if (Cell_Button == null)
  23. {
  24. Cell_Button = CreateButtonTexture(Color.white, new Color(0.75f, 0.75f, 0.75f), Color.black);
  25. Debug.Log("Generating CELL_BUTTON");
  26. }
  27. return Cell_Button;
  28. }
  29. }
  30. /// <summary>
  31. /// Texture of Cell when it has been clicked
  32. /// </summary>
  33. public static Texture2D CELL_CLICKED
  34. {
  35. get
  36. {
  37. if (Cell_Clicked == null)
  38. {
  39. 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));
  40. Debug.Log("Generating CELL_CLicked");
  41. }
  42. return Cell_Clicked;
  43. }
  44. }
  45. /// <summary>
  46. /// Style to use with a Cell_Button
  47. /// </summary>
  48. public static GUIStyle STYLE_CELL_BUTTON
  49. {
  50. get
  51. {
  52. if (Button_Style == null)
  53. {
  54. Debug.Log("Creating Cell Style");
  55. Button_Style = new GUIStyle();
  56. Button_Style.alignment = TextAnchor.MiddleCenter;
  57. Button_Style.normal.background = CELL_BUTTON;
  58. }
  59. return Button_Style;
  60. }
  61. }
  62. /// <summary>
  63. /// Style to use with a Cell_Button
  64. /// </summary>
  65. public static GUIStyle STYLE_CELL_CLICKED
  66. {
  67. get
  68. {
  69. if (Clicked_Style == null)
  70. {
  71. Debug.Log("Creating Cell Style Clicked");
  72. Clicked_Style = new GUIStyle();
  73. Clicked_Style.alignment = TextAnchor.MiddleCenter;
  74. Clicked_Style.normal.background = CELL_CLICKED;
  75. }
  76. return Clicked_Style;
  77. }
  78. }
  79. private static Texture2D CreateButtonTexture(Color highLight, Color mainColor, Color lowLight)
  80. {
  81. Texture2D retval = new Texture2D(CELL_SIZE, CELL_SIZE);
  82. for (int i = 0; i < CELL_SIZE; i++)
  83. {
  84. for (int j = 0; j < CELL_SIZE; j++)
  85. {
  86. if (i == 0 || j == CELL_SIZE - 1)
  87. {
  88. retval.SetPixel(i, j, highLight);
  89. }
  90. else if (i == CELL_SIZE - 1 || j == 0)
  91. {
  92. retval.SetPixel(i, j, lowLight);
  93. }
  94. else
  95. retval.SetPixel(i, j, mainColor);
  96. }
  97. }
  98. retval.Apply();
  99. return retval;
  100. }
  101. }
  102. public class Board
  103. {
  104. private Cell[,] Cells;
  105. private int MineCount = 10;
  106. public Board(Vector2Int Size)
  107. {
  108. Cells = new Cell[Size.x, Size.y];
  109. for (int i = 0; i < Size.x; i++)
  110. for (int j = 0; j < Size.y; j++)
  111. Cells[i, j] = new Cell(this, new Vector2Int(i, j));
  112. PlaceMines(new Vector2Int(0, 0));
  113. }
  114. public void OnGUI()
  115. {
  116. foreach (Cell cell in Cells)
  117. cell.DrawCell();
  118. }
  119. public void OnClick()
  120. {
  121. Event e = Event.current;
  122. if (e.type == EventType.MouseUp)
  123. {
  124. foreach (Cell cell in Cells)
  125. cell.OnClick(e.button, e.mousePosition);
  126. }
  127. }
  128. public Cell[] AdjacentCells(Vector2Int coords)
  129. {
  130. List<Cell> retVal = new List<Cell>();
  131. for (int i = -1; i <= 1; i++)
  132. {
  133. if (coords.x + i < 0 || coords.x + i >= Cells.GetLength(0))
  134. continue;
  135. for (int j = -1; j <= 1; j++)
  136. {
  137. if (coords.y + j < 0 || coords.y + j >= Cells.GetLength(0))
  138. continue;
  139. if (i == 0 && j == 0)
  140. continue;
  141. retVal.Add(Cells[coords.x + i, coords.y + j]);
  142. }
  143. }
  144. return retVal.ToArray();
  145. }
  146. public void PlaceMines(Vector2Int startPos)
  147. {
  148. int placedMines = 0;
  149. while (placedMines < MineCount)
  150. {
  151. int x = Random.Range(0, Cells.GetLength(0) - 1);
  152. int y = Random.Range(0, Cells.GetLength(1) - 1);
  153. if (!Cells[x, y].containsMine || startPos != new Vector2Int(x,y))
  154. {
  155. Cells[x, y].containsMine = true;
  156. Debug.Log("Mine at: (" + x + ", " + y + ")");
  157. placedMines++;
  158. }
  159. }
  160. }
  161. }
  162. public class Cell
  163. {
  164. public enum Mark { None,Flag,Question}
  165. public bool isClicked = false;
  166. public bool containsMine = false;
  167. public int adjacentMines = 0;
  168. public Board board;
  169. private Rect rect;
  170. Vector2Int coords;
  171. public bool isMarked = false;
  172. public Cell(Board board, Vector2Int coords)
  173. {
  174. this.board = board;
  175. this.coords = coords;
  176. rect = new Rect(coords.x * MineSweeperConstants.CELL_SIZE + 1, coords.y * MineSweeperConstants.CELL_SIZE + 1, MineSweeperConstants.CELL_SIZE, MineSweeperConstants.CELL_SIZE);
  177. }
  178. public void DrawCell()
  179. {
  180. if (!isClicked)
  181. {
  182. if (isMarked)
  183. GUI.Label(rect, "!", MineSweeperConstants.STYLE_CELL_BUTTON);
  184. else
  185. {
  186. GUI.Label(rect, "", MineSweeperConstants.STYLE_CELL_BUTTON);
  187. }
  188. }
  189. else
  190. {
  191. if (containsMine)
  192. GUI.Label(rect, "X", MineSweeperConstants.STYLE_CELL_CLICKED);
  193. else
  194. {
  195. MineSweeperConstants.STYLE_CELL_CLICKED.normal.textColor = MineSweeperEditor.getColor(adjacentMines);
  196. GUI.Label(rect, adjacentMines.ToString(), MineSweeperConstants.STYLE_CELL_CLICKED);
  197. MineSweeperConstants.STYLE_CELL_CLICKED.normal.textColor = Color.black;
  198. }
  199. }
  200. }
  201. public void OnClick(int button, Vector2 mousePos)
  202. {
  203. if (rect.Contains(mousePos))
  204. {
  205. if (button == 0)
  206. DoLeftClick();
  207. else if (button == 1)
  208. DoRightClick();
  209. }
  210. }
  211. private void DoLeftClick()
  212. {
  213. if (isClicked)
  214. return;
  215. isClicked = true;
  216. Cell[] adjacentCells = board.AdjacentCells(coords);
  217. foreach (Cell cell in adjacentCells)
  218. {
  219. if (cell.containsMine)
  220. adjacentMines++;
  221. }
  222. if (adjacentMines == 0 && !containsMine)
  223. foreach (Cell cell in adjacentCells)
  224. if (!cell.isClicked)
  225. cell.DoLeftClick();
  226. }
  227. private void DoRightClick()
  228. {
  229. isMarked = !isMarked;
  230. }
  231. }
  232. public struct Vector2Int
  233. {
  234. public int x;
  235. public int y;
  236. public Vector2Int(int x, int y)
  237. {
  238. this.x = x;
  239. this.y = y;
  240. }
  241. public override bool Equals(System.Object obj)
  242. {
  243. return obj is Vector2Int && this == (Vector2Int)obj;
  244. }
  245. public override int GetHashCode()
  246. {
  247. return x.GetHashCode() ^ y.GetHashCode();
  248. }
  249. public static bool operator ==(Vector2Int x, Vector2Int y)
  250. {
  251. return x.x == y.x && x.y == y.y;
  252. }
  253. public static bool operator !=(Vector2Int x, Vector2Int y)
  254. {
  255. return !(x == y);
  256. }
  257. }