Ledger Nano X - The secure hardware wallet
SHARE
TWEET

qweww

a guest Apr 9th, 2020 229 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include<stdlib.h>
  2. #include<stdio.h>
  3. #include<string.h>
  4. #include<ctype.h>
  5.  
  6.  
  7.  
  8. enum {
  9.     EMPTY,
  10.     PAWN, QUEEN, KING,
  11.     KNIGHT, BISHOP, ROOK,
  12.     BARRIER
  13. };
  14. enum {
  15.     ANGLE0, ANGLE45, ANGLE90, ANGLE135
  16. };
  17.  
  18. typedef unsigned char uchar;
  19. typedef struct {
  20.     uchar figure : 3;
  21.     uchar mobility : 2;
  22.     uchar color : 1;
  23.     uchar attacked : 1;
  24.     uchar special : 1;
  25. } cell_t;
  26.  
  27.  
  28.  
  29. cell_t desk[10][10];
  30.  
  31. void clear_desk() {
  32.     for (int i = 1; i <= 8; ++i) {
  33.         for (int j = 1; j <= 8; ++j) {
  34.             desk[i][j].figure = EMPTY;
  35.         }
  36.     }
  37. }
  38. void clear_desk_state() {
  39.     for (int i = 1; i <= 8; ++i) {
  40.         for (int j = 1; j <= 8; ++j) {
  41.             desk[i][j].attacked = 0;
  42.             desk[i][j].special = 0;
  43.         }
  44.     }
  45. }
  46. void init_desk() {
  47.     for (int i = 0; i < 10; ++i) {
  48.         desk[i][0].figure = BARRIER;
  49.         desk[i][9].figure = BARRIER;
  50.         desk[0][i].figure = BARRIER;
  51.         desk[9][i].figure = BARRIER;
  52.     }
  53.     clear_desk();
  54.     clear_desk_state();
  55. }
  56.  
  57.  
  58.  
  59. char **move_table;
  60. int moveptr_list[6] = { 0, 0, 0, 0, 0, 0 };
  61.  
  62. void clear_move_table() {
  63.     for (int i = 0; i < 6; ++i) {
  64.         moveptr_list[i] = 0;
  65.     }
  66. }
  67. void init_move_table() {
  68.     move_table = malloc(6 * sizeof(char*));
  69.     for (int i = 0; i < 6; ++i) {
  70.         move_table[i] = malloc(1024 * sizeof(char));
  71.     }
  72.     clear_move_table();
  73. }
  74. void destroy_move_table() {
  75.     for (int i = 0; i < 6; ++i) {
  76.         free(move_table[i]);
  77.     }
  78.     free(move_table);
  79. }
  80.  
  81. void add_move(int fromX, int fromY, int toX, int toY) {
  82.     char *move_list = move_table[desk[fromX][fromY].figure - 1];
  83.     int moveptr = moveptr_list[desk[fromX][fromY].figure - 1];
  84.     move_list[moveptr++] = fromX + 'a' - 1;
  85.     move_list[moveptr++] = fromY + '0';
  86.     move_list[moveptr++] = toX + 'a' - 1;
  87.     move_list[moveptr++] = toY + '0';
  88.     moveptr_list[desk[fromX][fromY].figure - 1] = moveptr;
  89. }
  90.  
  91.  
  92.  
  93. void update_castling(void);
  94. void extra_check(void);
  95.  
  96.  
  97. struct {
  98.     int fromX, fromY, toX, toY, figure;
  99. } current_move;
  100. int side;
  101. void set_current_move(int fromX, int fromY, int toX, int toY, int figure) {
  102.     current_move.fromX = fromX;
  103.     current_move.fromY = fromY;
  104.     current_move.toX = toX;
  105.     current_move.toY = toY;
  106.     current_move.figure = figure;
  107. }
  108. void release_current_move() {
  109.     int fromX = current_move.fromX,
  110.         fromY = current_move.fromY,
  111.         toX = current_move.toX,
  112.         toY = current_move.toY,
  113.         figure = current_move.figure;
  114.     side = !desk[fromX][fromY].color;
  115.     if (fromX == toX && fromY == toY) {
  116.         return;
  117.     }
  118.     update_castling();
  119.     extra_check();
  120.     if (desk[fromX][fromY].figure == KING && abs(fromX - toX) > 1) {
  121.         int _fromX = fromX < toX ? 8 : 1, _toX = (fromX + toX) / 2;
  122.         desk[_toX][toY] = desk[_fromX][fromY];
  123.         desk[_fromX][fromY].figure = EMPTY;
  124.     }
  125.     if (desk[fromX][fromY].figure == PAWN) {
  126.         if (toY == (side ? 1 : 8)) {
  127.             desk[fromX][fromY].figure = figure;
  128.         }
  129.         if (fromX != toX && desk[toX][toY].figure == EMPTY) {
  130.             desk[toX][fromY].figure = EMPTY;
  131.         }
  132.     }
  133.     desk[toX][toY] = desk[fromX][fromY];
  134.     desk[fromX][fromY].figure = EMPTY;
  135. }
  136.  
  137.  
  138. int castling_active[2][3];
  139. void update_castling() {
  140.     int fromX = current_move.fromX,
  141.         fromY = current_move.fromY,
  142.         toX = current_move.toX,
  143.         toY = current_move.toY;
  144.     for (int i = 1; i <= 8; i += 7) {
  145.         for (int j = 1; j <= 8; j += 3 + (j == 1)) {
  146.             castling_active[i < 8][j / 4] |= (fromX == j && fromY == i);
  147.             castling_active[i < 8][j / 4] |= (toX == j && toY == i);
  148.         }
  149.     }
  150. }
  151.  
  152.  
  153. struct {
  154.     int exist, X, Y;
  155. } extra;
  156. int extra_figure(const cell_t *cell) {
  157.     if (cell->figure == EMPTY) {
  158.         return 0;
  159.     }
  160.     if ((cell->color == side && cell->figure == KING) ||
  161.         (cell->color != side && (cell->figure == ROOK || cell->figure == QUEEN)))
  162.     {
  163.         return cell->figure;
  164.     } else {
  165.         return -1;
  166.     }
  167. }
  168. void extra_check() {
  169.     int fromX = current_move.fromX,
  170.         fromY = current_move.fromY,
  171.         toX = current_move.toX,
  172.         toY = current_move.toY;
  173.     extra.exist = 0;
  174.     if (desk[fromX][fromY].figure != PAWN || abs(fromY - toY) < 2) {
  175.         return;
  176.     }
  177.     int X, Y;
  178.     if (desk[toX - 1][toY].figure == PAWN && desk[toX - 1][toY].color == side) {
  179.         X = toX - 1;
  180.         Y = toY;
  181.     } else if (desk[toX + 1][toY].figure == PAWN && desk[toX + 1][toY].color == side) {
  182.         X = toX + 1;
  183.         Y = toY;
  184.     } else {
  185.         return;
  186.     }
  187.     extra.exist = 1;
  188.     extra.X = toX;
  189.     extra.Y = toY + (side ? 1 : -1);
  190.     int dec = 0, inc = 0;
  191.     for (int i = X - 1; i > 0; --i) {
  192.         int t = extra_figure(&desk[i][toY]);
  193.         if (t > 0) {
  194.             dec = t;
  195.             break;
  196.         } else if (t < 0) {
  197.             return;
  198.         }
  199.     }
  200.     for (int i = X + 1; i <= 8; ++i) {
  201.         int t = extra_figure(&desk[i][toY]);
  202.         if (t > 0) {
  203.             inc = t;
  204.             break;
  205.         } else if (t < 0) {
  206.             return;
  207.         }
  208.     }
  209.     if (inc && dec && (dec == KING || inc == KING)) {
  210.         extra.exist = 0;
  211.     }
  212. }
  213.  
  214.  
  215.  
  216. char get_figure_symbol(int figure) {
  217.     return (figure == PAWN) * 'p' + (figure == QUEEN) * 'q' + (figure == KING) * 'k'
  218.          + (figure == KNIGHT) * 'g' + (figure == BISHOP) * 'b' + (figure == ROOK) * 'r'
  219.          + (figure == EMPTY) * '.';
  220. }
  221. int get_figure_number(char figure) {
  222.     figure = tolower(figure);
  223.     return (figure == 'p') * PAWN + (figure == 'q') * QUEEN + (figure == 'k') * KING
  224.          + (figure == 'g') * KNIGHT + (figure == 'b') * BISHOP + (figure == 'r') * ROOK
  225.          + (figure == '.') * EMPTY;
  226. }
  227.  
  228. void unpack_desk(const char *position) {
  229.     init_desk();
  230.     for (int i = 0; i < 8; ++i) {
  231.         for (int j = 0; j < 8; ++j) {
  232.             const char c = position[i * 8 + j];
  233.             desk[j + 1][i + 1] = (cell_t) {
  234.                 get_figure_number(c), 0,
  235.                 (c >= 'a' && c <= 'z'), 0, 0
  236.             };
  237.         }
  238.     }
  239. }
  240. void unpack_castling(const char *position) {
  241.     for (int i = 0; i < 2; ++i) {
  242.         for (int j = 0; j < 3; ++j) {
  243.             castling_active[i][j] = position[i * 3 + j] - '0';
  244.         }
  245.     }
  246. }
  247. void unpack_move(const char *position) {
  248.     set_current_move(position[0] - 'a' + 1, position[1] - '0',
  249.                      position[2] - 'a' + 1, position[3] - '0',
  250.                         get_figure_number(position[4]));
  251. }
  252. void unpack_position(const char *position) {
  253.     unpack_desk(position);
  254.     unpack_castling(position + 64);
  255.     unpack_move(position + 70);
  256. }
  257.  
  258.  
  259.  
  260. char gamestate[50];
  261. int gamestate_move_released = 0;
  262.  
  263. void decode_desk() {
  264.     const char *target = gamestate;
  265.     init_desk();
  266.     static const int complete_offset[2][6] = {
  267.         { 8, 9, 10, 12, 14, 16 },
  268.         { 24, 25, 26, 28, 30, 32 }
  269.     };
  270.     int offset[2][6] = {
  271.         { 0, 8, 9, 10, 12, 14 },
  272.         { 16, 24, 25, 26, 28, 30 }
  273.     };
  274.     for (int i = 0; i < 2; ++i) {
  275.         for (int j = 0; j < 6; ++j) {
  276.             while (offset[i][j] != complete_offset[i][j]) {
  277.                 int pos = target[offset[i][j]] - 33;
  278.                 if (pos == (1 << 6)) {
  279.                     ++offset[i][j];
  280.                     break;
  281.                 }
  282.                 int x = (pos & 7) + 1,
  283.                     y = ((pos & (7 << 3)) >> 3) + 1;
  284.                 if (j + 1 == PAWN) {
  285.                     desk[x][y].figure = (((target[32 + offset[i][j] % 16] - 33) >> (i * 3)) & 7) + 1;
  286.                 } else {
  287.                     desk[x][y].figure = j + 1;
  288.                 }
  289.                 desk[x][y].color = i;
  290.                 ++offset[i][j];
  291.             }
  292.         }
  293.     }
  294. }
  295. void decode_castling() {
  296.     const char *target = gamestate + 40;
  297.     for (int i = 0; i < 6; ++i) {
  298.         castling_active[i / 3][i % 3] = ((target[0] - 33) >> i) & 1;
  299.     }
  300. }
  301. void decode_move() {
  302.     const char *target = gamestate + 41;
  303.     set_current_move(((target[0] - 33) & 7) + 1, (((target[0] - 33) >> 3) & 7) + 1,
  304.                      ((target[1] - 33) & 7) + 1, (((target[1] - 33) >> 3) & 7) + 1,
  305.                         target[2] - 33);
  306. }
  307. void decode_position() {
  308.     decode_desk();
  309.     decode_castling();
  310.     decode_move();
  311. }
  312.  
  313. void encode_desk() {
  314.     char *target = gamestate;
  315.     static const int complete_offset[2][6] = {
  316.         { 8, 9, 10, 12, 14, 16 },
  317.         { 24, 25, 26, 28, 30, 32 }
  318.     };
  319.     int offset[2][6] = {
  320.         { 0, 8, 9, 10, 12, 14 },
  321.         { 16, 24, 25, 26, 28, 30 }
  322.     };
  323.     for (int i = 32; i < 40; ++i) {
  324.         target[i] = 0;
  325.     }
  326.     for (int i = 0; i < 8; ++i) {
  327.         for (int j = 0; j < 8; ++j) {
  328.             if (desk[i + 1][j + 1].figure == EMPTY) {
  329.                 continue;
  330.             }
  331.             int color = desk[i + 1][j + 1].color,
  332.                 figure = desk[i + 1][j + 1].figure - 1;
  333.             if (offset[color][figure] != complete_offset[color][figure]) {
  334.                 target[offset[color][figure]++] = (0 | i | (j << 3)) + 33;
  335.                 continue;
  336.             }
  337.             target[offset[color][PAWN - 1]] = (0 | i | (j << 3)) + 33;
  338.             target[32 + offset[color][PAWN - 1] % 16] |= figure << (color * 3);
  339.             ++offset[color][PAWN - 1];
  340.         }
  341.     }
  342.     for (int i = 32; i < 40; ++i) {
  343.         target[i] += 33;
  344.     }
  345.     for (int i = 0; i < 2; ++i) {
  346.         for (int j = 0; j < 6; ++j) {
  347.             while (offset[i][j] != complete_offset[i][j]) {
  348.                 target[offset[i][j]++] = (1 << 6) + 33;
  349.             }
  350.         }
  351.     }
  352. }
  353. void encode_castling() {
  354.     char *target = gamestate + 40;
  355.     target[0] = 0;
  356.     for (int i = 0; i < 6; ++i) {
  357.         target[0] |= castling_active[i / 3][i % 3] << i;
  358.     }
  359.     target[0] += 33;
  360. }
  361. void encode_move() {
  362.     char *target = gamestate + 41;
  363.     target[0] = current_move.fromX - 1;
  364.     target[0] |= (current_move.fromY - 1) << 3;
  365.     target[0] += 33;
  366.     target[1] = current_move.toX - 1;
  367.     target[1] |= (current_move.toY - 1) << 3;
  368.     target[1] += 33;
  369.     target[2] = current_move.figure + 33;
  370. }
  371. void encode_position() {
  372.     encode_desk();
  373.     encode_castling();
  374.     encode_move();
  375. }
  376.  
  377.  
  378.  
  379. int atacks_on_king = 0;
  380.  
  381. int get_mobility(int dx, int dy) {
  382.     return abs(dx) == abs(dy) ? (dx == dy ? ANGLE45 : ANGLE135) : (dx ? ANGLE0 : ANGLE90);
  383. }
  384. int is_check() {
  385.     return atacks_on_king == 1;
  386. }
  387. int is_multicheck() {
  388.     return atacks_on_king > 1;
  389. }
  390. int is_correct(int x, int y) {
  391.     return x > 0 && x < 9 && y > 0 && y < 9;
  392. }
  393. int is_figure(const cell_t *cell) {
  394.     return cell->figure != EMPTY && cell->figure != BARRIER;
  395. }
  396. int is_ally(const cell_t *cell) {
  397.     return is_figure(cell) && cell->color == side;
  398. }
  399. int is_enemy(const cell_t *cell) {
  400.     return is_figure(cell) && cell->color != side;
  401. }
  402. int is_direction_correct(const cell_t *cell, int dx, int dy) {
  403.     return (cell->figure != KNIGHT && get_mobility(dx, dy) == cell->mobility)
  404.         || !cell->special;
  405. }
  406. int is_moveable(int x, int y, int dx, int dy) {
  407.     if (!is_correct(x + dx, y + dy) || is_ally(&desk[x + dx][y + dy])
  408.      || !is_direction_correct(&desk[x][y], dx, dy))
  409.     {
  410.         return 0;
  411.     }
  412.     return !is_check() || desk[x + dx][y + dy].special;
  413. }
  414.  
  415. void atack_handler(int x, int y, int dx, int dy) {
  416.     if (is_correct(x + dx, y + dy)) {
  417.         cell_t *cell = &desk[x + dx][y + dy];
  418.         cell->attacked = 1;
  419.         if (is_ally(cell) && cell->figure == KING) {
  420.             desk[x][y].special = 1;
  421.             ++atacks_on_king;
  422.         }
  423.     }
  424. }
  425. void pierce_block(int x, int y, int dx, int dy) {
  426.     desk[x][y].special = 1;
  427.     desk[x][y].mobility = get_mobility(dx, dy);
  428. }
  429.  
  430.  
  431. void ally_line_handler(int x, int y, int dx, int dy) {
  432.     if (!is_direction_correct(&desk[x][y], dx, dy)) {
  433.         return;
  434.     }
  435.     for (int i = dx, j = dy; is_correct(x + i, y + j); i += dx, j += dy) {
  436.         if (is_moveable(x, y, i, j)) {
  437.             add_move(x, y, x + i, y + j);
  438.         }
  439.         if (is_figure(&desk[x + i][y + j])) {
  440.             break;
  441.         }
  442.     }
  443. }
  444.  
  445. int pierce_detector(int x, int y, int dx, int dy, int cnt) {
  446.     cell_t *cell = &desk[x + dx][y + dy];
  447.     if (!cnt) {
  448.         atack_handler(x, y, dx, dy);
  449.     }
  450.     if (cell->figure == EMPTY) {
  451.         return cnt;
  452.     }
  453.     ++cnt;
  454.     cnt *= (cell->figure == KING ? -1 : 1);
  455.     if (cell->figure == BARRIER || is_enemy(cell) || cnt == 2) {
  456.         return -3;
  457.     } else {
  458.         return cnt;
  459.     }
  460. }
  461. void enemy_line_handler(int x, int y, int dx, int dy) {
  462.     int cnt = 0, i = 0, j = 0;
  463.     do {
  464.         i += dx;
  465.         j += dy;
  466.         cnt = pierce_detector(x, y, i, j, cnt);
  467.     } while (cnt >= 0);
  468.     if (cnt == -1) {
  469.         atack_handler(x, y, i + dx, j + dy);
  470.         for (i = x, j = y; desk[i][j].figure != KING; i += dx, j += dy) {
  471.             desk[i][j].special = 1;
  472.         }
  473.     } else if (cnt == -2) {
  474.         for (i = x, j = y; !is_ally(&desk[i][j]); i += dx, j += dy);
  475.         pierce_block(i, j, dx, dy);
  476.     }
  477. }
  478.  
  479. typedef void (*line_handler_t)(int, int, int, int);
  480. void X_handler(int x, int y, int vh, int d, line_handler_t handl) {
  481.     if (vh) {
  482.         handl(x, y, 1, 0);
  483.         handl(x, y, -1, 0);
  484.         handl(x, y, 0, 1);
  485.         handl(x, y, 0, -1);
  486.     }
  487.     if (d) {
  488.         handl(x, y, 1, 1);
  489.         handl(x, y, 1, -1);
  490.         handl(x, y, -1, 1);
  491.         handl(x, y, -1, -1);
  492.     }
  493. }
  494.  
  495.  
  496. void ally_knight_handler(int x, int y) {
  497.     for (int i = 1; i <= 2; ++i) {
  498.         int j = 3 - i;
  499.         if (is_moveable(x, y, i, j)) {
  500.             add_move(x, y, x + i, y + j);
  501.         }
  502.         if (is_moveable(x, y, i, -j)) {
  503.             add_move(x, y, x + i, y - j);
  504.         }
  505.         if (is_moveable(x, y, -i, j)) {
  506.             add_move(x, y, x - i, y + j);
  507.         }
  508.         if (is_moveable(x, y, -i, -j)) {
  509.             add_move(x, y, x - i, y - j);
  510.         }
  511.     }
  512. }
  513. void enemy_knight_handler(int x, int y) {
  514.     for (int i = 1; i <= 2; ++i) {
  515.         int j = 3 - i;
  516.         atack_handler(x, y, i, j);
  517.         atack_handler(x, y, i, -j);
  518.         atack_handler(x, y, -i, j);
  519.         atack_handler(x, y, -i, -j);
  520.     }
  521. }
  522.  
  523.  
  524. void ally_king_handler(int x, int y) {
  525.     for (int i = -1; i <= 1; ++i) {
  526.         for (int j = -1; j <= 1; ++j) {
  527.             if (is_correct(x + i, y + j) && !desk[x + i][y + j].attacked && !is_ally(&desk[x + i][y + j])) {
  528.                 add_move(x, y, x + i, y + j);
  529.             }
  530.         }
  531.     }
  532. }
  533. void enemy_king_handler(int x, int y) {
  534.     for (int i = -1; i <= 1; ++i) {
  535.         for (int j = -1; j <= 1; ++j) {
  536.             if (desk[x + i][y + j].figure != KING) {
  537.                 atack_handler(x, y, i, j);
  538.             }
  539.         }
  540.     }
  541. }
  542.  
  543.  
  544. void pawn_kill_move(int x, int y, int dx, int dy) {
  545.     if ((is_enemy(&desk[x + dx][y + dy]) && is_moveable(x, y, dx, dy))
  546.         || (extra.exist && x + dx == extra.X && y + dy == extra.Y
  547.             && (is_moveable(x, y, dx, dy) || is_moveable(x, y, dx, 0))
  548.            )
  549.        )
  550.     {
  551.         add_move(x, y, x + dx, y + dy);
  552.     }
  553. }
  554. void ally_pawn_handler(int x, int y) {
  555.     int t = (side ? 1 : -1);
  556.     pawn_kill_move(x, y, 1, t);
  557.     pawn_kill_move(x, y, -1, t);
  558.     if (is_figure(&desk[x][y + t])){
  559.         return;
  560.     }
  561.     if (is_moveable(x, y, 0, t)) {
  562.         add_move(x, y, x, y + t);
  563.     }
  564.     if (y == 7 - 5 * side && !is_figure(&desk[x][y + 2 * t]) && is_moveable(x, y, 0, 2 * t)) {
  565.         add_move(x, y, x, y + 2 * t);
  566.     }
  567. }
  568. void enemy_pawn_handler(int x, int y) {
  569.     atack_handler(x, y, 1, -(side ? 1 : -1));
  570.     atack_handler(x, y, -1, -(side ? 1 : -1));
  571. }
  572.  
  573.  
  574. void ally_figure_handler(int x, int y) {
  575.     if (!is_figure(&desk[x][y]) || is_enemy(&desk[x][y])
  576.      || (is_multicheck() && desk[x][y].figure != KING))
  577.     {
  578.         return;
  579.     } else if (desk[x][y].figure == PAWN) {
  580.         ally_pawn_handler(x, y);
  581.     } else if (desk[x][y].figure == KING) {
  582.         ally_king_handler(x, y);
  583.     } else if (desk[x][y].figure == KNIGHT) {
  584.         ally_knight_handler(x, y);
  585.     } else if (desk[x][y].figure == ROOK) {
  586.         X_handler(x, y, 1, 0, ally_line_handler);
  587.     } else if (desk[x][y].figure == BISHOP) {
  588.         X_handler(x, y, 0, 1, ally_line_handler);
  589.     } else if (desk[x][y].figure == QUEEN) {
  590.         X_handler(x, y, 1, 1, ally_line_handler);
  591.     }
  592. }
  593. void enemy_figure_handler(int x, int y) {
  594.     if (!is_figure(&desk[x][y]) || is_ally(&desk[x][y])) {
  595.         return;
  596.     } else if (desk[x][y].figure == PAWN) {
  597.         enemy_pawn_handler(x, y);
  598.     } else if (desk[x][y].figure == KING) {
  599.         enemy_king_handler(x, y);
  600.     } else if (desk[x][y].figure == KNIGHT) {
  601.         enemy_knight_handler(x, y);
  602.     } else if (desk[x][y].figure == ROOK) {
  603.         X_handler(x, y, 1, 0, enemy_line_handler);
  604.     } else if (desk[x][y].figure == BISHOP) {
  605.         X_handler(x, y, 0, 1, enemy_line_handler);
  606.     } else if (desk[x][y].figure == QUEEN) {
  607.         X_handler(x, y, 1, 1, enemy_line_handler);
  608.     }
  609. }
  610.  
  611.  
  612. typedef void (*cell_handler_t)(int, int);
  613. void desk_handler(cell_handler_t handl) {
  614.     for (int i = 1; i <= 8; ++i) {
  615.         for (int j = 1; j <= 8; ++j) {
  616.             handl(i, j);
  617.         }
  618.     }
  619. }
  620. void castle_handler() {
  621.     if (is_check() || is_multicheck() || castling_active[side][1]) {
  622.         return;
  623.     }
  624.     int sideline = 8 - side * 7;
  625.     if (!castling_active[side][0]
  626.      && !desk[4][sideline].attacked && !is_figure(&desk[4][sideline])
  627.      && !desk[3][sideline].attacked && !is_figure(&desk[3][sideline]))
  628.     {
  629.         add_move(5, sideline, 3, sideline);
  630.     }
  631.     if (!castling_active[side][2]
  632.      && !desk[6][sideline].attacked && !is_figure(&desk[6][sideline])
  633.      && !desk[7][sideline].attacked && !is_figure(&desk[7][sideline]))
  634.     {
  635.         add_move(5, sideline, 7, sideline);
  636.     }
  637. }
  638.  
  639.  
  640. void position_handler() {
  641.     atacks_on_king = 0;
  642.     clear_move_table();
  643.     clear_desk_state();
  644.     release_current_move();
  645.     desk_handler(enemy_figure_handler);
  646.     desk_handler(ally_figure_handler);
  647.     castle_handler();
  648. }
  649.  
  650.  
  651.  
  652. int is_gamestate_move_completed() {
  653.     const char *move = gamestate + 44;
  654.     return move[5] != '?' || (move[4] != '?' && (move[0] != 'p' || (move[4] != '1' && move[4] != '8')));
  655. }
  656. void clear_gamestate_move() {
  657.     memcpy(gamestate + 44, "??????", 6);
  658. }
  659. void gamestate_move_handler() {
  660.     gamestate_move_released = 0;
  661.     if (is_gamestate_move_completed()) {
  662.         unpack_move(gamestate + 45);
  663.         encode_position();
  664.         position_handler();
  665.         clear_gamestate_move();
  666.         gamestate_move_released = 1;
  667.     }
  668. }
  669.  
  670.  
  671. const char *starting =
  672.     "rgbqkbgr"
  673.     "pppppppp"
  674.     "........"
  675.     "........"
  676.     "........"
  677.     "........"
  678.     "PPPPPPPP"
  679.     "RGBQKBGR"
  680.     "000000e8e8k";
  681. void init_gamestate() {
  682.     unpack_position(starting);
  683.     position_handler();
  684.     encode_position();
  685.     clear_gamestate_move();
  686. }
  687. void gamestate_handler() {
  688.     decode_position();
  689.     position_handler();
  690.     gamestate_move_handler();
  691. }
  692.  
  693.  
  694.  
  695. void output_move_figures() {
  696.     char result[13];
  697.     int cnt = 0;
  698.     for (int i = 0; i < 6; ++i) {
  699.         if (moveptr_list[i]) {
  700.             result[cnt * 2] = get_figure_symbol(i + 1);
  701.             result[cnt * 2 + 1] = ' ';
  702.             ++cnt;
  703.         }
  704.     }
  705.     result[cnt * 2] = '\0';
  706.     puts(result);
  707. }
  708. void output_move_from(int figure) {
  709.     int cnt = moveptr_list[figure - 1] / 4, ptr = 0;
  710.     char *result = malloc((cnt * 3 + 1) * sizeof(char));
  711.     for (int i = 0; i < cnt; ++i) {
  712.         result[ptr * 3] = move_table[figure - 1][i * 4];
  713.         result[ptr * 3 + 1] = move_table[figure - 1][i * 4 + 1];
  714.         result[ptr * 3 + 2] = ' ';
  715.         if (i && result[ptr * 3 - 3] == result[ptr * 3]
  716.               && result[ptr * 3 - 2] == result[ptr * 3 + 1])
  717.         {
  718.             continue;
  719.         }
  720.         ++ptr;
  721.     }
  722.     result[ptr * 3] = '\0';
  723.     puts(result);
  724. }
  725. void output_move_to(int figure, const char *from) {
  726.     int cnt = 0, maxcnt = moveptr_list[figure - 1] / 4;
  727.     char *result = malloc((maxcnt * 3 + 1) * sizeof(char));
  728.     for (int i = 0; i < maxcnt; ++i) {
  729.         if (move_table[figure - 1][i * 4] == from[0] && move_table[figure - 1][i * 4 + 1] == from[1]) {
  730.             result[cnt * 3] = move_table[figure - 1][i * 4 + 2];
  731.             result[cnt * 3 + 1] = move_table[figure - 1][i * 4 + 3];
  732.             result[cnt * 3 + 2] = ' ';
  733.             ++cnt;
  734.         }
  735.     }
  736.     result[cnt * 3] = '\0';
  737.     puts(result);
  738. }
  739. void output_move_transform() {
  740.     puts("q g b r");
  741. }
  742.  
  743. void output_gamestate() {
  744.     fwrite(gamestate, 1, 50, stdout);
  745.     putchar('\n');
  746. }
  747. void output_desk() {
  748.     for (int i = 8; i >= 1; --i) {
  749.         for (int j = 1; j <= 8; ++j) {
  750.             putchar(get_figure_symbol(desk[j][i].figure) +
  751.                     (desk[j][i].color || desk[j][i].figure == EMPTY
  752.                         ? 0 : 'A' - 'a'));
  753.         }
  754.         putchar('\n');
  755.     }
  756. }
  757. void output_move_variants() {
  758.     const char *move = gamestate + 44;
  759.     if (move[0] == '?') {
  760.         output_move_figures();
  761.     } else if (move[1] == '?') {
  762.         output_move_from(get_figure_number(move[0]));
  763.     } else if (move[3] == '?') {
  764.         output_move_to(get_figure_number(move[0]), move + 1);
  765.     } else {
  766.         output_move_transform();
  767.     }
  768. }
  769.  
  770. void output_gamestate_info() {
  771.     output_gamestate();
  772.     output_desk();
  773.     output_move_variants();
  774.     printf("%d %d", side, gamestate_move_released);
  775. }
  776.  
  777.  
  778.  
  779. int main(int argc, char **argv) {
  780.  
  781.     init_move_table();
  782.  
  783.     if (argc < 2) {
  784.         return 0;
  785.     } else if (!strcmp(argv[1], "init")) {
  786.         init_gamestate();
  787.         output_gamestate_info();
  788.     } else if (!strcmp(argv[1], "handle")) {
  789.         memcpy(gamestate, argv[2], 50);
  790.         gamestate_handler();
  791.         output_gamestate_info();
  792.     }
  793.  
  794. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top