1 require 'observer_utils'
20 def initialize(game, opts = {})
22 @players = { } # player => ready
24 @kind = opts[:kind] || :local
25 @editable = opts.fetch(:editable, true)
30 return false if @history
31 return false if @players.has_key?(player)
32 return false if complete?
33 return false unless @game.players.include?(player.color)
35 @players[player] = false
36 fire :complete if complete?
41 return false if @history
42 return false unless complete?
43 return false unless @players[player] == false
45 @players[player] = true
46 if @players.values.all?
47 state = @game.state.new
49 @history = History.new(state)
57 def move(player, move, state = nil)
58 return false unless @history
59 # if player is nil, assume the current player is moving
61 player = current_player
63 return false unless @players.has_key?(player)
64 return false unless player.color == @history.state.turn
67 validate = @game.validator.new(@history.state)
68 valid = validate[move]
69 return false unless valid
71 old_state = @history.state
74 @history.add_move(state, move)
77 broadcast player, :move => {
81 :old_state => old_state }
86 broadcast nil, :time => time
90 @game.players.all? do |c|
91 @players.keys.find {|p| p.color == c }
108 @players.keys.find{|p| p.color == color }
111 def close(result, message)
112 @info[:result] = result
113 broadcast nil, :close => {
115 :message => message }
119 @info.merge(:players => @players.keys)
124 def broadcast(player, event)
126 @players.each_key do |p|
127 p.update any_to_event(event) unless p == player
132 @players.keys.find {|p| p.color == state.turn }