module DefduelGame
Constants
- PLUGIN
- ROUNDS
- STYLE_TITLE
Public Instance Methods
Source
# File lib/defduel_game.rb, line 153 def format_final(game) scores = game["scores"] || {} a = scores[game["challenger"]].to_i b = scores[game["target"]].to_i winner = if a > b game["challenger"] elsif b > a game["target"] else "tie" end lines = [format_header("Final")] lines << "#{game['challenger']}: #{a} ยท #{game['target']}: #{b}" lines << (winner == "tie" ? "Tie game!" : "Winner: #{winner}") lines << IrcFormat.report_footer("#{ROUNDS} rounds") lines.join("\n") end
Source
# File lib/defduel_game.rb, line 171 def format_header(title) IrcFormat.report_header(tag: "DUEL", title: title, style: STYLE_TITLE) end
Source
# File lib/defduel_game.rb, line 175 def format_status(game) return format_header("No game") + "\nNo definition duel active." unless game lines = [format_header("#{game['challenger']} vs #{game['target']} ยท round #{game['round']}")] lines << "Stage: #{game['stage']}" lines << IrcFormat.report_footer("definition duel") lines.join("\n") end
Source
# File lib/defduel_game.rb, line 37 def parse_command(text) base = AsyncDuel.parse_base(text, usage: usage_message) return base unless base[:action] == :unknown parts = base[:tail] case parts[0].downcase when "define" return { error: usage_message } if parts.length < 2 { action: :define, text: parts[1..].join(" ") } when "pick" return { error: usage_message } if parts.length < 2 num = parts[1].to_i return { error: "Pick 1, 2, or 3." } unless (1..3).include?(num) { action: :pick, choice: num } else { error: usage_message } end end
Source
# File lib/defduel_game.rb, line 148 def score_message(game) scores = game["scores"] || {} "#{format_header('Round score')}\n#{game['challenger']}: #{scores[game['challenger']]} ยท #{game['target']}: #{scores[game['target']]}\nReal answer was ##{game['last_answer']}" end
Source
# File lib/defduel_game.rb, line 138 def score_round(game) answer = game["answer_index"].to_i + 1 scores = game["scores"] || { game["challenger"] => 0, game["target"] => 0 } game["picks"].each do |player, pick| scores[player] = scores[player].to_i + (pick == answer ? 1 : 0) end game["scores"] = scores game["last_answer"] = answer end
Source
# File lib/defduel_game.rb, line 99 def shuffle_options(game, rand: ->(max) { Random.rand(0...max) }) real = game["entry"][:definition] fakes = game["definitions"].values list = [real, *fakes] shuffled = list.dup (shuffled.length - 1).downto(1) do |i| j = rand.call(i + 1) shuffled[i], shuffled[j] = shuffled[j], shuffled[i] end game["answer_index"] = shuffled.index(real) shuffled end
Source
# File lib/defduel_game.rb, line 59 def start_round(game, rand: ->(max) { Random.rand(0...max) }) entry = DefduelWords.pick(rand: rand) game = game.dup round = (game["round"].to_i + 1) game["round"] = round game["stage"] = "define" game["entry"] = entry game["definitions"] = {} game["picks"] = {} { game: game, message: "#{format_header("Round #{round}")}\nWord: #{entry[:word]}\nBoth players: !defduel define <fake definition>" } end
Source
# File lib/defduel_game.rb, line 74 def submit_definition(game:, user:, text:) return { error: "Not accepting definitions." } unless game && game["stage"] == "define" return { error: "You are not in this game." } unless AsyncDuel.player?(game, user) definition = text.to_s.strip return { error: "Definition cannot be empty." } if definition.empty? game = game.dup defs = (game["definitions"] || {}).dup key = GameStore.norm_nick(user) return { error: "You already submitted." } if defs[key] defs[key] = definition game["definitions"] = defs if defs.size >= 2 game["stage"] = "pick" game["options"] = shuffle_options(game, rand: ->(max) { Random.rand(0...max) }) opts = game["options"].each_with_index.map { |d, i| "#{i + 1}. #{d}" }.join("\n") { game: game, message: "#{format_header('Pick the real one')}\n#{opts}\n!defduel pick <1-3>" } else { game: game, message: "Definition recorded." } end end
Source
# File lib/defduel_game.rb, line 112 def submit_pick(game:, user:, choice:) return { error: "Not in picking phase." } unless game && game["stage"] == "pick" return { error: "You are not in this game." } unless AsyncDuel.player?(game, user) game = game.dup picks = (game["picks"] || {}).dup key = GameStore.norm_nick(user) return { error: "You already picked." } if picks[key] picks[key] = choice game["picks"] = picks if picks.size >= 2 score_round(game) if game["round"].to_i >= ROUNDS game["stage"] = "done" { game: game, message: format_final(game), done: true } else start = start_round(game) { game: start[:game], message: score_message(game) + "\n" + start[:message] } end else { game: game, message: "Pick recorded." } end end
Source
# File lib/defduel_game.rb, line 33 def usage_message "Usage: !defduel challenge <nick> | accept | decline | define <fake definition> | pick <1-3> | status" end