Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
7 / 7 / 5
Регистрация: 27.10.2013
Сообщений: 170
1

Сапер

18.11.2014, 20:10. Показов 2113. Ответов 4
Метки нет (Все метки)

Ребят не пойму как правильно сделать рекурсию, мой алгоритм не правильный. Бывает просто 0 откроет и все, бывает нули еще рядом не открытые остаются..

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
procedure TForm1.OpenCell(i, j: integer);
begin
 if status = 2 then exit;  
 
 
 if Pole[i,j]= -1 then exit; // Если тут граница
 
 nOpened[i,j]:=true; //Флаг что мы ее открывали
 
 SG.Cells[i-1,j-1]:=IntToStr(Pole[i,j]);
 
 
if Pole[i,j]= 9 then
begin
 status:=2;
ShowMessage('Вы проиграли!');
end;
 
 if (Pole[i,j]=0) and (Pole[i-1,j]>-1) and Not(nOpened[i-1,j])  then
  begin
    if (Pole[i-1,j]<=3) and (Pole[i-1,j]>-1) and Not(nOpened[i-1,j]) then OpenCell(i-1,j);
    if (Pole[i+1,j]<=3) and (Pole[i-1,j]>-1) and Not(nOpened[i+1,j]) then OpenCell(i+1,j);
    if (Pole[i,j-1]<=3) and (Pole[i-1,j]>-1) and Not(nOpened[i,j-1]) then OpenCell(i,j-1);
    if (Pole[i,j+1]<=3) and (Pole[i-1,j]>-1) and Not(nOpened[i,j+1]) then OpenCell(i,j+1);
 
    if (Pole[i-1,j-1]<=3) and (Pole[i-1,j-1]>-1) and Not(nOpened[i-1,j-1]) then OpenCell(i-1,j-1);
    if (Pole[i+1,j+1]<=3) and (Pole[i+1,j+1]>-1) and Not(nOpened[i+1,j+1]) then OpenCell(i+1,j+1);
    if (Pole[i+1,j-1]<=3) and (Pole[i-1,j+1]>-1) and Not(nOpened[i+1,j-1]) then OpenCell(i+1,j-1);
    if (Pole[i-1,j+1]<=3) and (Pole[i-1,j-1]>-1) and Not(nOpened[i-1,j+1]) then OpenCell(i-1,j+1);
  end;
end;
Миниатюры
Сапер  
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.11.2014, 20:10
Ответы с готовыми решениями:

Сапер
Кто подскажет как сделать в сапере чтобы он выводил в конце игры время за которое ты прошел, и...

Сапер на Delphi
Хочу написать сапера на делфи. Принимаю любую помощь и предложения.

Программа игра Сапер
В Borland Delphi составить программы, реализующие следующие компьютерные игры Сапер. просьба, с...

Нужен исходник игры Сапер
Нигде не могу найти нормальный исходник игры Сапер 2002. Помогите пожалуйста.

4
2 / 4 / 0
Регистрация: 27.10.2014
Сообщений: 84
18.11.2014, 20:33 2
Mikky Lova,

вот полный листинг сейчас выложу

Процедура NewGame

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// новая игра — генерирует новое поле
 
procedure NewGame ();
 
 
row,col : integer; // координаты клетки (индексы массива)
 
n : integer; // количество поставленных мин 
 
k : integer; // кол-во мин в соседних клетках
 
begin
 
 
// Очистим эл-ты массива, соответствующие клеткам 
 
// игрового поля 
 
for row :=1 to MR do 
 
for col :=1 to MC do Pole[row,col] := 0;
 
 
// расставим мины
 
 
Randomize О; // инициализация ГСЧ
 
 
n := 0; // кол-во мин
 
 
repeat
 
 
row := Random(MR) + 1; 
 
col := Random(MC) + 1; 
 
if (Pole[row,col] <> 9) then begin
 
 
Pole[row,col] := 9; n := n+1; 
 
end;
 
until (n = NM);
 
 
// для каждой клетки вычислим // кол-во мин в соседних клетках
 
for row := 1 to MR do 
 
for col := 1 to MC do
 
 
if (Pole[row,col] <> 9) then
 
begin k :=0 ;
 
 
if Pole[row-l,col-l] = 9 then k = k + 1;
 
 
if Pole[row-1,col] =' 9 then k = k + 1;
 
 
if Pole[row-1,col+1] = 9 then k = k + 1;
 
 
if Pole[row,col-1] = 9 then k = k + 1;
 
 
if Pole[row,col+1] = 9 then k = k + 1;
 
 
if Pole[row+1,col-1] = 9 then k = k + 1;
 
 
if Pole[row+1,col] = 9 then k = k + 1;
 
 
if Pole[row+l,col+l] = 9 then k := k + 1;
 
Pole[row,col] := k; 
 
end;
 
 
status := 0; // начало игры 
 
nMin := 0; // нет обнаруженных мин 
 
nFlag := 0; // нет поставленных флагов
 
end;
Добавлено через 2 минуты
Mikky Lova,

После того как процедура NewGame расставит мины, процедура showPoie выводит изображение игрового поля.


Листинг Процедура ShowPole

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Показывает поле
 
 
Procedure ShowPoie(Canvas : TCanvas; status : integer); 
 
var
 
 
row,col : integer; 
 
begin
 
 
for row := 1 to MR do 
 
for col := 1 to MC do
 
 
Kletka(Canvas, row, col, status);
 
end;
Процедура showPoie выводит изображение поля последовательно, клетка за клеткой. Вывод изображения отдельной клетки выполняет процедура Kletka. Процедура Kletka используется для вывода изображения поля в начале игры, во время игры и в ее конце. В начале игры (значение параметра status = 0) процедура выводит только контур клетки, во время игры — количество мин в соседних клетках или флажок, а в конце отображает исходное состояние клетки и действия пользователя. Информацию о фазе игры процедура Kletka получает через параметр status.


Листинг Процедура Kletka


Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// выводит на экран изображение клетки
 
 
Procedure Kletka(Canvas : TCanvas;
 
row, col, status : integer);
 
var
 
 
x,y : integer; // координаты области вывода
 
begin
 
 
x := (col-1)* W + I; у := (row-1)* H + 1;
 
 
if status = 0 then begin
 
 
Canvas.Brush.Color := clLtGray;
 
 
Canvas.Rectangle(x-1,y-1,x+W,y+H);
 
 
exit;
 
end;
 
 
if Pole[row,col] < 100 then 
 
begin
 
 
Canvas.Brush.Color := clLtGray; // неоткрытые — серые 
 
Canvas.Rectangle(x-1,y-l,x+W,y+H);
 
 
// если игра завершена (status = 2), то показать мины 
 
if (status = 2) and (Pole[row,col] = 9)
 
 
then Mina(Canvas, x, y) ; exit; end;
 
 
// открытая клетка
 
 
Canvas.Brush.Color := clWhite; // открытые белые
 
 
Canvas.Rectangle(x-1,y-l,x+W,y+H);
 
 
if (Pole[row,col] = 100)
 
 
then exit; // клетка открыта, но она пустая
 
 
if (Pole[row,col] >= 101)
 
and (Pole[row,col] <= 108)
 
then begin // в соседних клетках есть мины
 
 
Canvas.Font.Size := 14;
 
 
Canvas.Font.Color := clBlue;
 
 
Canvas.TextOut(x+3,y+2,IntToStr(Pole[row,col] -100));
 
 
exit;
 
end;
 
 
if (Pole[row,col] >= 200)
 
then Flag(Canvas, x, y);
 
 
if (Pole[row,col] = 109) 
 
then // на этой мине подорвались! 
 
begin
 
 
Canvas.Brush.Color := clRed;
 
Canvas.Rectangle(x-1,y-1,x+W,y+H);
 
 
end;
 
 
if ((Pole[row,col] mod 10) = 9)
 
and (status = 2) then
 
 
Mina(Canvas, x, y);
 
end;
Добавлено через 1 минуту
Mikky Lova,

Во время игры программа воспринимает нажатия кнопок мыши и, в соответствии с правилами игры, открывает клетки или ставит в клетки флажки.


Основную работу выполняет процедура обработки события onMouseDown . Сначала процедура преобразует координаты точки, в которой игрок нажал кнопку мыши, в координаты клетки игрового поля. Затем делает необходимые изменения в массиве Pole и, если нажата правая кнопка, рисует в клетке флажок. Если нажата левая кнопка в клетке, в которой нет мины, то эта клетка открывается, на экран выводится ее содержимое. Если нажата левая кнопка в клетке, в которой есть мина, то вызывается процедура showPole, которая показывает все мины, в том числе и те, которые игрок не успел найти.


Листинг Обработка события OnMouseDown на поверхности игрового поля

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// нажатие кнопки мыши на игровом поле
 
 
procedure TForm1.Form1MouseDown(Sender: TObject; 
 
Button: TMouseButton;
 
 
Shift: TShiftState; X, Y: Integer);
 
var
 
 
row, col : integer;
 
begin
 
 
if status = 2 // игра завершена 
 
then exit;
 
 
if status = 0 then // первый щелчок
 
status := 1;
 
 
// преобразуем координаты мыши в индексы
 
 
// клетки поля
 
 
row := Trunc(y/H) + 1;
 
 
col := Trunc(x/W) + 1;
 
 
if Button = mbLeft then
 
 
begin
 
 
if Pole[row,col] = 9 then
 
 
begin // открыта клетка, в которой есть мина 
 
Pole[row,col] := Pole[row,col] + 100;
 
status := 2; // игра закончена 
 
ShowPole(Form1.Canvas, status); 
 
end else 
 
if Pole[row,col] < 9 then
 
 
Open(row,col);
 
end else
 
 
if Button = mbRight then
 
 
if Pole[row,col] > 200 then begin
 
 
// уберем флаг и закроем клетку 
 
nFlag := nFlag — 1;
 
 
Pole[row,col] := Pole[row,col]-200;
 
// уберем флаг 
 
x := (col-D* W + 1; у := (row-1)* H + 1; 
 
Canvas.Brush.Color := clLtGray; 
 
Canvas.Rectangle(x-1,y-1,x+W,y+H); 
 
end else
 
 
begin // поставить в клетку флаг 
 
nFlag := nFlag + 1; if Pole[row,col] = 9
 
 
then nMin := nMin + 1;
 
 
Pole[row,col]:=Pole[row,col]+200;
 
// поставили флаг 
 
if (nMin = NM) and (nFlag = NM) then begin
 
 
status := 2; 
 
// игра закончена 
 
ShowPole(Form1.Canvas, status); 
 
end
 
 
else Kletka(Form1.Canvas, row, col, status); 
 
end; 
 
end;
0
7 / 7 / 5
Регистрация: 27.10.2013
Сообщений: 170
18.11.2014, 20:42  [ТС] 3
Спасибо, но мне надо разобраться в своей ошибке и исправить , у меня работает не много по другому. Через массив чисел и булевский массив где открыта ячейка, а где нет.
0
Модератор
3477 / 2600 / 741
Регистрация: 19.09.2012
Сообщений: 7,967
18.11.2014, 20:43 4
Возможно, проблема в том, что в строках 21-24 "среднее" выражение везде одно и то же: (Pole[i-1,j]>-1)
1
7 / 7 / 5
Регистрация: 27.10.2013
Сообщений: 170
18.11.2014, 20:53  [ТС] 5
Спасибо)
Вот как,
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
procedure TForm1.OpenCell(i, j: integer);
begin
 if status = 2 then exit; //
 
 
 if Pole[i,j]= -1 then exit; // Åñëè ïîïàëè íà ãðàíèöó ïîëÿ
 
 nOpened[i,j]:=true; //Ôëàã ÷òî òóò îòêðûâàëè
 
 SG.Cells[i-1,j-1]:=IntToStr(Pole[i,j]);
 
if Pole[i,j]= 9 then
begin
 status:=2;
ShowMessage('Âû ïðîèãðàëè!');
end;
 
 if (Pole[i,j]=0) and (Pole[i,j]>-1)  then
  begin
    if (Pole[i-1,j]<=3) and (Pole[i-1,j]>-1) and Not(nOpened[i-1,j]) then OpenCell(i-1,j);
    if (Pole[i+1,j]<=3) and (Pole[i+1,j]>-1) and Not(nOpened[i+1,j]) then OpenCell(i+1,j);
    if (Pole[i,j-1]<=3) and (Pole[i,j-1]>-1) and Not(nOpened[i,j-1]) then OpenCell(i,j-1);
    if (Pole[i,j+1]<=3) and (Pole[i,j+1]>-1) and Not(nOpened[i,j+1]) then OpenCell(i,j+1);
 
    if (Pole[i-1,j-1]<=3) and (Pole[i-1,j-1]>-1) and Not(nOpened[i-1,j-1]) then OpenCell(i-1,j-1);
    if (Pole[i+1,j+1]<=3) and (Pole[i+1,j+1]>-1) and Not(nOpened[i+1,j+1]) then OpenCell(i+1,j+1);
    if (Pole[i+1,j-1]<=3) and (Pole[i-1,j+1]>-1) and Not(nOpened[i+1,j-1]) then OpenCell(i+1,j-1);
    if (Pole[i-1,j+1]<=3) and (Pole[i-1,j-1]>-1) and Not(nOpened[i-1,j+1]) then OpenCell(i-1,j+1);
  end;
 
 
end;
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
18.11.2014, 20:53

игра сапер через массив из кнопок
я пишу через массив из кнопок и столкнулся с проблемой. не могу сообразить как завершить программу...

Сапер. При открытии ячеек stackoverflow
Здравствуйте. Пишу сапера, и появилась проблема. Пытаюсь реализовать следующую фишку: при нажатии...

Составить блок-схему для программы Сапер
Помогите составить блок-схему для программы Сапер код: unit Minesf; interface uses ...

Подскажите как вынести пару процедур в DLL (игра Сапер)
Игра сапер Нужно перенести в DLL модуль операции по двум процедурам TForm1.N1Click и...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru