• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

shogi-server source


Commit MetaInfo

修訂0800fb9ae1c8d130852e28e66386b45eafd33ca1 (tree)
時間2004-06-05 19:50:14
作者nabeken <nabeken@b8c6...>
Commiternabeken

Log Message

need to update message from server to client

Change Summary

差異

--- a/shogi-server
+++ b/shogi-server
@@ -21,7 +21,6 @@ DEFAULT_TIMEOUT = 10 # for single socket operation
2121 Total_Time = 1500
2222 Least_Time_Per_Move = 1
2323 Watchdog_Time = 30 # time for ping
24-Agree_Time = 300 # time for AGREE
2524 Login_Time = 300 # time for LOGIN
2625
2726 Release = "$Name$".split[1].sub(/\A[^\d]*/, '').gsub(/_/, '.')
@@ -87,6 +86,19 @@ class League
8786 return false
8887 end
8988 end
89+ def get_player(status, game_name, sente)
90+ @hash.each do |name, player|
91+ if ((player.status == status)
92+ (player.game_name == game_name)
93+ (player.sente == sente))
94+ return player
95+ end
96+ end
97+ return nil
98+ end
99+ def new_game(game_name, player0, player1)
100+ game = Game::new(game_name, player0, player1)
101+ end
90102 end
91103
92104
@@ -97,11 +109,12 @@ class Player
97109 @name = nil
98110 @password = nil
99111 @socket = socket
100- @state = "connected" # wait_game -> game
112+ @status = "connected" # game_waiting -> agree_waiting -> start_waiting -> game
101113
102114 @x1 = false # extention protocol
103115 @eol = "\m" # favorite eol code
104116 @game = nil
117+ @game_name = ""
105118 @mytime = Total_Time
106119 @sente = nil
107120 @watchdog_thread = nil
@@ -109,12 +122,44 @@ class Player
109122 login(str)
110123 end
111124
112- attr_accessor :name, :password, :socket, :state
113- attr_accessor :x1, :eol, :game, :mytime, :watchdog_thread
125+ attr_accessor :name, :password, :socket, :status
126+ attr_accessor :x1, :eol, :game, :mytime, :watchdog_thread, :game_name, :sente
114127
128+ def finish
129+ Thread::kill(@watchdog_thread) if @watchdog_thread
130+ @socket.close
131+ end
132+
133+ def watchdog(time)
134+ while true
135+ begin
136+ Ping.pingecho(@socket.addr[3])
137+ rescue
138+ end
139+ sleep(time)
140+ end
141+ end
142+
143+ def to_s
144+ if ((status == "game_waiting") ||
145+ (status == "agree_waiting") ||
146+ (status == "game"))
147+ if (@sente)
148+ return sprintf("%s %s %s +", @name, @status, @game_name, "+")
149+ else
150+ return sprintf("%s %s %s -", @name, @status, @game_name, "-")
151+ end
152+ else
153+ return sprintf("%s %s", @name, @status)
154+ end
155+ end
156+
157+ def write_help(str)
158+ @socket.write_safe('## available commands "%%WHO", "%%CHAT str", "%%GAME game_name +", "%%GAME game_name -"')
159+ end
115160
116161 def write_safe(str)
117- @socket.write_safe(str + @eol)
162+ @socket.write_safe(str.gsub(/[\r\n]+/, @eol))
118163 end
119164
120165 def login(str)
@@ -123,12 +168,15 @@ class Player
123168 str.chomp!
124169 (login, @name, @password, ext) = str.split
125170 @x1 = true if (ext)
171+ @watchdog_thread = Thread::start do
172+ watchdog(Watchdog_Time)
173+ end
126174 end
127-
175+
128176 def run
129177 if (@x1)
130178 log_message(sprintf("user %s run in x1 mode", @name))
131- write_safe("## LOGIN in x1 mode")
179+ write_safe("## LOGIN in x1 mode\n")
132180 else
133181 log_message(sprintf("user %s run in CSA mode", @name))
134182 end
@@ -136,11 +184,37 @@ class Player
136184 while (str = @socket.gets_safe)
137185 str.chomp!
138186 case str
187+ when /^[\+\-%][^%]/
188+ if (@status == "game")
189+ @game.handle_one_move(str, self)
190+ else
191+ write_safe("## you are in %s status. %s in game status\n", @status)
192+ next
193+ end
194+ when /^AGREE/
195+ if (@status == "agree_waiting")
196+ @status = "start_waiting"
197+ if ((@game.sente.status == "start_waiting") &&
198+ (@game.gote.status == "start_waiting"))
199+ @game.start
200+ @game.sente.status = "game"
201+ @game.gote.status = "game"
202+ end
203+ else
204+ write_safe("## you are in %s status. AGREE is valid in agree_waiting status\n", @status)
205+ next
206+ end
139207 when /^%%HELP/
140208 write_help
141209 when /^%%GAME\s+(\S+)\s+([\+\-])/
142- game_name = $1
143- @state = "game_waiting"
210+ if ((@status == "connected") || (@status == "game_waiting"))
211+ @status = "game_waiting"
212+ else
213+ write_safe("## you are in %s status. GAME is valid in connected or game_waiting status\n", @status)
214+ next
215+ end
216+ @status = "game_waiting"
217+ @game_name = $1
144218 if ($2 == "+")
145219 @sente = true
146220 rival_sente = false
@@ -148,25 +222,26 @@ class Player
148222 @sente = false
149223 rival_sente = true
150224 end
151- rival = LEAGUE.get_player(game_name, rival_sente)
225+ rival = LEAGUE.get_player("game_waiting", @game_name, rival_sente)
152226 if (rival)
153- @state = "game"
154- LEAGUE.start_game(game_name, self, rival)
227+ LEAGUE.new_game(@game_name, self, rival)
228+ self.status = "agree_waiting"
229+ rival.status = "agree_waiting"
155230 end
156231 when /^%%CHAT\s+(\S+)/
157232 message = $1
158233 LEAGUE.hash.each do |name, player|
159- s = player.write_safe(sprintf("## [%s] %s", @name, message))
234+ s = player.write_safe(sprintf("## [%s] %s\n", @name, message))
160235 player.status = "zombie" if (! s)
161236 end
162237 when /^%%WHO/
163238 LEAGUE.hash.each do |name, player|
164- write_safe(sprintf("## %s %s", name, player.state))
239+ write_safe(sprintf("## %s\n", player.to_s))
165240 end
166241 when /^%%LOGOUT/
167242 break
168243 else
169- write_safe(sprintf("## unknown command %s", str))
244+ write_safe(sprintf("## unknown command %s\n", str))
170245 end
171246 end
172247 end
@@ -176,24 +251,83 @@ class Board
176251 end
177252
178253 class Game
179- def initialize(event, sente, gote)
180- @id = sprintf("%s-%s-%s-%s", event, sente.name, gote.name, Time::new.strftime("%Y%m%d%H%M%S"))
254+ def initialize(game_name, player0, player1)
255+ @game_name = game_name
256+ if (player0.sente)
257+ @sente = player0
258+ @gote = player1
259+ else
260+ @sente = player0
261+ @gote = player1
262+ end
263+ @current_player = @sente
264+ @next_player = @gote
265+
266+ @sente.game = self
267+ @gote.game = self
268+ @sente.status = "agree_waiting"
269+ @gote.status = "agree_waiting"
270+ @id = sprintf("%s-%s-%s-%s", @game_name, @sente.name, @gote.name, Time::new.strftime("%Y%m%d%H%M%S"))
271+ log_message(sprintf("game created %s %s %s", game_name, sente.name, gote.name))
272+
181273 @logfile = @id + ".csa"
182- @sente = sente
183- @gote = gote
184- @sente.sg_flag = "+"
185- @gote.sg_flag = "-"
186274 @board = Board::new
187- @currnet_player = sente
188- @next_player = gote
275+ @start_time = nil
189276 @fh = nil
190- printf("%s: new game %s %s %s\n", Time::new.to_s, @id, @sente.name, @gote.name)
277+
278+ propose
279+ end
280+ attr_accessor :game_name, :sente, :gote, :id, :board, :current_player, :next_player, :fh
281+
282+ def handle_one_move(str, player)
283+ if (@current_player == player)
284+ @end_time = Time::new
285+ t = @end_time - @start_time
286+ t = Least_Time_Per_Move if (t < Least_Time_Per_Move)
287+ @sente.write_safe(sprintf("%s,T%d\n", str, t))
288+ @gote.write_safe(sprintf("%s,T%d\n", str, t))
289+ @current_player.mytime = @current_player.mytime - t
290+ if (@current_player < 0)
291+ timeout_end()
292+ elsif (str =~ /%KACHI/)
293+ kachi_end()
294+ elsif (str =~ /%TORYO/)
295+ toryo_end
296+ end
297+ (@current_player, @next_player) = [@next_player, @current_player]
298+ @start_time = Time::new
299+ end
300+ end
301+
302+ def timeout_end
303+ @current_player.status = "connected"
304+ @next_player.status = "connected"
305+ @current_player.write("#TIME_UP\n#LOSE\n")
306+ @next_player.write("#TIME_UP\n#WIN\n")
307+ end
308+
309+ def kachi_end
310+ @current_player.status = "connected"
311+ @next_player.status = "connected"
312+ @current_player.write("#JISHOGI\n#WIN\n")
313+ @next_player.write("#JISHOGI\n#LOSE\n")
191314 end
315+
316+ def toryo_end
317+ @current_player.status = "connected"
318+ @next_player.status = "connected"
319+ @current_player.write("#RESIGN\n#LOSE\n")
320+ @next_player.write("#RESIGN\n#WIN\n")
321+ end
322+
192323 def start
193- begin
194- @sente.watchdog_start(Watchdog_Time)
195- @gote.watchdog_start(Watchdog_Time)
324+ @sente.write_safe(sprintf("START:%s\n", @id))
325+ @gote.write_safe(sprintf("START:%s\n", @id))
326+ @start_time = Time::new
327+ end
196328
329+ def propose
330+ begin
197331 @fh = open(@logfile, "w")
198332 @fh.sync = true
199333
@@ -201,10 +335,9 @@ class Game
201335 @fh.printf("N+%s\n", @sente.name)
202336 @fh.printf("N-%s\n", @gote.name)
203337 @fh.printf("$EVENT:%s\n", @id)
204- @sente.write(start_message("+"))
205- @gote.write(start_message("-"))
206- @sente.wait_agree(Agree_Time)
207- @gote.wait_agree(Agree_Time)
338+
339+ @sente.write_safe(propose_message("+"))
340+ @gote.write_safe(propose_message("-"))
208341
209342 @fh.printf("$START_TIME:%s\n", Time::new.strftime("%Y/%m/%d %H:%M:%S"))
210343 @fh.print <<EOM
@@ -219,83 +352,10 @@ P8 * +KA * * * * * +HI *
219352 P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
220353 +
221354 EOM
222-
223- @sente.write(sprintf("START:%s\n", @id))
224- @gote.write(sprintf("START:%s\n", @id))
225- while(true)
226- @currnet_player = @sente
227- @next_player = @gote
228- handle_one_move(@currnet_player, @next_player)
229-
230- @currnet_player = @gote
231- @next_player = @sente
232- handle_one_move(@currnet_player, @next_player)
233- end
234- rescue ShogiWatchdogTimeout
235- sg_flag_of_timeout = $!.message
236- if (sg_flag_of_timeout == "+")
237- loser = @sente
238- winner = @gote
239- else
240- loser = @sente
241- winner = @gote
242- end
243- printf("watchdog timeout by %s\n", loser.name)
244- loser.write("#TIME_UP\n#LOSE\n")
245- winner.write("#TIME_UP\n#WIN\n")
246- rescue TimeoutError, ShogiTimeout
247- printf("%s: end timeup by %s\n", Time::new.to_s, @currnet_player.name)
248- @currnet_player.write("#TIME_UP\n#LOSE\n")
249- @next_player.write("#TIME_UP\n#WIN\n")
250- rescue ShogiReject
251- sender = $!.message
252- printf("%s: reject by %s\n", Time::new.to_s, sender)
253- str = sprintf("REJECT:%s by %s\n", @id, sender)
254- @sente.write(str)
255- @gote.write(str)
256- rescue ShogiIllegalMove
257- printf("%s: end illegal move by %s\n", Time::new.to_s, @currnet_player.name)
258- move = $!.message
259- @fh.printf("%%ERROR\n")
260- @currnet_player.write(sprintf("%s\n#ILLEGAL_MOVE\n#LOSE\n", move))
261- @next_player.write(sprintf("%s\n#ILLEGAL_MOVE\n#WIN\n", move))
262- rescue ShogiEnd
263- printf("%s: end by %s\n", Time::new.to_s, @currnet_player.name)
264- move = $!.message
265- case move
266- when "%TORYO"
267- @currnet_player.write(sprintf("%s\n#RESIGN\n#LOSE\n", move))
268- @next_player.write(sprintf("%s\n#RESIGN\n#WIN\n", move))
269- when "%KACHI"
270- @currnet_player.write(sprintf("%s\n#JISHOGI\n#WIN\n", move))
271- @next_player.write(sprintf("%s\n#JISHOGI\n#LOSE\n", move))
272- end
273355 end
274- @fh.printf("'END_TIME:%s\n", Time::new.strftime("%Y/%m/%d %H:%M:%S"))
275- end
276-
277- def handle_one_move(current_player, next_player)
278- start_time = Time::new
279- str = current_player.get_move
280- @fh.printf("%s\n", str)
281- end_time = Time::new
282- time = (end_time - start_time).truncate
283- time = Least_Time_Per_Move if (time < Least_Time_Per_Move)
284- current_player.sub_time(time)
285- raise ShogiEnd, str if (str =~ /\A%/)
286- @sente.write(sprintf("%s,T%d\n", str, time))
287- @gote.write(sprintf("%s,T%d\n", str, time))
288- @fh.printf("T%s\n", time)
289- end
290-
291- def finish
292- @sente.finish
293- @gote.finish
294- @fh.close
295- printf("%s: end game %s %s %s\n", Time::new.to_s, @id, @sente.name, @gote.name)
296356 end
297357
298- def start_message(sg_flag)
358+ def propose_message(sg_flag)
299359 str = <<EOM
300360 Protocol_Mode:Server
301361 Format:Shogi 1.0
@@ -324,6 +384,8 @@ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
324384 P+
325385 P-
326386 +
387+END Position
388+END Game_Summary
327389 EOM
328390 return str
329391 end
@@ -425,7 +487,7 @@ def main
425487 if (good_login?(str))
426488 player = Player::new(str, client)
427489 if (LEAGUE.duplicated?(player))
428- client.write_safe(sprintf("username %s is already connected", player.name))
490+ client.write_safe(sprintf("username %s is already connected%s", player.name, eol))
429491 next
430492 end
431493 LEAGUE.add(player)