2 Copyright (c) 2006 Paolo Capriotti <p.capriotti@gmail.com>
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.
11 #include "editposition.h"
12 #include "graphicalsystem.h"
13 #include "entities/userentity.h"
14 #include "piecefunction.h"
18 using namespace boost
;
22 UndoHistory::UndoHistory() {
26 void UndoHistory::add(const UndoAction
& action
) {
27 m_history
.erase(m_history
.begin() + m_index
,
29 m_history
.push_back(action
);
33 const UndoAction
* UndoHistory::undo() {
34 if (m_index
<= 0) return 0;
37 return &m_history
[m_index
];
40 const UndoAction
* UndoHistory::redo() {
41 if (m_index
>= m_history
.size()) return 0;
43 UndoAction
* res
= &m_history
[m_index
];
50 class EditAction
: public AbstractMove
{
51 typedef variant
<NormalUserMove
, DropUserMove
> UserMove
;
54 class ConvertToNormalUserMove
: public static_visitor
<NormalUserMove
> {
56 NormalUserMove
operator()(const NormalUserMove
& m
) const {
60 NormalUserMove
operator()(const DropUserMove
& m
) const {
61 return NormalUserMove(Point::invalid(), m
.m_to
);
65 EditAction(const UserMove
& move
)
67 virtual QString
SAN(boost::shared_ptr
<AbstractPosition
>) const { return QString(); }
68 virtual DecoratedMove
toDecoratedMove(boost::shared_ptr
<AbstractPosition
>) const {
69 return DecoratedMove(); }
70 virtual QString
toString(boost::shared_ptr
<AbstractPosition
>) const { return QString(); }
71 virtual NormalUserMove
toUserMove() const {
72 return apply_visitor(ConvertToNormalUserMove(), m_move
);
74 virtual AbstractPiece::Ptr
pieceHint() const {
75 if (const DropUserMove
* move
= get
<DropUserMove
>(&m_move
))
78 return AbstractPiece::Ptr();
80 virtual bool equals(AbstractMove::Ptr
/*other*/) const {
81 // EditAction* move = dynamic_cast<EditAction*>(other.get());
82 // return move && (m_move == move->m_move);
83 // FIXME: the above does not compile
87 UserMove
& move() { return m_move
; }
90 class EditPositionEntity
: public UserEntity
{
91 struct EditPositionEntityInternal
{
92 shared_ptr
<GraphicalInfo
> m_graphical
;
93 VariantInfo
* m_variant
;
94 EditPositionEntityInternal(const shared_ptr
<GraphicalInfo
>& graphical
,
96 : m_graphical(graphical
)
97 , m_variant(variant
) { }
99 EditPositionEntityInternal m_data
;
100 UndoHistory
& m_undo_history
;
102 class ExecuteMoveVisitor
: public static_visitor
<UndoAction
> {
103 EditPositionEntityInternal
& m_data
;
105 ExecuteMoveVisitor(EditPositionEntityInternal
& data
)
108 UndoAction
operator()(const NormalUserMove
& move
) {
109 if (move
.to
.valid()) {
110 Element removedElement
= m_data
.m_graphical
->getElement(move
.to
);
111 m_data
.m_graphical
->setElement(
113 m_data
.m_graphical
->getElement(move
.from
));
114 m_data
.m_graphical
->adjustSprite(move
.to
);
115 m_data
.m_graphical
->removeElement(move
.from
);
116 return MoveAction(move
.from
, move
.to
, removedElement
.piece());
119 Element removedElement
= m_data
.m_graphical
->getElement(move
.from
);
120 m_data
.m_graphical
->removeElement(move
.from
);
121 return RemoveAction(move
.from
, removedElement
.piece());
125 UndoAction
operator()(const DropUserMove
& move
) {
126 AbstractPiece::Ptr dropped
= move
.m_piece
;
127 m_data
.m_graphical
->setPiece(
131 m_data
.m_graphical
->adjustSprite(move
.m_to
);
132 return DropAction(move
.m_to
, dropped
);
136 class UndoActionVisitor
: public static_visitor
<void> {
137 EditPositionEntityInternal
& m_data
;
139 UndoActionVisitor(EditPositionEntityInternal
& data
)
142 void operator()(const DropAction
& action
) {
143 m_data
.m_graphical
->removeElement(action
.m_to
);
146 void operator()(const RemoveAction
& action
) {
148 m_data
.m_graphical
->setPiece(action
.m_to
, action
.m_piece
);
151 void operator()(const MoveAction
& action
) {
152 m_data
.m_graphical
->setElement(
154 m_data
.m_graphical
->getElement(action
.m_to
));
156 m_data
.m_graphical
->setPiece(action
.m_to
, action
.m_piece
);
158 m_data
.m_graphical
->removeElement(action
.m_to
);
159 m_data
.m_graphical
->adjustSprite(action
.m_from
);
162 void operator()(const WarpAction
& action
) {
163 kDebug() << "undo warp from:";
164 kDebug() << action
.m_from
->fen(0, 0);
166 kDebug() << action
.m_to
->fen(0, 0);
167 m_data
.m_graphical
->warp(AbstractMove::Ptr(), action
.m_from
);
171 class RedoActionVisitor
: public static_visitor
<void> {
172 EditPositionEntityInternal
& m_data
;
174 RedoActionVisitor(EditPositionEntityInternal
& data
)
177 void operator()(const DropAction
& action
) {
179 m_data
.m_graphical
->setPiece(action
.m_to
, action
.m_piece
);
182 void operator()(const RemoveAction
& action
) {
183 m_data
.m_graphical
->removeElement(action
.m_to
);
186 void operator()(const MoveAction
& action
) {
187 m_data
.m_graphical
->setElement(
189 m_data
.m_graphical
->getElement(action
.m_from
));
190 m_data
.m_graphical
->removeElement(action
.m_from
);
191 m_data
.m_graphical
->adjustSprite(action
.m_to
);
194 void operator()(const WarpAction
& action
) {
195 m_data
.m_graphical
->warp(AbstractMove::Ptr(), action
.m_to
);
199 EditPositionEntity(VariantInfo
* variant
,
200 const shared_ptr
<GraphicalInfo
>& graphical
,
201 UndoHistory
& undo_history
)
203 , m_data(graphical
, variant
)
204 , m_undo_history(undo_history
) { }
206 virtual QString
save() const { return ""; }
207 virtual void loadPGN(const PGN
&) { }
209 virtual AbstractMove::Ptr
testMove(const NormalUserMove
& m
) const {
210 return AbstractMove::Ptr(new EditAction(m
));
213 virtual AbstractMove::Ptr
testMove(const DropUserMove
& m
) const {
214 return AbstractMove::Ptr(new EditAction(m
));
217 virtual bool testPremove(const NormalUserMove
&) const { return false; }
218 virtual bool testPremove(const DropUserMove
&) const { return false; }
220 virtual void executeMove(AbstractMove::Ptr move
) {
221 EditAction
* action
= dynamic_cast<EditAction
*>(move
.get());
223 ExecuteMoveVisitor
visitor(m_data
);
224 UndoAction undo_action
= apply_visitor(visitor
, action
->move());
225 m_undo_history
.add(undo_action
);
229 virtual void handleRightClick(const Point
& p
) const {
230 Element removedElement
= m_data
.m_graphical
->getElement(p
);
231 UndoAction action
= RemoveAction(p
, removedElement
.piece());
232 m_data
.m_graphical
->removeElement(p
);
233 m_undo_history
.add(action
);
236 virtual void addPremove(const NormalUserMove
&) { }
237 virtual void addPremove(const DropUserMove
&) { }
238 virtual void cancelPremove() { }
240 virtual Action
validTurn(const Point
&) const { return Moving
; }
241 virtual Action
validTurn(int) const { return Moving
; }
242 virtual bool movable(const Point
&) const { return true; }
243 virtual bool jump(const Index
&) { return false; }
244 virtual bool goTo(const Index
&) { return false; }
245 virtual bool gotoFirst() { return false; }
246 virtual bool gotoLast() { return false; }
247 virtual bool forward() { return false; }
248 virtual bool back() { return false; }
250 virtual bool undo() {
251 if (const UndoAction
* action
= m_undo_history
.undo()) {
252 UndoActionVisitor
visitor(m_data
);
253 apply_visitor(visitor
, *action
);
259 virtual bool redo() {
260 if (const UndoAction
* action
= m_undo_history
.redo()) {
261 RedoActionVisitor
visitor(m_data
);
262 apply_visitor(visitor
, *action
);
268 virtual bool truncate() { return false; }
269 virtual bool promoteVariation() { return false; }
271 virtual void notifyClockUpdate(int, int) { }
272 virtual void notifyMove(AbstractMove::Ptr
, AbstractPosition::Ptr
) { }
273 virtual void notifyBack() { }
274 virtual void notifyForward() { }
275 virtual void notifyGotoFirst() { }
276 virtual void notifyGotoLast() { }
279 class FillPool
: public PieceFunction
{
280 shared_ptr
<GraphicalInfo
> m_graphical
;
281 VariantInfo
* m_variant
;
283 FillPool(VariantInfo
* variant
, const shared_ptr
<GraphicalInfo
>& graphical
)
284 : m_graphical(graphical
)
285 , m_variant(variant
) { }
287 virtual void operator()(int color
, int type
) {
288 m_graphical
->addToPool(
289 m_variant
->createPiece(color
, type
),
295 EditPositionController::EditPositionController(ChessTable
* view
, VariantInfo
* variant
)
297 , m_variant(variant
) {
298 m_graphical
= shared_ptr
<GraphicalInfo
>(
299 new GraphicalInfo(m_view
, AbstractPosition::Ptr(), m_variant
));
300 m_entity
= shared_ptr
<EditPositionEntity
>(
301 new EditPositionEntity(m_variant
, m_graphical
, m_undo_history
));
302 m_graphical
->setup(m_entity
);
304 FillPool
fill_pool(m_variant
, m_graphical
);
305 m_variant
->forallPieces(fill_pool
);
308 shared_ptr
<UserEntity
> EditPositionController::entity() const {
312 bool EditPositionController::clearBoard() {
313 AbstractPosition::Ptr position
= m_variant
->createPosition();
314 m_undo_history
.add(WarpAction(m_graphical
->position()->clone(), position
));
315 m_graphical
->warp(AbstractMove::Ptr(), position
);
319 bool EditPositionController::setStartingPosition() {
320 AbstractPosition::Ptr startingPosition
= m_variant
->createPosition();
321 startingPosition
->setup();
322 kDebug() << "adding warp to undo history:";
323 kDebug() << m_graphical
->position()->fen(0, 0);
324 kDebug() << startingPosition
->fen(0, 0);
325 m_undo_history
.add(WarpAction(m_graphical
->position()->clone(), startingPosition
));
326 m_graphical
->warp(AbstractMove::Ptr(), startingPosition
);
330 QString
EditPositionController::fen() {
331 return m_graphical
->position()->fen(0,0);
334 bool EditPositionController::setFEN(const QString
& fen
) {
335 AbstractPosition::Ptr pos
= m_variant
->createPositionFromFEN(fen
);
337 kDebug() << "warping to fen " << fen
;
338 m_undo_history
.add(WarpAction(m_graphical
->position()->clone(), pos
));
339 m_graphical
->warp(AbstractMove::Ptr(), pos
);
343 kDebug() << "invalid fen";
348 void EditPositionController::setTurn(int turn
) {
349 m_graphical
->setTurn(turn
);
352 AbstractPosition::Ptr
EditPositionController::currentPosition() const {
353 return m_graphical
->position();