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;
|
|
|
|
/// <summary>
|
|
/// Height and Width of a Cell in Pixels
|
|
/// </summary>
|
|
public static int CELL_SIZE { get { return 20; } }
|
|
|
|
/// <summary>
|
|
/// Texture of Cell when it hasn't been clicked
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Texture of Cell when it has been clicked
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Style to use with a Cell_Button
|
|
/// </summary>
|
|
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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Style to use with a Cell_Button
|
|
/// </summary>
|
|
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<Cell> retVal = new List<Cell>();
|
|
|
|
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);
|
|
}
|
|
}
|