+ #
+ #
+ class DeleteBuoyCommand < Command
+ def initialize(str, player, game_name)
+ super(str, player)
+ @game_name = game_name
+ end
+
+ def call
+ buoy = Buoy.new
+ buoy_game = buoy.get_game(@game_name)
+ if buoy_game.instance_of?(NilBuoyGame)
+ @player.write_safe(sprintf("##[ERROR] buoy game not found: %s\n", @game_name))
+ log_error "Game name not found: %s by %s" % [@game_name, @player.name]
+ return :continue
+ end
+
+ if buoy_game.owner != @player.name
+ @player.write_safe(sprintf("##[ERROR] you are not allowed to delete a buoy game that you did not set: %s\n", @game_name))
+ log_error "%s are not allowed to delete a game: %s" % [@player.name, @game_name]
+ return :continue
+ end
+
+ buoy.delete_game(buoy_game)
+ @player.write_safe(sprintf("##[DELETEBUOY] +OK\n"))
+ log_info("A buoy game was deleted: %s" % [@game_name])
+ return :continue
+ end
+ end
+
+ #
+ #
+ class GetBuoyCountCommand < Command
+ def initialize(str, player, game_name)
+ super(str, player)
+ @game_name = game_name
+ end
+
+ def call
+ buoy = Buoy.new
+ buoy_game = buoy.get_game(@game_name)
+ if buoy_game.instance_of?(NilBuoyGame)
+ @player.write_safe("##[GETBUOYCOUNT] -1\n")
+ else
+ @player.write_safe("##[GETBUOYCOUNT] %s\n" % [buoy_game.count])
+ end
+ @player.write_safe("##[GETBUOYCOUNT] +OK\n")
+ return :continue
+ end
+ end
+
+ # %%FORK <source_game> <new_buoy_game> [<nth-move>]
+ # Fork a new game from the posistion where the n-th (starting from 1) move
+ # of a source game is played. The new game should be a valid buoy game
+ # name. The default value of n is the position where the previous position
+ # of the last one.
+ #
+ class ForkCommand < Command
+ def initialize(str, player, source_game, new_buoy_game, nth_move)
+ super(str, player)
+ @source_game = source_game
+ @new_buoy_game = new_buoy_game
+ @nth_move = nth_move # may be nil
+ end
+ attr_reader :new_buoy_game
+
+ def decide_new_buoy_game_name
+ name = nil
+ total_time = nil
+ byo_time = nil
+
+ if @source_game.split("+").size >= 2 &&
+ /^([^-]+)-(\d+)-(\d+)/ =~ @source_game.split("+")[1]
+ name = $1
+ total_time = $2
+ byo_time = $3
+ end
+ if name == nil || total_time == nil || byo_time == nil
+ @player.write_safe(sprintf("##[ERROR] wrong source game name to make a new buoy game name: %s\n", @source_game))
+ log_error "Received a wrong source game name to make a new buoy game name: %s from %s." % [@source_game, @player.name]
+ return :continue
+ end
+ @new_buoy_game = "buoy_%s_%d-%s-%s" % [name, @nth_move, total_time, byo_time]
+ @player.write_safe(sprintf("##[FORK]: new buoy game name: %s\n", @new_buoy_game))
+ @player.write_safe("##[FORK] +OK\n")
+ end
+
+ def call
+ game = $league.games[@source_game]
+ unless game
+ @player.write_safe(sprintf("##[ERROR] wrong source game name: %s\n", @source_game))
+ log_error "Received a wrong source game name: %s from %s." % [@source_game, @player.name]
+ return :continue
+ end
+
+ moves = game.read_moves # [["+7776FU","T2"],["-3334FU","T5"]]
+ @nth_move = moves.size - 1 unless @nth_move
+ if @nth_move > moves.size or @nth_move < 1
+ @player.write_safe(sprintf("##[ERROR] number of moves to fork is out of range: %s.\n", moves.size))
+ log_error "Number of moves to fork is out of range: %s [%s]" % [@nth_move, @player.name]
+ return :continue
+ end
+ new_moves_str = ""
+ moves[0...@nth_move].each do |m|
+ new_moves_str << m.join(",")
+ end
+
+ unless @new_buoy_game
+ decide_new_buoy_game_name
+ end
+
+ buoy_cmd = SetBuoyCommand.new(@str, @player, @new_buoy_game, new_moves_str, 1)
+ return buoy_cmd.call
+ end
+ end