Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef USE_PCH
00025 #include "sys.h"
00026 #include <iostream>
00027 #endif
00028
00029 #include "ChessNotation.h"
00030
00031 namespace cwchess {
00032
00033 std::ostream& operator<<(std::ostream& os, ChessNotation const& chess_notation)
00034 {
00035 if (chess_notation.M_type)
00036 chess_notation.print_on(os,* chess_notation.M_type);
00037 if (chess_notation.M_piece)
00038 chess_notation.print_on(os,* chess_notation.M_piece);
00039 if (chess_notation.M_index)
00040 chess_notation.print_on(os,* chess_notation.M_index);
00041 if (chess_notation.M_move)
00042 chess_notation.print_on(os,* chess_notation.M_move);
00043 return os;
00044 }
00045
00046 void ChessNotation::print_on(std::ostream& os, Piece const& piece) const
00047 {
00048 print_on(os, piece.type());
00049 }
00050
00051 void ChessNotation::print_on(std::ostream& os, Type const& type) const
00052 {
00053 switch(type())
00054 {
00055 case knight_bits:
00056 os << 'N';
00057 break;
00058 case king_bits:
00059 os << 'K';
00060 break;
00061 case bishop_bits:
00062 os << 'B';
00063 break;
00064 case rook_bits:
00065 os << 'R';
00066 break;
00067 case queen_bits:
00068 os << 'Q';
00069 break;
00070 }
00071 }
00072
00073 void ChessNotation::print_on(std::ostream& os, Index const& index) const
00074 {
00075 char column = 'a' + index.col();
00076 char rank = '1' + index.row();
00077 os << column << rank;
00078 }
00079
00080 void ChessNotation::print_on(std::ostream& os, Move const& move) const
00081 {
00082 Piece const& piece(M_chess_position.piece_at(move.from()));
00083 int col_diff = move.from().col() - move.to().col();
00084 if (piece == king && (col_diff == 2 || col_diff == -2))
00085 {
00086 if (col_diff == 2)
00087 os << "0-0-0";
00088 else
00089 os << "0-0";
00090 }
00091 else
00092 {
00093 print_on(os, piece);
00094 print_on(os, move.from());
00095 bool target_square_empty = M_chess_position.piece_at(move.to()) == nothing;
00096 bool en_passant = col_diff != 0 && piece == pawn && target_square_empty;
00097 if (target_square_empty && !en_passant)
00098 os << '-';
00099 else
00100 os << 'x';
00101 print_on(os, move.to());
00102 if (en_passant)
00103 os << " e.p.";
00104 if (move.is_promotion())
00105 {
00106 os << '(';
00107 print_on(os, move.promotion_type());
00108 os << ')';
00109 }
00110 }
00111 Debug(dc::place.off());
00112 ChessPosition tmp(M_chess_position);
00113 if (!tmp.legal(move))
00114 os << " illegal move!";
00115 else
00116 {
00117 bool draw = tmp.execute(move);
00118
00119 int moves = 0;
00120 for (PieceIterator piece_iter = tmp.piece_begin(tmp.to_move()); piece_iter != tmp.piece_end(); ++piece_iter)
00121 {
00122 MoveIterator move_end(tmp.move_end());
00123 for (MoveIterator iter = tmp.move_begin(piece_iter.index()); iter != move_end; ++iter)
00124 ++moves;
00125 }
00126 bool check = tmp.check();
00127 bool check_mate = false;
00128 bool stale_mate = false;
00129 if (moves == 0)
00130 {
00131 if (check)
00132 {
00133 check_mate = true;
00134 draw = false;
00135 }
00136 else
00137 {
00138 stale_mate = true;
00139 draw = true;
00140 }
00141 }
00142 if (check_mate)
00143 os << '#';
00144 else if (stale_mate)
00145 os << " stale mate";
00146 if (check_mate)
00147 {
00148 if (tmp.to_move() == black)
00149 os << " 1-0";
00150 else
00151 os << " 0-1";
00152 }
00153 else if (check)
00154 os << '+';
00155 if (draw)
00156 os << " 1/2-1/2";
00157 }
00158 Debug(dc::place.on());
00159 }
00160
00161 }