Factor common code out of xboard and gnushogi engines.
[kaya/ydirson.git] / lib / board / pool_animator.rb
blob6a59e47096fb236bd543d0d3f8aac203554be8ed
1 # Copyright (c) 2009 Paolo Capriotti <p.capriotti@gmail.com>
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 require 'animator_helper'
10 class PoolAnimator
11   include AnimatorHelper
12   
13   attr_reader :pool
14   alias :board :pool # for AnimatorHelper
15   
16   def initialize(pool)
17     @pool = pool
18   end
19   
20   def warp(pool)
21     pieces = pool.pieces.
22       map{|piece, count| [piece] * count}.
23       inject([]){|a, b| a.concat(b)}.
24       sort {|p1, p2| board.compare(p1, p2) }
25       
26     anims = []
27       
28     index = 0
29     while index < pieces.size
30       # precondition: pool and graphical pool match up to index
31     
32       # no more sprites on the graphical pool
33       if index >= board.items.size
34         # add extra sprites
35         (index...pieces.size).each do |i|
36           anims << appear_on!(i, pieces[i])
37         end
38   
39         # done
40         break;
41       end
42       
43       piece = pieces[index]
44       item = board.items[index]
45       i = pieces[index..-1].detect_index {|p| item.name == p }
46       
47       if i
48         # matching piece found on the pool
49         # insert all pieces before this one on the graphical pool
50         (index...index + i).each do |j|
51           anims << insert_piece(j, pieces[j])
52         end
53         index += i + 1
54       else
55         # no such piece found: remove it from the graphical pool
56         anims << remove_piece(index)
57       end
58     end
59     
60     while board.items.size > pieces.size
61       anims << disappear_on!(pieces.size)
62     end
63     
64     group(*anims)
65   end
66   
67   def insert_piece(index, piece)
68     anim = appear_on! index, piece
69     
70     # shift following items to make room
71     shift = (index + 1...board.items.size).map do |i|
72       movement(board.items[i], i - 1, i, Path::Linear)
73     end
74     
75     group(anim, *shift)
76   end
77   
78   def remove_piece(index)
79     anim = disappear_on! index
81     # shift following items to fill void
82     shift = (index...board.items.size).map do |i|
83       movement(board.items[i], i + 1, i, Path::Linear)
84     end
85     
86     group(anim, *shift)
87   end
88 end