1 # Copyright (c) 2010 Paolo Capriotti <p.capriotti@gmail.com>
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_bundle 'ics', 'style12'
14 # Helper mixin to create and start ICS matches.
18 # Create an appropriate MatchHelper instance for the given style12
20 def self.from_style12(style12)
21 @@helpers ||= {}.tap do |h|
22 h[Style12::Relation::EXAMINING] = ExaminingMatchHelper.instance
23 h[Style12::Relation::NOT_MY_MOVE] = DefaultMatchHelper.instance
24 h[Style12::Relation::MY_MOVE] = h[Style12::Relation::NOT_MY_MOVE]
27 @@helpers[style12.relation]
31 # Get the helper instance for this type.
33 # Currently supported types: :default, :examining, :observing.
36 ICS.const_get(type.to_s.capitalize + "MatchHelper").instance
40 # Create the opponent player. By default, create an ICSPlayer that
41 # will respond to future style12 events.
43 def create_opponent(protocol, color, match_info)
44 send = lambda {|msg| protocol.connection.send_text(msg) }
45 opponent = ICSPlayer.new(send, color, match_info[:match], match_info)
46 match_info[:icsplayer] = opponent
51 # Create a player for this match.
53 def create_player(user, color, match_info)
54 raise "not implemented"
58 # Create a new match instance.
60 def create_match(match_info)
61 raise "not implemented"
65 # Perform post-creation initialization for players.
67 def setup_players(user, players)
71 # Return or create a match. Called on an existing match when a new style12
73 # If no match for that style12 event is found, the match argument
76 def get_match(protocol, match_info, style12)
81 # Return an array of colors to be assigned to the players.
83 def colors(state, rel)
84 turns = [state.turn, state.opposite_turn(state.turn)]
85 if rel == Style12::Relation::NOT_MY_MOVE
93 # Start an existing match. Called when the first style12
94 # for the given match is received.
96 def start(protocol, user, match_info, style12)
97 rel = style12.relation
99 turns = [state.turn, state.opposite_turn(state.turn)]
101 user_color, opponent_color = colors(state, rel)
104 opponent = create_opponent(protocol, opponent_color, match_info)
105 player = create_player(user, user_color, match_info)
106 setup_players(user, [player, opponent])
109 match = match_info[:match]
110 match.register(player)
111 match.register(opponent)
113 match.start(opponent)
114 raise "couldn't start match" unless match.started?
116 # set initial state and time
117 unless match_info[:icsapi].same_state(match.state, style12.state)
118 match.history.state = style12.state
120 match.update_time(style12.time)
128 # Helper class to setup normal ICS games.
130 class DefaultMatchHelper
134 def create_player(user, color, match_info)
135 # do not create a new player, just return user
138 user.name = match_info[color][:name]
142 def create_match(match_info)
143 match = Match.new(match_info[:game],
146 :time_running => true)
147 match_info.merge(:match => match)
152 # Helper class to setup matches in examination mode
154 class ExaminingMatchHelper
158 def create_player(user, color, match_info)
161 # create a controlled player
162 player = DummyPlayer.new(color)
163 player.name = match_info[color][:name]
168 def setup_players(user, players)
169 players.each do |player|
170 user.add_controlled_player(player)
174 def get_match(protocol, match_info, style12)
176 # Examined games on ics have no header, so we have to be prepared to
177 # create a new match on the fly at this point.
178 # Create an editable Game.dummy match for the moment.
179 match_info = create_match(style12.match_info)
181 # We want to change the game type at some point, so request the game
182 # movelist to the server.
183 protocol.connection.send_text('moves')
189 def create_match(match_info)
190 match = Match.new(Game.dummy,
194 match_info.merge(:match => match)
199 # Helper class to setup matches in observation mode
201 class ObservingMatchHelper