class TimeClock
def TimeClock.factory(least_time_per_move, game_name)
- total_time_str = nil
- byoyomi_str = nil
- if (game_name =~ /-(\d+)-(\d+)$/)
- total_time_str = $1
- byoyomi_str = $2
- end
- total_time = total_time_str.to_i
- byoyomi = byoyomi_str.to_i
-
- if (byoyomi_str == "060")
- @time_clock = StopWatchClock.new(least_time_per_move, total_time, byoyomi)
+ time_map = Game.parse_time game_name
+
+ if time_map[:stop_watch]
+ @time_clock = StopWatchClock.new(least_time_per_move, time_map[:total_time], time_map[: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,
+ time_map[:total_time],
+ time_map[:byoyomi],
+ time_map[:fischer])
+ else
+ @time_clock = ChessClock.new(least_time_per_move,
+ time_map[:total_time],
+ time_map[:byoyomi],
+ time_map[:fischer])
+ end
end
+
+ @time_clock
end
- def initialize(least_time_per_move, total_time, byoyomi)
+ def initialize(least_time_per_move, total_time, byoyomi, fischer=0)
@least_time_per_move = least_time_per_move
@total_time = total_time
- @byoyomi = byoyomi
+ @byoyomi = byoyomi
+ @fischer = fischer
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
+ # Returns what "Time_Unit:" in CSA protocol should provide.
+ #
+ def time_unit
+ return "1sec"
+ end
+
# If thinking time runs out, returns true; false otherwise.
#
def timeout?(player, start_time, end_time)
# 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 += @fischer
player.mytime -= t
if (player.mytime < 0)
player.mytime = 0
# Calculates thinking time with chess clock.
#
class ChessClock < TimeClock
- def initialize(least_time_per_move, total_time, byoyomi)
+ def initialize(least_time_per_move, total_time, byoyomi, fischer=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)))
+ if ((player.mytime - t + @byoyomi + @fischer <= 0) &&
+ ((@total_time > 0) || (@byoyomi > 0) || (@fischer > 0)))
return true
else
return false
end
def to_s
- return "ChessClock: LeastTimePerMove %d; TotalTime %d; Byoyomi %d" % [@least_time_per_move, @total_time, @byoyomi]
+ return "ChessClock: LeastTimePerMove %d; TotalTime %d; Byoyomi %d; Fischer" %
+ [@least_time_per_move, @total_time, @byoyomi, @fischer]
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, fischer=0)
+ if least_time_per_move != 0
+ raise ArgumentError, "least_time_per_move #{least_time_per_move} should be 0."
+ end
+ super
+ end
+
+ def to_s
+ return "ChessClockWithLeastZero: LeastTimePerMove %d; TotalTime %d; Byoyomi %d; Fischer %d" %
+ [@least_time_per_move, @total_time, @byoyomi, @fischer]
+ end
+end
+
+# StopWatchClock does not support Fischer time.
+#
class StopWatchClock < TimeClock
def initialize(least_time_per_move, total_time, byoyomi)
- super
+ super least_time_per_move, total_time, byoyomi, 0
+ end
+
+ def time_unit
+ 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