![]() |
![]() |
cooler |
![]()
Сообщение
#1
|
![]() Бывалый ![]() ![]() ![]() Группа: Пользователи Сообщений: 178 Пол: Мужской Репутация: ![]() ![]() ![]() |
Обращаюсь прежде всего к volvo и мисс_графити.
Прошу помочь 2м нуждающимся (мне и DRAKON'у). Есть у нас такая программа крестики-нолики. Я (не знаю как DRAKON) не прошу комментировать текст программы (сам бы на вашем месте не стал) прошу лишь показать и пояснить хотя бы 2 места в программе: проверка 5 символов в ряд и как компьютер определяет место для своего хода. Я думаю так, проверка 5 в ряд здесь: Код type tvert=array[1..20] of integer; const vert : tvert = (0,0,0,0,0, -1,-2,-3,-4,-5, 0,0,0,0,0, 1,2,3,4,5); hor : tvert = (-1,-2,-3,-4,-5, 0,0,0,0,0, 1,2,3,4,5, 0,0,0,0,0); diag1 : tvert = (-1,-2,-3,-4,-5, -1,-2,-3,-4,-5, 1,2,3,4,5, 1,2,3,4,5); diag2 : tvert = (1,2,3,4,5, -1,-2,-3,-4,-5, -1,-2,-3,-4,-5, 1,2,3,4,5); const ee=10; function evaluate(color:integer):longint; var ii,jj,i,j,k,l,pos,ev,pol : longint; fl,fl1,win,fl2 : boolean; procedure ev_(vert:tvert); var i : integer; begin pos:=1; pol:=1; fl:=false; fl1:=true; fl2:=false; for i:=1 to 4 do begin if field[ii+vert[i],jj+vert[i+5]]=color then begin if fl1 then pos:=pos+1; pol:=pol*ee; end else case field[ii+vert[i],jj+vert[i+5]] of null,rad1,rad2: begin if i<4 then if field[ii+vert[i+1],jj+vert[i+6]]=color then fl:=true else break else if field[ii+vert[i+1],jj+vert[i+6]]=color then begin pol:=pol*ee; fl2:=true; end; fl1:=false; end; else begin fl:=true; k:=i; break; end; end;{case} end; fl1:=true; for i:=11 to 14 do begin if field[ii+vert[i],jj+vert[i+5]]=color then begin if fl1 then pos:=pos+1; pol:=pol*ee; end else case field[ii+vert[i],jj+vert[i+5]] of null,rad1,rad2: begin if i<14 then if field[ii+vert[i+1]+0,jj+vert[i+6]]=color then fl2:=true else break else if field[ii+vert[i+1]+0,jj+vert[i+6]]=color then begin pol:=pol*ee; end; fl1:=false; end; else begin if fl and(k+i-10<5) then pol:=0; fl:=true; break; end; end;{case} end; if pol>10000000 then pol:=10000000; if fl or fl2 then ev:=ev+pol else ev:=ev+pol*ee; if pos>4 then win:=true; end; begin ev:=0; win:=false; for ii:=1 to n do begin for jj:=1 to n do begin if field[ii,jj]=color then begin ev_(vert); ev_(hor); ev_(diag1); ev_(diag2); end;{if} if win then break; end; if win then break; end; if win then ev:=inf; evaluate:=ev; end; function ev_step(color:integer;ii,jj:longint):longint; var i,j,k,l,pos,ev,pol : longint; fl,fl1,win,fl2 : boolean; procedure ev_(vert:tvert); var i : integer; begin pos:=1; pol:=1; fl:=false; fl1:=true; fl2:=false; for i:=1 to 4 do begin if field[ii+vert[i],jj+vert[i+5]]=color then begin if fl1 then pos:=pos+1; pol:=pol*ee; end else case field[ii+vert[i],jj+vert[i+5]] of null,rad1,rad2: begin if i<4 then if field[ii+vert[i+1],jj+vert[i+6]]=color then fl:=true else break else if field[ii+vert[i+1],jj+vert[i+6]]=color then begin pol:=pol*ee; fl2:=true; end; fl1:=false; end; else begin fl:=true; k:=i; break; end; end;{case} end; fl1:=true; for i:=11 to 14 do begin if field[ii+vert[i],jj+vert[i+5]]=color then begin if fl1 then pos:=pos+1; pol:=pol*ee; end else case field[ii+vert[i],jj+vert[i+5]] of null,rad1,rad2: begin if i<14 then if field[ii+vert[i+1]+0,jj+vert[i+6]]=color then fl2:=true else break else if field[ii+vert[i+1]+0,jj+vert[i+6]]=color then begin pol:=pol*ee; end; fl1:=false; end; else begin if fl and(k+i-10<5) then pol:=0; fl:=true; break; end; end;{case} end; if pol>10000000 then pol:=10000000; if fl or fl2 then ev:=ev+pol else ev:=ev+pol*ee; if pos>4 then win:=true; end; begin win:=false; if field[ii,jj]=color then begin ev_(vert); ev_(hor); ev_(diag1); ev_(diag2); end;{if} if win then ev:=inf; ev_step:=ev; end; Что здесь происходит? Помогите найти как компьютер ходит?(если можно поясните принцип) И ещё 2 маленьких вопроса: Что за массивы заполняются в начале программы? Зачем так много процедур в модуле?(зачем они вообще) Если чем поможете можем и отблагодарить. Заранее не могу, т.к уже нет времени. Просто физически не смогу. Заранее благодарен. |
![]() ![]() |
Archon |
![]()
Сообщение
#2
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 618 Пол: Мужской Репутация: ![]() ![]() ![]() |
Брррр... Автор кода явно не утруждал себя коментариями. Но так как все мы стараемся быть немного телепатами, я попробую это расшифровать. Не гарантирую, что объясню весь код за один присест, но уж на что терпения хватит
![]() Сперва опишу пару массивов: field : array[-2..n+3,-2..n+3] of integer; Первый - это игровой поле, оно задано явно больше чем нужно, то есть реально используется только диапазон [1..n,1..n]. В первую очередь это сделано для того, чтобы не проверять каждый раз границы массива. Второй - это набор игровых полей. Сделано глупо, проще было написать "array[0..max_ply] of field;", тогда бы и сохранение/загрузка игрового поля в хистори было бы проще. Массив этот нужен, чтобы хранить в нем историю ходов (чтобы ходы отменять потом можно было). Далее процедуры и функции: procedure intro; Просто вывод заставки. Ничего особенного. procedure activate_field; Процедура заполняет игровое поле начальными значениями. Кстати, клетки на игровом поле могут принимать множество значений заданных константами, вот их описание: nol = -2 - нолик cross = -1 - крестик null = 4 - пустая клетка rad1 = 1 - Название от "радиус 1". Этим значением помечаются клетки, прилегающие вплотную к заполненным (то есть тем, в которых уже стоят крестик или нолик) rad2 = 2 - Аналогично. Только эти клетки отстоят от заполненных на 2. Чтобы лучше представить это, нарисуйте на листочке в клеточку несколько крестиков и ноликов, потом обведите то что получится по периметру единичками, а потом то что получится еще раз по периметру, только двойками. Зачем это нужно? Подозреваю, что для исскуственного интеллекта. out = -3 - клетка за пределами игрового поля. procedure makemove(move:tmove;ply:integer); Процедура делает ход. Сами параметры хода находятся в записи move. Сперва процедура сохраняет текущее игровое поле в хистори, потом собственно устанавливает крестик или нолик, а потом происходит установка тех самых rad1 и rad2, то есть просматриваются клетки, отстоящие на 1 клетку (туда устанавливается rad1), и клетки, отстоящие на 2 клетки (туда - rad2). Вот для этого и нужны массивы mr1 и mr2. В них хранятся смещения по координатам x и y, чтобы клетки мможно было проверить в цикле, а не набором условий вроде: if field[x-1,y-1]>0 then field[x-1,y-1]:=rad1; procedure unmakemove(ply:integer); восстанавливает игровое поле из хистори, то есть это, по сути, отмена хода. Уф... Пока все... Потом продолжу. PS cooler, ты угадал, функция evaluate осуществляет проверку на 5 в ряд, а поиск хода для AI осуществляет функция search1 Сообщение отредактировано: Archon - 9.06.2007 12:28 -------------------- Close the World...txeN eht nepO
|
![]() ![]() |
![]() |
Текстовая версия | 7.08.2025 21:09 |