init_tables

Тема в разделе "Машинное отделение", создана пользователем Orlov, 13 май 2007.

  1. WildCat
    Оффлайн

    WildCat Коршунов Игорь Команда форума

    Репутация:
    0
    Ты неправильно доску нарисовал. Надо 12 горизонталей, а то риальна конь ускачит :D
     
  2. Counter
    Оффлайн

    Counter Учаcтник

    Репутация:
    0
    Взял бы да объяснил человеку :), как сделать, чтобы не выходили за границу.
    Я вот не видел исходников ни одной программы, использующей представление 10x12.
    Наверно, номер вертикали приходится определять остатком от деления на 10.
    int File(int square)
    {
    return square % 10;
    }
    У WildCat все очень просто получается. Но без списков фигур, ни 10x12 ни 0x88 вряд ли эффективны. Как сделать цикл по всем полям? Что-то не встречал в этом форуме, как списки фигур лучше делать. На битбордах как раз проще выходит, так как они сами списками фигур и являются. А еще проще, для начала, уж массив из 64 элементов. Тогда и списки фигур можно и не делать.
     
  3. WildCat
    Оффлайн

    WildCat Коршунов Игорь Команда форума

    Репутация:
    0
    В принципе, битборды не самый плохой вариант. Если интересно как списки фигур делать, сделай отдельную ветку.
     
  4. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    по этому поводу - в свое время я работал на Агатах - юыли такие компьютеры для школ. и была в комплекте для них шахматная программа. начал я с ней играть. выиграл ладью - вдруг и у меня ладья пропала. приготовился забрать другую - с доски ферзь "ушел" :) я с компьютерным Бендером тогда забросил играть :) а когда сам начал программировать - то понял в чем была ошибка - неправильно восстанавливались битые фигуры при расчете вариантов...
    а какой самый плохой?
     
  5. Orlov
    Оффлайн

    Orlov Учаcтник

    Репутация:
    0
    TSCP
    int mailbox[120] = {
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, 0, 1, 2, 3, 4, 5, 6, 7, -1,
    -1, 8, 9, 10, 11, 12, 13, 14, 15, -1,
    -1, 16, 17, 18, 19, 20, 21, 22, 23, -1,
    -1, 24, 25, 26, 27, 28, 29, 30, 31, -1,
    -1, 32, 33, 34, 35, 36, 37, 38, 39, -1,
    -1, 40, 41, 42, 43, 44, 45, 46, 47, -1,
    -1, 48, 49, 50, 51, 52, 53, 54, 55, -1,
    -1, 56, 57, 58, 59, 60, 61, 62, 63, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
    };

    только понять не могу что здесь хорошего?
     
  6. Counter
    Оффлайн

    Counter Учаcтник

    Репутация:
    0
    TSCP - не mailbox, а массив из 64 элементов. То что в генераторе ходов координаты 64 переводятся в 120, не особо важно. И ничего хорошего в этом нет.

    /*
    * DATA.H
    * Tom Kerrigan's Simple Chess Program (TSCP)
    *
    * Copyright 1997 Tom Kerrigan
    */


    /* this is basically a copy of data.c that's included by most
    of the source files so they can use the data.c variables */

    extern int color[64];
    extern int piece[64];
     
  7. ProstoTak
    Оффлайн

    ProstoTak Старожил

    Репутация:
    1
    Ты издеваешся? Какая в хрен разница? Если будет 12 горизонталий и 10 вертикалей то конь в сторону свалится, а не вниз.
     
  8. Counter
    Оффлайн

    Counter Учаcтник

    Репутация:
    0
    ни свалица :)
     
  9. Counter
    Оффлайн

    Counter Учаcтник

    Репутация:
    0
    Так вопрос обычно не стоит. Всем интересно какой самый хороший, но самого хорошего нет, иначе бы все его использовали. Если неохота делать возвращение ходов назад, то лучше всего просто маасив из 64 элементов, так меньше байт копировать в новую позицию придеться.
     
  10. WildCat
    Оффлайн

    WildCat Коршунов Игорь Команда форума

    Репутация:
    0
    В том то и фишка, что некуда в сторону убегать.
     
  11. WildCat
    Оффлайн

    WildCat Коршунов Игорь Команда форума

    Репутация:
    0
    Пока самый плохой - это 0..77 :)

    Counter, заканчивай цитировать целые посты. Цитировать нужно лишь то, на что непосредственно ты хочешь ответить.

    Mailbox - это самое простое и удобное представление доски.
     
  12. ProstoTak
    Оффлайн

    ProstoTak Старожил

    Репутация:
    1
    Ой-Ой-Ой... какие мы вумные.. Да я сам уже допер... но тебе котяра я это припомню :)

    Я просто на сях не очень много работал. В паскале просто такое не проходит если стоит контроль выхода за границы массива.
     
  13. WildCat
    Оффлайн

    WildCat Коршунов Игорь Команда форума

    Репутация:
    0
    Это неудачная шутка...
     
  14. ProstoTak
    Оффлайн

    ProstoTak Старожил

    Репутация:
    1
    Я тя не понимаю. Какая шутка?
     
  15. WildCat
    Оффлайн

    WildCat Коршунов Игорь Команда форума

    Репутация:
    0
    Про выход за границы массива.
     
  16. Orlov
    Оффлайн

    Orlov Учаcтник

    Репутация:
    0
    у меня на паскале так:

    const ChessBoard=[0..7,10..17,20..27,30..37,40..47,50..57,60..67,70..77];

    и потом вот так:

    if(To in ChessBoard) ...

    где тут шутка?

    уж попроще чем в Си наверное
     
  17. ProstoTak
    Оффлайн

    ProstoTak Старожил

    Репутация:
    1
    to WildCat
    Ну если в ПАСКАЛЕ поставить контроль то при компиляции (или и при выполнении, уже не помню) будет выдавать ошибку. Ну типа если a:Array[1..8,1..8] of Byte, а обратишся к a[1,9]. Попробуй если не веришь.
     
  18. WildCat
    Оффлайн

    WildCat Коршунов Игорь Команда форума

    Репутация:
    0
    Это пока самое сложное из того, что я видел.

    ProstoTak, мы же про 0..120 говорили. Там никаких выходов за границы нет.
     
  19. ProstoTak
    Оффлайн

    ProstoTak Старожил

    Репутация:
    1
    Короче, какая теперь разница. Я же сказал что догнал как работать с 0..119 ( :) ) А тебе, Котяра, я всё припомню, будет и на моей улице праздник :D
     
  20. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    Выход "за боковой край" одномерного массива в Паскале это LOL! :lol:
     
  21. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    Такие тормоза словишь... В Паскале хорошо работают множества не более чем на 32 элемента, да и то тормоза, всяко уж лучше 0x88 либо 10x12. Причем 10x12 быстрее.

    Для теста можешь замерить что быстрее
    (To in ChessBoard) или (To and 136)
    Второй случай это прроверка выхода за пределы массива в 0x88
     
  22. Kirpich
    Оффлайн

    Kirpich Учаcтник

    Репутация:
    0
    Народ, а где можно почитать об использовании битбордов для генерации ходов? С азов такскать. Что такое битовые операции знаю.
     
  23. WinPooh
    Оффлайн

    WinPooh В.М. Команда форума

    Репутация:
    95
    В Википедии, конечно.
    http://en.wikipedia.org/wiki/Bitboard
     
  24. Kirpich
    Оффлайн

    Kirpich Учаcтник

    Репутация:
    0
    спасибо, сам не додумался :D
     
  25. ProstoTak
    Оффлайн

    ProstoTak Старожил

    Репутация:
    1
    Я тоже посмотрел. Ох чуйствую займусь таки :D
     
  26. ProstoTak
    Оффлайн

    ProstoTak Старожил

    Репутация:
    1
    Начал ваять генератор ходов на сях, на доске char table[120]. Чуйствую основные тормоза будут при проверке на шах своему королю. Есть идеи по ускорениию проверки на шах?
     
  27. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    А какая она (проверка) сейчас?
     
  28. ProstoTak
    Оффлайн

    ProstoTak Старожил

    Репутация:
    1
    Сейчас никакой. Вот думаю. Но всё очень навороченно получается.
     
  29. WildCat
    Оффлайн

    WildCat Коршунов Игорь Команда форума

    Репутация:
    0
    Тормозов много не будет.
     
  30. ProstoTak
    Оффлайн

    ProstoTak Старожил

    Репутация:
    1
    Код:
    #include <stdio.h>
    #include <conio.h>
    //—————————————————————————————————————
    #define WP 1
    #define WR 2
    #define WN 3
    #define WB 4
    #define WQ 5
    #define WK 6
    #define BP 7
    #define BR 8
    #define BN 9
    #define BB 10
    #define BQ 11
    #define BK 12
    //—————————————————————————————————————
    char table[120]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                     -1,WR,WP, 0, 0, 0, 0,BP,BR,-1,
                     -1,WN,WP, 0, 0, 0, 0,BP,BN,-1,
                     -1,WB,WP, 0, 0, 0, 0,BP,BB,-1,
                     -1,WQ,WP, 0, 0, 0, 0,BP,BQ,-1,
                     -1,WK,WP, 0, 0, 0, 0,BP,BK,-1,
                     -1,WB,WP, 0, 0, 0, 0,BP,BB,-1,
                     -1,WN,WP, 0, 0, 0, 0,BP,BN,-1,
                     -1,WR,WP, 0, 0, 0, 0,BP,BR,-1,
                     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
                     -1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
    
    char LN[]={-21,-19,-12,-8,8,12,19,21}; // Лучи коня
    char LR[]={-10,-1,1,10};               // Лучи ладьи
    char LB[]={-11,-9,9,11};               // Лучи слона
    char LK[]={-11,-10,-9,-1,1,9,10,11};   // Лучи короля
    #define LQ LK                          // Лучи ферзя
    //—————————————————————————————————————
    void CreateMoveWP(char);
    void CreateMoveWR(char);
    void AddMoveWR(char,char);
    void CreateMoveWN(char);
    void AddMoveWN(char,char);
    void CreateMoveWB(char);
    void AddMoveWB(char,char);
    void CreateMoveWQ(char);
    void AddMoveWQ(char,char);
    void CreateMoveWK(char);
    void AddMoveWK(char,char);
    //==========================================================================
    
                                         main()
    {
    char v,g,p,f;
    
    clrscr();
    
    for(g=0;g<8;g++) {
      for(v=0;v<8;v++) {
        f=table[p=10*v+g+21];
        if(f>=WP && f<=WK) {
          switch (f) {
            case WP: CreateMoveWP(p); break;
            case WR: CreateMoveWR(p); break;
            case WN: CreateMoveWN(p); break;
            case WB: CreateMoveWB(p); break;
            case WQ: CreateMoveWQ(p); break;
            case WK: CreateMoveWK(p); break;
          }
        }
      }
    }
    
    getch();
    
    return 0;
    
    }
    //==========================================================================
    void CreateMoveWP(char p) {
      printf("%c%d - Pawn\n",p/10+63,p%10);
    }
    //—————————————————————————————————————
    void CreateMoveWR(char p1) {
    char L,p2,f;
      printf("(%c%d)Rock: ",p1/10+63,p1%10);
      for(L=0;L<4;L++){
         f=table[p2=p1+LR[L]];
         while(f==0 || (f>=BP && f<=BK)) {
           AddMoveWR(p1,p2);
           f=table[p2+=LR[L]];
           if(f>=WP && f<=WK) break;
           if(f>=BP && f<=BK) { AddMoveWR(p1,p2); break;}
         }
      }
      printf("\n");
    }
    //—————————————————————————————————————
    void AddMoveWR(char p1, char p2) {
    // Здесь проверяем возможен ли ход ладьёй с поля p1 на поле p2
    // (на предмет шаха своему королю) и если да то добавляем ход в список ходов
    
    
      printf("%c%d-%c%d  ",p1/10+63,p1%10,p2/10+63,p2%10); // Пока заглушка
    }
    //—————————————————————————————————————
    void CreateMoveWN(char p1) {
    char L,p2,f;
      printf("(%c%d)Knight: ",p1/10+63,p1%10);
      for(L=0;L<8;L++){
         f=table[p2=p1+LN[L]];
         if(f==0 || (f>=BP && f<=BK)) AddMoveWN(p1,p2);
      }
      printf("\n");
    }
    //—————————————————————————————————————
    void AddMoveWN(char p1, char p2) {
    // Здесь проверяем возможен ли ход конём с поля p1 на поле p2
    // (на предмет шаха своему королю) и если да то добавляем ход в список ходов
    
      printf("%c%d-%c%d  ",p1/10+63,p1%10,p2/10+63,p2%10); // Пока заглушка
    }
    //—————————————————————————————————————
    void CreateMoveWB(char p1) {
    
    char L,p2,f;
      printf("(%c%d)Bishop: ",p1/10+63,p1%10);
      for(L=0;L<4;L++){
         f=table[p2=p1+LB[L]];
         while(f==0 || (f>=BP && f<=BK)) {
           AddMoveWB(p1,p2);
           f=table[p2+=LB[L]];
           if(f>=WP && f<=WK) break;
           if(f>=BP && f<=BK) { AddMoveWB(p1,p2); break;}
         }
      }
      printf("\n");
    }
    //—————————————————————————————————————
    void AddMoveWB(char p1, char p2) {
    // Здесь проверяем возможен ли ход слоном с поля p1 на поле p2
    // (на предмет шаха своему королю) и если да то добавляем ход в список ходов
    
      printf("%c%d-%c%d  ",p1/10+63,p1%10,p2/10+63,p2%10); // Пока заглушка
    }
    //—————————————————————————————————————
    void CreateMoveWQ(char p1) {
    char L,p2,f;
      printf("(%c%d)Quin: ",p1/10+63,p1%10);
      for(L=0;L<8;L++){
         f=table[p2=p1+LQ[L]];
         while(f==0 || (f>=BP && f<=BK)) {
           AddMoveWQ(p1,p2);
           f=table[p2+=LQ[L]];
           if(f>=WP && f<=WK) break;
           if(f>=BP && f<=BK) { AddMoveWQ(p1,p2); break;}
         }
      }
      printf("\n");
    }
    //—————————————————————————————————————
    void AddMoveWQ(char p1, char p2) {
    // Здесь проверяем возможен ли ход ферзём с поля p1 на поле p2
    // (на предмет шаха своему королю) и если да то добавляем ход в список ходов
    
    
      printf("%c%d-%c%d  ",p1/10+63,p1%10,p2/10+63,p2%10); // Пока заглушка
    }
    //—————————————————————————————————————
    void CreateMoveWK(char p1) {
    char L,p2,f;
      printf("(%c%d)King: ",p1/10+63,p1%10);
      for(L=0;L<8;L++){
         f=table[p2=p1+LK[L]];
         if(f==0 || (f>=BP && f<=BK)) AddMoveWK(p1,p2);
      }
      printf("\n");
    }
    //—————————————————————————————————————
    void AddMoveWK(char p1, char p2) {
    // Здесь проверяем возможен ли ход королём с поля p1 на поле p2
    // (на предмет шаха своему королю) и если да то добавляем ход в список ходов
    
    
      printf("%c%d-%c%d  ",p1/10+63,p1%10,p2/10+63,p2%10); // Пока заглушка
    }
    //==========================================================================
    Вот что наваял пока. Можете начинать пинать ногами :)

    P.S. Приведённый выше код можно скомпилить, он рабочий. И начальную позицию можно выставить самому какую хошь. Особенно мне нравится реализация ходов дальнобойных фигур. :)
     
  31. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    Проверка, у меня такая (у меня не 10x12, а 0x88)

    Код:
    if ChKor[otkuda-Bking+128]>0 Then
             Begin
                Check_itW:=true;
                exit;
             end;
        // Пешка.
        if BKolPeshka>0 then
        begin
          kuda:=otkuda+17;
          if ((kuda and 136)=0) and (shortint(pole[kuda])=-1) then
          Begin
            Check_itW:=true;
            exit;
          end;
          kuda:=otkuda+15;
          if ((kuda and 136)=0) and (shortint(pole[kuda])=-1) then
          Begin
            Check_itW:=true;
            exit;
          end;
        end;
        // конь
        if BKolKon>0 then
        begin
          kuda:=otkuda+byte(33);
          if ((kuda and 136)=0) and (shortint(pole[kuda])=-2) then
          Begin
            Check_itW:=true;
            exit;
          end;
          kuda:=otkuda+byte(-33);
          if ((kuda and 136)=0) and (shortint(pole[kuda])=-2) then
          Begin
            Check_itW:=true;
            exit;
          end;
           kuda:=otkuda+byte(31);
          if ((kuda and 136)=0) and (shortint(pole[kuda])=-2) then
          Begin
            Check_itW:=true;
            exit;
          end;
          kuda:=otkuda+byte(-31);
          if ((kuda and 136)=0) and (shortint(pole[kuda])=-2) then
          Begin
            Check_itW:=true;
            exit;
          end;
             kuda:=otkuda+byte(14);
          if ((kuda and 136)=0) and (shortint(pole[kuda])=-2) then
          Begin
            Check_itW:=true;
            exit;
          end;
          kuda:=otkuda+byte(-14);
          if ((kuda and 136)=0) and (shortint(pole[kuda])=-2) then
          Begin
            Check_itW:=true;
            exit;
          end;
           kuda:=otkuda+byte(18);
          if ((kuda and 136)=0) and (shortint(pole[kuda])=-2) then
          Begin
            Check_itW:=true;
            exit;
          end;
          kuda:=otkuda+byte(-18);
          if ((kuda and 136)=0) and (shortint(pole[kuda])=-2) then
          Begin
            Check_itW:=true;
            exit;
          end;
        end;
          // слон или ферзь
          if (BKolBishop+BKolFerz)>0 then
          begin
          kuda:=otkuda+byte(-17);
          while (kuda and 136)=0 do
            begin
            chto:=shortint(pole[kuda]);
            if chto<>0 then
              begin
              if (chto=-3)or(chto=-5) then
               begin
               check_itW:=true;
               exit;
               end;
              break;
              end;
              kuda:=kuda+byte(-17);
            end;
    
            kuda:=otkuda+byte(17);
          while (kuda and 136)=0 do
            begin
            chto:=shortint(pole[kuda]);
            if chto<>0 then
              begin
              if (chto=-3)or(chto=-5) then
               begin
               check_itW:=true;
               exit;
               end;
              break;
              end;
              kuda:=kuda+byte(17);
            end;
     ....
     
  32. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    Смысл такой - ходим от короля каждым видом фигуры соперника (если такой вид присутствует на доске)
     
  33. ProstoTak
    Оффлайн

    ProstoTak Старожил

    Репутация:
    1
    Я так и собирался. Но нельзя ли как то поксорить или поандидь? :)
     
  34. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    Можно - смотри первые строки - смотрю по предварительно рассчитанному массиву.
    У меня нет списка фигур, поэтому могу таким образом проверить только на шах королем :) (используется для проверки легальности хода)
     
  35. WinPooh
    Оффлайн

    WinPooh В.М. Команда форума

    Репутация:
    95
    Код:
    int IsAttacked(const Position* pos, FLD f, COLOR side)
    {
        FLD from;
        PIECE p1, p2, patt;
        int delta;
        Sq* p;
    
        int fwd = 32 * side - 16;
    
        /* SLIDERS */
    
    #define TRACE_RAY(offset)                                                          \
                                                                                                     \
        from = f + offset;                                                                \
        while (Good(from))                                                              \
        {                                                                                       \
            if (Free(pos, from))                                                      \
            {                                                                               \
                from += offset;                                                  \
                continue;                                                           \
            }                                                                              \
                                                                                                    \
            patt = pos->board[from].piece;                             \
            if (patt == p1 || patt == p2)                            \
                return 1;                                \
                                                    \
            break;                                             \
        }
    
        p1 = QUEENW | side;
        p2 = BISHOPW | side;
    
        TRACE_RAY(15);
        TRACE_RAY(17);
        TRACE_RAY(-15);
        TRACE_RAY(-17);
    
        p2 = ROOKW | side;
    
        TRACE_RAY(16);
        TRACE_RAY(1);
        TRACE_RAY(-16);
        TRACE_RAY(-1);
    
    #undef TRACE_RAY
    
        /* KNIGHTS */
    
        p = pos->base[KNIGHTW | side].pnext;
        while (p != pos->pNF)
       {
            from = p - pos->board;
            delta = from - f;
            if (delta < 0)
                delta = - delta;
            
            if (delta < 34)
            {
                if (delta == 33 || delta == 31 || delta == 18 || delta == 14)
                    return 1;
            }
    
            p = p->pnext;
        }
    
        /* PAWNS */
    
        from = f - fwd - 1;
        if (Good(from) && pos->board[from].piece == (PAWNW | side))
            return 1;
    
        from = f - fwd + 1;
        if (Good(from) && pos->board[from].piece == (PAWNW | side))
            return 1;
    
        /* KING */
    
        delta = pos->King[side] - f;
    
        if (delta < 0)
            delta = - delta;
    
        if (delta < 18)
        {
            if (delta == 15 || delta == 16 || delta == 17 || delta == 1)
                return 1;
        }
    
        return 0;
    }
    Вот как-то так. Пример из одной из старых версий Греки, в которой было 0x88-представление позиции.