Advertisement
Guest User

Untitled

a guest
Sep 20th, 2017
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.61 KB | None | 0 0
  1. /*
  2. File: board.h
  3.  
  4. Content on and manipulation of a chess board implemented as 10x12 squares,
  5. with default out_of_border values.
  6.  
  7. "magic" numbers will be used, they aren't magic if you know this structure.
  8. Source way too messy with a lot of variable names and variable calculations instead of plain numbers.
  9.  
  10. Author: Ken Rouwas
  11. Date 2017-09-14
  12. */
  13.  
  14. #pragma once
  15.  
  16. #include <array>
  17.  
  18. namespace Chess{
  19.  
  20. const size_t board_size = 10*12;
  21.  
  22. enum class Color { white, black, none };
  23.  
  24. enum class Piece {
  25. king, // a king without castle potential
  26. king_castle, // a king with castle potential
  27. queen,
  28. pawn, // a pawn without en passant potential
  29. pawn_en_passant, // a pawn with en passant potential
  30. rook,
  31. rook_castle,
  32. knight,
  33. bishop,
  34. none,
  35. out_of_board // Illegal position
  36. };
  37.  
  38. struct Square {
  39. Color piece_color;
  40. Piece piece;
  41. Square(Piece, Color);
  42. Square();
  43. };
  44.  
  45. class Board {
  46. private:
  47. std::array<Square, board_size> squares;
  48. public:
  49. void set(const size_t where, Square);
  50. Square get(const size_t where) const;
  51. };
  52.  
  53. void init_classic_board(Board&);
  54.  
  55. }
  56.  
  57. // File: board.cpp
  58.  
  59. #include "board.h"
  60.  
  61.  
  62. namespace Chess {
  63. Square::Square(Piece p, Color c){
  64. piece = p;
  65. piece_color = c;
  66. }
  67.  
  68. Square::Square(){
  69. piece = Piece::out_of_board;
  70. piece_color = Color::none;
  71. }
  72.  
  73.  
  74. void Board::set(const size_t where, Square s) {
  75. if (where >= board_size)
  76. return;
  77. squares[where] = s;
  78. }
  79.  
  80. Square Board::get(const size_t where) const {
  81. if (where >= board_size)
  82. return Square (Piece::out_of_board, Color::none);
  83. return squares[where];
  84. }
  85.  
  86. void init_classic_board(Board& b) {
  87. // Place pawns
  88. for(size_t i = 0; i < 8; ++i){
  89. b.set(31 /*col 1, 2nd row*/ + i, Square(Piece::pawn, Color::black));
  90. b.set(81 /*col 1, 7th row*/ + i, Square(Piece::pawn, Color::white));
  91. }
  92.  
  93. // Place the rest but with s/kings/queens
  94. int w = 0;
  95. for( auto p : {Piece::rook_castle, Piece::knight, Piece::bishop, Piece::queen} ) {
  96. b.set(21+w, Square(p, Color::black));
  97. b.set(28 /*col 8, 1st row*/ - w, Square(p, Color::black));
  98. b.set(91 /*col 1, 8th row*/ + w, Square(p, Color::white));
  99. b.set(98 /*col 8, 8th row*/ - w, Square(p, Color::white));
  100. ++w;
  101. }
  102.  
  103. // Place kings
  104. b.set(25, Square(Piece::king_castle, Color::black));
  105. b.set(95, Square(Piece::king_castle, Color::white));
  106.  
  107. // Empty squares inbetween the pieces
  108. for(int x=0; x < 8; ++x)
  109. for(int y=0; y < 4; ++y)
  110. b.set(41+x+y*10,Square(Piece::none, Color::none));
  111. }
  112.  
  113. }
  114.  
  115. /*
  116. File: move.h
  117.  
  118. Move utils and move history utils.
  119. Assumes that a history list and the board it's used with are consistent.
  120.  
  121. Boardhistory:
  122. A move event consists of a series of board changes and a "move done",
  123. namely BoardChange.where == (boardsize = move_done), which is pushed last for each move event.
  124.  
  125. Author: Ken Rouwas
  126. Date 2017-09-14
  127. */
  128.  
  129. #pragma once
  130.  
  131. #include <list>
  132. #include <vector>
  133.  
  134. #include "board.h"
  135.  
  136. namespace Chess {
  137.  
  138. const size_t move_done = board_size;
  139.  
  140. struct Move {
  141. ssize_t from, to;
  142. Move(ssize_t, ssize_t);
  143. Move();
  144. };
  145.  
  146. struct BoardChange {
  147. size_t where;
  148. Square old_square;
  149. };
  150.  
  151. using Boardhistory = std::list<BoardChange>;
  152. using MoveSet = std::vector<Move>;
  153.  
  154. void undo_move(Board&, Boardhistory&);
  155.  
  156. /* Castling is identified by king move to its castling destination if permitted.
  157. Pawn promotion move deduced.
  158. All other moves are unconditional moves.
  159. */
  160. void do_move(Move, Board&, Boardhistory&, Piece pawn_promotion = Piece::queen);
  161.  
  162. MoveSet valid_moves(Board&, Color turn); // This is the move generator
  163.  
  164. }
  165.  
  166. #include <iostream>
  167. #include "move.h"
  168.  
  169. // Read move.h for specifications
  170.  
  171. namespace Chess {
  172.  
  173. Move::Move(ssize_t _from, ssize_t _to) {
  174. from = _from;
  175. to = _to;
  176. }
  177.  
  178. Move::Move(){}
  179.  
  180. void undo_move(Board& b, Boardhistory& ml){
  181. if(!ml.size())
  182. return;
  183. if(ml.back().where == move_done)
  184. ml.pop_back();
  185.  
  186. while(ml.size() && ml.back().where != move_done){
  187. b.set( ml.back().where, ml.back().old_square );
  188. ml.pop_back();
  189. }
  190. }
  191.  
  192. static void do_change(Board& b, Boardhistory& bh, size_t where, Square new_square) {
  193. BoardChange change;
  194. change.old_square = b.get(where);
  195. change.where = where;
  196. bh.push_back(change);
  197. b.set(where, new_square);
  198. }
  199.  
  200. void do_move(Move m, Board& b, Boardhistory& bh, Piece pawn_promotion){
  201. // Pawn promotion
  202. if(b.get(m.from).piece == Piece::pawn && m.to/10 == 2)
  203. do_change(b, bh, m.from, Square(pawn_promotion, Color::white));
  204.  
  205. if(b.get(m.from).piece == Piece::pawn && m.to/10 == 9)
  206. do_change(b, bh, m.from, Square(pawn_promotion, Color::black));
  207.  
  208. // Move rook if castling
  209. if(b.get(m.from).piece == Piece::king_castle && (m.from-m.to == 2 || m.from-m.to == -2)){
  210. if(m.to == 23){
  211. do_change(b, bh, 21, Square(Piece::none, Color::none));
  212. do_change(b, bh, 24, Square(Piece::rook, Color::black));
  213. }
  214.  
  215. if(m.to == 27){
  216. do_change(b, bh, 28, Square(Piece::none, Color::none));
  217. do_change(b, bh, 26, Square(Piece::rook, Color::black));
  218. }
  219.  
  220. if(m.to == 93){
  221. do_change(b, bh, 91, Square(Piece::none, Color::none));
  222. do_change(b, bh, 94, Square(Piece::rook, Color::white));
  223. }
  224.  
  225. if(m.to == 97){
  226. do_change(b, bh, 98, Square(Piece::none, Color::none));
  227. do_change(b, bh, 96, Square(Piece::rook, Color::white));
  228. }
  229. }
  230.  
  231.  
  232. Piece pawn_replaced = b.get(m.to).piece;
  233. // Regular piece move
  234. do_change(b, bh, m.to, b.get(m.from));
  235. do_change(b, bh, m.from, Square(Piece::none, Color::none));
  236.  
  237.  
  238. // Pawn replaced empty square
  239. if(b.get(m.to).piece == Piece::pawn && pawn_replaced == Piece::none) {
  240. // En passant move
  241. if(b.get(m.from-1).piece == Piece::pawn_en_passant && (m.from-m.to == 11 || m.from-m.to == -9))
  242. do_change(b, bh, m.from-1, Square(Piece::none, Color::none));
  243. else if (b.get(m.from+1).piece == Piece::pawn_en_passant && (m.from-m.to == 9 || m.from-m.to == -11))
  244. do_change(b, bh, m.from+1, Square(Piece::none, Color::none));
  245. }
  246.  
  247.  
  248. // clear flag of pawns with en passant potential
  249. for(size_t i=1; i < 9; ++i){
  250. if(b.get(50+i).piece == Piece::pawn_en_passant)
  251. do_change(b, bh, 50+i, Square(Piece::pawn, Color::black));
  252. if(b.get(60+i).piece == Piece::pawn_en_passant)
  253. do_change(b, bh, 60+i, Square(Piece::pawn, Color::white));
  254. }
  255.  
  256. // Give two-square moved pawns en passant flag
  257. if(b.get(m.to).piece == Piece::pawn) {
  258. if(m.from/10 == 3 && m.to/10 == 5)
  259. do_change(b, bh, m.to, Square(Piece::pawn_en_passant, Color::black));
  260.  
  261. if(m.from/10 == 8 && m.to/10 == 6)
  262. do_change(b, bh, m.to, Square(Piece::pawn_en_passant, Color::white));
  263. }
  264.  
  265. // Lose castling potential
  266. if(b.get(m.to).piece == Piece::king_castle)
  267. do_change(b, bh, m.to, Square(Piece::king, b.get(m.to).piece_color));
  268. if(b.get(m.to).piece == Piece::rook_castle)
  269. do_change(b, bh, m.to, Square(Piece::rook, b.get(m.to).piece_color));
  270.  
  271. BoardChange done;
  272. done.where = move_done;
  273. bh.push_back(done);
  274. }
  275.  
  276. MoveSet valid_moves(Board& b, Color turn){
  277. MoveSet ret;
  278. Color enemy_color = (turn == Color::white) ? Color::black : Color::white;
  279. int pawn_dir = (turn == Color::white) ? -1 : 1;
  280.  
  281.  
  282. for(size_t from = 21 /*skip padding*/; from < 99 /*padding after this*/ ; ++from){
  283. if(b.get(from).piece_color == turn){
  284. switch(b.get(from).piece){
  285. case Piece::king_castle:
  286. if(from == 95 && b.get(96).piece == Piece::none && b.get(97).piece == Piece::none && b.get(98).piece == Piece::rook_castle)
  287. ret.push_back(Move(from, 97));
  288. if(from == 25 && b.get(26).piece == Piece::none && b.get(27).piece == Piece::none && b.get(28).piece == Piece::rook_castle)
  289. ret.push_back(Move(from, 27));
  290. if(from == 95 && b.get(94).piece == Piece::none && b.get(93).piece == Piece::none && b.get(92).piece == Piece::none && b.get(91).piece == Piece::rook_castle)
  291. ret.push_back(Move(from, 93));
  292. if(from == 25 && b.get(24).piece == Piece::none && b.get(23).piece == Piece::none && b.get(22).piece == Piece::none && b.get(21).piece == Piece::rook_castle)
  293. ret.push_back(Move(from, 23));
  294. // fallthrough
  295. case Piece::king:
  296. for(auto to : {from-11, from-10, from-9,from-1, from+1, from+9, from+10,from+11}) {
  297. if(b.get(to).piece_color == turn || b.get(to).piece == Piece::out_of_board)
  298. continue;
  299. ret.push_back(Move(from, to));
  300. }
  301. break;
  302. case Piece::pawn:
  303. if(b.get(from+pawn_dir*11).piece_color == enemy_color)
  304. ret.push_back(Move(from, from+pawn_dir*11));
  305. if(b.get(from+pawn_dir*9).piece_color == enemy_color)
  306. ret.push_back(Move(from, from+pawn_dir*9));
  307. if(b.get(from+pawn_dir*10).piece == Piece::none)
  308. ret.push_back(Move(from, from+pawn_dir*10));
  309. if(b.get(from+pawn_dir*10).piece == Piece::none && b.get(from+pawn_dir*20).piece == Piece::none){
  310. size_t row = from/10;
  311. if((row == 3 && pawn_dir == 1) || (row == 8 && pawn_dir == -1))
  312. ret.push_back(Move(from, from+pawn_dir*20));
  313. }
  314. if(b.get(from-1).piece == Piece::pawn_en_passant && pawn_dir == -1)
  315. ret.push_back( Move(from, from-11) );
  316. if(b.get(from+1).piece == Piece::pawn_en_passant && pawn_dir == -1)
  317. ret.push_back( Move(from, from-9) );
  318. if(b.get(from-1).piece == Piece::pawn_en_passant && pawn_dir == 1)
  319. ret.push_back( Move(from, from+9) );
  320. if(b.get(from+1).piece == Piece::pawn_en_passant && pawn_dir == 1)
  321. ret.push_back( Move(from, from+11) );
  322. break;
  323. case Piece::knight:
  324. for(auto to : {from+8, from+12, from+19, from+21, from-8, from-12, from-21, from-19}) {
  325. if(b.get(to).piece_color == turn || b.get(to).piece == Piece::out_of_board)
  326. continue;
  327. ret.push_back(Move(from, to));
  328. }
  329. break;
  330. case Piece::queen:
  331. //fallthrough
  332. case Piece::rook:
  333. case Piece::rook_castle:
  334. for(int dd : {1,-1,10,-10})
  335. for(int d=dd; b.get(from+d).piece_color != b.get(from).piece_color && b.get(from+d).piece != Piece::out_of_board ;d+=dd) {
  336. ret.push_back(Move(from, from+d));
  337. if(b.get(from+d).piece != Piece::none)
  338. break;
  339. }
  340. if(b.get(from).piece != Piece::queen)
  341. break;
  342. case Piece::bishop:
  343. for(int dd : {9,11,-9,-11})
  344. for(int d=dd; b.get(from+d).piece_color != b.get(from).piece_color && b.get(from+d).piece != Piece::out_of_board ;d+=dd) {
  345. ret.push_back(Move(from, from+d));
  346. if(b.get(from+d).piece != Piece::none)
  347. break;
  348. }
  349. break;
  350. default: // warnings unwanted
  351. break;
  352. }
  353. }
  354. }
  355. return ret;
  356. }
  357. }
  358.  
  359. /*
  360. // File: main.cpp
  361.  
  362. TODO: don't allow moves that leaves king in check, and count check-mate as victory. Hence, perft will be off by a few.
  363. TODO: prompt pawn promotion, instead of the default queen.
  364. TODO: handle cases of no valid moves
  365. */
  366.  
  367. #include <iostream>
  368. #include <ctime>
  369. #include "board.h"
  370. #include "move.h"
  371. #include "gui.h"
  372. #include "ai.h"
  373.  
  374. using namespace Chess;
  375.  
  376.  
  377. unsigned long perft(Board &b, Boardhistory &h, int depth, Color turn) {
  378. turn = (turn == Color::white) ? Color::black : Color::white;
  379. if(!depth)
  380. return 1;
  381. int leafs = 0;
  382. for(Move m : valid_moves(b, turn)){
  383. if(b.get(m.to).piece == Piece::king || b.get(m.to).piece == Piece::king_castle){
  384. ++leafs;
  385. continue;
  386. }
  387. do_move(m,b,h);
  388. leafs += perft(b,h,depth-1,turn);
  389. undo_move(b,h);
  390. }
  391. return leafs;
  392. }
  393.  
  394.  
  395. int main(){
  396. std::cout<<"nChesscpu 1.0nn";
  397. std::cout<<"Commands:nyxyx: fromto move.n0: regret move (last AI move will be reverted as well).n1: change color (AI will make this move)n2: exit.nn";
  398. Board b;
  399. Boardhistory h;
  400. init_classic_board(b);
  401.  
  402. Color turn = Color::white;
  403. Color ai_color = Color::black;
  404.  
  405. bool ai_has_king = true;
  406. bool human_has_king = true;
  407.  
  408.  
  409. if(false) {
  410. unsigned long t = time(0);
  411. std::cout<<"DEBUG: Perft(5) result (expecting 4897256): "<<perft(b,h,5,Color::black);
  412. t = time(0) - t;
  413. std::cout<<"nTime "<<t<<"n";
  414. return 0;
  415. }
  416.  
  417. if(false){
  418. Move mv;
  419. unsigned long t = time(0);
  420. ai_move(b, h, turn, 7, mv);
  421. t = time(0) - t;
  422. std::cout<<"nAI Time: "<<t<<"n";
  423. return 0;
  424. }
  425.  
  426. Move mv {0,0};
  427. while(ai_has_king && human_has_king){
  428. print_board(b, mv);
  429. if(turn == ai_color)
  430. ai_move(b, h, turn, 7, mv);
  431. else
  432. mv = read_move(valid_moves(b, turn), turn);
  433.  
  434. if(mv.from == 0) {
  435. undo_move(b,h);
  436. undo_move(b,h);
  437. continue;
  438. } else if (mv.from == 1) {
  439. ai_color = ai_color == Color::white ? Color::black : Color::white;
  440. continue;
  441. } else if (mv.from == 2) {
  442. human_has_king = false;
  443. break;
  444. }
  445.  
  446. do_move(mv, b, h);
  447. turn = turn == Color::white ? Color::black : Color::white;
  448.  
  449. ai_has_king = human_has_king = false;
  450. for(size_t i = 21; i < 99; ++i) { // board.h about these magic numbers
  451. if(b.get(i).piece == Piece::king || b.get(i).piece == Piece::king_castle) {
  452. if(b.get(i).piece_color == ai_color) {
  453. ai_has_king = true;
  454. } else {
  455. human_has_king = true;
  456. }
  457. }
  458. }
  459.  
  460. }
  461. print_board(b, mv);
  462.  
  463. std::cout<<"nn";
  464. if(!human_has_king)
  465. std::cout<<"You lose.";
  466. if(!ai_has_king)
  467. std::cout<<"You win.";
  468. std::cout<<"nnBye!nn";
  469. }
  470.  
  471. /*
  472. File: ai.h
  473.  
  474. Takes a board, returns an heuristically optimized move.
  475.  
  476. Author: Ken Rouwas
  477. Date 2017-09-14
  478. */
  479.  
  480. #pragma once
  481.  
  482. #include "move.h"
  483.  
  484. namespace Chess {
  485. int ai_move(Board& b, Boardhistory& bh, Color turn, int depth, Move& _bm, int alpha = -400, int beta = 400);
  486. }
  487.  
  488. // See board.h on "magic numbers"
  489. // File: ai.cpp
  490.  
  491. #include "ai.h"
  492. #include <random>
  493. #include <algorithm>
  494. #include <iostream>
  495.  
  496.  
  497. namespace Chess {
  498. std::mt19937 mt(time(0));
  499.  
  500.  
  501. void moveorder(MoveSet& ms) {
  502. std::random_shuffle(ms.begin(), ms.end());
  503. }
  504.  
  505. static int evaluate_leaf(const Board& b) {
  506. int sum = 0;
  507. for(size_t i = 21; i < 99; ++i) {
  508. if(b.get(i).piece_color == Color::none)
  509. continue;
  510. int c = b.get(i).piece_color == Color::white ? 1 : -1;
  511. int v = 0;
  512. switch(b.get(i).piece){
  513. case Piece::pawn:
  514. case Piece::pawn_en_passant:
  515. v = 1;
  516. break;
  517. case Piece::rook:
  518. case Piece::rook_castle:
  519. v = 5;
  520. break;
  521. case Piece::knight:
  522. case Piece::bishop:
  523. v = 3;
  524. break;
  525. case Piece::queen:
  526. v = 9;
  527. break;
  528. default:
  529. break;
  530. }
  531. sum += c*v;
  532. }
  533. return sum;
  534. }
  535.  
  536. static Color flipped_turn(Color turn) {
  537. if(turn == Color::white)
  538. return Color::black;
  539. return Color::white;
  540. }
  541.  
  542. int ai_move(Board& b, Boardhistory& bh, Color turn, int depth, Move& _bm, int alpha, int beta) {
  543. /*
  544. MoveSet valid = valid_moves(b, turn);
  545. _bm = valid[mt()%valid.size()];
  546. return 0;
  547. */
  548.  
  549. Move best_move;
  550. int best_score = turn == Color::white ? -300 : 300;
  551. if(!depth)
  552. return evaluate_leaf(b);
  553.  
  554. MoveSet vmoves = valid_moves(b, turn);
  555. moveorder(vmoves);
  556. //int progress = 0; // Temporary hack to show progress
  557. for(Move m : vmoves){
  558. //if(depth == 8) // Temporary hack to show progress
  559. // std::cout<<"r"<<++progress<<"/"<<vmoves.size()<<std::flush;
  560.  
  561. if(b.get(m.to).piece == Piece::king || b.get(m.to).piece == Piece::king_castle){
  562. best_score = turn==Color::white ? 200+depth : -200-depth;
  563. best_move = m;
  564. break;
  565. }
  566.  
  567. do_move(m, b, bh);
  568. int new_score = ai_move(b, bh, flipped_turn(turn), depth-1, _bm, alpha, beta);
  569. undo_move(b,bh);
  570.  
  571. if((turn == Color::white && new_score > best_score) || (turn == Color::black && new_score < best_score)){
  572. best_move = m;
  573. best_score = new_score;
  574.  
  575. if(turn == Color::black) {
  576. beta = new_score;
  577. if(beta <= alpha)
  578. break;
  579. }
  580.  
  581. if(turn == Color::white) {
  582. alpha = new_score;
  583. if(alpha >= beta)
  584. break;
  585. }
  586. }
  587.  
  588. }
  589. _bm = best_move;
  590. return best_score;
  591.  
  592. }
  593. }
  594.  
  595. /*
  596. File: gui.h
  597.  
  598. Interactive graphical interface of a chess board.
  599.  
  600. This is temporarily a quick and dirty solution.
  601.  
  602. Author: Ken Rouwas
  603. Date 2017-09-15
  604. */
  605.  
  606. #pragma once
  607.  
  608. #include <vector>
  609. #include "board.h"
  610. #include "move.h"
  611.  
  612. namespace Chess {
  613.  
  614. void print_board(const Board&, Move last_move);
  615.  
  616. /* Returns when one of the provided valid moves is read */
  617. Move read_move(const MoveSet& valid_moves, Color turn);
  618.  
  619. }
  620.  
  621. // File: gui.cpp
  622. // This is quick, ugly, pragmatic, temporary.
  623.  
  624. #include <iostream>
  625. #include <cctype>
  626. #include <map>
  627. #include "gui.h"
  628.  
  629.  
  630.  
  631. namespace Chess {
  632.  
  633. using namespace std;
  634.  
  635. static const std::map<Piece, char> sprites = {
  636. { Piece::pawn, 'A' },
  637. { Piece::pawn_en_passant, 'P' },
  638. { Piece::rook, 'H' },
  639. { Piece::rook_castle, 'H' },
  640. { Piece::knight, 'F' },
  641. { Piece::bishop, 'I' },
  642. { Piece::king, 'K' },
  643. { Piece::king_castle, 'K' },
  644. { Piece::none, '+' },
  645. { Piece::out_of_board, '#' },
  646. { Piece::queen, 'Q' }
  647. };
  648.  
  649. void print_board(const Board& b, Move last_move) {
  650. cout<<"n 1 2 3 4 5 6 7 8";
  651. for(ssize_t i=20; i < (ssize_t)board_size; ++i){
  652. if(i%10 == 9)
  653. continue;
  654. if(i/10 == 10)
  655. break;
  656. if(i%10 == 0) {
  657. cout<<"n "<<i/10<<" ";
  658. continue;
  659. }
  660. char s = sprites.at(b.get(i).piece);
  661. if(b.get(i).piece_color == Color::black)
  662. s = tolower(s);
  663. cout<<s;
  664. if(last_move.from == i || last_move.to == i)
  665. cout<<'<';
  666. else
  667. cout<<' ';
  668. }
  669. cout<<"n"<<endl;
  670. }
  671.  
  672. Move read_move(const MoveSet& valid_moves, Color turn) {
  673. if(cin.fail()) {
  674. cin.clear();
  675. string dummy;
  676. cin >> dummy;
  677. }
  678.  
  679. int in;
  680. Move ret;
  681. cout<<"Your move, "<<( turn == Color::white ? "white" : "black" )<<": ";
  682. cin>>in;
  683.  
  684. // Command to undo 1 or 2 moves (2 to revert AI+own)
  685. if(in == 0 || in == 1 || in == 2){
  686. ret.from = in;
  687. return ret;
  688. }
  689.  
  690. ret.to = in%10+in/10%10*10;
  691. in /= 100;
  692. ret.from = in%10+in/10%10*10;
  693.  
  694. for(const auto m : valid_moves)
  695. if(m.from == ret.from && m.to == ret.to)
  696. return ret;
  697. cout<<"Invalid moven";
  698. return read_move(valid_moves, turn);
  699. }
  700.  
  701. }
  702.  
  703. if (m.to == 23) { // why 23? What is its meaning?
  704. do_change(b, bh, 21, Square(Piece::none, Color::none)); // why 21?
  705. do_change(b, bh, 24, Square(Piece::rook, Color::black)); // why 24?
  706. }
  707.  
  708. void init_classic_board(Board&);
  709.  
  710. Board b = init_classic_board();
  711.  
  712. static const std::map<Piece, char> sprites = {
  713. { Piece::pawn, ' A' },
  714. { Piece::pawn_en_passant, 'P' },
  715. { Piece::rook, 'H' },
  716. { Piece::rook_castle, 'H' },
  717. { Piece::knight, 'F' },
  718. { Piece::bishop, 'I' },
  719. { Piece::king, 'K' },
  720. { Piece::king_castle, 'K' },
  721. { Piece::none, '+' },
  722. { Piece::out_of_board, '#' },
  723. { Piece::queen, 'Q' }
  724. };
  725.  
  726. static const std::map<Piece, char> sprites = {
  727. { Piece::pawn, 'A' },
  728. { Piece::pawn_en_passant, 'P' },
  729. { Piece::rook, 'H' },
  730. { Piece::rook_castle, 'H' },
  731. { Piece::knight, 'F' },
  732. { Piece::bishop, 'I' },
  733. { Piece::king, 'K' },
  734. { Piece::king_castle, 'K' },
  735. { Piece::none, '+' },
  736. { Piece::out_of_board, '#' },
  737. { Piece::queen, 'Q' }
  738. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement