- A new log summary type, "max_moves_draw", has been assigned for games
drawing with max moves.
'summary:max_moves_draw:name_sente draw:name_gote draw
+ - Least time per move:
+ - New command line option: --least-time-per-move n
+ This opotion specifies a least time in second per move, which
+ was previously 1 sec but is now by default 1, meaning that a
+ decimal fraction of time for a move will be truncated.
2014-07-19 Daigo Moriwaki <daigo at debian dot org>
port_number
a port number for the server to listen.
4081 is often used.
+ --least-time-per-move n
+ Least time in second per move: 0, 1 (default 1).
+ - 0: The new rule that CSA introduced in November 2014.
+ - 1: The old rule before it.
--max-moves n
when a game with the n-th move played does not end, make the game a draw.
Default 256. 0 disables this feature.
def parse_command_line
options = Hash::new
parser = GetoptLong.new(
- ["--daemon", GetoptLong::REQUIRED_ARGUMENT],
- ["--floodgate-games", GetoptLong::REQUIRED_ARGUMENT],
- ["--max-moves", GetoptLong::REQUIRED_ARGUMENT],
- ["--pid-file", GetoptLong::REQUIRED_ARGUMENT],
- ["--player-log-dir", GetoptLong::REQUIRED_ARGUMENT])
+ ["--daemon", GetoptLong::REQUIRED_ARGUMENT],
+ ["--floodgate-games", GetoptLong::REQUIRED_ARGUMENT],
+ ["--least-time-per-move", GetoptLong::REQUIRED_ARGUMENT],
+ ["--max-moves", GetoptLong::REQUIRED_ARGUMENT],
+ ["--pid-file", GetoptLong::REQUIRED_ARGUMENT],
+ ["--player-log-dir", GetoptLong::REQUIRED_ARGUMENT])
parser.quiet = true
begin
parser.each_option do |name, arg|
$options["max-moves"] ||= 256
$options["max-moves"] = $options["max-moves"].to_i
+
+ $options["least-time-per-move"] ||= 1
+ $options["least-time-per-move"] = $options["least-time-per-move"].to_i
end
# See if a file can be created in the directory.
Default_Timeout = 60 # for single socket operation
Default_Game_Name = "default-1500-0"
One_Time = 10
-Least_Time_Per_Move = 1
Login_Time = 300 # time for LOGIN
Revision = "20131215"
@total_time = $1.to_i
@byoyomi = $2.to_i
- @time_clock = TimeClock::factory(Least_Time_Per_Move, @game_name)
+ @time_clock = TimeClock::factory($options["least-time-per-move"], @game_name)
end
if (player0.sente)
Time_Unit:#{@time_clock.time_unit}
Total_Time:#{@total_time}
Byoyomi:#{@byoyomi}
-Least_Time_Per_Move:#{Least_Time_Per_Move}
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
Remaining_Time+:#{@sente.mytime}
Remaining_Time-:#{@gote.mytime}
Last_Move:#{@last_move}
Time_Unit:#{@time_clock.time_unit}
Total_Time:#{@total_time}
Byoyomi:#{@byoyomi}
-Least_Time_Per_Move:#{Least_Time_Per_Move}
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
END Time
BEGIN Position
#{@board.initial_string.chomp}
if (byoyomi_str == "060")
@time_clock = StopWatchClock.new(least_time_per_move, total_time, byoyomi)
else
- @time_clock = ChessClock.new(least_time_per_move, total_time, byoyomi)
+ if least_time_per_move == 0
+ @time_clock = ChessClockWithLeastZero.new(least_time_per_move, total_time, byoyomi)
+ else
+ @time_clock = ChessClock.new(least_time_per_move, total_time, byoyomi)
+ end
end
end
# Returns thinking time duration
#
- def time_duration(start_time, end_time)
+ def time_duration(mytime, start_time, end_time)
# implement this
return 9999999
end
# Updates a player's remaining time and returns thinking time.
#
def process_time(player, start_time, end_time)
- t = time_duration(start_time, end_time)
+ t = time_duration(player.mytime, start_time, end_time)
player.mytime -= t
if (player.mytime < 0)
super
end
- def time_duration(start_time, end_time)
+ def time_duration(mytime, start_time, end_time)
return [(end_time - start_time).floor, @least_time_per_move].max
end
def timeout?(player, start_time, end_time)
- t = time_duration(start_time, end_time)
+ t = time_duration(player.mytime, start_time, end_time)
if ((player.mytime - t <= -@byoyomi) &&
((@total_time > 0) || (@byoyomi > 0)))
end
end
+# Calculates thinking time with chess clock, truncating decimal seconds for
+# thinking time. This is a new rule that CSA introduced in November 2014.
+#
+# least_time_per_move should be 0.
+# byoyomi should be more than 0.
+#
+class ChessClockWithLeastZero < ChessClock
+ def initialize(least_time_per_move, total_time, byoyomi)
+ if least_time_per_move != 0
+ raise ArgumentError, "least_time_per_move #{least_time_per_move} should be 0."
+ end
+ super
+ end
+
+ def time_duration(mytime, start_time, end_time)
+ t = end_time - start_time
+ if @byoyomi > 0
+ # If the remaining thinking time covers the duration t, floor it.
+ if mytime + @byoyomi - t > 0
+ t = t.floor
+ else
+ t = t.ceil
+ end
+ else
+ # Thinking time only
+ t = t.floor
+ end
+
+ return t
+ end
+
+ def to_s
+ return "ChessClockWithLeastZero: LeastTimePerMove %d; TotalTime %d; Byoyomi %d" % [@least_time_per_move, @total_time, @byoyomi]
+ end
+end
+
class StopWatchClock < TimeClock
def initialize(least_time_per_move, total_time, byoyomi)
super
return "1min"
end
- def time_duration(start_time, end_time)
+ def time_duration(mytime, start_time, end_time)
t = [(end_time - start_time).floor, @least_time_per_move].max
return (t / @byoyomi) * @byoyomi
end
def timeout?(player, start_time, end_time)
- t = time_duration(start_time, end_time)
+ t = time_duration(player.mytime, start_time, end_time)
if (player.mytime <= t)
return true
require 'TC_fork'
require 'TC_functional'
require 'TC_game'
+require 'TC_game_least_0'
require 'TC_game_result'
require 'TC_handicapped_boards'
# This game has more thatn 256 moves.
def test_wrong_game
@admin = SocketPlayer.new "dummy", "admin", false
@admin.connect
+ sleep 0.1
@admin.reader
+ sleep 0.1
@admin.login
+ sleep 0.1
result, result2 = handshake do
@admin.puts "%%FORK wronggame-900-0 buoy_WrongGame-900-0"
def test_too_short_fork
@admin = SocketPlayer.new "dummy", "admin", false
@admin.connect
+ sleep 0.1
@admin.reader
+ sleep 0.1
@admin.login
+ sleep 0.1
result, result2 = handshake do
source_game = parse_game_name(@admin)
@admin = SocketPlayer.new "dummy", "admin", "*"
@admin.connect
+ sleep 0.1
@admin.reader
+ sleep 0.1
@admin.login
+ sleep 0.1
+
assert buoy.is_new_game?("buoy_Fork-1500-0")
result, result2 = handshake do
@p1 = SocketPlayer.new "buoy_Fork", "p1", true
@p2 = SocketPlayer.new "buoy_Fork", "p2", false
@p1.connect
+ sleep 0.1
@p2.connect
+ sleep 0.1
@p1.reader
+ sleep 0.1
@p2.reader
+ sleep 0.1
@p1.login
+ sleep 0.1
@p2.login
- sleep 1
+ sleep 0.1
@p1.game
+ sleep 0.1
@p2.game
- sleep 1
@p1.agree
+ sleep 0.1
@p2.agree
- sleep 1
+ sleep 0.1
assert /^Total_Time:1500/ =~ @p1.message
assert /^Total_Time:1500/ =~ @p2.message
@p2.move("-3334FU")
- sleep 1
+ sleep 0.1
@p1.toryo
- sleep 1
+ sleep 0.1
@p2.logout
+ sleep 0.1
@p1.logout
+ sleep 0.1
@admin.logout
end
@admin = SocketPlayer.new "dummy", "admin", "*"
@admin.connect
+ sleep 0.1
@admin.reader
+ sleep 0.1
@admin.login
+ sleep 0.1
result, result2 = handshake do
source_game = parse_game_name(@admin)
@p1 = SocketPlayer.new "buoy_TestFork_1", "p1", true
@p2 = SocketPlayer.new "buoy_TestFork_1", "p2", false
@p1.connect
+ sleep 0.1
@p2.connect
+ sleep 0.1
@p1.reader
+ sleep 0.1
@p2.reader
+ sleep 0.1
@p1.login
+ sleep 0.1
@p2.login
- sleep 1
+ sleep 0.1
@p1.game
+ sleep 0.1
@p2.game
- sleep 1
+ sleep 0.1
@p1.agree
+ sleep 0.1
@p2.agree
- sleep 1
+ sleep 0.1
assert /^Total_Time:1500/ =~ @p1.message
assert /^Total_Time:1500/ =~ @p2.message
@p2.move("-3334FU")
- sleep 1
+ sleep 0.1
@p1.toryo
- sleep 1
+ sleep 0.1
@p2.logout
+ sleep 0.1
@p1.logout
+ sleep 0.1
@admin.logout
end
require 'shogi_server/game'
require 'shogi_server/player'
+$options = {}
+$options["least-time-per-move"] = 1
+
def log_message(str)
$stderr.puts str
end
Time_Unit:1sec
Total_Time:1500
Byoyomi:0
-Least_Time_Per_Move:1
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
END Time
BEGIN Position
P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
Time_Unit:1sec
Total_Time:1500
Byoyomi:0
-Least_Time_Per_Move:1
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
END Time
BEGIN Position
P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
Time_Unit:1sec
Total_Time:1500
Byoyomi:0
-Least_Time_Per_Move:1
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
END Time
BEGIN Position
P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
Time_Unit:1sec
Total_Time:1500
Byoyomi:0
-Least_Time_Per_Move:1
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
END Time
BEGIN Position
P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
Time_Unit:1sec
Total_Time:1500
Byoyomi:0
-Least_Time_Per_Move:1
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
END Time
BEGIN Position
P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
Time_Unit:1sec
Total_Time:1500
Byoyomi:0
-Least_Time_Per_Move:1
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
END Time
BEGIN Position
P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
--- /dev/null
+$:.unshift File.join(File.dirname(__FILE__), "..")
+require 'test/unit'
+require 'test/mock_player'
+require 'shogi_server/board'
+require 'shogi_server/game'
+require 'shogi_server/player'
+
+$options = {}
+$options["least-time-per-move"] = 0
+
+def log_message(str)
+ $stderr.puts str
+end
+
+def log_warning(str)
+ $stderr.puts str
+end
+
+def log_error(str)
+ $stderr.puts str
+end
+
+$league = ShogiServer::League.new(File.dirname(__FILE__))
+$league.event = "test"
+
+class TestGameWithLeastZero < Test::Unit::TestCase
+
+ def test_new
+ game_name = "hoge-1500-10"
+ board = ShogiServer::Board.new
+ board.initial
+ p1 = MockPlayer.new
+ p1.sente = true
+ p1.name = "p1"
+ p2 = MockPlayer.new
+ p2.sente = false
+ p2.name = "p2"
+
+ game = ShogiServer::Game.new game_name, p1, p2, board
+ assert_equal "", game.last_move
+
+ p1_out = <<EOF
+BEGIN Game_Summary
+Protocol_Version:1.1
+Protocol_Mode:Server
+Format:Shogi 1.0
+Declaration:Jishogi 1.1
+Game_ID:#{game.game_id}
+Name+:p1
+Name-:p2
+Your_Turn:+
+Rematch_On_Draw:NO
+To_Move:+
+BEGIN Time
+Time_Unit:1sec
+Total_Time:1500
+Byoyomi:10
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
+END Time
+BEGIN Position
+P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
+P2 * -HI * * * * * -KA *
+P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
+P4 * * * * * * * * *
+P5 * * * * * * * * *
+P6 * * * * * * * * *
+P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
+P8 * +KA * * * * * +HI *
+P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
++
+END Position
+END Game_Summary
+EOF
+ assert_equal(p1_out, p1.out.first)
+
+ p2_out = <<EOF
+BEGIN Game_Summary
+Protocol_Version:1.1
+Protocol_Mode:Server
+Format:Shogi 1.0
+Declaration:Jishogi 1.1
+Game_ID:#{game.game_id}
+Name+:p1
+Name-:p2
+Your_Turn:-
+Rematch_On_Draw:NO
+To_Move:+
+BEGIN Time
+Time_Unit:1sec
+Total_Time:1500
+Byoyomi:10
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
+END Time
+BEGIN Position
+P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
+P2 * -HI * * * * * -KA *
+P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
+P4 * * * * * * * * *
+P5 * * * * * * * * *
+P6 * * * * * * * * *
+P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
+P8 * +KA * * * * * +HI *
+P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
++
+END Position
+END Game_Summary
+EOF
+ assert_equal(p2_out, p2.out.first)
+
+ file = Pathname.new(game.logfile)
+ log = file.read
+ assert_equal(<<EOF, log.gsub(/^\$START_TIME.*?\n/,''))
+V2
+N+p1
+N-p2
+$EVENT:#{game.game_id}
+P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
+P2 * -HI * * * * * -KA *
+P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
+P4 * * * * * * * * *
+P5 * * * * * * * * *
+P6 * * * * * * * * *
+P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
+P8 * +KA * * * * * +HI *
+P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
++
+EOF
+ end
+
+ def test_new_buoy_1_move
+ game_name = "buoyhoge-1500-10"
+ board = ShogiServer::Board.new
+ board.set_from_moves ["+7776FU"]
+ p1 = MockPlayer.new
+ p1.sente = true
+ p1.name = "p1"
+ p2 = MockPlayer.new
+ p2.sente = false
+ p2.name = "p2"
+
+ game = ShogiServer::Game.new game_name, p1, p2, board
+ assert_equal "+7776FU,T1", game.last_move
+
+ p1_out = <<EOF
+BEGIN Game_Summary
+Protocol_Version:1.1
+Protocol_Mode:Server
+Format:Shogi 1.0
+Declaration:Jishogi 1.1
+Game_ID:#{game.game_id}
+Name+:p1
+Name-:p2
+Your_Turn:+
+Rematch_On_Draw:NO
+To_Move:-
+BEGIN Time
+Time_Unit:1sec
+Total_Time:1500
+Byoyomi:10
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
+END Time
+BEGIN Position
+P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
+P2 * -HI * * * * * -KA *
+P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
+P4 * * * * * * * * *
+P5 * * * * * * * * *
+P6 * * * * * * * * *
+P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
+P8 * +KA * * * * * +HI *
+P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
++
++7776FU,T1
+END Position
+END Game_Summary
+EOF
+ assert_equal(p1_out, p1.out.first)
+
+ p2_out = <<EOF
+BEGIN Game_Summary
+Protocol_Version:1.1
+Protocol_Mode:Server
+Format:Shogi 1.0
+Declaration:Jishogi 1.1
+Game_ID:#{game.game_id}
+Name+:p1
+Name-:p2
+Your_Turn:-
+Rematch_On_Draw:NO
+To_Move:-
+BEGIN Time
+Time_Unit:1sec
+Total_Time:1500
+Byoyomi:10
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
+END Time
+BEGIN Position
+P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
+P2 * -HI * * * * * -KA *
+P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
+P4 * * * * * * * * *
+P5 * * * * * * * * *
+P6 * * * * * * * * *
+P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
+P8 * +KA * * * * * +HI *
+P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
++
++7776FU,T1
+END Position
+END Game_Summary
+EOF
+ assert_equal(p2_out, p2.out.first)
+
+ file = Pathname.new(game.logfile)
+ log = file.read
+ assert_equal(<<EOF, log.gsub(/^\$START_TIME.*?\n/,''))
+V2
+N+p1
+N-p2
+$EVENT:#{game.game_id}
+P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
+P2 * -HI * * * * * -KA *
+P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
+P4 * * * * * * * * *
+P5 * * * * * * * * *
+P6 * * * * * * * * *
+P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
+P8 * +KA * * * * * +HI *
+P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
++
+'buoy game starting with 1 moves
++7776FU
+T1
+EOF
+ end
+
+ def test_new_buoy_2_moves
+ game_name = "buoyhoge-1500-10"
+ board = ShogiServer::Board.new
+ board.set_from_moves ["+7776FU", "-3334FU"]
+ p1 = MockPlayer.new
+ p1.sente = true
+ p1.name = "p1"
+ p2 = MockPlayer.new
+ p2.sente = false
+ p2.name = "p2"
+
+ game = ShogiServer::Game.new game_name, p1, p2, board
+ assert_equal "-3334FU,T1", game.last_move
+
+ p1_out = <<EOF
+BEGIN Game_Summary
+Protocol_Version:1.1
+Protocol_Mode:Server
+Format:Shogi 1.0
+Declaration:Jishogi 1.1
+Game_ID:#{game.game_id}
+Name+:p1
+Name-:p2
+Your_Turn:+
+Rematch_On_Draw:NO
+To_Move:+
+BEGIN Time
+Time_Unit:1sec
+Total_Time:1500
+Byoyomi:10
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
+END Time
+BEGIN Position
+P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
+P2 * -HI * * * * * -KA *
+P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
+P4 * * * * * * * * *
+P5 * * * * * * * * *
+P6 * * * * * * * * *
+P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
+P8 * +KA * * * * * +HI *
+P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
++
++7776FU,T1
+-3334FU,T1
+END Position
+END Game_Summary
+EOF
+ assert_equal(p1_out, p1.out.first)
+
+ p2_out = <<EOF
+BEGIN Game_Summary
+Protocol_Version:1.1
+Protocol_Mode:Server
+Format:Shogi 1.0
+Declaration:Jishogi 1.1
+Game_ID:#{game.game_id}
+Name+:p1
+Name-:p2
+Your_Turn:-
+Rematch_On_Draw:NO
+To_Move:+
+BEGIN Time
+Time_Unit:1sec
+Total_Time:1500
+Byoyomi:10
+Least_Time_Per_Move:#{$options["least-time-per-move"]}
+END Time
+BEGIN Position
+P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
+P2 * -HI * * * * * -KA *
+P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
+P4 * * * * * * * * *
+P5 * * * * * * * * *
+P6 * * * * * * * * *
+P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
+P8 * +KA * * * * * +HI *
+P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
++
++7776FU,T1
+-3334FU,T1
+END Position
+END Game_Summary
+EOF
+ assert_equal(p2_out, p2.out.first)
+
+ file = Pathname.new(game.logfile)
+ log = file.read
+ assert_equal(<<EOF, log.gsub(/^\$START_TIME.*?\n/,''))
+V2
+N+p1
+N-p2
+$EVENT:#{game.game_id}
+P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
+P2 * -HI * * * * * -KA *
+P3-FU-FU-FU-FU-FU-FU-FU-FU-FU
+P4 * * * * * * * * *
+P5 * * * * * * * * *
+P6 * * * * * * * * *
+P7+FU+FU+FU+FU+FU+FU+FU+FU+FU
+P8 * +KA * * * * * +HI *
+P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
++
+'buoy game starting with 2 moves
++7776FU
+T1
+-3334FU
+T1
+EOF
+ end
+
+ def test_monitor_add
+ game_name = "hoge-1500-10"
+ board = ShogiServer::Board.new
+ board.initial
+ p1 = MockPlayer.new
+ p1.sente = true
+ p1.name = "p1"
+ p2 = MockPlayer.new
+ p2.sente = false
+ p2.name = "p2"
+
+ game = ShogiServer::Game.new game_name, p1, p2, board
+ handler1 = ShogiServer::MonitorHandler1.new p1
+ handler2 = ShogiServer::MonitorHandler2.new p2
+
+ assert_equal(0, game.monitors.size)
+ game.monitoron(handler1)
+ assert_equal(1, game.monitors.size)
+ game.monitoron(handler2)
+ assert_equal(2, game.monitors.size)
+ game.monitoroff(handler1)
+ assert_equal(1, game.monitors.size)
+ assert_equal(handler2, game.monitors.last)
+ game.monitoroff(handler2)
+ assert_equal(0, game.monitors.size)
+ end
+
+ def test_decide_turns
+ p1 = MockPlayer.new
+ p1.name = "p1"
+ p2 = MockPlayer.new
+ p2.name = "p2"
+
+ p1.sente=nil; p2.sente=false
+ ShogiServer::Game::decide_turns(p1, "+", p2)
+ assert_equal true, p1.sente
+
+ p1.sente=nil; p2.sente=nil
+ ShogiServer::Game::decide_turns(p1, "+", p2)
+ assert_equal true, p1.sente
+
+ p1.sente=nil; p2.sente=true
+ ShogiServer::Game::decide_turns(p1, "-", p2)
+ assert_equal false, p1.sente
+
+ p1.sente=nil; p2.sente=nil
+ ShogiServer::Game::decide_turns(p1, "-", p2)
+ assert_equal false, p1.sente
+
+ p1.sente=nil; p2.sente=false
+ ShogiServer::Game::decide_turns(p1, "*", p2)
+ assert_equal true, p1.sente
+
+ p1.sente=nil; p2.sente=true
+ ShogiServer::Game::decide_turns(p1, "*", p2)
+ assert_equal false, p1.sente
+
+ p1.sente=nil; p2.sente=nil
+ ShogiServer::Game::decide_turns(p1, "*", p2)
+ assert (p1.sente == true && p2.sente == false) ||
+ (p1.sente == false && p2.sente == true)
+ end
+end
+
class TestChessClock < Test::Unit::TestCase
def test_time_duration
tc = ShogiServer::ChessClock.new(1, 1500, 60)
- assert_equal(1, tc.time_duration(100.1, 100.9))
- assert_equal(1, tc.time_duration(100, 101))
- assert_equal(1, tc.time_duration(100.1, 101.9))
- assert_equal(2, tc.time_duration(100.1, 102.9))
- assert_equal(2, tc.time_duration(100, 102))
+ assert_equal(1, tc.time_duration(nil, 100.1, 100.9))
+ assert_equal(1, tc.time_duration(nil, 100, 101))
+ assert_equal(1, tc.time_duration(nil, 100.1, 101.9))
+ assert_equal(2, tc.time_duration(nil, 100.1, 102.9))
+ assert_equal(2, tc.time_duration(nil, 100, 102))
end
def test_without_byoyomi
end
end
+class TestChessClockWithLeastZero < Test::Unit::TestCase
+ def test_time_duration_within_thinking_time
+ tc = ShogiServer::ChessClockWithLeastZero.new(0, 900, 10)
+ assert_equal(0, tc.time_duration(100, 100.1, 100.9)) # 0.8
+ assert_equal(1, tc.time_duration(100, 100, 101)) # 1
+ assert_equal(1, tc.time_duration(100, 100.1, 101.9)) # 1.8
+ assert_equal(1, tc.time_duration(1, 100, 101)) # 1
+ assert_equal(2, tc.time_duration(100, 100.1, 102.9)) # 2.8
+ assert_equal(2, tc.time_duration(100, 100, 102)) # 2
+ end
+
+ def test_time_duration_over_thinking_time
+ tc = ShogiServer::ChessClockWithLeastZero.new(0, 900, 10)
+ assert_equal(1, tc.time_duration(1, 100.1, 101.9)) # 1.8
+ assert_equal(2, tc.time_duration(2, 100.1, 102.9)) # 2.8
+ end
+
+ def test_with_byoyomi
+ tc = ShogiServer::ChessClockWithLeastZero.new(0, 900, 10)
+
+ p = DummyPlayer.new 100
+ assert(!tc.timeout?(p, 100, 101)) # 1
+ assert(!tc.timeout?(p, 100, 209)) # 109
+ assert(!tc.timeout?(p, 100, 209.9)) # 109.9
+ assert(tc.timeout?(p, 100, 210)) # 110
+ assert(tc.timeout?(p, 100, 210.1)) # 110.1
+ assert(tc.timeout?(p, 100, 211)) # 111
+ end
+
+ def test_with_byoyomi2
+ tc = ShogiServer::ChessClockWithLeastZero.new(0, 0, 10)
+
+ p = DummyPlayer.new 0
+ assert(!tc.timeout?(p, 100, 109)) # 9
+ assert(!tc.timeout?(p, 100, 109.9)) # 9.9
+ assert(tc.timeout?(p, 100, 110)) # 10
+ assert(tc.timeout?(p, 100, 110.1)) # 10.1
+ assert(tc.timeout?(p, 100, 110)) # 10.1
+ end
+end
+
class TestStopWatchClock < Test::Unit::TestCase
def test_time_duration
tc = ShogiServer::StopWatchClock.new(1, 1500, 60)
- assert_equal(0, tc.time_duration(100.1, 100.9))
- assert_equal(0, tc.time_duration(100, 101))
- assert_equal(0, tc.time_duration(100, 159.9))
- assert_equal(60, tc.time_duration(100, 160))
- assert_equal(60, tc.time_duration(100, 219))
- assert_equal(120, tc.time_duration(100, 220))
+ assert_equal(0, tc.time_duration(nil, 100.1, 100.9))
+ assert_equal(0, tc.time_duration(nil, 100, 101))
+ assert_equal(0, tc.time_duration(nil, 100, 159.9))
+ assert_equal(60, tc.time_duration(nil, 100, 160))
+ assert_equal(60, tc.time_duration(nil, 100, 219))
+ assert_equal(120, tc.time_duration(nil, 100, 220))
end
def test_with_byoyomi
end
def login
+ sleep 0.1
@p1.connect
+ sleep 0.1
@p2.connect
+ sleep 0.1
@p1.login
+ sleep 0.1
@p2.login
+ sleep 0.1
@p1.game
+ sleep 0.1
@p2.game
+ sleep 0.1
@p1.wait_game
+ sleep 0.1
@p2.wait_game
end
def agree
+ sleep 0.1
@p1.agree
+ sleep 0.1
@p2.agree
+ sleep 0.1
@p1.wait_agree
+ sleep 0.1
@p2.wait_agree
end