Sapper.cs

Лістинг коду

Сапер» - комп'ютерна гра,головоломка.

Sapper

Плоске або об'ємне ігрове поле розділене на суміжні клітинкидеякі з яких «заміновані»; кількість «замінованих» осередківвідомо. Метою гри є відкриття всіх осередків,не містять міни.

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Windows.Forms;

namespace Supper

{

public partial class Sapper: Form

{

int

FieldHeight, // кол-во клеток по вертикали

FieldWight,// кол-во клеток по горизонтали

Mines, // кол-во мин

W = 28, // ширина клетки

H = 28; // высота клетки

// игровое (минное) поле

int[,] Field;

// значение элемента массива:

// 0..8 - количество мин в соседних клетках

// 9 - в клетке мина

// 100..109 - клетка открыта

// 200..209 - в клетку поставлен флаг

// 50..59 - 50/50

private int FindMines; // кол-во найденных мин

private int FindFlags; // кол-во поставленных флагов

// статус игры

private int status; // 0 - начало игры,// 1 - игра,// 2 – результат проигрыш

// 3 - результат победа // графическая поверхность формы

private System.Drawing.Graphics g;

// прямоугольник поля

Rectangle rt;

// звуки

System.Media.SoundPlayer click = new System.Media.SoundPlayer("Click.wav");

System.Media.SoundPlayer bomb = new System.Media.SoundPlayer("Bomb.wav");

System.Media.SoundPlayer tic = new System.Media.SoundPlayer("Tic.wav");

System.Media.SoundPlayer win = new System.Media.SoundPlayer("Win.wav");

bool soundcheck;

public Sapper()

{

InitializeComponent();

beginnerToolStripMenuItem.PerformClick();

// загружаем звуки

click.Load();

bomb.Load();

tic.Load();

win.Load();

}

public void Start()

{

// В неотображаемые эл-ты массива -3 для рекурсиии

Field = new int[FieldHeight + 2, FieldWight + 2];

for (int row = 0; row <= FieldHeight + 1; row++)

{

Field[row, 0] = -3;

Field[row, FieldWight + 1] = -3;

}

for (int col = 0; col <= FieldWight + 1; col++)

{

Field[0, col] = -3;

Field[FieldHeight + 1, col] = -3;

}

// устанавливаем размер формы в соответствии с размером игрового поля

this.ClientSize = new Size(W * FieldWight + 1, H * FieldHeight + MenuStrip.Height + 41);

newGame(); // новая игра

Restart();

}

public void Restart()

{

// задаём постоянные графические эл-ты

g = GameField.CreateGraphics();

int x = GameField.Size.Width / 2 - 25;

int y = H * FieldHeight + MenuStrip.Height - 23;

Point Loc = new Point(x, y);

SmileBox.Location = Loc;

SmileBox.Image = Image.FromFile("good.jpg");

MinetextBox.Location = new Point(2, H * FieldHeight + MenuStrip.Height - 20);

TimetextBox.Location = new Point(GameField.Width - 87, H * FieldHeight + MenuStrip.Height - 20);

TimetextBox.Font = new Font("Tahoma", 16);

TimetextBox.Text = "00:00:00";

}

public int MinesAround(int row, int col)

{

int k;

for (row = 1; row <= FieldHeight; row++)

for (col = 1; col <= FieldWight; col++)

if (Field[row, col]!= 9)

{

k = 0;

if (Field[row - 1, col - 1] == 9) k++;

if (Field[row - 1, col] == 9) k++;

if (Field[row - 1, col + 1] == 9) k++;

if (Field[row, col - 1] == 9) k++;

if (Field[row, col + 1] == 9) k++;

if (Field[row + 1, col - 1] == 9) k++;

if (Field[row + 1, col] == 9) k++;

if (Field[row + 1, col + 1] == 9) k++;

Field[row, col] = k;

}

return Field[row, col];

}

private void newGame()

{

int row, col;// индексы клетки

int n = 0; // количество поставленных мин

// очищаем поле

for (row = 1; row <= FieldHeight; row++)

{

for (col = 1; col <= FieldWight; col++)

{

Field[row, col] = 0;

}

}

Random rnd = new Random();

// расставим мины

do

{

row = rnd.Next(FieldHeight) + 1;

col = rnd.Next(FieldWight) + 1;

if (Field[row, col]!= 9)

{

Field[row, col] = 9;

n++;

}

}

while (n!= Mines);

// для каждой клетки вычислим кол-во мин вокруг

MinesAround(row, col);

// начинаем

status = 0;

FindMines = 0;

FindFlags = 0;

MinetextBox.Font = new Font("Tahoma", 16);

MinetextBox.Text = Mines.ToString();

}

// рисует поле

private void showField(Graphics g, int status)

{

for (int row = 1; row <= FieldHeight; row++)

for (int col = 1; col <= FieldWight; col++)

this.cell(g, row, col, status);

}

// рисует клетку

private void cell(Graphics g, int row, int col, int status)

{

int x, y;// координаты левого верхнего угла клетки

x = (col - 1) * W + 1;

y = (row - 1) * H + 1;

// не открытые клетки

if (Field[row, col] < 100)

g.FillRectangle(Brushes.Gray,

x - 1, y - 1, W, H);

// открытые или помеченные клетки

if (Field[row, col] >= 100 && Field[row, col] < 200)

{

// открываем клетку

if (Field[row, col]!= 109)

g.FillRectangle(Brushes.White,

x - 1, y - 1, W, H);

else

// взрыв!

g.FillRectangle(Brushes.Red,

x - 1, y - 1, W, H);

// если в соседних клетках есть мины, указываем их количество

if ((Field[row, col] >= 101) && (Field[row, col] <= 108))

{

if (Field[row, col] == 101)

{

g.DrawString((Field[row, col] - 100).ToString(), new Font("Tahoma", 16, System.Drawing.FontStyle.Regular), Brushes.Blue, x + 3, y + 2);

}

if (Field[row, col] == 102)

{

g.DrawString((Field[row, col] - 100).ToString(), new Font("Tahoma", 16, System.Drawing.FontStyle.Regular), Brushes.Green, x + 3, y + 2);

}

if (Field[row, col] >= 103)

{

g.DrawString((Field[row, col] - 100).ToString(), new Font("Tahoma", 16, System.Drawing.FontStyle.Regular), Brushes.Red, x + 3, y + 2);

}

}

}

// в клетке поставлен флаг

if (Field[row, col] >= 200)

this.flag(g, x, y);

// в клетке 50/50

if (Field[row, col] >= 50 && Field[row, col] < 100)

this.question(g, x, y);

// рисуем границу клетки

g.DrawRectangle(Pens.Black,

x - 1, y - 1, W, H);

// если игра завершена (status = 2),

// показываем мины

if ((status == 2) && ((Field[row, col] % 10) == 9))

{

this.mine(g, x, y);

if (Field[row, col] == 209)

{

g.FillRectangle(Brushes.Gray,

x - 1, y - 1, W, H);

this.mine(g, x, y);

Pen MyPen = new Pen(Color.Red, 2);

g.DrawLine(MyPen, x + 2, y + 2, x + 25, y + 25);

g.DrawLine(MyPen, x + 25, y + 2, x + 2, y + 25);

}

}

}

// рекурсия

private void open(int row, int col)

{

// координаты области вывода

int x = (col - 1) * W + 1,

y = (row - 1) * H + 1;

if (Field[row, col] == 0)

{

Field[row, col] = 100;

// отобразить содержимое клетки

this.cell(g, row, col, status);

// открыть примыкающие клетки

this.open(row, col - 1);

this.open(row - 1, col);

this.open(row, col + 1);

this.open(row + 1, col);

this.open(row - 1, col - 1);

this.open(row - 1, col + 1);

this.open(row + 1, col - 1);

this.open(row + 1, col + 1);

}

else

if ((Field[row, col] < 50) && (Field[row, col]!= -3))

{

Field[row, col] += 100;

this.cell(g, row, col, status);

}

}

//мина

private void mine(Graphics g, int x, int y)

{

Pen pn = new Pen(Brushes.Black);

g.DrawRectangle(pn, x - 1, y - 1, W, H);

g.FillEllipse(Brushes.Black, x + 7, y + 7, 14, 14);

g.DrawLine(Pens.Black, x + 14, y + 14, x + 6, y + 6);

g.DrawLine(Pens.Black, x + 14, y + 14, x + 22, y + 22);

g.DrawLine(Pens.Black, x + 14, y + 14, x + 6, y + 22);

g.DrawLine(Pens.Black, x + 14, y + 14, x + 22, y + 6);

g.DrawLine(Pens.Black, x + 14, y + 14, x + 6, y + 14);

g.DrawLine(Pens.Black, x + 14, y + 14, x + 22, y + 14);

g.DrawLine(Pens.Black, x + 14, y + 14, x + 14, y + 6);

g.DrawLine(Pens.Black, x + 14, y + 14, x + 14, y + 22);

g.FillEllipse(Brushes.White, x + 9, y + 9, 5, 5);

}

}

//флаг

private void flag(Graphics g, int x, int y)

{

Pen pn = new Pen(Brushes.Black);

g.DrawRectangle(pn, x - 1, y - 1, W, H);

g.FillRectangle(Brushes.Gray, x - 1, y - 1, W, H);

Point[] p = new Point[3];

Point[] m = new Point[5];

p[0].X = x + 14; p[0].Y = y + 3;

p[1].X = x + 2; p[1].Y = y + 10;

p[2].X = x + 14; p[2].Y = y + 13;

g.FillPolygon(Brushes.Red, p);

g.DrawLine(Pens.Black, x + 14, y + 4, x + 14, y + 17);

Rectangle Rec = new Rectangle(x + 6, y + 17, 15, 5);

g.FillRectangle(Brushes.Black, Rec);

}

DateTime Time;

private void LeftButton(int row, int col)

{

// открыта клетка, в которой есть мина

if (Field[row, col] == 9)

{

if (soundcheck == true)

{

bomb.Play();

}

Field[row, col] += 100;

Timer.Stop();

// игра закончена

status = 2;

MinetextBox.Text = "LOSS";

this.GameField.Invalidate();

}

else

{

if (Field[row, col] == 59)

{

if (soundcheck == true)

{

bomb.Play();

}

Field[row, col] += 50;

Timer.Stop();

// игра закончена

status = 2;

MinetextBox.Text = "LOSS";

this.GameField.Invalidate();

click.Play();

}

if (Field[row, col] < 9)

{

if (soundcheck == true)

{

click.Play();

}

this.open(row, col);

}

}

}

private void GameField_MouseClick_1(object sender, MouseEventArgs e)

{

Point p = new Point(e.X, e.Y);

if (rt.Contains(p))

{

// первый щелчок

if (status == 0)

{

Time = DateTime.Now;

Timer.Start();

status = 1;

}

// координаты мыши в индексы

int row = (int)(e.Y / H) + 1,

col = (int)(e.X / W) + 1;

// координаты области вывода

int x = (col - 1) * W + 1,

y = (row - 1) * H + 1;

// игра завершена

if (status == 2) return;

// щелчок левой кнопки мыши

if (e.Button == MouseButtons.Left)

{

LeftButton(row, col);

}

// щелчок правой кнопки мыши

if (e.Button == MouseButtons.Right)

{

if (soundcheck == true)

{

click.Play();

}

if (status!= 3)

{

int m = int.Parse(MinetextBox.Text) - 1;

// в клетке не было флага, ставим его

if ((Field[row, col] <= 9) && Double.Parse(MinetextBox.Text) > 0)

{

this.cell(g, row, col, status);

MinetextBox.Text = m.ToString();

FindFlags += 1;

if (Field[row, col] == 9)

FindMines += 1;

Field[row, col] += 200;

if ((FindMines == Mines) && (FindFlags == Mines))

{

if (soundcheck == true)

{

win.Play();

}

// игра закончена

status = 3;

Timer.Stop();

this.flag(g, x, y);

this.Invalidate();

MinetextBox.Text = "WIN!!!";

}

else

this.cell(g, row, col, status);

}

else

if (Field[row, col] >= 200)

{

int k = int.Parse(MinetextBox.Text) + 1;

MinetextBox.Text = k.ToString();

FindFlags -= 1;

Field[row, col] -= 150;

this.cell(g, row, col, status);

this.question(g, x, y);

}

else

if (Field[row, col] >= 50 && Field[row, col] <= 59)

{

Field[row, col] -= 50;

this.cell(g, row, col, status);

}

}

}

//нажатие скрола

if (e.Button == MouseButtons.Middle)

{

if (Field[row, col] > 100 && Field[row, col] < 109)

{

int f = 0;

if (Field[row - 1, col - 1] >= 200 && Field[row - 1, col - 1] <= 209) f++;

if (Field[row - 1, col] >= 200 && Field[row - 1, col - 1] <= 209) f++;

if (Field[row - 1, col + 1] >= 200 && Field[row - 1, col - 1] <= 209) f++;

if (Field[row, col - 1] >= 200 && Field[row - 1, col - 1] <= 209) f++;

if (Field[row, col + 1] >= 200 && Field[row - 1, col - 1] <= 209) f++;

if (Field[row + 1, col - 1] >= 200 && Field[row - 1, col - 1] <= 209) f++;

if (Field[row + 1, col] >= 200 && Field[row - 1, col - 1] <= 209) f++;

if (Field[row + 1, col + 1] >= 200 && Field[row - 1, col - 1] <= 209) f++;

int k = Field[row, col] - 100;

if (f == k)

{

LeftButton(row, col - 1);

LeftButton(row - 1, col);

LeftButton(row, col + 1);

LeftButton(row + 1, col);

LeftButton(row - 1, col - 1);

LeftButton(row - 1, col + 1);

LeftButton(row + 1, col - 1);

LeftButton(row + 1, col + 1);

}

}

}

}

}

private void GameField_Paint_1(object sender, PaintEventArgs e)

{

showField(g, status);

}

private void SmileBox_Click(object sender, EventArgs e)

{

newGame();

showField(g, status);

SmileBox.Image = Image.FromFile("good.jpg");

Timer.Stop();

TimetextBox.Text = "00:00:00";

MinetextBox.Text = Mines.ToString();

}

private void amateurToolStripMenuItem_Click(object sender, EventArgs e)

{

amateurToolStripMenuItem.CheckState = CheckState.Checked;

beginnerToolStripMenuItem.CheckState = CheckState.Unchecked;

professionalToolStripMenuItem.CheckState = CheckState.Unchecked;

crazyToolStripMenuItem.CheckState = CheckState.Unchecked;

FieldHeight = 16;

FieldWight = 16;

Mines = 25;

rt = new Rectangle(0, 0, FieldWight * W, FieldHeight * H);

GameField.Invalidate();

Timer.Stop();

TimetextBox.Text = "00:00:00";

Start();

}

private void professionalToolStripMenuItem_Click(object sender, EventArgs e)

{

professionalToolStripMenuItem.CheckState = CheckState.Checked;

beginnerToolStripMenuItem.CheckState = CheckState.Unchecked;

amateurToolStripMenuItem.CheckState = CheckState.Unchecked;

crazyToolStripMenuItem.CheckState = CheckState.Unchecked;

FieldHeight = 16;

FieldWight = 21;

Mines = 50;

rt = new Rectangle(0, 0, FieldWight * W, FieldHeight * H);

GameField.Invalidate();

Timer.Stop();

TimetextBox.Text = "00:00:00";

Start();

}

private void crezyToolStripMenuItem_Click(object sender, EventArgs e)

{

crazyToolStripMenuItem.CheckState = CheckState.Checked;

professionalToolStripMenuItem.CheckState = CheckState.Unchecked;

beginnerToolStripMenuItem.CheckState = CheckState.Unchecked;

amateurToolStripMenuItem.CheckState = CheckState.Unchecked;

FieldHeight = 16;

FieldWight = 21;

Mines = 100;

rt = new Rectangle(0, 0, FieldWight * W, FieldHeight * H);

GameField.Invalidate();

Timer.Stop();

TimetextBox.Text = "00:00:00";

Start();

}

}

}


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: