7 def initialize(game_name, name, sente)
9 @name = "%s_%s" % [game_name, name]
13 @turn_mark = sente ? "+" : "-"
19 @login_command = "LOGIN #{@name} dummy x1"
22 attr_accessor :login_command
26 @socket = TCPSocket.open("localhost", port)
33 @socket.close if @socket && !@socket.closed?
37 @thread = Thread.new do
40 # break if @socket.closed?
41 if r = select([@socket], nil, nil, 10)
45 if %r!^[\+\-]\d{4}\w{2},T\d+$! =~ str
58 @thread.kill if @thread
64 return if reg =~ @message
73 return if @received_moves == n
81 $stderr.puts str if $DEBUG
87 str = "%%GAME #{@game_name}-1500-0 #{@turn_mark}"
88 $stderr.puts str if $DEBUG
93 str = "%%CHALLENGE #{@game_name}-1500-0 #{@turn_mark}"
94 $stderr.puts str if $DEBUG
99 wait %r!^END Game_Summary!
118 @socket.puts "%TORYO"
122 wait %r!^#(WIN|LOSE)!
127 @socket.puts "LOGOUT"
132 class SocketCSAPlayer < SocketPlayer
133 def initialize(game_name, name, sente)
135 @login_command = "LOGIN #{@name} dummy"
140 $stderr.puts str if $DEBUG
150 class BaseClient < Test::Unit::TestCase
151 attr_accessor :game_name, :p1_name, :p2_name
154 @game_name = self.class.name
160 @p1 = SocketPlayer.new @game_name, @p1_name, true
161 @p2 = SocketPlayer.new @game_name, @p2_name, false
169 attr_reader :src1, :src2
205 yield if block_given?
208 [@p1.message, @p2.message]
218 raise "do not reach!"
225 @p2.wait_nmoves @nmoves
231 @p1.wait_nmoves @nmoves
262 class ReadFileClient < BaseClient
263 def filepath(csa_file_name)
264 return File.join(File.dirname(__FILE__), "csa", csa_file_name)
271 csa_io = StringIO.new(csa)
272 while line = csa_io.gets do
274 when /^[\+\-]\d{4}\w{2}/
276 $stderr.puts s if $DEBUG
284 class CSABaseClient < BaseClient
286 # In CSA mode, the server decides sente or gote at random; and sockets are closed
287 # just after the game ends (i.e. %TORYO is sent)
290 @p1 = SocketCSAPlayer.new @game_name, @p1_name, true
291 @p2 = SocketCSAPlayer.new @game_name, @p2_name, false
307 if /Your_Turn:\+/ =~ @p1.message
314 yield if block_given?
316 [@p1.message, @p2.message]