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
сообщение 10.06.2007 0:43
Сообщение #2


Профи
****

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

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


Ладно, объясняю принцип игры компа. Теперь собственно поиск хода:
Как видно, алгоритм ищет лучший ход перебирая только клетки, значение которых rad1 или rad2, думаю понятно почему именно их (нет смысла ходить далеко от уже поставленных х/о). Алгоритм представляет собой обычный рекурсивный перебор в глубину с оценкой. Глубина перебора задается константой ply_max1. Я говорил, что функция evaluate осуществляет проверку на 5 в ряд... Так вот, это не точно. На самом деле это оценочная функция, она определяет "качество" позиции для заданного игрока. То есть чем больше возвращаемое функцией значение, тем выгоднее эта позиция для указанного игрока. Константа inf задает условную бесконечность. То есть если функция evaluate вернула значение inf, значит игрок победил.

Как происходит оценка позиции в функции evaluate? Предположим проверяется "качество" позиции для крестиков. Тогда для каждого найденного на поле крестика вызывается функция ev_, которая проверяет все клетки в заданном направлении. Направление задается массивами vert, hor, diag1, diag2. В каждом из этих массивов содержатся относительные смещения координат (как в случае с массивами mr1 и mr2). Функция ev_ рассматривает полоску длинной в 11 клеток в заданном направлении и с центром в заданной точке. Она вызывается для каждого из возможных направлений. Что она делает с этой полоской? Оценивает ее и результат прибавляет к общей оценке всей игровой позиции. Если в полоске есть 5 в ряд, ev_ устанавливает флаг win и заканчивает свое выполнение. Как функция ev_ оценивает полоску? У меня нет никакого желания разбираться. Слишком путано написано. Проще написать с нуля, тем более, что это не сложно. Нужно учитывать вот что:
* Чем больше в ряд, тем лучше
* Последовательность обесценивается если в ней собрать 5 невозможно в принципе (к примеру противник ограничил)
* Если 3 или 4 в ряд и не ограничены противником с обоих сторон, то цена позиции - очень большая (это практически победа)

Все! Если есть вопросы, задавайте.

Сообщение отредактировано: Archon - 10.06.2007 0:46


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

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


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

 



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