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
);
61 static ChessPiece
fromDescription(const QString
& description
);
63 inline Point
kingStartingPosition() const { return Point(4, color() == WHITE
? 7 : 0); }
64 inline int startingRank() const { return color() == WHITE
? 6 : 1; }
65 inline Point
direction() const { return direction(color()); }
66 static Point
direction(Color color
) { return Point(0, color
== WHITE
? -1 : 1); }
67 inline int promotionRank() const { return color() == WHITE
? 0 : 7; }
68 bool operator==(const ChessPiece
& p
) const;
69 bool operator!=(const ChessPiece
& p
) const { return !operator==(p
); }
70 bool operator!() const { return !valid(); }
71 bool operator<(const ChessPiece
& p
) const {
72 return m_color
!= p
.m_color
?
75 operator bool() const { return valid(); }
78 std::ostream
& operator<<(std::ostream
& os
, const ChessPiece
& p
);
80 template <typename Pos
>
81 ChessPiece::Move::Type
ChessPiece::canMove(const Pos
& position
,
82 Point from
, Point to
) const {
90 PathInfo path
= position
.path(from
, to
);
91 if (path
.parallel() && path
.clear() && !sameColor(position
[to
]))
100 return Move::Invalid
;
101 PathInfo path
= position
.path(from
, to
);
102 if (path
.diagonal() && path
.clear() && !sameColor(position
[to
]))
105 return Move::Invalid
;
109 if (sameColor(position
[to
]))
110 return Move::Invalid
;
113 Point delta
= from
- to
;
114 if (abs(delta
.x
) == 1 && abs(delta
.y
) == 2)
116 if (abs(delta
.y
) == 1 && abs(delta
.x
) == 2)
118 return Move::Invalid
;
124 return Move::Invalid
;
125 PathInfo path
= position
.path(from
, to
);
126 if (path
.valid() && path
.clear() && !sameColor(position
[to
]))
129 return Move::Invalid
;
135 return Move::Invalid
;
136 Point delta
= to
- from
;
137 if (abs(delta
.x
) <= 1 && abs(delta
.y
) <= 1 && !sameColor(position
[to
]))
139 else if (from
== kingStartingPosition()) {
140 if (delta
== Point(2,0)) {
141 if (!position
[from
+ Point(1,0)] &&
143 position
.castleKing(color()))
144 return Move::KingSideCastling
;
146 else if (delta
== Point(-2,0)) {
147 if (!position
[from
- Point(1,0)] &&
148 !position
[from
- Point(2,0)] &&
150 position
.castleQueen(color()))
151 return Move::QueenSideCastling
;
154 return Move::Invalid
;
159 ChessPiece destinationPiece
= position
[to
];
160 Point delta
= to
- from
;
161 bool enPassant
= position
.enPassantSquare() == to
;
164 if (!destinationPiece
&& !enPassant
) {
165 if (delta
== direction())
166 if (to
.y
== promotionRank())
167 return Move::Promotion
;
170 if (from
.y
== startingRank() && delta
== direction() * 2
171 && !position
[from
+ direction()])
172 return Move::EnPassantTrigger
;
174 return Move::Invalid
;
178 else if (enPassant
|| !sameColor(destinationPiece
))
179 if (delta
.y
== direction().y
&& abs(delta
.x
) == 1)
181 return Move::EnPassantCapture
;
182 else if (to
.y
== promotionRank())
183 return Move::Promotion
;
187 return Move::Invalid
;
191 return Move::Invalid
;