Pool receives and displays updates.
[kaya/ydirson.git] / lib / controller.rb
blob391692880e0d4379ba9249f1c0b79bf17e10add0
1 require 'observer_utils'
2 require 'history'
4 class Controller
5   include Observer
6   
7   attr_reader :history
8   
9   def initialize(elements, game, history)
10     @board = elements[:board]
11     @pools = elements[:pools]
13     @game = game
14     @history = history
15     @animator = @game.animator.new(@board)
16     @field = AnimationField.new(20)
17     @board.reset(history.state.board)
18     
19     c = self
20     @board.observe(:click) {|p| c.on_board_click(p) }
21   end
22   
23   def on_board_click(p)
24     state = @history.state
25     if @board.selection
26       move = @game.policy.new_move(state, @board.selection, p)
27       validate = @game.validator.new(state)
28       if validate[move]
29         perform! move
30       end
31       
32       @board.selection = nil
33     elsif @game.policy.movable?(state, p) and movable?(p)
34       @board.selection = p
35     end
36   end
37   
38   def perform!(move)
39     state = @history.state.dup
40     state.perform! move
41     @history.add_move(state, move)
42     
43     @pools.each {|color, pool| pool.warp(state.pool(color)) }
44     animate(:forward, state, move)
45     @board.highlight(move)
46   end
47   
48   def back
49     state, move = @history.back
50     @pools.each {|color, pool| pool.warp(state.pool(color)) }
51     animate(:back, state, move)
52     @board.highlight(@history.move)
53   rescue History::OutOfBound
54     puts "error: first move"
55   end
56   
57   def forward
58     state, move = @history.forward
59     @pools.each {|color, pool| pool.warp(state.pool(color)) }
60     animate(:forward, state, move)
61     @board.highlight(move)
62   rescue History::OutOfBound
63     puts "error: last move"
64   end
65   
66   def animate(direction, state, move)
67     anim = @animator.send(direction, state, move)
68     @field.run anim
69   end
70   
71   def movable?(p)
72     true
73   end
74 end