TheChess
|
00001 /* 00002 * thechess, chess game web application written in C++ and based on Wt 00003 * Copyright (C) 2010 Boris Nagaev 00004 * 00005 * thechess is licensed under the GNU GPL Version 2. 00006 * Other versions of the GPL do not apply. 00007 * See the LICENSE file for terms of use. 00008 */ 00009 00010 // 00011 #ifndef THECHESS_BOARD_H_ 00012 #define THECHESS_BOARD_H_ 00013 00014 namespace thechess { 00015 namespace chess { 00016 class Board; 00017 } 00018 } 00019 00020 #include <string> 00021 #include <ostream> 00022 00023 #include "tests.hpp" 00024 #include "move.hpp" 00025 #include "xy.hpp" 00026 #include "field.hpp" 00027 00028 namespace thechess { 00029 namespace chess { 00030 00031 const int order_byte = 32; 00032 const int castling_byte = 33; 00033 const int fields_size = 34; 00034 typedef unsigned char byte; 00035 typedef byte Fields[34]; 00036 00037 enum FinishState { 00038 nothing = 0, 00039 checkmate = 1, // мат 00040 stalemate = 2 // пат 00041 }; 00042 00043 class Board { 00044 public: 00045 void init_chessmans(Yname y, Color color); 00046 void init_pawns(Yname y, Color color); 00047 Board(); 00048 const Fields& fields() const { 00049 return fields_; 00050 } 00051 00052 bool isset(Xy xy) const; 00053 Color color(Xy xy) const; 00054 Chessman chessman(Xy xy) const; 00055 Field field(Xy xy) const; 00056 00057 void make_move(const Move move); 00058 00059 Color order() const; 00060 bool castling(Xy rock_xy) const; 00061 bool long_pawn() const; 00062 Xname long_pawn_x() const; 00063 00064 bool test_move(const Move move) const; 00065 bool test_attack(Xy xy, Color c) const; 00066 bool test_attack(Move move) const; 00067 FinishState test_end() const; 00068 00069 const std::string to_string() const { 00070 return std::string((char*)fields_, sizeof(fields_)); 00071 } 00072 const std::string to_table() const; 00073 00074 Xy some_target(Xy from) const; 00075 Xy some_source(Xy to) const; 00076 Move some_move() const; 00077 bool can_move(Xy from) const { 00078 return some_target(from) != xy_null; 00079 } 00080 bool test_shah(Color color) const; 00081 bool test_shah() const { 00082 return test_shah(order()); 00083 } 00084 Xy find_king(Color c) const; 00085 00086 bool test_takes(const Move move) const; 00087 bool test_castling(const Move move) const; 00088 00089 void fen(std::ostream& out, int halfmove, int fullmove) const; 00090 00091 private: 00092 Fields fields_; 00093 byte q(Xy xy) const; // quarta of this field 00094 void q(Xy xy, byte q_); 00095 00096 void unset(Xy xy); 00097 void color(Xy xy, Color c); 00098 void chessman(Xy xy, Chessman chessman); 00099 void field(Xy xy, Field field); 00100 00101 void order(Color c); 00102 void change_order(); 00103 void castling_reset(); 00104 void castling_off(Xy rock_xy); 00105 void long_pawn(bool value, int x=0); 00106 00107 void simple_move(const Move move); 00108 bool simple_test_move(Move move) const; 00109 bool test_attack(Xy xy) const; 00110 00111 void fen_pieces(std::ostream& out) const; 00112 void fen_castling(std::ostream& out) const; 00113 00114 friend void run_tests(); 00115 }; 00116 00117 } 00118 } 00119 00120 /* fields_: 34 bytes: 00121 * 00122 * 1) 64 * 4 bites = 32 bytes (0-31) 00123 * 4 bites = (Color << 3 | Chessman) 00124 * if is not set: 4 bites = 0 00125 * 2) 1 byte (32'd): == bool Order (Color) 00126 * 3) 1 byte (33'th): 00127 * castling (4) = a1, h1, a8, h8 00128 * Last pawn long move: 1 bit (0 if was not) + 3 bits (X of pawn) 00129 * Note: (a1, h1 - white; a8, h8 - black, a1, a8 - long; h1, h8 - short) 00130 */ 00131 00132 00133 #endif // THECHESS_BOARD_H_