Restored back and forward functionalities.
[kaya.git] / lib / interaction / match.rb
blob90cd31d2affaa86475ba5d31f9bf37143f89e009
1 require 'observer_utils'
2 require 'history'
4 module Player
5   include Observer
6 end
8 class Match
9   include Observable
10   
11   attr_reader :game
12   attr_reader :history
13   attr_reader :kind
14   attr_reader :index
15   
16   def initialize(game, opts = {})
17     @game = game
18     @players = { } # player => ready
19     @history = nil
20     @kind = opts[:kind] || :local
21     @editable = opts.fetch(:editable, true)
22   end
23   
24   def register(player)
25     return false if @history
26     return false if @players.has_key?(player)
27     return false if complete?
28     return false unless @game.players.include?(player.color)
29     
30     @players[player] = false
31     fire :complete if complete?
32     true
33   end
34   
35   def start(player)
36     return false if @history
37     return false unless complete?
38     return false unless @players[player] == false
39     
40     @players[player] = true
41     if @players.values.all?
42       state = @game.state.new
43       state.setup
44       @history = History.new(state)
45       @index = 0
46       fire :started
47     end
49     true
50   end
51   
52   def move(player, move, state = nil)
53     return false unless @history
54     # if player is nil, assume the current player is moving
55     if player == nil
56       player = current_player
57     else
58       return false unless @players.has_key?(player)
59       return false unless player.color == @history.state.turn
60     end
62     validate = @game.validator.new(@history.state)
63     valid = validate[move]
64     return false unless valid
66     old_state = @history.state
67     state = old_state.dup
68     state.perform! move
69     @history.add_move(state, move)
70     @index += 1
71     
72     broadcast player, :move => {
73       :player => player,
74       :move => move,
75       :state => state,
76       :old_state => old_state }
77     true
78   end
79   
80   def complete?
81     @game.players.all? do |c| 
82       @players.keys.find {|p| p.color == c }
83     end
84   end
85   
86   def started?
87     ! ! @history
88   end
89   
90   def state
91     @history.state
92   end
93   
94   def editable?
95     @editable
96   end
97     
98   private
99   
100   def broadcast(player, event)
101     fire event
102     @players.each_key do |p|
103       p.update any_to_event(event) unless p == player
104     end
105   end
106   
107   def current_player
108     @players.keys.find {|p| p.color == state.turn }
109   end