Actually save files instead of printing them.
[kaya.git] / lib / interaction / match.rb
blob1f7e38007b4503366d41afdc3c6c8bcd0c91e62e
1 require 'observer_utils'
2 require 'history'
4 module Player
5   include Observer
6   
7   def name
8   end
9 end
11 class Match
12   include Observable
13   
14   attr_reader :game
15   attr_reader :history
16   attr_reader :kind
17   attr_reader :index
18   attr_accessor :url
19   
20   def initialize(game, opts = {})
21     @game = game
22     @players = { } # player => ready
23     @history = nil
24     @kind = opts[:kind] || :local
25     @editable = opts.fetch(:editable, true)
26     @info = { }
27   end
28   
29   def register(player)
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)
34     
35     @players[player] = false
36     fire :complete if complete?
37     true
38   end
39   
40   def start(player)
41     return false if @history
42     return false unless complete?
43     return false unless @players[player] == false
44     
45     @players[player] = true
46     if @players.values.all?
47       state = @game.state.new
48       state.setup
49       @history = History.new(state)
50       @index = 0
51       fire :started
52     end
54     true
55   end
56   
57   def move(player, move, state = nil)
58     return false unless @history
59     # if player is nil, assume the current player is moving
60     if player == nil
61       player = current_player
62     else
63       return false unless @players.has_key?(player)
64       return false unless player.color == @history.state.turn
65     end
67     validate = @game.validator.new(@history.state)
68     valid = validate[move]
69     return false unless valid
71     old_state = @history.state
72     state = old_state.dup
73     state.perform! move
74     @history.add_move(state, move)
75     @index += 1
76     
77     broadcast player, :move => {
78       :player => player,
79       :move => move,
80       :state => state,
81       :old_state => old_state }
82     true
83   end
84   
85   def update_time(time)
86     broadcast nil, :time => time
87   end
88   
89   def complete?
90     @game.players.all? do |c| 
91       @players.keys.find {|p| p.color == c }
92     end
93   end
94   
95   def started?
96     ! ! @history
97   end
98   
99   def state
100     @history.state
101   end
102   
103   def editable?
104     @editable
105   end
106     
107   def player(color)
108     @players.keys.find{|p| p.color == color }
109   end
110   
111   def close(result, message)
112     @info[:result] = result
113     broadcast nil, :close => { 
114       :result => result,
115       :message => message }
116   end
117   
118   def info
119     @info.merge(:players => @players.keys)
120   end
121     
122   private
123   
124   def broadcast(player, event)
125     fire event
126     @players.each_key do |p|
127       p.update any_to_event(event) unless p == player
128     end
129   end
130   
131   def current_player
132     @players.keys.find {|p| p.color == state.turn }
133   end