Форум программистов, компьютерный форум, киберфорум
PascalABC.NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.69/13: Рейтинг темы: голосов - 13, средняя оценка - 4.69
0 / 0 / 1
Регистрация: 12.01.2017
Сообщений: 104
1

Глобальные переменные и процедуры

14.01.2017, 10:45. Показов 2578. Ответов 2
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Итак, я решил, что начать изучение этого языка лучше начать с написания чего-то интересного и простого. Крестики-нолики показались мне идеальным выбором. А теперь к проблеме: (коротко: я делаю в процедуре так: глобалка winl:=true, а winl посылает меня и не становится true в глобальном смысле)
Суть кода примерно такая: (ход мой, ход компа)*4+мой ход+проверка ничьей.
При этом в каждой процедуре хода есть процедура проверки победы. Если размотать этот клубок до конца и выйти к моей проблеме, то получится следующие: есть глобальная переменная winl, при победе (не важно чьей) я присваиваю ей значение истины. Но, судя по всему, это не работает. Ей не присваивается нужное значение. Ничья, возникающая при значении "победа=ложь" после последнего хода работает, а присваивание истины при победе - нет. Выяснил я это, решив сделав игру бесконечной - чтобы после победы/поражения/ничьей она начиналась сначала.
Я убрал из побед halt и добавил в процедуры ходов первой строчкой строку if winl=true then exit;
Как итог - программа просто упрямо выполнялась до конца, не обращая ни малейшего внимания на ту строку. Вывод один - присваивание не работает. Хотелось бы спросить, что здесь не так и почему оно не работает? Заранее спасибо
Под спойлером сама программа.
Кликните здесь для просмотра всего текста
Pascal
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
program xoxoxoxox;
 
uses crt;
    //Переменная победа/поражения, для определения ничьей
var winl:boolean;
    //Выйти?
    quit:char;
    //Создаю массив символов
    field:array[0..2,0..2] of char;
    //Запись поля тильдами
procedure recording_empty_in_memory;
var i,n:byte;
begin
    i:=0;
    n:=0;
            for a:byte:=1 to 3 do
            begin
                for b:byte:=1 to 3 do
                    begin
                    field[n,i]:='~';
                    i:=i+1;
                    end;
            n:=n+1;
            i:=0;
            end;
end;
    //Отрисовка поля в текущем его состоянии
procedure draw;
var i,n:byte;
begin
    i:=0;
    n:=0;
            for a:byte:=1 to 3 do
            begin
            write(' ');
                for b:byte:=1 to 3 do
                    begin
                    write(field[n,i]);
                    i:=i+1;
                    end;
            n:=n+1;
            i:=0;
            writeln;
            end;
end;    
    //Ввод
procedure read_user_key;
var key:char;
    i:byte;
begin
    repeat
        i:=0;
        key:=readkey;
        if ((key<='9') and (key>='1')) then
            case key of
'7':if ((field[0,0]<>'X')and(field[0,0]<>'O')) then field[0,0]:='X' else i:=1;
'8':if ((field[0,1]<>'X')and(field[0,1]<>'O')) then field[0,1]:='X' else i:=1;
'9':if ((field[0,2]<>'X')and(field[0,2]<>'O')) then field[0,2]:='X' else i:=1;
'4':if ((field[1,0]<>'X')and(field[1,0]<>'O')) then field[1,0]:='X' else i:=1;
'5':if ((field[1,1]<>'X')and(field[1,1]<>'O')) then field[1,1]:='X' else i:=1;
'6':if ((field[1,2]<>'X')and(field[1,2]<>'O')) then field[1,2]:='X' else i:=1;
'1':if ((field[2,0]<>'X')and(field[2,0]<>'O')) then field[2,0]:='X' else i:=1;
'2':if ((field[2,1]<>'X')and(field[2,1]<>'O')) then field[2,1]:='X' else i:=1;
'3':if ((field[2,2]<>'X')and(field[2,2]<>'O')) then field[2,2]:='X' else i:=1;
            end
                    else
                        i:=1;
    until i=0;       
end;
    //ИИ
procedure AI;
var i,k,n:byte;
begin
n:=0;
    repeat
    i:=random(0,2);
    k:=random(0,2);
        if ((field[i,k]<>'X')and(field[i,k]<>'O')) then 
            begin 
                field[i,k]:='O';
                n:=9;
            end 
        else 
            n:=n+1;
    until n=9;
 
end; 
    //Действия при победе игрока
procedure winp(winl:boolean);
begin
winl:=true;
writeln(#10,' Вы победили!'); 
readkey; 
halt;
end;
    //Действия при победе компьютера
procedure winc(winl:boolean);
begin
winl:=true;
writeln(#10,' Вы проиграли!'); 
readkey; 
halt;
end;
    //Проверка на победу кого-либо. Выводит, кто победил
function winvec:char;
var x,y,i,n:byte;
begin
    begin
    y:=0;
    x:=0;
    i:=0;
    n:=0;
            for b:byte:=1 to 3 do
                                    begin
        for a:byte:=1 to 3 do
            begin
            if field[x,y]='X' then i:=i+1;
            if field[x,y]='O' then n:=n+1;
            if n=3 then winvec:='O';
            if i=3 then winvec:='X';
            y:=y+1;
            end;
                                        x:=x+1;
                                        y:=0;
                                        n:=0;
                                        i:=0;
                                    end;
    y:=0;
    x:=0;
    i:=0;
    n:=0;
            for b:byte:=1 to 3 do
                                    begin
        for a:byte:=1 to 3 do
            begin
            if field[x,y]='X' then i:=i+1;
            if field[x,y]='O' then n:=n+1;
            if n=3 then winvec:='O';
            if i=3 then winvec:='X';
            x:=x+1;
            end;
                x:=0;
                n:=0;
                i:=0;
                y:=y+1;
                                    end;
    y:=0;
    x:=0;
    i:=0;
    n:=0;
 
        for a:byte:=1 to 3 do
            begin
            if field[x,y]='X' then i:=i+1;
            if field[x,y]='O' then n:=n+1;
            if n=3 then winvec:='O';
            if i=3 then winvec:='X';
            x:=x+1;
            y:=y+1;
            end;
    y:=2;
    x:=0;
    i:=0;
    n:=0;
 
        for a:byte:=1 to 3 do
            begin
            if field[x,y]='X' then i:=i+1;
            if field[x,y]='O' then n:=n+1;
            if n=3 then winvec:='O';
            if i=3 then winvec:='X';
            x:=x+1;
            y:=y-1;
            end;
    end;
end;
    //Действия в зависимости от чьей-либо победы
procedure win(winvec:char);
begin
if winvec='X' then winp(winl);
if winvec='O' then winc(winl);
end;
    //Ход игрока
procedure user;
begin
clrscr;
    draw;
        writeln(#10,' Ваш ход: ');
    read_user_key;
clrscr;
    draw;
        win(winvec);
    writeln(#10,' Нажмите любую клавишу для совершения компьютером своего хода');
readkey;
end;
    //Ход компьютера
procedure com;
begin
AI;
clrscr;
draw;
win(winvec);
end;
    //Вся игра собрана в одну процеру
procedure game(winl:boolean);
begin
    recording_empty_in_memory;
    randomize;
    winl:=false;
        draw;        
 
    user;
        com;
    user;
        com;
    user;
        com;
    user;
        com;
        
clrscr;
draw;
writeln(#10,' Ваш ход: ');
read_user_key;
clrscr;
draw;
 
win(winvec);
 
if winl=false then 
begin 
writeln(#10,' Ничья');
readkey; 
halt;
end;
end;
 
begin
repeat
game(winl);
writeln(#10,' Для выхода нажмите q');
quit:=readkey
until quit='q';
end.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.01.2017, 10:45
Ответы с готовыми решениями:

Куда помещать свои переменные, процедуры и функции?
unit Unit1; interface uses System, System.Drawing, System.Windows.Forms; type Form1 =...

Глобальные переменные
Написать программу, которая с помощью подпрограммы процедуры находит сумму элементов одномерного...

глобальные переменные
Помогите пожалуйста избавиться от глобальных переменных! Заношу все в процедуры, программа не идет...

Глобальные переменные
помогите переделать программу надо убрать глобальные переменные у самого не получается=(( program...

2
3 / 2 / 1
Регистрация: 19.07.2019
Сообщений: 1
19.07.2019, 20:53 2
Лучший ответ Сообщение было отмечено Kujivunia как решение

Решение

ваш код, начинающийся со строки 88:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Действия при победе игрока
procedure winp(winl:boolean);
begin
winl:=true;
writeln(#10,' Вы победили!'); 
readkey; 
halt;
end;
* * //Действия при победе компьютера
procedure winc(winl:boolean);
begin
winl:=true;
writeln(#10,' Вы проиграли!'); 
readkey; 
halt;
end;
Не разбирался с вашим кодом полностью, но здесь видно, что у вас конфликт имён.
в начале программы (
Pascal
1
2
//Переменная победа/поражения, для определения ничьей
var winl:boolean;
)
вы объявляете переменную winl.
В наведенных мной процедурах вы используете переменную winl как аргумент, то есть во время выполнения процедуры существует ДВЕ переменные с именем winl, при этом переменная, которая объявлена в заголовке процедуры имеет больший приоритет, чем глобальная, то есть если в процедуре вы присваиваете переменной winl значение true, оно присваивается ЛОКАЛЬНОЙ переменной winl (которая, кстати, удаляется при завершении процедуры).
Тут надо бы менять название переменной в заголовке процедур, но конкретно в вашем случае, процедуре ВООБЩЕ не нужны какие-либо входные данные. То есть, код, начинающийся на строке 88 должен выглядеть как-то так:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//Действия при победе игрока
procedure winp;
begin
winl:=true;
writeln(#10,' Вы победили!'); 
readkey; 
halt;
end;
//Действия при победе компьютера
procedure winc;
begin
winl:=true;
writeln(#10,' Вы проиграли!'); 
readkey; 
halt;
end;
так же вам надо "починить" обращение к этим процедурам и пересмотреть остальной код (может там еще какая-то ошибка такого рода =)
надеюсь, понятно объяснил)
2
5079 / 2651 / 2349
Регистрация: 10.12.2014
Сообщений: 10,028
21.07.2019, 14:36 3
Во-первых, ваше форматирование… Совершенно не понятно где какие операторные скобки! А форматирование текста программы именно и приводит к лёгкости чтения кода.

Во-вторых, Kujivunia, очень странный код после такого вопроса: Как считать файл с текстом в одну переменную типа string максимально быстро?

Добавлено через 9 минут
Вы объявляете массив [0..2, 0..2], но зачем-то используете какие-то „костыли“, чтобы обратиться к конкретной ячейке этого массива.
К примеру, для заполнения массива в процедуре recording_empty_in_memory можно было же просто:
Pascal
1
2
3
  for var row := 0 to 2 do
    for var col := 0 to 2 do
      field[row, col] := '~';
Или процедура draw:
Pascal
1
2
3
4
5
6
7
  for a: byte := 0 to 2 do
  begin
    write(' ');
    for b: byte := 0 to 2 do
      write(field[a, b]);
    writeln;
  end;
Добавлено через 50 минут
Процедура read_user_key: зачем делать двойные проверки на <>X и <>O, когда достаточно одной =~:
Pascal
1
2
3
4
5
6
7
8
9
10
11
      case key of
        '7': if field[0, 0] = '~' then field[0, 0] := 'X' else i := 1;
        '8': if field[0, 1] = '~' then field[0, 1] := 'X' else i := 1;
        '9': if field[0, 2] = '~' then field[0, 2] := 'X' else i := 1;
        '4': if field[1, 0] = '~' then field[1, 0] := 'X' else i := 1;
        '5': if field[1, 1] = '~' then field[1, 1] := 'X' else i := 1;
        '6': if field[1, 2] = '~' then field[1, 2] := 'X' else i := 1;
        '1': if field[2, 0] = '~' then field[2, 0] := 'X' else i := 1;
        '2': if field[2, 1] = '~' then field[2, 1] := 'X' else i := 1;
        '3': if field[2, 2] = '~' then field[2, 2] := 'X' else i := 1;
      end
Да и, в принципе, case здесь лишнее:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
procedure read_user_key;
begin
  var theEnd := False;
  repeat
    var key := readkey;
    if key.InRange('1','9') then
      begin
        var n := StrToInt(key) - 1;
        var(row, col) := (2 - n div 3, n mod 3);
        if field[row, col] = '~' then
          (field[row, col], theEnd) := ('X', True);
      end;
  until theEnd;       
end;
Добавлено через 2 часа 29 минут
AI — просто верх совершенства! Ни какой логики! Тупой рандом…

С проверкой на выигрыш сильно… Масштабировать до 4-х в ряд вы не собираетесь, поэтому можно проще:
Pascal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function winvec: char;
begin
  if (field[0,0] <> '~') and (field[0,0] = field[0,1]) and (field[0,1] = field[0,2]) then // 1 ряд
    begin winvec := field[0,0]; Exit; end;
  if (field[1,0] <> '~') and (field[1,0] = field[1,1]) and (field[1,1] = field[1,2]) then // 2 ряд
    begin winvec := field[1,0]; Exit; end;
  if (field[2,0] <> '~') and (field[2,0] = field[2,1]) and (field[2,1] = field[2,2]) then // 3 ряд
    begin winvec := field[2,0]; Exit; end;
    
  if (field[0,0] <> '~') and (field[0,0] = field[1,0]) and (field[1,0] = field[2,0]) then // 1 колонка
    begin winvec := field[0,0]; Exit; end;
  if (field[0,1] <> '~') and (field[0,1] = field[1,1]) and (field[1,1] = field[2,1]) then // 1 колонка
    begin winvec := field[0,1]; Exit; end;
  if (field[0,2] <> '~') and (field[0,2] = field[1,2]) and (field[1,2] = field[2,2]) then // 1 колонка
    begin winvec := field[0,2]; Exit; end;
    
  if (field[0,0] <> '~') and (field[0,0] = field[1,1]) and (field[1,1] = field[2,2]) then // главная диагональ
    begin winvec := field[0,0]; Exit; end;
  if (field[0,2] <> '~') and (field[0,2] = field[1,1]) and (field[1,1] = field[2,0]) then // побочная диагональ
    begin winvec := field[0,2]; Exit; end;
end;
1
21.07.2019, 14:36
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.07.2019, 14:36
Помогаю со студенческими работами здесь

Модули и глобальные переменные
Писала курсовой проект, зная только задание. Позже выяснилось, что требуется использование модулей...

Локальные и глобальные переменные.
ОГбьясните пожалуйста чем отличаются Procedure и Function Да и что такое глобальные и локальные...

Локальные и глобальные переменные
var a,b,c,d:integer; procedure p(x:integer; var a:integer); var c:integer; begin x:=5;...

Глобальные и локальные переменные, одна и та же прога в процедуре Не работает, а просто так работает. Почему?
Здравствуйте, есть программка которая переводит из 2-ной системы в 10-ную. Она работает. А вот...

Задать переменные для процедуры val
Подскажите, кто может..как правильно задать для процедуры val a,b,c?по идеи эти числа должны быть в...

Какие в коде имеются глобальные переменные, процедуры и функции
И за что они отвечают? #include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;locale&gt; #include...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru