OSDN Git Service

- shogi_server/pairing.rb:
[shogi-server/shogi-server.git] / test / benchmark.rb
1 #!/usr/bin/ruby
2
3 require 'socket'
4 require 'thread'
5
6 class BenchPlayer
7   def initialize(game_name, name, sente)
8     @game_name = game_name
9     @name = "%s_%s" % [game_name, name]
10     @turn_mark = sente ? "+" : "-"
11     @nmoves = 0
12   end
13   attr_reader :nmoves
14
15   def connect
16     port = 4000
17     @socket = TCPSocket.open("localhost", port)
18     @socket.sync = true
19     @message = ""
20     reader
21   end
22
23   def reader
24     Thread.new do
25       loop do 
26         if r = select([@socket], nil, nil, 10)
27           str = r[0].first.gets
28           if %r!^[\+\-]\d{4}\w{2},T\d+$! =~ str
29             @nmoves += 1
30           end
31           @message << str
32         else
33           raise "timed out"
34         end
35       end
36     end
37   end
38
39   def wait(reg)
40     loop do 
41       break if reg =~ @message
42       sleep 0.1
43     end
44   end
45
46   def wait_nmoves(n)
47     loop do
48       break if @nmoves == n
49       sleep 0.01
50     end
51   end
52
53   def login
54     @socket.puts "LOGIN #{@name} dummy x1"
55     wait %r!^LOGIN!
56   end
57
58   def game
59     @socket.puts "%%GAME #{@game_name}-1500-0 #{@turn_mark}"
60   end
61
62   def agree
63     @socket.puts "AGREE"
64   end
65
66   def move(m)
67     @socket.puts m
68   end
69
70   def toryo
71     @socket.puts "%TORYO"
72   end
73
74   def logout
75     @socket.puts "LOGOUT"
76   end
77
78 end
79
80 class BenchGame
81   @@mutex = Mutex.new
82   @@count = 0
83   def initialize(game_name, csa)
84     @game_name = game_name
85     @csa = csa
86     @@mutex.synchronize do 
87       @p1 = BenchPlayer.new(@game_name, "bp#{@@count+=1}", true)
88       @p2 = BenchPlayer.new(@game_name, "bp#{@@count+=1}", false)
89     end
90   end
91
92   def each_player
93     [@p1, @p2].each {|player| yield player}
94   end
95
96   def start
97     each_player {|player| player.connect}
98     each_player {|player| player.login}
99     each_player {|player| player.game}
100     each_player {|player| player.wait %r!^END Game_Summary!}
101     each_player {|player| player.agree}
102     each_player {|player| player.wait %r!^START:!}
103     turn = true # black
104     nmoves = 0
105     @csa.each_line do |line|
106       case line
107       when /^\+\d{4}\w{2}/
108         @p1.wait_nmoves nmoves
109         @p1.move $&
110         turn = false
111         nmoves += 1
112       when /^\-\d{4}\w{2}/
113         @p2.wait_nmoves nmoves
114         @p2.move $&
115         turn = true
116         nmoves += 1
117       when /^%TORYO/
118         turn ? @p1.toryo : @p2.toryo
119       end
120     end
121     each_player {|player| player.logout}
122   end
123 end
124
125
126 if __FILE__ == $0
127   filepath = ARGV.shift || File.join(File.dirname(__FILE__), "csa", "wdoor+floodgate-900-0+gps_normal+gps_l+20100507120007.csa")
128   csa = File.open(filepath){|f| f.read} 
129
130   nclients = ARGV.shift || 1
131   nclients = nclients.to_i
132   threads = []
133   nclients.times do |i|
134     threads << Thread.new do
135       game = BenchGame.new("b#{i}", csa)
136       game.start
137     end
138   end
139   threads.each {|t| t.join}
140
141 end
142