• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

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

shogi-server source


Commit MetaInfo

Revision2cd1b586a47ec74efc2d9b49aac09b87e8175ba4 (tree)
Time2013-03-17 14:49:40
AuthorDaigo Moriwaki <beatles@user...>
CommiterDaigo Moriwaki

Log Message

Improved %%FORK command. Thinking times of each move are also provided.

Change Summary

Incremental Difference

--- a/changelog
+++ b/changelog
@@ -13,9 +13,6 @@
1313 with this command you can restart a new buoy game from the
1414 previous stable position.
1515 ex. %%FORK server-denou-14400-60+p1+p2+20130223185013 buoy_denou-14400-60
16- - Note that this feature does not provice accurate thinking
17- time estimate. The thinking time of the last posision is carried
18- over to the new game regardless nth-move.
1916
2017 2012-12-30 Daigo Moriwaki <daigo at debian dot org>
2118
--- a/shogi_server/board.rb
+++ b/shogi_server/board.rb
@@ -43,17 +43,42 @@ EOF
4343
4444 # Split a moves line into an array of a move string.
4545 # If it fails to parse the moves, it raises WrongMoves.
46- # @param moves a moves line. Ex. "+776FU-3334Fu"
47- # @return an array of a move string. Ex. ["+7776FU", "-3334FU"]
46+ # @param moves a moves line. Ex. "+776FU-3334FU" or
47+ # moves with times. Ex "+776FU,T2-3334FU,T5"
48+ # @return an array of a move string. Ex. ["+7776FU", "-3334FU"] or
49+ # an array of arrays. Ex. [["+7776FU","T2"], ["-3334FU", "T5"]]
4850 #
4951 def Board.split_moves(moves)
5052 ret = []
5153
52- rs = moves.gsub %r{[\+\-]\d{4}\w{2}} do |s|
53- ret << s
54- ""
55- end
56- raise WrongMoves, rs unless rs.empty?
54+ i=0
55+ tmp = ""
56+ while i<moves.size
57+ if moves[i,1] == "+" ||
58+ moves[i,1] == "-" ||
59+ i == moves.size - 1
60+ if i == moves.size - 1
61+ tmp << moves[i,1]
62+ end
63+ unless tmp.empty?
64+ a = tmp.split(",")
65+ if a[0].size != 7
66+ raise WrongMoves, a[0]
67+ end
68+ if a.size == 1 # "+7776FU"
69+ ret << a[0]
70+ else # "+7776FU,T2"
71+ unless /^T\d+/ =~ a[1]
72+ raise WrongMoves, a[1]
73+ end
74+ ret << a
75+ end
76+ tmp = ""
77+ end
78+ end
79+ tmp << moves[i,1]
80+ i += 1
81+ end
5782
5883 return ret
5984 end
@@ -230,14 +255,21 @@ EOF
230255
231256 # Set up a board starting with a position after the moves.
232257 # Failing to parse the moves raises an ArgumentError.
233- # @param moves an array of moves. ex. ["+7776FU", "-3334FU"]
258+ # @param moves an array of moves. ex. ["+7776FU", "-3334FU"] or
259+ # an array of arrays. ex. [["+7776FU","T2"], ["-3334FU","T5"]]
234260 #
235261 def set_from_moves(moves)
236262 initial()
237263 return :normal if moves.empty?
238264 rt = nil
239265 moves.each do |move|
240- rt = handle_one_move(move, @teban)
266+ rt = nil
267+ case move
268+ when Array
269+ rt = handle_one_move(move[0], @teban)
270+ when String
271+ rt = handle_one_move(move, @teban)
272+ end
241273 raise ArgumentError, "bad moves: #{moves}" unless rt == :normal
242274 end
243275 @initial_moves = moves.dup
--- a/shogi_server/buoy.rb
+++ b/shogi_server/buoy.rb
@@ -10,12 +10,10 @@ module ShogiServer
1010 attr_reader :moves
1111 attr_reader :owner
1212 attr_reader :count
13- attr_reader :sente_time
14- attr_reader :gote_time
1513
16- def initialize(game_name, moves, owner, count, sente_time, gote_time)
14+ def initialize(game_name, moves, owner, count)
1715 raise "owner name is required" if owner && !owner.instance_of?(String)
18- @game_name, @moves, @owner, @count, @sente_time, @gote_time = game_name, moves, owner, count, sente_time, gote_time
16+ @game_name, @moves, @owner, @count = game_name, moves, owner, count
1917 end
2018
2119 def decrement_count
@@ -23,18 +21,16 @@ module ShogiServer
2321 end
2422
2523 def ==(rhs)
26- return (@game_name == rhs.game_name &&
27- @moves == rhs.moves &&
28- @owner == rhs.owner &&
29- @count == rhs.count &&
30- @sente_time == rhs.sente_time &&
31- @gote_time == rhs.gote_time)
24+ return (@game_name == rhs.game_name &&
25+ @moves == rhs.moves &&
26+ @owner == rhs.owner &&
27+ @count == rhs.count)
3228 end
3329 end
3430
3531 class NilBuoyGame < BuoyGame
3632 def initialize
37- super(nil, nil, nil, 0, nil, nil)
33+ super(nil, nil, nil, 0)
3834 end
3935 end
4036
@@ -66,11 +62,9 @@ module ShogiServer
6662 if @db.root?(buoy_game.game_name)
6763 # error
6864 else
69- hash = {'moves' => buoy_game.moves,
70- 'owner' => buoy_game.owner,
71- 'count' => buoy_game.count,
72- 'sente_time' => buoy_game.sente_time,
73- 'gote_time' => buoy_game.gote_time}
65+ hash = {'moves' => buoy_game.moves,
66+ 'owner' => buoy_game.owner,
67+ 'count' => buoy_game.count}
7468 @db[buoy_game.game_name] = hash
7569 end
7670 end
@@ -79,11 +73,9 @@ module ShogiServer
7973 def update_game(buoy_game)
8074 @db.transaction do
8175 if @db.root?(buoy_game.game_name)
82- hash = {'moves' => buoy_game.moves,
83- 'owner' => buoy_game.owner,
84- 'count' => buoy_game.count,
85- 'sene_time' => buoy_game.sente_time,
86- 'gote_time' => buoy_game.gote_time}
76+ hash = {'moves' => buoy_game.moves,
77+ 'owner' => buoy_game.owner,
78+ 'count' => buoy_game.count}
8779 @db[buoy_game.game_name] = hash
8880 else
8981 # error
@@ -101,12 +93,10 @@ module ShogiServer
10193 @db.transaction(true) do
10294 hash = @db[game_name]
10395 if hash
104- moves = hash['moves']
105- owner = hash['owner']
106- count = hash['count'].to_i
107- sente_time = hash['sente_time'] ? hash['sente_time'].to_i : nil
108- gote_time = hash['gote_time'] ? hash['gote_time'].to_i : nil
109- return BuoyGame.new(game_name, moves, owner, count, sente_time, gote_time)
96+ moves = hash['moves']
97+ owner = hash['owner']
98+ count = hash['count'].to_i
99+ return BuoyGame.new(game_name, moves, owner, count)
110100 else
111101 return NilBuoyGame.new
112102 end
--- a/shogi_server/command.rb
+++ b/shogi_server/command.rb
@@ -540,9 +540,7 @@ module ShogiServer
540540 return :continue
541541 end
542542 buoy.decrement_count(buoy_game)
543- options = {:sente_time => buoy_game.sente_time,
544- :gote_time => buoy_game.gote_time}
545- Game::new(@player.game_name, @player, rival, board, options)
543+ Game::new(@player.game_name, @player, rival, board)
546544 end
547545 else
548546 klass = Login.handicapped_game_name?(@game_name) || Board
@@ -702,16 +700,6 @@ module ShogiServer
702700 @game_name = game_name
703701 @moves = moves
704702 @count = count
705- @sente_time = nil
706- @gote_time = nil
707- end
708-
709- # ForkCommand may call this method to set remaining time of both
710- # players.
711- #
712- def set_initial_time(sente_time, gote_time)
713- @sente_time = sente_time
714- @gote_time = gote_time
715703 end
716704
717705 def call
@@ -741,7 +729,7 @@ module ShogiServer
741729 raise WrongMoves
742730 end
743731
744- buoy_game = BuoyGame.new(@game_name, @moves, @player.name, @count, @sente_time, @gote_time)
732+ buoy_game = BuoyGame.new(@game_name, @moves, @player.name, @count)
745733 buoy.add_game(buoy_game)
746734 @player.write_safe(sprintf("##[SETBUOY] +OK\n"))
747735 log_info("A buoy game was created: %s by %s" % [@game_name, @player.name])
@@ -769,11 +757,7 @@ module ShogiServer
769757 # found two players: p1 and p2
770758 log_info("Starting a buoy game: %s with %s and %s" % [@game_name, p1.name, p2.name])
771759 buoy.decrement_count(buoy_game)
772-
773- # remaining time for ForkCommand
774- options = {:sente_time => buoy_game.sente_time,
775- :gote_time => buoy_game.gote_time}
776- game = Game::new(@game_name, p1, p2, board, options)
760+ game = Game::new(@game_name, p1, p2, board)
777761 return :continue
778762
779763 rescue WrongMoves => e
@@ -855,17 +839,18 @@ module ShogiServer
855839 return :continue
856840 end
857841
858- moves = game.read_moves
842+ moves = game.read_moves # [["+7776FU","T2"],["-3334FU","T5"]]
859843 @nth_move = moves.size - 1 unless @nth_move
860844 if @nth_move > moves.size or @nth_move < 1
861845 @player.write_safe(sprintf("##[ERROR] number of moves to fork is out of range: %s.\n", moves.size))
862846 log_error "Number of moves to fork is out of range: %s [%s]" % [@nth_move, @player.name]
863847 return :continue
864848 end
865- new_moves = moves[0...@nth_move]
866-
867- buoy_cmd = SetBuoyCommand.new(@str, @player, @new_buoy_game, new_moves.join(""), 1)
868- buoy_cmd.set_initial_time(game.sente.mytime, game.gote.mytime)
849+ new_moves_str = ""
850+ moves[0...@nth_move].each do |m|
851+ new_moves_str << m.join(",")
852+ end
853+ buoy_cmd = SetBuoyCommand.new(@str, @player, @new_buoy_game, new_moves_str, 1)
869854 return buoy_cmd.call
870855 end
871856 end
--- a/shogi_server/game.rb
+++ b/shogi_server/game.rb
@@ -63,10 +63,7 @@ class Game
6363 end
6464
6565
66- # options may or may not have follwing keys: :sente_time, :gote_time; they
67- # are used for %%FORK command to set remaining times at the restart.
68- #
69- def initialize(game_name, player0, player1, board, options={})
66+ def initialize(game_name, player0, player1, board)
7067 @monitors = Array::new # array of MonitorHandler*
7168 @game_name = game_name
7269 if (@game_name =~ /-(\d+)-(\d+)$/)
@@ -90,7 +87,16 @@ class Game
9087 @sente.game = self
9188 @gote.game = self
9289
93- @last_move = @board.initial_moves.empty? ? "" : "%s,T1" % [@board.initial_moves.last]
90+ @last_move = ""
91+ unless @board.initial_moves.empty?
92+ last_move = @board.initial_moves.last
93+ case last_move
94+ when Array
95+ @last_move = last_move.join(",")
96+ when String
97+ @last_move = "%s,T1" % [last_move]
98+ end
99+ end
94100 @current_turn = @board.initial_moves.size
95101
96102 @sente.status = "agree_waiting"
@@ -119,8 +125,6 @@ class Game
119125 @fh.sync = true
120126 @result = nil
121127
122- @options = options.dup
123-
124128 propose
125129 end
126130 attr_accessor :game_name, :total_time, :byoyomi, :sente, :gote, :game_id, :board, :current_player, :next_player, :fh, :monitors
@@ -312,8 +316,8 @@ class Game
312316 @gote.status = "game"
313317 @sente.write_safe(sprintf("START:%s\n", @game_id))
314318 @gote.write_safe(sprintf("START:%s\n", @game_id))
315- @sente.mytime = @options[:sente_time] || @total_time
316- @gote.mytime = @options[:gote_time] || @total_time
319+ @sente.mytime = @total_time
320+ @gote.mytime = @total_time
317321 @start_time = Time.now
318322 end
319323
@@ -337,8 +341,14 @@ class Game
337341 unless @board.initial_moves.empty?
338342 @fh.puts "'buoy game starting with %d moves" % [@board.initial_moves.size]
339343 @board.initial_moves.each do |move|
340- @fh.puts move
341- @fh.puts "T1"
344+ case move
345+ when Array
346+ @fh.puts move[0]
347+ @fh.puts move[1]
348+ when String
349+ @fh.puts move
350+ @fh.puts "T1"
351+ end
342352 end
343353 end
344354 end
@@ -377,13 +387,6 @@ EOM
377387 end
378388
379389 def propose_message(sg_flag)
380- time = @total_time
381- if @options[:sente_time] && sg_flag == "+"
382- time = @options[:sente_time]
383- elsif @options[:gote_time] && sg_flag == "-"
384- time = @options[:gote_time]
385- end
386-
387390 str = <<EOM
388391 BEGIN Game_Summary
389392 Protocol_Version:1.1
@@ -398,13 +401,20 @@ Rematch_On_Draw:NO
398401 To_Move:#{@board.teban ? "+" : "-"}
399402 BEGIN Time
400403 Time_Unit:1sec
401-Total_Time:#{time}
404+Total_Time:#{@total_time}
402405 Byoyomi:#{@byoyomi}
403406 Least_Time_Per_Move:#{Least_Time_Per_Move}
404407 END Time
405408 BEGIN Position
406409 #{@board.initial_string.chomp}
407-#{@board.initial_moves.collect {|m| m + ",T1"}.join("\n")}
410+#{@board.initial_moves.collect do |m|
411+ case m
412+ when Array
413+ m.join(",")
414+ when String
415+ m + ",T1"
416+ end
417+end.join("\n")}
408418 END Position
409419 END Game_Summary
410420 EOM
@@ -421,14 +431,16 @@ EOM
421431 return false
422432 end
423433
424- # Read the .csa file and returns an array of moves.
425- # ex. ["+7776FU", "-3334FU"]
434+ # Read the .csa file and returns an array of moves and times.
435+ # ex. [["+7776FU","T2"], ["-3334FU","T5"]]
426436 #
427437 def read_moves
428438 ret = []
429439 IO.foreach(@logfile) do |line|
430440 if /^[\+\-]\d{4}[A-Z]{2}/ =~ line
431- ret << line.chomp
441+ ret << [line.chomp]
442+ elsif /^T\d*/ =~ line
443+ ret[-1] << line.chomp
432444 end
433445 end
434446 return ret
--- a/test/TC_buoy.rb
+++ b/test/TC_buoy.rb
@@ -9,32 +9,14 @@ require 'mock_log_message'
99
1010 class TestBuoyGame < Test::Unit::TestCase
1111 def test_equal
12- g1 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1, nil, nil)
13- g2 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1, nil, nil)
14- assert_equal g1, g2
15- end
16-
17- def test_equal2
18- g1 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1, 10, 20)
19- g2 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1, 10, 20)
12+ g1 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1)
13+ g2 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1)
2014 assert_equal g1, g2
2115 end
2216
2317 def test_not_equal
24- g1 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1, nil, nil)
25- g2 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 2, nil, nil)
26- assert_not_equal g1, g2
27- end
28-
29- def test_not_equal2
30- g1 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1, 10, 20)
31- g2 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1, 10, 200)
32- assert_not_equal g1, g2
33- end
34-
35- def test_not_equal3
36- g1 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1, 10, nil)
37- g2 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1, 10, 200)
18+ g1 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1)
19+ g2 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 2)
3820 assert_not_equal g1, g2
3921 end
4022 end
@@ -67,18 +49,7 @@ class TestBuoy < Test::Unit::TestCase
6749 end
6850
6951 def test_add_game
70- game = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1, nil, nil)
71- @buoy.add_game(game)
72- assert !@buoy.is_new_game?("buoy_1234-900-0")
73- game2 = @buoy.get_game(game.game_name)
74- assert_equal game, game2
75-
76- @buoy.delete_game game
77- assert @buoy.is_new_game?("buoy_1234-900-0")
78- end
79-
80- def test_add_game2
81- game = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1, 10, 20)
52+ game = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1)
8253 @buoy.add_game(game)
8354 assert !@buoy.is_new_game?("buoy_1234-900-0")
8455 game2 = @buoy.get_game(game.game_name)
@@ -89,9 +60,9 @@ class TestBuoy < Test::Unit::TestCase
8960 end
9061
9162 def test_update_game
92- game = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 2, nil, nil)
63+ game = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 2)
9364 @buoy.add_game(game)
94- g2 = ShogiServer::BuoyGame.new(game.game_name, game.moves, game.owner, game.count-1, nil, nil)
65+ g2 = ShogiServer::BuoyGame.new(game.game_name, game.moves, game.owner, game.count-1)
9566 @buoy.update_game(g2)
9667
9768 get = @buoy.get_game(g2.game_name)
--- a/test/TC_command.rb
+++ b/test/TC_command.rb
@@ -842,7 +842,7 @@ class TestSetBuoyCommand < BaseTestBuoyCommand
842842 assert !$p1.out.empty?
843843 assert !$p2.out.empty?
844844 buoy_game2 = @buoy.get_game("buoy_hoge-1500-0")
845- assert_equal ShogiServer::BuoyGame.new("buoy_hoge-1500-0", "+7776FU", @p.name, 1, nil, nil), buoy_game2
845+ assert_equal ShogiServer::BuoyGame.new("buoy_hoge-1500-0", "+7776FU", @p.name, 1), buoy_game2
846846 end
847847
848848 def test_call_1
@@ -867,7 +867,7 @@ class TestSetBuoyCommand < BaseTestBuoyCommand
867867
868868 def test_call_error_duplicated_game_name
869869 assert @buoy.is_new_game?("buoy_duplicated-1500-0")
870- bg = ShogiServer::BuoyGame.new("buoy_duplicated-1500-0", ["+7776FU"], @p.name, 1, nil, nil)
870+ bg = ShogiServer::BuoyGame.new("buoy_duplicated-1500-0", ["+7776FU"], @p.name, 1)
871871 @buoy.add_game bg
872872 assert !@buoy.is_new_game?("buoy_duplicated-1500-0")
873873
@@ -905,7 +905,7 @@ end
905905 #
906906 class TestDeleteBuoyCommand < BaseTestBuoyCommand
907907 def test_call
908- buoy_game = ShogiServer::BuoyGame.new("buoy_testdeletebuoy-1500-0", "+7776FU", @p.name, 1, nil, nil)
908+ buoy_game = ShogiServer::BuoyGame.new("buoy_testdeletebuoy-1500-0", "+7776FU", @p.name, 1)
909909 assert @buoy.is_new_game?(buoy_game.game_name)
910910 @buoy.add_game buoy_game
911911 assert !@buoy.is_new_game?(buoy_game.game_name)
@@ -918,7 +918,7 @@ class TestDeleteBuoyCommand < BaseTestBuoyCommand
918918 end
919919
920920 def test_call_not_exist
921- buoy_game = ShogiServer::BuoyGame.new("buoy_notexist-1500-0", "+7776FU", @p.name, 1, nil, nil)
921+ buoy_game = ShogiServer::BuoyGame.new("buoy_notexist-1500-0", "+7776FU", @p.name, 1)
922922 assert @buoy.is_new_game?(buoy_game.game_name)
923923 cmd = ShogiServer::DeleteBuoyCommand.new "%%DELETEBUOY", @p, buoy_game.game_name
924924 rt = cmd.call
@@ -929,7 +929,7 @@ class TestDeleteBuoyCommand < BaseTestBuoyCommand
929929 end
930930
931931 def test_call_another_player
932- buoy_game = ShogiServer::BuoyGame.new("buoy_anotherplayer-1500-0", "+7776FU", "another_player", 1, nil, nil)
932+ buoy_game = ShogiServer::BuoyGame.new("buoy_anotherplayer-1500-0", "+7776FU", "another_player", 1)
933933 assert @buoy.is_new_game?(buoy_game.game_name)
934934 @buoy.add_game(buoy_game)
935935 assert !@buoy.is_new_game?(buoy_game.game_name)
@@ -946,7 +946,7 @@ end
946946 #
947947 class TestGetBuoyCountCommand < BaseTestBuoyCommand
948948 def test_call
949- buoy_game = ShogiServer::BuoyGame.new("buoy_testdeletebuoy-1500-0", "+7776FU", @p.name, 1, nil, nil)
949+ buoy_game = ShogiServer::BuoyGame.new("buoy_testdeletebuoy-1500-0", "+7776FU", @p.name, 1)
950950 assert @buoy.is_new_game?(buoy_game.game_name)
951951 @buoy.add_game buoy_game
952952 assert !@buoy.is_new_game?(buoy_game.game_name)
@@ -957,7 +957,7 @@ class TestGetBuoyCountCommand < BaseTestBuoyCommand
957957 end
958958
959959 def test_call_not_exist
960- buoy_game = ShogiServer::BuoyGame.new("buoy_notexist-1500-0", "+7776FU", @p.name, 1, nil, nil)
960+ buoy_game = ShogiServer::BuoyGame.new("buoy_notexist-1500-0", "+7776FU", @p.name, 1)
961961 assert @buoy.is_new_game?(buoy_game.game_name)
962962 cmd = ShogiServer::GetBuoyCountCommand.new "%%GETBUOYCOUNT", @p, buoy_game.game_name
963963 rt = cmd.call
--- a/test/TC_fork.rb
+++ b/test/TC_fork.rb
@@ -74,8 +74,8 @@ class TestFork < BaseClient
7474 @p1.agree
7575 @p2.agree
7676 sleep 1
77- assert /^Total_Time:1499/ =~ @p1.message
78- assert /^Total_Time:1499/ =~ @p2.message
77+ assert /^Total_Time:1500/ =~ @p1.message
78+ assert /^Total_Time:1500/ =~ @p2.message
7979 @p2.move("-3334FU")
8080 sleep 1
8181 @p1.toryo