Skip to content

Instantly share code, notes, and snippets.

@nothke
Created April 24, 2020 00:58
Show Gist options
  • Select an option

  • Save nothke/2d68c1f4f37c38c7121e3abab9bd9673 to your computer and use it in GitHub Desktop.

Select an option

Save nothke/2d68c1f4f37c38c7121e3abab9bd9673 to your computer and use it in GitHub Desktop.
/// A little Minesweeper for Unity using GUI
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Minesweeper : MonoBehaviour
{
public enum TileState
{
Hidden,
Uncovered,
Marked
};
byte[,] tiles;
TileState[,] states;
const byte BOMB = 13;
const int SIZE = 16;
HashSet<(int, int)> fillSet;
int bombsCount = 10;
void Start()
{
// Create grid
tiles = new byte[SIZE, SIZE];
states = new TileState[SIZE, SIZE];
fillSet = new HashSet<(int, int)>();
// Set Random bomb
for (int i = 0; i < bombsCount; i++)
{
Repeat:
int x = Random.Range(0, SIZE);
int y = Random.Range(0, SIZE);
if (tiles[x, y] == BOMB)
goto Repeat;
tiles[x, y] = BOMB;
}
// Find surrounding bombs and set this tile's number
for (int x = 0; x < SIZE; x++)
{
for (int y = 0; y < SIZE; y++)
{
if (tiles[x, y] == BOMB)
continue;
byte ct = 0;
for (int sx = -1; sx <= 1; sx++)
{
for (int sy = -1; sy <= 1; sy++)
{
int tx = x + sx;
int ty = y + sy;
if (tx < 0 || tx >= SIZE
|| ty < 0 || ty >= SIZE)
continue;
//Debug.Log(tx + ", " + ty);
ct += tiles[tx, ty] == BOMB ? (byte)1 : (byte)0;
}
}
tiles[x, y] = ct;
}
}
// Debug
{
for (int y = 0; y < SIZE; y++)
{
string str = "";
for (int x = 0; x < SIZE; x++)
{
if (tiles[x, y] == BOMB)
str += "B" + ", ";
else
str += tiles[x, y] + ", ";
}
Debug.Log(str);
}
}
}
void Reveal(int x, int y)
{
if (tiles[x, y] == 0)
{
fillSet.Clear();
FloodReveal(x, y);
}
else if (tiles[x, y] < BOMB)
{
states[x, y] = TileState.Uncovered;
}
else if (tiles[x, y] == BOMB)
{
Boom();
}
}
void FloodReveal(int x, int y)
{
if (x < 0 || x >= SIZE) return;
if (y < 0 || y >= SIZE) return;
if (fillSet.Contains((x, y)))
return;
fillSet.Add((x, y));
if (tiles[x, y] < BOMB)
{
states[x, y] = TileState.Uncovered;
if (tiles[x, y] < 1)
{
FloodReveal(x + 1, y);
FloodReveal(x, y + 1);
FloodReveal(x - 1, y);
FloodReveal(x, y - 1);
}
}
}
void CheckWinCondition()
{
int revealedCt = 0;
int testBombs = 0;
for (int x = 0; x < SIZE; x++)
{
for (int y = 0; y < SIZE; y++)
{
if (states[x, y] == TileState.Uncovered)
revealedCt++;
if (tiles[x, y] == BOMB)
testBombs++;
}
}
int leftToReveal = SIZE * SIZE - revealedCt - bombsCount;
Debug.Log(leftToReveal);
if (leftToReveal == 0)
{
Win();
}
}
void Win()
{
Debug.Log("You win!");
}
void Boom()
{
Debug.LogError("You ded");
}
void OnGUI()
{
for (int x = 0; x < SIZE; x++)
{
for (int y = 0; y < SIZE; y++)
{
string str = "";
if (states[x, y] == TileState.Uncovered)
{
str = tiles[x, y].ToString();
}
else
if (states[x, y] == TileState.Marked)
{
str = "?";
}
if (GUI.Button(new Rect(x * 40, y * 40, 40, 40), str))
{
if (Input.GetMouseButtonUp(1))
{
states[x, y] = states[x, y] == TileState.Marked ? TileState.Hidden : TileState.Marked;
}
else
{
if (states[x, y] != TileState.Uncovered)
{
Reveal(x, y);
CheckWinCondition();
}
}
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment