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.
18 #include "piecetype.h"
25 typedef PieceType Type
;
26 typedef Type PromotionType
;
27 typedef PieceColor Color
;
29 typedef ChessMove Move
;
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;
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;
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
?
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 {
89 PathInfo path
= position
.path(from
, to
);
90 if (path
.parallel() && path
.clear() && !sameColor(position
[to
]))
100 PathInfo path
= position
.path(from
, to
);
101 if (path
.diagonal() && path
.clear() && !sameColor(position
[to
]))
104 return Move::Invalid
;
108 if (sameColor(position
[to
]))
109 return Move::Invalid
;
112 Point delta
= from
- to
;
113 if (abs(delta
.x
) == 1 && abs(delta
.y
) == 2)
115 if (abs(delta
.y
) == 1 && abs(delta
.x
) == 2)
117 return Move::Invalid
;
123 return Move::Invalid
;
124 PathInfo path
= position
.path(from
, to
);
125 if (path
.valid() && path
.clear() && !sameColor(position
[to
]))
128 return Move::Invalid
;
134 return Move::Invalid
;
135 Point delta
= to
- from
;
136 if (abs(delta
.x
) <= 1 && abs(delta
.y
) <= 1 && !sameColor(position
[to
]))
138 else if (from
== kingStartingPosition()) {
139 if (delta
== Point(2,0)) {
140 if (!position
[from
+ Point(1,0)] &&
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)] &&
149 position
.castleQueen(color()))
150 return Move::QueenSideCastling
;
153 return Move::Invalid
;
158 ChessPiece destinationPiece
= position
[to
];
159 Point delta
= to
- from
;
160 bool enPassant
= position
.enPassantSquare() == to
;
163 if (!destinationPiece
&& !enPassant
) {
164 if (delta
== direction())
165 if (to
.y
== promotionRank())
166 return Move::Promotion
;
169 if (from
.y
== startingRank() && delta
== direction() * 2
170 && !position
[from
+ direction()])
171 return Move::EnPassantTrigger
;
173 return Move::Invalid
;
177 else if (enPassant
|| !sameColor(destinationPiece
))
178 if (delta
.y
== direction().y
&& abs(delta
.x
) == 1)
180 return Move::EnPassantCapture
;
181 else if (to
.y
== promotionRank())
182 return Move::Promotion
;
186 return Move::Invalid
;
190 return Move::Invalid
;