shogi-server source
リビジョン | d168a77d26b0ee995991ee798ef1f675bdb30528 (tree) |
---|---|
日時 | 2013-02-24 17:42:43 |
作者 | Daigo Moriwaki <beatles@user...> |
コミッター | Daigo Moriwaki |
Implemented a new command: %%FORK
@@ -1,3 +1,22 @@ | ||
1 | +2013-02-23 Daigo Moriwaki <daigo at debian dot org> | |
2 | + | |
3 | + * [shogi-server] | |
4 | + - New command: %%FORK <source_game> <new_buoy_game> [<nth-move>] | |
5 | + Fork a new game from the posistion where the n-th (starting from | |
6 | + one) move of a source game is played. The new game should be a | |
7 | + valid buoy game name. The default value of n is the position | |
8 | + where the previous position of the last one. | |
9 | + - The objective of this command: The shogi-server may be used as | |
10 | + the back end server of computer-human match where a human player | |
11 | + plays with a real board and someone, or a proxy, inputs moves to | |
12 | + the shogi-server. If the proxy happens to enter a wrong move, | |
13 | + with this command you can restart a new buoy game from the | |
14 | + previous stable position. | |
15 | + 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. | |
19 | + | |
1 | 20 | 2012-12-30 Daigo Moriwaki <daigo at debian dot org> |
2 | 21 | |
3 | 22 | * [shogi-server] |
@@ -10,10 +10,12 @@ module ShogiServer | ||
10 | 10 | attr_reader :moves |
11 | 11 | attr_reader :owner |
12 | 12 | attr_reader :count |
13 | + attr_reader :sente_time | |
14 | + attr_reader :gote_time | |
13 | 15 | |
14 | - def initialize(game_name, moves, owner, count) | |
16 | + def initialize(game_name, moves, owner, count, sente_time, gote_time) | |
15 | 17 | raise "owner name is required" if owner && !owner.instance_of?(String) |
16 | - @game_name, @moves, @owner, @count = game_name, moves, owner, count | |
18 | + @game_name, @moves, @owner, @count, @sente_time, @gote_time = game_name, moves, owner, count, sente_time, gote_time | |
17 | 19 | end |
18 | 20 | |
19 | 21 | def decrement_count |
@@ -21,16 +23,18 @@ module ShogiServer | ||
21 | 23 | end |
22 | 24 | |
23 | 25 | def ==(rhs) |
24 | - return (@game_name == rhs.game_name && | |
25 | - @moves == rhs.moves && | |
26 | - @owner == rhs.owner && | |
27 | - @count == rhs.count) | |
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) | |
28 | 32 | end |
29 | 33 | end |
30 | 34 | |
31 | 35 | class NilBuoyGame < BuoyGame |
32 | 36 | def initialize |
33 | - super(nil, nil, nil, 0) | |
37 | + super(nil, nil, nil, 0, nil, nil) | |
34 | 38 | end |
35 | 39 | end |
36 | 40 |
@@ -62,9 +66,11 @@ module ShogiServer | ||
62 | 66 | if @db.root?(buoy_game.game_name) |
63 | 67 | # error |
64 | 68 | else |
65 | - hash = {'moves' => buoy_game.moves, | |
66 | - 'owner' => buoy_game.owner, | |
67 | - 'count' => buoy_game.count} | |
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} | |
68 | 74 | @db[buoy_game.game_name] = hash |
69 | 75 | end |
70 | 76 | end |
@@ -73,9 +79,11 @@ module ShogiServer | ||
73 | 79 | def update_game(buoy_game) |
74 | 80 | @db.transaction do |
75 | 81 | if @db.root?(buoy_game.game_name) |
76 | - hash = {'moves' => buoy_game.moves, | |
77 | - 'owner' => buoy_game.owner, | |
78 | - 'count' => buoy_game.count} | |
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} | |
79 | 87 | @db[buoy_game.game_name] = hash |
80 | 88 | else |
81 | 89 | # error |
@@ -93,10 +101,12 @@ module ShogiServer | ||
93 | 101 | @db.transaction(true) do |
94 | 102 | hash = @db[game_name] |
95 | 103 | if hash |
96 | - moves = hash['moves'] | |
97 | - owner = hash['owner'] | |
98 | - count = hash['count'].to_i | |
99 | - return BuoyGame.new(game_name, moves, owner, count) | |
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) | |
100 | 110 | else |
101 | 111 | return NilBuoyGame.new |
102 | 112 | end |
@@ -94,6 +94,14 @@ module ShogiServer | ||
94 | 94 | when /^%%GETBUOYCOUNT\s+(\S+)/ |
95 | 95 | game_name = $1 |
96 | 96 | cmd = GetBuoyCountCommand.new(str, player, game_name) |
97 | + when /^%%FORK\s+(\S+)\s+(\S+)(.*)/ | |
98 | + source_game = $1 | |
99 | + new_buoy_game = $2 | |
100 | + nth_move = nil | |
101 | + if $3 && /^\s+(\d+)/ =~ $3 | |
102 | + nth_move = $3.to_i | |
103 | + end | |
104 | + cmd = ForkCommand.new(str, player, source_game, new_buoy_game, nth_move) | |
97 | 105 | when /^\s*$/ |
98 | 106 | cmd = SpaceCommand.new(str, player) |
99 | 107 | when /^%%%[^%]/ |
@@ -532,7 +540,9 @@ module ShogiServer | ||
532 | 540 | return :continue |
533 | 541 | end |
534 | 542 | buoy.decrement_count(buoy_game) |
535 | - Game::new(@player.game_name, @player, rival, board) | |
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) | |
536 | 546 | end |
537 | 547 | else |
538 | 548 | klass = Login.handicapped_game_name?(@game_name) || Board |
@@ -692,6 +702,16 @@ module ShogiServer | ||
692 | 702 | @game_name = game_name |
693 | 703 | @moves = moves |
694 | 704 | @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 | |
695 | 715 | end |
696 | 716 | |
697 | 717 | def call |
@@ -721,7 +741,7 @@ module ShogiServer | ||
721 | 741 | raise WrongMoves |
722 | 742 | end |
723 | 743 | |
724 | - buoy_game = BuoyGame.new(@game_name, @moves, @player.name, @count) | |
744 | + buoy_game = BuoyGame.new(@game_name, @moves, @player.name, @count, @sente_time, @gote_time) | |
725 | 745 | buoy.add_game(buoy_game) |
726 | 746 | @player.write_safe(sprintf("##[SETBUOY] +OK\n")) |
727 | 747 | log_info("A buoy game was created: %s by %s" % [@game_name, @player.name]) |
@@ -749,7 +769,11 @@ module ShogiServer | ||
749 | 769 | # found two players: p1 and p2 |
750 | 770 | log_info("Starting a buoy game: %s with %s and %s" % [@game_name, p1.name, p2.name]) |
751 | 771 | buoy.decrement_count(buoy_game) |
752 | - game = Game::new(@game_name, p1, p2, board) | |
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) | |
753 | 777 | return :continue |
754 | 778 | |
755 | 779 | rescue WrongMoves => e |
@@ -809,4 +833,41 @@ module ShogiServer | ||
809 | 833 | end |
810 | 834 | end |
811 | 835 | |
836 | + # %%FORK <source_game> <new_buoy_game> [<nth-move>] | |
837 | + # Fork a new game from the posistion where the n-th (starting from 1) move | |
838 | + # of a source game is played. The new game should be a valid buoy game | |
839 | + # name. The default value of n is the position where the previous position | |
840 | + # of the last one. | |
841 | + # | |
842 | + class ForkCommand < Command | |
843 | + def initialize(str, player, source_game, new_buoy_game, nth_move) | |
844 | + super(str, player) | |
845 | + @source_game = source_game | |
846 | + @new_buoy_game = new_buoy_game | |
847 | + @nth_move = nth_move # may be nil | |
848 | + end | |
849 | + | |
850 | + def call | |
851 | + game = $league.games[@source_game] | |
852 | + unless game | |
853 | + @player.write_safe(sprintf("##[ERROR] wrong source game name: %s\n", @source_game)) | |
854 | + log_error "Received a wrong source game name: %s from %s." % [@source_game, @player.name] | |
855 | + return :continue | |
856 | + end | |
857 | + | |
858 | + moves = game.read_moves | |
859 | + @nth_move = moves.size - 1 unless @nth_move | |
860 | + if @nth_move > moves.size or @nth_move < 1 | |
861 | + @player.write_safe(sprintf("##[ERROR] number of moves to fork is out of range: %s.\n", moves.size)) | |
862 | + log_error "Number of moves to fork is out of range: %s [%s]" % [@nth_move, @player.name] | |
863 | + return :continue | |
864 | + 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) | |
869 | + return buoy_cmd.call | |
870 | + end | |
871 | + end | |
872 | + | |
812 | 873 | end # module ShogiServer |
@@ -63,7 +63,10 @@ class Game | ||
63 | 63 | end |
64 | 64 | |
65 | 65 | |
66 | - def initialize(game_name, player0, player1, board) | |
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={}) | |
67 | 70 | @monitors = Array::new # array of MonitorHandler* |
68 | 71 | @game_name = game_name |
69 | 72 | if (@game_name =~ /-(\d+)-(\d+)$/) |
@@ -116,6 +119,8 @@ class Game | ||
116 | 119 | @fh.sync = true |
117 | 120 | @result = nil |
118 | 121 | |
122 | + @options = options.dup | |
123 | + | |
119 | 124 | propose |
120 | 125 | end |
121 | 126 | attr_accessor :game_name, :total_time, :byoyomi, :sente, :gote, :game_id, :board, :current_player, :next_player, :fh, :monitors |
@@ -307,8 +312,8 @@ class Game | ||
307 | 312 | @gote.status = "game" |
308 | 313 | @sente.write_safe(sprintf("START:%s\n", @game_id)) |
309 | 314 | @gote.write_safe(sprintf("START:%s\n", @game_id)) |
310 | - @sente.mytime = @total_time | |
311 | - @gote.mytime = @total_time | |
315 | + @sente.mytime = @options[:sente_time] || @total_time | |
316 | + @gote.mytime = @options[:gote_time] || @total_time | |
312 | 317 | @start_time = Time.now |
313 | 318 | end |
314 | 319 |
@@ -372,6 +377,13 @@ EOM | ||
372 | 377 | end |
373 | 378 | |
374 | 379 | 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 | + | |
375 | 387 | str = <<EOM |
376 | 388 | BEGIN Game_Summary |
377 | 389 | Protocol_Version:1.1 |
@@ -386,7 +398,7 @@ Rematch_On_Draw:NO | ||
386 | 398 | To_Move:#{@board.teban ? "+" : "-"} |
387 | 399 | BEGIN Time |
388 | 400 | Time_Unit:1sec |
389 | -Total_Time:#{@total_time} | |
401 | +Total_Time:#{time} | |
390 | 402 | Byoyomi:#{@byoyomi} |
391 | 403 | Least_Time_Per_Move:#{Least_Time_Per_Move} |
392 | 404 | END Time |
@@ -408,6 +420,19 @@ EOM | ||
408 | 420 | |
409 | 421 | return false |
410 | 422 | end |
423 | + | |
424 | + # Read the .csa file and returns an array of moves. | |
425 | + # ex. ["+7776FU", "-3334FU"] | |
426 | + # | |
427 | + def read_moves | |
428 | + ret = [] | |
429 | + IO.foreach(@logfile) do |line| | |
430 | + if /^[\+\-]\d{4}[A-Z]{2}/ =~ line | |
431 | + ret << line.chomp | |
432 | + end | |
433 | + end | |
434 | + return ret | |
435 | + end | |
411 | 436 | |
412 | 437 | private |
413 | 438 |
@@ -9,6 +9,7 @@ require 'TC_floodgate' | ||
9 | 9 | require 'TC_floodgate_history' |
10 | 10 | require 'TC_floodgate_next_time_generator' |
11 | 11 | require 'TC_floodgate_thread.rb' |
12 | +require 'TC_fork' | |
12 | 13 | require 'TC_functional' |
13 | 14 | require 'TC_game' |
14 | 15 | require 'TC_game_result' |
@@ -9,14 +9,32 @@ require 'mock_log_message' | ||
9 | 9 | |
10 | 10 | class TestBuoyGame < Test::Unit::TestCase |
11 | 11 | def test_equal |
12 | - g1 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1) | |
13 | - g2 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1) | |
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) | |
14 | 20 | assert_equal g1, g2 |
15 | 21 | end |
16 | 22 | |
17 | 23 | def test_not_equal |
18 | - g1 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1) | |
19 | - g2 = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 2) | |
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) | |
20 | 38 | assert_not_equal g1, g2 |
21 | 39 | end |
22 | 40 | end |
@@ -49,7 +67,18 @@ class TestBuoy < Test::Unit::TestCase | ||
49 | 67 | end |
50 | 68 | |
51 | 69 | def test_add_game |
52 | - game = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 1) | |
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) | |
53 | 82 | @buoy.add_game(game) |
54 | 83 | assert !@buoy.is_new_game?("buoy_1234-900-0") |
55 | 84 | game2 = @buoy.get_game(game.game_name) |
@@ -60,9 +89,9 @@ class TestBuoy < Test::Unit::TestCase | ||
60 | 89 | end |
61 | 90 | |
62 | 91 | def test_update_game |
63 | - game = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 2) | |
92 | + game = ShogiServer::BuoyGame.new("buoy_1234-900-0", [], "p1", 2, nil, nil) | |
64 | 93 | @buoy.add_game(game) |
65 | - g2 = ShogiServer::BuoyGame.new(game.game_name, game.moves, game.owner, game.count-1) | |
94 | + g2 = ShogiServer::BuoyGame.new(game.game_name, game.moves, game.owner, game.count-1, nil, nil) | |
66 | 95 | @buoy.update_game(g2) |
67 | 96 | |
68 | 97 | get = @buoy.get_game(g2.game_name) |
@@ -228,6 +228,11 @@ class TestFactoryMethod < Test::Unit::TestCase | ||
228 | 228 | assert_instance_of(ShogiServer::GetBuoyCountCommand, cmd) |
229 | 229 | end |
230 | 230 | |
231 | + def test_fork_command | |
232 | + cmd = ShogiServer::Command.factory("%%FORK server-denou-14400-60+p1+p2+20130223185013 buoy_denou-14400-60", @p) | |
233 | + assert_instance_of(ShogiServer::ForkCommand, cmd) | |
234 | + end | |
235 | + | |
231 | 236 | def test_void_command |
232 | 237 | cmd = ShogiServer::Command.factory("%%%HOGE", @p) |
233 | 238 | assert_instance_of(ShogiServer::VoidCommand, cmd) |
@@ -837,7 +842,7 @@ class TestSetBuoyCommand < BaseTestBuoyCommand | ||
837 | 842 | assert !$p1.out.empty? |
838 | 843 | assert !$p2.out.empty? |
839 | 844 | buoy_game2 = @buoy.get_game("buoy_hoge-1500-0") |
840 | - assert_equal ShogiServer::BuoyGame.new("buoy_hoge-1500-0", "+7776FU", @p.name, 1), buoy_game2 | |
845 | + assert_equal ShogiServer::BuoyGame.new("buoy_hoge-1500-0", "+7776FU", @p.name, 1, nil, nil), buoy_game2 | |
841 | 846 | end |
842 | 847 | |
843 | 848 | def test_call_1 |
@@ -862,7 +867,7 @@ class TestSetBuoyCommand < BaseTestBuoyCommand | ||
862 | 867 | |
863 | 868 | def test_call_error_duplicated_game_name |
864 | 869 | assert @buoy.is_new_game?("buoy_duplicated-1500-0") |
865 | - bg = ShogiServer::BuoyGame.new("buoy_duplicated-1500-0", ["+7776FU"], @p.name, 1) | |
870 | + bg = ShogiServer::BuoyGame.new("buoy_duplicated-1500-0", ["+7776FU"], @p.name, 1, nil, nil) | |
866 | 871 | @buoy.add_game bg |
867 | 872 | assert !@buoy.is_new_game?("buoy_duplicated-1500-0") |
868 | 873 |
@@ -900,7 +905,7 @@ end | ||
900 | 905 | # |
901 | 906 | class TestDeleteBuoyCommand < BaseTestBuoyCommand |
902 | 907 | def test_call |
903 | - buoy_game = ShogiServer::BuoyGame.new("buoy_testdeletebuoy-1500-0", "+7776FU", @p.name, 1) | |
908 | + buoy_game = ShogiServer::BuoyGame.new("buoy_testdeletebuoy-1500-0", "+7776FU", @p.name, 1, nil, nil) | |
904 | 909 | assert @buoy.is_new_game?(buoy_game.game_name) |
905 | 910 | @buoy.add_game buoy_game |
906 | 911 | assert !@buoy.is_new_game?(buoy_game.game_name) |
@@ -913,7 +918,7 @@ class TestDeleteBuoyCommand < BaseTestBuoyCommand | ||
913 | 918 | end |
914 | 919 | |
915 | 920 | def test_call_not_exist |
916 | - buoy_game = ShogiServer::BuoyGame.new("buoy_notexist-1500-0", "+7776FU", @p.name, 1) | |
921 | + buoy_game = ShogiServer::BuoyGame.new("buoy_notexist-1500-0", "+7776FU", @p.name, 1, nil, nil) | |
917 | 922 | assert @buoy.is_new_game?(buoy_game.game_name) |
918 | 923 | cmd = ShogiServer::DeleteBuoyCommand.new "%%DELETEBUOY", @p, buoy_game.game_name |
919 | 924 | rt = cmd.call |
@@ -924,7 +929,7 @@ class TestDeleteBuoyCommand < BaseTestBuoyCommand | ||
924 | 929 | end |
925 | 930 | |
926 | 931 | def test_call_another_player |
927 | - buoy_game = ShogiServer::BuoyGame.new("buoy_anotherplayer-1500-0", "+7776FU", "another_player", 1) | |
932 | + buoy_game = ShogiServer::BuoyGame.new("buoy_anotherplayer-1500-0", "+7776FU", "another_player", 1, nil, nil) | |
928 | 933 | assert @buoy.is_new_game?(buoy_game.game_name) |
929 | 934 | @buoy.add_game(buoy_game) |
930 | 935 | assert !@buoy.is_new_game?(buoy_game.game_name) |
@@ -941,7 +946,7 @@ end | ||
941 | 946 | # |
942 | 947 | class TestGetBuoyCountCommand < BaseTestBuoyCommand |
943 | 948 | def test_call |
944 | - buoy_game = ShogiServer::BuoyGame.new("buoy_testdeletebuoy-1500-0", "+7776FU", @p.name, 1) | |
949 | + buoy_game = ShogiServer::BuoyGame.new("buoy_testdeletebuoy-1500-0", "+7776FU", @p.name, 1, nil, nil) | |
945 | 950 | assert @buoy.is_new_game?(buoy_game.game_name) |
946 | 951 | @buoy.add_game buoy_game |
947 | 952 | assert !@buoy.is_new_game?(buoy_game.game_name) |
@@ -952,7 +957,7 @@ class TestGetBuoyCountCommand < BaseTestBuoyCommand | ||
952 | 957 | end |
953 | 958 | |
954 | 959 | def test_call_not_exist |
955 | - buoy_game = ShogiServer::BuoyGame.new("buoy_notexist-1500-0", "+7776FU", @p.name, 1) | |
960 | + buoy_game = ShogiServer::BuoyGame.new("buoy_notexist-1500-0", "+7776FU", @p.name, 1, nil, nil) | |
956 | 961 | assert @buoy.is_new_game?(buoy_game.game_name) |
957 | 962 | cmd = ShogiServer::GetBuoyCountCommand.new "%%GETBUOYCOUNT", @p, buoy_game.game_name |
958 | 963 | rt = cmd.call |
@@ -0,0 +1,88 @@ | ||
1 | +$:.unshift File.join(File.dirname(__FILE__), "..") | |
2 | +$topdir = File.expand_path File.dirname(__FILE__) | |
3 | +require "baseclient" | |
4 | +require "shogi_server/buoy.rb" | |
5 | + | |
6 | +class TestFork < BaseClient | |
7 | + def parse_game_name(player) | |
8 | + player.puts "%%LIST" | |
9 | + sleep 1 | |
10 | + if /##\[LIST\] (.*)/ =~ player.message | |
11 | + return $1 | |
12 | + end | |
13 | + end | |
14 | + | |
15 | + def test_wrong_game | |
16 | + @admin = SocketPlayer.new "dummy", "admin", false | |
17 | + @admin.connect | |
18 | + @admin.reader | |
19 | + @admin.login | |
20 | + | |
21 | + result, result2 = handshake do | |
22 | + @admin.puts "%%FORK wronggame-900-0 buoy_WrongGame-900-0" | |
23 | + sleep 1 | |
24 | + end | |
25 | + | |
26 | + assert /##\[ERROR\] wrong source game name/ =~ @admin.message | |
27 | + @admin.logout | |
28 | + end | |
29 | + | |
30 | + def test_too_short_fork | |
31 | + @admin = SocketPlayer.new "dummy", "admin", false | |
32 | + @admin.connect | |
33 | + @admin.reader | |
34 | + @admin.login | |
35 | + | |
36 | + result, result2 = handshake do | |
37 | + source_game = parse_game_name(@admin) | |
38 | + @admin.puts "%%FORK #{source_game} buoy_TooShortFork-900-0 0" | |
39 | + sleep 1 | |
40 | + end | |
41 | + | |
42 | + assert /##\[ERROR\] number of moves to fork is out of range/ =~ @admin.message | |
43 | + @admin.logout | |
44 | + end | |
45 | + | |
46 | + def test_fork | |
47 | + buoy = ShogiServer::Buoy.new | |
48 | + | |
49 | + @admin = SocketPlayer.new "dummy", "admin", "*" | |
50 | + @admin.connect | |
51 | + @admin.reader | |
52 | + @admin.login | |
53 | + assert buoy.is_new_game?("buoy_Fork-1500-0") | |
54 | + | |
55 | + result, result2 = handshake do | |
56 | + source_game = parse_game_name(@admin) | |
57 | + @admin.puts "%%FORK #{source_game} buoy_Fork-1500-0" | |
58 | + sleep 1 | |
59 | + end | |
60 | + | |
61 | + assert buoy.is_new_game?("buoy_Fork-1500-0") | |
62 | + @p1 = SocketPlayer.new "buoy_Fork", "p1", true | |
63 | + @p2 = SocketPlayer.new "buoy_Fork", "p2", false | |
64 | + @p1.connect | |
65 | + @p2.connect | |
66 | + @p1.reader | |
67 | + @p2.reader | |
68 | + @p1.login | |
69 | + @p2.login | |
70 | + sleep 1 | |
71 | + @p1.game | |
72 | + @p2.game | |
73 | + sleep 1 | |
74 | + @p1.agree | |
75 | + @p2.agree | |
76 | + sleep 1 | |
77 | + assert /^Total_Time:1499/ =~ @p1.message | |
78 | + assert /^Total_Time:1499/ =~ @p2.message | |
79 | + @p2.move("-3334FU") | |
80 | + sleep 1 | |
81 | + @p1.toryo | |
82 | + sleep 1 | |
83 | + @p2.logout | |
84 | + @p1.logout | |
85 | + | |
86 | + @admin.logout | |
87 | + end | |
88 | +end |