Sunday, July 21, 2013

Solving the Minesweeper

Problem:


Have you ever played Minesweeper? This cute little game comes with a certain op-
erating system whose name we can’t remember. The goal of the game is to find where
all the mines are located within a M × N field.
The game shows a number in a square which tells you how many mines there are
adjacent to that square. Each square has at most eight adjacent squares. The 4 × 4 field
on the left contains two mines, each represented by a “*” character. If we represent the
same field by the hint numbers described above, we end up with the field on the right:

*...
....
.*..
....

*100
2210
1*10
1110

Input

The input will consist of an arbitrary number of fields. The first line of each field
contains two integers n and m (0 < n, m ≤ 100) which stand for the number of lines
and columns of the field, respectively. Each of the next n lines contains exactly m
characters, representing the field.
Safe squares are denoted by “.” and mine squares by “*,” both without the quotes.
The first field line where n = m = 0 represents the end of input and should not be
processed.

Output

For each field, print the message Field #x: on a line alone, where x stands for the
number of the field starting from 1. The next n lines should contain the field with the
“.” characters replaced by the number of mines adjacent to that square. There must
be an empty line between field outputs.

Sample Input

4 4
*...
....
.*..
....
3 5
**...
.....
.*...
0 0

Sample Output

 

Field #1:
*100
2210
1*10
1110

Field #2:
**100
33200
1*100

Solution:


This Can be optimized much further, but the main trick is not to get out of array's bounds.

static void Main(string[] args) { int n, m; string[] inputRowsCols = new string[2]; string[,] grid; char[] row; string[,] solvedGrid; StringBuilder results = new StringBuilder(); int gridCounter = 0; inputRowsCols = GetInput(inputRowsCols, out n, out m); while ((n > 0 && n <= 100) && (m > 0 && m <= 100)) { gridCounter++; grid = new string[n, m]; row = new char[m]; solvedGrid = new string[n, m]; for (int i = 0; i < n; i++) { row = Console.ReadLine().ToCharArray(); for (int j = 0; j < row.Length; j++) { grid[i, j] = row[j].ToString(); } } SolveGrid(n, m, grid, solvedGrid); AppendResult(n, m, solvedGrid, results, gridCounter); inputRowsCols = GetInput(inputRowsCols, out n, out m); } Console.WriteLine(results.ToString()); Console.ReadKey(); } private static void AppendResult(int n, int m, string[,] solvedGrid, StringBuilder results, int gridCounter) { results.AppendFormat("Field #{0}\n", gridCounter); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { results.Append(solvedGrid[i, j].ToString()); } results.AppendLine(); } results.AppendLine(); } private static void SolveGrid(int n, int m, string[,] grid, string[,] solvedGrid) { int starCount = 0; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (grid[i, j] == "*") solvedGrid[i, j] = "*"; if (i > 0 && j > 0) if (grid[i - 1, j - 1] == "*") starCount++; if (i < n - 1 && j < m - 1) if (grid[i + 1, j + 1] == "*") starCount++; if (i < n - 1) if (grid[i + 1, j] == "*") starCount++; if (i < n - 1 && j > 0) if (grid[i + 1, j - 1] == "*") starCount++; if (j < m - 1) if (grid[i, j + 1] == "*") starCount++; if (j < m - 1 && i > 0) if (grid[i - 1, j + 1] == "*") starCount++; if (i > 0) if (grid[i - 1, j] == "*") starCount++; if (j > 0) if (grid[i, j - 1] == "*") starCount++; if (solvedGrid[i, j] != "*") { solvedGrid[i, j] = Convert.ToString(starCount); } starCount = 0; } } } private static string[] GetInput(string[] inputRowsCols, out int n, out int m) { inputRowsCols = Console.ReadLine().Split(' '); n = int.Parse(inputRowsCols[0]); m = int.Parse(inputRowsCols[1]); return inputRowsCols; }
Predicted output:

No comments:

Post a Comment