GNUShogi engine.
[tagua/yd.git] / src / variants / xchess / dropanimator.impl.h
blob68938d255b97692fc642e5a87d05dcc54efcc1bc
1 #ifndef XCHESS__DROPANIMATOR_IMPL_H
2 #define XCHESS__DROPANIMATOR_IMPL_H
4 #include "dropanimator.h"
5 #include "animator.impl.h"
7 #include <KDebug>
9 template <typename Base>
10 DropAnimatorMixin<Base>::DropAnimatorMixin(API cinterface)
11 : Base(cinterface) { }
14 template <typename Base>
15 void DropAnimatorMixin<Base>::updatePool(const Position& final) {
16 for(int color = 0; color < 2; color++) {
17 typename Piece::Color c = static_cast<typename Piece::Color>(color);
18 const typename Position::PlayerPool& before = m_cinterface->position()->rawPool(c);
19 const typename Position::PlayerPool& after = final.rawPool(c);
20 typename Position::PlayerPool::const_iterator before_it = before.begin();
21 typename Position::PlayerPool::const_iterator after_it = after.begin();
23 int pos = 0;
25 // oh, a nice bunch of write-only magic shit
26 while(before_it != before.end() || after_it != after.end()) {
27 bool skip_after = (after_it == after.end() || (before_it != before.end()
28 && before_it->first < after_it->first ));
29 bool skip_before = (before_it == before.end() || (after_it != after.end()
30 && after_it->first < before_it->first ));
31 int na = skip_after ? 0 : after_it->second;
32 int nb = skip_before ? 0 : before_it->second;
34 if(nb < na) {
35 for(int i = nb; i < na; i++)
36 m_cinterface->insertPoolPiece(color, pos + (i - nb), Piece(c, after_it->first) );
38 else if(na < nb) {
39 for(int i = na; i < nb; i++)
40 m_cinterface->removePoolSprite(color, pos);
43 if(!skip_before)
44 ++before_it;
45 if(!skip_after) {
46 pos += after_it->second;
47 ++after_it;
53 template <typename Base>
54 AnimationGroupPtr DropAnimatorMixin<Base>::warp(const Position& final) {
55 updatePool(final);
56 return Base::warp(final);
59 template <typename Base>
60 AnimationGroupPtr DropAnimatorMixin<Base>::forward(const Position& final, const Move& move) {
61 AnimationFactory res(m_cinterface->inner());
63 if(move.drop()) {
64 std::pair<int, int> dropped = m_cinterface->droppedPoolPiece();
65 if(dropped.first != -1 && dropped.second != -1
66 && m_cinterface->position()->pool(dropped.first).get(dropped.second) == move.drop()) {
67 NamedSprite drop = m_cinterface->takePoolSprite(dropped.first, dropped.second);
68 m_cinterface->setSprite(move.to, drop);
69 res.addPreAnimation(Animate::move(drop, move.to));
70 return res;
72 else {
73 NamedSprite drop = m_cinterface->setPiece(move.to, move.drop(), false);
74 res.addPreAnimation(Animate::appear(drop));
77 else {
78 res.setGroup(Base::forward(final, move));
81 updatePool(final);
82 return res;
85 template <typename Base>
86 AnimationGroupPtr DropAnimatorMixin<Base>::back(const Position& final, const Move& move) {
87 AnimationFactory res(m_cinterface->inner());
89 if(move.drop()) {
90 NamedSprite drop = m_cinterface->takeSprite(move.to);
91 res.addPostAnimation(Animate::disappear(drop));
94 else {
95 res.setGroup(Base::back(final, move));
98 updatePool(final);
99 return res;
102 #endif // XCHESS__DROPANIMATOR_IMPL_H