removed clock pref widget. clock prefs are definitively part of the lua theme.
[kboard.git] / src / variants / xchess / piece.h
blobe6d977cd95916d596bfcadce491adfa3b22ecab3
1 /*
2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@sns.it>
3 (c) 2006 Maurizio Monge <maurizio.monge@kdemail.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9 */
11 #ifndef PIECE_H
12 #define PIECE_H
14 #include <iostream>
16 #include "point.h"
17 #include "move.h"
18 #include "piecetype.h"
19 #include "common.h"
20 #include "pathinfo.h"
23 class ChessPiece {
24 public:
25 typedef PieceType Type;
26 typedef Type PromotionType;
27 typedef PieceColor Color;
28 protected:
29 typedef ChessMove Move;
30 private:
31 Color m_color;
32 Type m_type;
33 public:
34 ChessPiece(Color = INVALID_COLOR, Type = INVALID_TYPE);
35 ChessPiece(const ChessPiece& p);
36 ChessPiece& operator=(const ChessPiece& p);
37 ChessPiece* clone() const;
39 virtual ~ChessPiece() {}
40 inline static Color oppositeColor(Color color) { return color == WHITE ? BLACK :
41 color == BLACK ? WHITE : INVALID_COLOR; }
43 inline Color color() const { return m_color; }
44 inline Type type() const { return m_type; }
45 inline bool valid() const { return m_color != INVALID_COLOR &&
46 m_type != INVALID_TYPE; }
47 QString typeName() const;
48 QString name() const;
50 template <typename Pos>
51 Move::Type canMove(const Pos& position, Point from, Point to) const;
53 bool equals(const ChessPiece& other) const;
54 bool sameColor(const ChessPiece& other) const;
55 int id() const;
56 static Color colorFromId(int);
57 static Type typeFromId(int);
59 static Type getType(const QString& str);
60 static QString typeSymbol(Type type);
62 inline Point kingStartingPosition() const { return Point(4, color() == WHITE? 7 : 0); }
63 inline int startingRank() const { return color() == WHITE? 6 : 1; }
64 inline Point direction() const { return direction(color()); }
65 static Point direction(Color color) { return Point(0, color == WHITE? -1 : 1); }
66 inline int promotionRank() const { return color() == WHITE? 0 : 7; }
67 bool operator==(const ChessPiece& p) const;
68 bool operator!=(const ChessPiece& p) const { return !operator==(p); }
69 bool operator!() const { return !valid(); }
70 bool operator<(const ChessPiece& p) const {
71 return m_color != p.m_color ?
72 m_color < p.m_color :
73 m_type < p.m_type; }
74 operator bool() const { return valid(); }
77 std::ostream& operator<<(std::ostream& os, const ChessPiece& p);
79 template <typename Pos>
80 ChessPiece::Move::Type ChessPiece::canMove(const Pos& position,
81 Point from, Point to) const {
82 switch (m_type)
85 case ROOK:
87 if (from == to)
88 return Move::Invalid;
89 PathInfo path = position.path(from, to);
90 if (path.parallel() && path.clear() && !sameColor(position[to]))
91 return Move::Normal;
92 else
93 return Move::Invalid;
96 case BISHOP:
98 if (from == to)
99 return Move::Invalid;
100 PathInfo path = position.path(from, to);
101 if (path.diagonal() && path.clear() && !sameColor(position[to]))
102 return Move::Normal;
103 else
104 return Move::Invalid;
107 case KNIGHT:
108 if (sameColor(position[to]))
109 return Move::Invalid;
110 else
112 Point delta = from - to;
113 if (abs(delta.x) == 1 && abs(delta.y) == 2)
114 return Move::Normal;
115 if (abs(delta.y) == 1 && abs(delta.x) == 2)
116 return Move::Normal;
117 return Move::Invalid;
120 case QUEEN:
122 if (from == to)
123 return Move::Invalid;
124 PathInfo path = position.path(from, to);
125 if (path.valid() && path.clear() && !sameColor(position[to]))
126 return Move::Normal;
127 else
128 return Move::Invalid;
131 case KING:
133 if (from == to)
134 return Move::Invalid;
135 Point delta = to - from;
136 if (abs(delta.x) <= 1 && abs(delta.y) <= 1 && !sameColor(position[to]))
137 return Move::Normal;
138 else if (from == kingStartingPosition()) {
139 if (delta == Point(2,0)) {
140 if (!position[from + Point(1,0)] &&
141 !position[to] &&
142 position.castleKing(color()))
143 return Move::KingSideCastling;
145 else if (delta == Point(-2,0)) {
146 if (!position[from - Point(1,0)] &&
147 !position[from - Point(2,0)] &&
148 !position[to] &&
149 position.castleQueen(color()))
150 return Move::QueenSideCastling;
153 return Move::Invalid;
156 case PAWN:
158 ChessPiece destinationPiece = position[to];
159 Point delta = to - from;
160 bool enPassant = position.enPassantSquare() == to;
162 // moving
163 if (!destinationPiece && !enPassant) {
164 if (delta == direction())
165 if (to.y == promotionRank())
166 return Move::Promotion;
167 else
168 return Move::Normal;
169 if (from.y == startingRank() && delta == direction() * 2
170 && !position[from + direction()])
171 return Move::EnPassantTrigger;
172 else
173 return Move::Invalid;
176 // capturing
177 else if (enPassant || !sameColor(destinationPiece))
178 if (delta.y == direction().y && abs(delta.x) == 1)
179 if (enPassant)
180 return Move::EnPassantCapture;
181 else if (to.y == promotionRank())
182 return Move::Promotion;
183 else
184 return Move::Normal;
186 return Move::Invalid;
189 default:
190 return Move::Invalid;
194 #endif // PIECE_H