Last active
March 5, 2020 21:41
-
-
Save tomaszbartoszewski/414c6560baec4626cc6308b206c82ceb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Text; | |
namespace Minesweeper | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Console.OutputEncoding = Encoding.UTF8; | |
var gameEngine = new GameEngine(); | |
gameEngine.NewGame(new BoardDefinition { Height = 10, Width = 10, NumberOfBombs = 10 }); | |
PrintBoard(gameEngine.GetCurrentBoard()); | |
var gameStatus = GameStatus.InProgress; | |
while (gameStatus == GameStatus.InProgress) | |
{ | |
string selection = string.Empty; | |
while (selection != "F" && selection != "C" && selection != "U") | |
{ | |
Console.WriteLine("For flag press F, unflag U, for Checking press C"); | |
selection = Console.ReadLine(); | |
} | |
int? column = null; | |
while (!column.HasValue) | |
{ | |
Console.WriteLine("Provide column Id:"); | |
var columnString = Console.ReadLine(); | |
int columnValue; | |
if (int.TryParse(columnString, out columnValue)) | |
column = columnValue; | |
} | |
int? row = null; | |
while (!row.HasValue) | |
{ | |
Console.WriteLine("Provide row Id:"); | |
var rowString = Console.ReadLine(); | |
int rowValue; | |
if (int.TryParse(rowString, out rowValue)) | |
row = rowValue; | |
} | |
switch (selection) | |
{ | |
case "F": | |
gameEngine.Flag(column.Value, row.Value); | |
break; | |
case "U": | |
gameEngine.UnFlag(column.Value, row.Value); | |
break; | |
default: | |
gameStatus = gameEngine.CheckField(column.Value, row.Value); | |
break; | |
} | |
Console.Clear(); | |
PrintBoard(gameEngine.GetCurrentBoard()); | |
} | |
if (gameStatus == GameStatus.Failed) | |
Console.WriteLine("Failed"); | |
if (gameStatus == GameStatus.Success) | |
Console.WriteLine("Success"); | |
Console.ReadLine(); | |
} | |
private static void PrintBoard(FieldValue[,] board) | |
{ | |
Console.Write(" "); | |
for (int h = 0; h < board.GetLength(0); h++) | |
Console.Write(h); | |
Console.WriteLine(); | |
for (int w = 0; w < board.GetLength(1); w++) | |
{ | |
Console.Write(w); | |
for (int h = 0; h < board.GetLength(0); h++) | |
{ | |
Console.Write(GetFieldValue(board[h, w])); | |
} | |
Console.WriteLine(); | |
} | |
} | |
private static string GetFieldValue(FieldValue fieldValue) | |
{ | |
switch (fieldValue) | |
{ | |
case FieldValue.Flag: | |
return "X"; | |
case FieldValue.Hidden: | |
return " "; | |
case FieldValue.Bomb: | |
return "*"; | |
default: | |
return ((int)fieldValue).ToString(); | |
} | |
} | |
} | |
public class GameEngine | |
{ | |
private GameStatus gameStatus; | |
private FieldValue[,] revealBoard; | |
private FieldValue[,] board; | |
private BoardDefinition boardDefinition; | |
private int remainingFields; | |
public void NewGame(BoardDefinition boardDefinition) | |
{ | |
gameStatus = GameStatus.InProgress; | |
this.boardDefinition = boardDefinition; | |
remainingFields = boardDefinition.Width * boardDefinition.Height; | |
var boardGenerator = new BoardGenerator(); | |
board = boardGenerator.CreateBoard(boardDefinition); | |
revealBoard = new FieldValue[boardDefinition.Height, boardDefinition.Width]; | |
for (var i = 0; i < boardDefinition.Height; i++) | |
for (var j = 0; j < boardDefinition.Height; j++) | |
revealBoard[i,j] = FieldValue.Hidden; | |
} | |
public GameStatus CheckField(int column, int row) | |
{ | |
if(column < 0 || column >= boardDefinition.Width || row < 0 || row >= boardDefinition.Height) | |
return gameStatus; | |
if (revealBoard[column, row] != FieldValue.Hidden) | |
return gameStatus; | |
if (board[column, row] == FieldValue.Bomb) | |
gameStatus = GameStatus.Failed; | |
revealBoard[column, row] = board[column, row]; | |
remainingFields--; | |
if (board[column, row] == FieldValue.V0) | |
{ | |
for (var i = -1; i <= 1; i++) | |
for (var j = -1; j <= 1; j++) | |
CheckField(i + column, row + j); | |
} | |
if (remainingFields == boardDefinition.NumberOfBombs) | |
gameStatus = GameStatus.Success; | |
return gameStatus; | |
} | |
public void Flag(int column, int row) | |
{ | |
if (revealBoard[column, row] == FieldValue.Hidden) | |
revealBoard[column, row] = FieldValue.Flag; | |
} | |
public void UnFlag(int column, int row) | |
{ | |
if (revealBoard[column, row] == FieldValue.Flag) | |
revealBoard[column, row] = FieldValue.Hidden; | |
} | |
public FieldValue[,] GetCurrentBoard() | |
{ | |
return revealBoard; | |
} | |
} | |
public class BoardGenerator | |
{ | |
private BoardDefinition boardDefinition; | |
private FieldValue[,] board; | |
public FieldValue[,] CreateBoard(BoardDefinition boardDefinition) | |
{ | |
this.boardDefinition = boardDefinition; | |
board = new FieldValue[boardDefinition.Height, boardDefinition.Width]; | |
AddBombs(); | |
return board; | |
} | |
private void AddBombs() | |
{ | |
var rnd = new Random(); | |
var numberOfBombs = boardDefinition.NumberOfBombs; | |
while (numberOfBombs > 0) | |
{ | |
var height = rnd.Next(0, boardDefinition.Height); | |
var width = rnd.Next(0, boardDefinition.Width); | |
if (board[height, width] == FieldValue.Bomb) continue; | |
board[height, width] = FieldValue.Bomb; | |
numberOfBombs--; | |
RefreshNumbersAround(height, width); | |
} | |
} | |
private void RefreshNumbersAround(int height, int width) | |
{ | |
for (var h = height - 1; h <= height + 1; h++) | |
for (var w = width - 1; w <= width + 1; w++) | |
if (h >= 0 && h < boardDefinition.Height | |
&& w >= 0 && w < boardDefinition.Width | |
&& board[h, w] != FieldValue.Bomb) | |
board[h, w]++; | |
} | |
} | |
public class BoardDefinition | |
{ | |
public int Width { get; set; } | |
public int Height { get; set; } | |
public int NumberOfBombs { get; set; } | |
} | |
public enum GameStatus | |
{ | |
InProgress, | |
Success, | |
Failed | |
} | |
public enum FieldValue | |
{ | |
Flag = -3, | |
Hidden = -2, | |
Bomb = -1, | |
V0 = 0, | |
V1 = 1, | |
V2 = 2, | |
V3 = 3, | |
V4 = 4, | |
V5 = 5, | |
V6 = 6, | |
V7 = 7, | |
V8 = 8 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment