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.

268 lines
6.5 KiB

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor;
  5. public class MineSweeperEditor : EditorWindow {
  6. public const int CELL_SIZE = 20;
  7. public Texture2D ButtonImage;
  8. public Texture2D EmptyImage;
  9. public int MineCount = 10;
  10. private Cell[,] Board = new Cell[10, 10];
  11. // Add menu named "My Window" to the Window menu
  12. [MenuItem("Addon/Mine Sweeper")]
  13. static void Init()
  14. {
  15. // Get existing open window or if none, make a new one:
  16. MineSweeperEditor window = (MineSweeperEditor)EditorWindow.GetWindow(typeof(MineSweeperEditor));
  17. window.Show();
  18. }
  19. private void Awake()
  20. {
  21. Board = new Cell[10, 10];
  22. for (int i = 0; i < Board.GetLength(0); i++) {
  23. for (int j = 0; j < Board.GetLength(1); j++) {
  24. Board[i, j] = new Cell(this, i, j);
  25. }
  26. }
  27. int placedMines = 0;
  28. while (placedMines < MineCount) {
  29. int x = Random.Range(0, Board.GetLength(0) - 1);
  30. int y = Random.Range(0, Board.GetLength(1) - 1);
  31. if (!Board[x, y].containsMine) {
  32. Board[x, y].containsMine = true;
  33. Debug.Log("Mine at: (" + x + ", " + y + ")");
  34. placedMines++;
  35. }
  36. }
  37. ButtonImage = CreateButtonTexture(CELL_SIZE, Color.white, new Color(0.75f, 0.75f, 0.75f), Color.black);
  38. EmptyImage = CreateButtonTexture(CELL_SIZE, new Color(0.2f, 0.2f, 0.2f), new Color(0.75f, 0.75f, 0.75f), new Color(0.8f, 0.8f, 0.8f));
  39. }
  40. void OnGUI()
  41. {
  42. HeaderGUI();
  43. BoardGUI();
  44. DoClick();
  45. }
  46. private void Update()
  47. {
  48. Repaint();
  49. }
  50. private void HeaderGUI()
  51. {
  52. GUIStyle style = GUI.skin.label;
  53. style.normal.textColor = Color.red;
  54. style.normal.background = EmptyImage;
  55. GUILayout.BeginHorizontal();
  56. GUILayout.Label("000", style);
  57. GUILayout.FlexibleSpace();
  58. GUILayout.EndHorizontal();
  59. }
  60. private void BoardGUI()
  61. {
  62. for (int i = 0; i < Board.GetLength(0); i++) {
  63. GUILayout.BeginHorizontal();
  64. for (int j = 0; j < Board.GetLength(1); j++) {
  65. Board[i, j].DrawCell();
  66. }
  67. GUILayout.EndHorizontal();
  68. GUILayout.Space(CELL_SIZE + 1);
  69. }
  70. }
  71. private void DoClick()
  72. {
  73. Event e = Event.current;
  74. if (e.type == EventType.MouseUp) {
  75. foreach (Cell cell in Board) {
  76. cell.OnClick(e.button, e.mousePosition);
  77. }
  78. }
  79. }
  80. public static Texture2D CreateButtonTexture(int size, Color highLight, Color mainColor, Color lowLight)
  81. {
  82. Texture2D retval = new Texture2D(size, size);
  83. for (int i = 0; i < size; i++) {
  84. for (int j = 0; j < size; j++) {
  85. if (i == 0 || j == size - 1) {
  86. retval.SetPixel(i, j, highLight);
  87. } else if (i == size - 1 || j == 0) {
  88. retval.SetPixel(i, j, lowLight);
  89. } else
  90. retval.SetPixel(i, j, mainColor);
  91. }
  92. }
  93. retval.Apply();
  94. return retval;
  95. }
  96. public Cell[] AdjacentCells(int x, int y)
  97. {
  98. List<Cell> retVal = new List<Cell>();
  99. for (int i = -1; i <= 1; i++) {
  100. if (x + i < 0 || x + i >= Board.GetLength(0))
  101. continue;
  102. for (int j = -1; j <= 1; j++) {
  103. if (y + j < 0 || y + j >= Board.GetLength(0))
  104. continue;
  105. if (i == 0 && j == 0)
  106. continue;
  107. retVal.Add(Board[x + i, y + j]);
  108. }
  109. }
  110. return retVal.ToArray();
  111. }
  112. public static Color getColor(int count){
  113. switch (count) {
  114. case 1:
  115. return Color.blue;
  116. case 2:
  117. return Color.green;
  118. case 3:
  119. return Color.red;
  120. case 4:
  121. return new Color(0, 0, 0.54f);
  122. case 5:
  123. return new Color(0.64f, 0.16f, 0.16f);
  124. case 6:
  125. return Color.cyan;
  126. case 7:
  127. return Color.grey;
  128. case 8:
  129. return Color.black;
  130. default:
  131. return Color.black;
  132. }
  133. }
  134. }
  135. public class Cell {
  136. public bool isOpen = false;
  137. public bool containsMine = false;
  138. public int adjacentMines = 0;
  139. public MineSweeperEditor editor;
  140. private Rect rect;
  141. int x;
  142. int y;
  143. public bool isMarked = false;
  144. public Cell(MineSweeperEditor editor, int x, int y)
  145. {
  146. this.editor = editor;
  147. this.x = x;
  148. this.y = y;
  149. }
  150. public void DrawCell()
  151. {
  152. GUILayout.Space(MineSweeperEditor.CELL_SIZE + 1);
  153. if (Event.current.type == EventType.Repaint)
  154. rect = GUILayoutUtility.GetLastRect();
  155. rect.height = MineSweeperEditor.CELL_SIZE;
  156. rect.width = MineSweeperEditor.CELL_SIZE;
  157. GUIStyle style = new GUIStyle();
  158. style.alignment = TextAnchor.MiddleCenter;
  159. if (!isOpen) {
  160. GUI.DrawTexture(rect, editor.ButtonImage);
  161. if (isMarked)
  162. GUI.Label(rect, "!",style);
  163. } else {
  164. GUI.DrawTexture(rect, editor.EmptyImage);
  165. if (containsMine)
  166. GUI.Label(rect, "X",style);
  167. else if (adjacentMines > 0) {
  168. style.normal.textColor = MineSweeperEditor.getColor(adjacentMines);
  169. GUI.Label(rect,adjacentMines.ToString(),style);
  170. //GUI.contentColor = Color.black;
  171. }
  172. }
  173. }
  174. public void OnClick(int button, Vector2 mousePos)
  175. {
  176. if (rect.Contains(mousePos)) {
  177. if (button == 0)
  178. DoLeftClick();
  179. else if (button == 1)
  180. DoRightClick();
  181. EditorUtility.SetDirty(editor);
  182. }
  183. Debug.Log("MousePos: " + mousePos);
  184. }
  185. private void DoLeftClick()
  186. {
  187. isOpen = true;
  188. Cell[] adjacentCells = editor.AdjacentCells(x, y);
  189. foreach (Cell cell in adjacentCells) {
  190. if (cell.containsMine)
  191. adjacentMines++;
  192. }
  193. if (adjacentMines == 0 && !containsMine)
  194. foreach (Cell cell in adjacentCells)
  195. if (!cell.isOpen)
  196. cell.DoLeftClick();
  197. }
  198. private void DoRightClick()
  199. {
  200. isMarked = !isMarked;
  201. }
  202. }