IPB
ЛогинПароль:

> ПРОСЬБА-ОБРАЩЕНИЕ, злополучные крестики-нолики
cooler
сообщение 8.06.2007 19:46
Сообщение #1


Бывалый
***

Группа: Пользователи
Сообщений: 178
Пол: Мужской

Репутация: -  0  +


Обращаюсь прежде всего к 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 маленьких вопроса:
Что за массивы заполняются в начале программы?
Зачем так много процедур в модуле?(зачем они вообще)

Если чем поможете можем и отблагодарить. Заранее не могу, т.к уже нет времени. Просто физически не смогу.

Заранее благодарен.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
Archon
сообщение 9.06.2007 12:25
Сообщение #2


Профи
****

Группа: Пользователи
Сообщений: 618
Пол: Мужской

Репутация: -  24  +


Брррр... Автор кода явно не утруждал себя коментариями. Но так как все мы стараемся быть немного телепатами, я попробую это расшифровать. Не гарантирую, что объясню весь код за один присест, но уж на что терпения хватит smile.gif

Сперва опишу пару массивов:
field : array[-2..n+3,-2..n+3] of integer;
history : array[0..max_ply,-2..n+3,-2..n+3] of shortint;

Первый - это игровой поле, оно задано явно больше чем нужно, то есть реально используется только диапазон [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;
if field[x,y-1]>0 then field[x,y-1]:=rad1;
if field[x+1,y-1]>0 then field[x+1,y-1]:=rad1;
if field[x-1,y]>0 then field[x-1,y]:=rad1;
...

procedure unmakemove(ply:integer);
восстанавливает игровое поле из хистори, то есть это, по сути, отмена хода.

Уф... Пока все... Потом продолжу.

PS cooler, ты угадал, функция evaluate осуществляет проверку на 5 в ряд, а поиск хода для AI осуществляет функция search1

Сообщение отредактировано: Archon - 9.06.2007 12:28


--------------------
Close the World...txeN eht nepO
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

Сообщений в этой теме


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 7.08.2025 21:09
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"