using System;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
namespace SAPER2
{
public class FormMain : Form
{
private const int CellWidth = 40;
private const int CellHeight = 40;
private readonly Font CellFont = new Font(FontFamily.GenericMonospace, 20F, FontStyle.Bold);
private Random _rand = new Random();
private CellState[,] _grid = null;
public FormMain()
{
Paint += Form_Paint;
MouseClick += Form_MouseClick;
SetStyle(ControlStyles.Opaque, true);
DoubleBuffered = true;
FormBorderStyle = FormBorderStyle.FixedSingle;
init(8, 8, 4);
}
private void init(int width, int height, int count)
{
_grid = new CellState[width, height];
for(int i=0; i < width; i++)
for(int j=0; j < height; j++)
_grid[i,j] = CellState.NotTestedFree;
if (width * height < count)
count = width * height;
for (int i = 0; i < count; i++)
{
int x,y;
do
{
x = _rand.Next(width);
y = _rand.Next(height);
} while (_grid[x, y] != CellState.NotTestedFree);
_grid[x, y] = CellState.NotTestedMine;
}
ClientSize = new Size(CellWidth * _grid.GetLength(0), CellHeight * _grid.GetLength(1));
Invalidate();
}
private void drawGrid(Graphics g)
{
for (int x = 0; x < _grid.GetLength(0); x++)
for (int y = 0; y < _grid.GetLength(1); y++)
drawCell(g, x, y);
}
private void drawCell(Graphics g, int x, int y)
{
CellState value = _grid[x, y];
Rectangle rect = new Rectangle(x * CellWidth, y * CellHeight, CellWidth, CellHeight);
Rectangle subRect = new Rectangle(rect.X + 1, rect.Y + 1, rect.Width - 2, rect.Height - 2);
g.FillRectangle(Brushes.Silver, rect);
switch(value)
{
case CellState.NotTestedFree:
case CellState.NotTestedMine:
g.FillRectangle(Brushes.Gray, subRect);
break;
case CellState.TestedFree:
g.FillRectangle(Brushes.Green, subRect);
drawMineCount(g, subRect, x, y, CellFont);
break;
case CellState.TestedMine:
g.FillEllipse(Brushes.Black, subRect);
break;
case CellState.TestedMineExplode:
g.FillRectangle(Brushes.Red, subRect);
g.FillEllipse(Brushes.Black, subRect);
break;
}
}
private void drawMineCount(Graphics g, Rectangle rect, int x, int y, Font font)
{
int mineCount = getMineCount(x, y);
if (mineCount < 1)
return;
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Center;
sf.LineAlignment = StringAlignment.Center;
g.DrawString(mineCount.ToString(), font, Brushes.Red, rect, sf);
}
private int getMineCount(int x, int y)
{
int count = 0;
if (y > 0)
{
if (x > 0 && testIsMine(x - 1, y - 1)) count++;
if (testIsMine(x, y - 1)) count++;
if (x < _grid.GetLength(0)-1 && testIsMine(x + 1, y - 1)) count++;
}
if (x > 0 && testIsMine(x - 1, y)) count++;
if (x < _grid.GetLength(0)-1 && testIsMine(x + 1, y)) count++;
if (y < _grid.GetLength(1)-1)
{
if (x > 0 && testIsMine(x - 1, y + 1)) count++;
if (testIsMine(x, y + 1)) count++;
if (x < _grid.GetLength(0)-1 && testIsMine(x + 1, y + 1)) count++;
}
return count;
}
private bool testIsMine(int x, int y)
{
CellState value = _grid[x, y];
return value == CellState.NotTestedMine || value == CellState.TestedMine || value == CellState.TestedMineExplode;
}
private StepResult check(int x, int y)
{
StepResult result = StepResult.Win;
switch (_grid[x, y])
{
case CellState.NotTestedFree:
_grid[x, y] = CellState.TestedFree;
break;
case CellState.NotTestedMine:
for (int i = 0; i < _grid.GetLength(0); i++)
for (int j = 0; j < _grid.GetLength(1); j++)
{
if (_grid[i, j] == CellState.NotTestedMine)
_grid[i, j] = CellState.TestedMine;
}
_grid[x, y] = CellState.TestedMineExplode;
result = StepResult.Lose;
break;
}
if (result != StepResult.Lose)
for (int i = 0; i < _grid.GetLength(0); i++)
for (int j = 0; j < _grid.GetLength(1); j++)
if (_grid[i, j] == CellState.NotTestedFree)
{
result = StepResult.None;
break;
}
Invalidate();
return result;
}
protected void Form_Paint(object sender, PaintEventArgs e)
{
drawGrid(e.Graphics);
}
protected void Form_MouseClick(object sender, MouseEventArgs e)
{
int x = e.X / CellWidth;
int y = e.Y / CellHeight;
if (x >= 0 && y >= 0 && x < _grid.GetLength(0) && y < _grid.GetLength(1))
{
StepResult result = check(x, y);
if (result == StepResult.Lose || result == StepResult.Win)
{
MessageBox.Show("You are " + result.ToString());
init(8, 8, 4);
}
}
}
}
public enum CellState
{
NotTestedFree,
TestedFree,
NotTestedMine,
TestedMine,
TestedMineExplode,
}
public enum StepResult
{
None,
Lose,
Win,
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain());
}
}
}