TheChess

chess/moves.hpp

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 
00012 #ifndef THECHESS_MOVES_H_
00013 #define THECHESS_MOVES_H_
00014 
00015 namespace thechess {
00016 namespace chess {
00017 struct MovesCheck;
00018 class Moves;
00019 class MovesIterator;
00020 }
00021 }
00022 
00023 #include <vector>
00024 
00025 #include "move.hpp"
00026 #include "xy.hpp"
00027 #include "board.hpp"
00028 #include "tests.hpp"
00029 
00030 typedef unsigned char byte;
00031 
00032 namespace thechess {
00033 namespace chess {
00034 
00035 struct MovesCheck {
00036     bool correct;
00037     int move_with_error;
00038     Board board;
00039 };
00040 
00041 enum Xy_type {
00042     xy_from = 0,
00043     xy_to = 1
00044 };
00045 
00046 typedef std::vector<byte> svuc;
00047 
00048 class Moves : public svuc {
00049 public:
00050     Moves(int moves_count=0);
00051     Moves(Move moves[], int moves_count);
00052     const svuc& as_svuc() const {
00053         return *this;
00054     }
00055     svuc& as_svuc() {
00056         return *this;
00057     }
00058     int size() const {
00059         return (this->svuc::size() * 8) / 12;
00060     }
00061 
00062     void push_move(Move move);
00063     void pop_move();
00064     void pop_moves(int number);
00065 
00066     Move move_at(int n, const Board& board) const {
00067         return Move(xy_(n, xy_from), xy_(n, xy_to), board);
00068     }
00069     Move move_at(int n) const {
00070         return Move(xy_(n, xy_from), xy_(n, xy_to));
00071     }
00072     Board board_at(int n) const; // returns board position BEFORE move number n
00073 
00074     int check() const; // -1 = no errors, other value -- n of wrong move
00075 
00076     static int n_to_human(int move_n) {
00077         return (move_n + 2) / 2;
00078     }
00079     static int size_to_human(int size) {
00080         return n_to_human(size - 1);
00081     }
00082     static int n_from_human(int human_i, Color color) {
00083         return (human_i - 1) * 2 + ((color == white) ? 0 : 1);
00084     }
00085     int human_size() const {
00086         return size_to_human(size());
00087     }
00088 
00089     static int order_int(int move_n) {
00090         return move_n % 2;
00091     }
00092     static Color order(int move_n) {
00093         return order_int(move_n) == 0 ? white : black;
00094     }
00095 
00096     void pgn(std::ostream& out, const std::string& result,
00097              bool reduced=false) const;
00098 
00099 private:
00100     byte q(int i) const {
00101         return (byte)((*this)[i]);
00102     }
00103 
00104     Xy xy_(int i) const;
00105     Xy xy_(int n, Xy_type xy_type) const {
00106         return xy_(n * 2 + (int)xy_type);
00107     }
00108     void xy_(int i, Xy xy);
00109     void xy_(int n, Xy_type xy_type, Xy xy) {
00110         xy_(n * 2 + (int)xy_type, xy);
00111     }
00112 
00113     void set_move(int n, Move move);
00114     void fill(int moves_count);
00115     friend void run_tests();
00116 };
00117 
00118 class MovesIterator {
00119 public:
00120     MovesIterator(const Moves* moves, Board& board, int from=0);
00121     //~ MovesIterator(const Moves* moves, int from=0);
00122     Move move() const {
00123         return moves_->move_at(n, board_);
00124     }
00125     Move operator*() const {
00126         return move();
00127     }
00128     MovesIterator& operator ++() {
00129         board_.make_move(move());
00130         n++;
00131         return *this;
00132     }
00133     const Moves* moves_;
00134     Board& board_;
00135     int n;
00136 };
00137 
00138 
00139 #define THECHESS_MOVES_FROM_TO(move_it, moves, board, from, to) \
00140 for (thechess::chess::MovesIterator move_it = \
00141 thechess::chess::MovesIterator(moves, board, from); \
00142 move_it.n < to; ++move_it)
00143 
00144 #define THECHESS_MOVES_TO(move_it, moves, board, to) \
00145 THECHESS_MOVES_FROM_TO(move_it, moves, board, 0, to)
00146 
00147 #define THECHESS_MOVES_FROM(move_it, moves, board, from) \
00148 THECHESS_MOVES_FROM_TO(move_it, moves, board, from, (moves)->size())
00149 
00150 #define THECHESS_MOVES_FOREACH(move_it, moves, board) \
00151 THECHESS_MOVES_FROM(move_it, moves, board, 0)
00152 
00153 }
00154 }
00155 
00156 
00157 /* moves_:
00158  * each move takes 12 bites, each Xy -- 6 bits, each coordinate -- 3 bits
00159  * pair of moves -- 3 bytes
00160  */
00161 
00162 #endif // THECHESS_MOVES_H_
00163 
 All Classes Functions Enumerations Enumerator