hlockey 5 → 7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/data/election.json +23 -0
  3. data/data/infinileague.json +189 -0
  4. data/data/information.json +6 -0
  5. data/data/league.json +2042 -0
  6. data/data/links.json +5 -0
  7. data/data/messages.json +46 -0
  8. data/data/previous_election_results.json +91 -0
  9. data/lib/hlockey/actions.rb +22 -0
  10. data/lib/hlockey/data.rb +6 -5
  11. data/lib/hlockey/game/fight.rb +100 -40
  12. data/lib/hlockey/game/weather/audacity.rb +1 -1
  13. data/lib/hlockey/game/weather/chicken.rb +3 -2
  14. data/lib/hlockey/game/weather/incline.rb +2 -1
  15. data/lib/hlockey/game/weather/stars.rb +1 -1
  16. data/lib/hlockey/game/weather/sunset.rb +2 -4
  17. data/lib/hlockey/game/weather/waves.rb +9 -5
  18. data/lib/hlockey/game/weather/weatherable.rb +9 -9
  19. data/lib/hlockey/game.rb +182 -116
  20. data/lib/hlockey/league.rb +90 -73
  21. data/lib/hlockey/message.rb +23 -153
  22. data/lib/hlockey/mod/fencebuilder.rb +15 -0
  23. data/lib/hlockey/mod/fencedestroyer.rb +16 -0
  24. data/lib/hlockey/mod/handholding.rb +57 -0
  25. data/lib/hlockey/mod/immaterial.rb +28 -0
  26. data/lib/hlockey/mod/locked.rb +28 -0
  27. data/lib/hlockey/mod/moddable.rb +70 -0
  28. data/lib/hlockey/mod/nonconfrontational.rb +17 -0
  29. data/lib/hlockey/mod/powernapper.rb +50 -0
  30. data/lib/hlockey/mod/punchy.rb +21 -0
  31. data/lib/hlockey/mod.rb +25 -0
  32. data/lib/hlockey/selfdescribable.rb +7 -0
  33. data/lib/hlockey/team/player.rb +40 -58
  34. data/lib/hlockey/team/stadium.rb +10 -7
  35. data/lib/hlockey/team.rb +56 -41
  36. data/lib/hlockey/utils.rb +36 -4
  37. data/lib/hlockey/version.rb +1 -1
  38. data/lib/hlockey.rb +15 -0
  39. metadata +30 -18
  40. data/data/election.yaml +0 -21
  41. data/data/external/names.txt +0 -19948
  42. data/data/information.yaml +0 -24
  43. data/data/league.yaml +0 -1694
  44. data/data/links.yaml +0 -3
  45. data/data/previous_election_results.yaml +0 -65
  46. data/lib/hlockey/game/actions.rb +0 -24
data/data/links.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "Website": "https://hlockey.gay",
3
+ "Source Code": "https://codeberg.org/LavenderPerry/hlockey",
4
+ "Discord": "https://discord.gg/2N8VN8Q69E"
5
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "season_day": "Season %{season} day %{day}",
3
+ "season_starts": "Season %{season} starts at %{time}.",
4
+ "season_champion": "Your season %{season} champions are the %{team}!",
5
+ "season_off": "no games right now. it is the offseason. join the Hlockey Discord for updates.",
6
+
7
+ "game_start": "Hocky!",
8
+ "game_end": "Game over.\n%{winning_team} win!",
9
+ "game_score": "%{home} %{home_score}, %{away} %{away_score}",
10
+ "game_period_start": "Start of period %{period}.",
11
+ "game_period_end": "End of period %{period}.",
12
+ "game_faceoff": "%{winning_player} wins the faceoff!",
13
+ "game_pass": "%{sender} passes to %{receiver}.",
14
+ "game_pass_intercept": "%{sender}'s pass to %{receiver} is intercepted by %{interceptor}!",
15
+ "game_hit": "%{defender} hits %{puck_holder}.",
16
+ "game_shot": "%{shooter} takes a shot...",
17
+ "game_shot_audacious": "%{shooter} takes an audacious shot...",
18
+ "game_shot_scored": "%{shooter} scores!",
19
+ "game_shot_blocked": "%{blocker} blocks the shot.",
20
+ "game_partying": "%{player} is partying!",
21
+ "game_possession_change": "%{player} takes the puck!\n%{new_puck_team} have possession.",
22
+
23
+ "fight_start": "%{home_player} and %{away_player} start fighting!",
24
+ "fight_player_join": "%{player} from %{team} joins the fight!",
25
+ "fight_player_withdraw": "%{player} withdraws from the fight!",
26
+ "fight_attack": "%{player} is going for a punch...",
27
+ "fight_hit": "The punch lands to hit %{player}!",
28
+ "fight_block": "%{player} blocks the punch!",
29
+ "fight_dodge": "%{player} dodges the punch!",
30
+ "fight_end": "The fight has ended.",
31
+ "fight_end_morale_gain": "%{team} gains %{num} morale.",
32
+ "fight_end_morale_loss": "%{team} loses %{num} morale.",
33
+
34
+ "weather_chicken_event": "%{prev_player} chickened out!\nReplaced by %{next_player} for the game.",
35
+ "weather_incline_event": "The incline favors %{team}.",
36
+ "weather_stars_event": "The stars align for %{team}. They get half a goal.",
37
+ "weather_waves_event": "%{prev_player} is washed away by the waves...\nReplaced by %{next_player} for the season.",
38
+
39
+ "mod_immaterial_event": "%{hitting_player} goes right through %{player}!",
40
+ "mod_fence_event": "%{player} is a fence%{type}.\n%{player} swaps with %{swap_player} instead.",
41
+ "mod_handholding_event": "%{player} is holding %{other_player}'s hand.\n%{other_player} follows %{player} by swapping with %{swap_player}.",
42
+ "mod_locked_event": "%{player} is locked and does not get swapped with %{swap_player}",
43
+ "mod_powernap_start": "%{player} gets a boost from powernapping!",
44
+ "mod_powernap_end": "%{player}'s powernap boost has ended.",
45
+ "mod_punchy_event": "%{player} is looking for a fight..."
46
+ }
@@ -0,0 +1,91 @@
1
+ {
2
+ "vote_amt": 91,
3
+ "categories": {
4
+ "Treasure (64 votes)": {
5
+ "Dave": {
6
+ "winner": "Cape Town Transplants (2 votes / 7 total)"
7
+ },
8
+ "Nice": {
9
+ "winner": "Stony Brook Reapers (1 vote / 15 total)",
10
+ "most_votes": "Dawson City Impostors (9 votes)"
11
+ },
12
+ "Vengabus": {
13
+ "winner": "Stony Brook Reapers (1 vote / 11 total)",
14
+ "most_votes": "Rio de Janeiro Directors (4 votes)"
15
+ },
16
+ "Shared Training": {
17
+ "winner": "Pompei Eruptions (Dry Warm) (1 votes / 15 total)",
18
+ "most_votes": "Kyoto Payphones (3 votes)"
19
+ },
20
+ "Theft": {
21
+ "winner": "Baden Hallucinations (1 vote / 14 total)",
22
+ "most_votes": "Rio de Janeiro Directors (3 votes)"
23
+ },
24
+ "Shadow Lock": {
25
+ "winner": "Nagqu Paint (2 votes / 2 total)"
26
+ }
27
+ },
28
+ "Coaching (27 votes)": {
29
+ "Antalya Pirates": {
30
+ "winner": "Draft (1 vote / 1 total)"
31
+ },
32
+ "Baden Hallucinations": {
33
+ "winner": "Draft (2 votes / 2 total)"
34
+ },
35
+ "Kópavogur Seals": {
36
+ "winner": "Please Block Shots (0 votes / 0 total)"
37
+ },
38
+ "Lagos Soup": {
39
+ "winner": "Small Gamble (0 votes / 0 total)"
40
+ },
41
+ "Pica Acid": {
42
+ "winner": "Big Gamble (0 votes / 0 total)"
43
+ },
44
+ "Dawson City Impostors": {
45
+ "winner": "Please Block Shots (2 votes / 5 total)"
46
+ },
47
+ "Erlangen Ohms": {
48
+ "winner": "Clock Wise (1 vote / 1 total)"
49
+ },
50
+ "Pompei Eruptions": {
51
+ "winner": "Please Win Faceoffs (1 vote / 1 total)"
52
+ },
53
+ "Rio de Janeiro Directors": {
54
+ "winner": "Please Win Faceoffs (3 votes / 3 total)"
55
+ },
56
+ "Wyrzysk Rockets": {
57
+ "winner": "Revolution (0 votes / 0 total)"
58
+ },
59
+ "Cape Town Transplants": {
60
+ "winner": "Small Gamble (0 votes / 0 total)"
61
+ },
62
+ "Manbij Fish": {
63
+ "winner": "Clock Wise (0 votes / 0 total)"
64
+ },
65
+ "Nagqu Paint": {
66
+ "winner": "Please Win Faceoffs (1 vote / 1 total)"
67
+ },
68
+ "Nice Backflippers": {
69
+ "winner": "Please Block Shots (1 vote / 1 total)"
70
+ },
71
+ "Orcadas Base Fog": {
72
+ "winner": "Small Gamble (1 vote / 1 total)"
73
+ },
74
+ "Baghdad Abacuses": {
75
+ "winner": "Please Win Faceoffs (0 votes / 0 total)"
76
+ },
77
+ "Jakarta Architects": {
78
+ "winner": "Please Win Faceoffs (0 votes / 0 total)"
79
+ },
80
+ "Kyoto Payphones": {
81
+ "winner": "Big Gamble (6 votes / 6 total)"
82
+ },
83
+ "Stony Brook Reapers": {
84
+ "winner": "Clock Unwise (1 vote / 1 total)"
85
+ },
86
+ "Sydney Thinkers": {
87
+ "winner": "Draft (3 votes / 4 total)"
88
+ }
89
+ }
90
+ }
91
+ }
@@ -0,0 +1,22 @@
1
+ require("hlockey/constants")
2
+
3
+ module Hlockey
4
+ ##
5
+ # For classes that deal with actions within a Hlockey game.
6
+ module Actions
7
+ private
8
+
9
+ # For an event that should happen randomly about a certain amount of times per game,
10
+ # returns if the event should happen or not. Should be called once per action.
11
+ # @param times [Integer] the approximate amount of times the event should occur
12
+ # @return [Boolean] if the event should occur
13
+ def random_event_occurs?(times = 1, prng: @prng) =
14
+ prng.rand(NON_OT_ACTIONS / times).zero?
15
+
16
+ # @param succeed_boost [Numeric] increases chance of action succeeding
17
+ # @param fail_boost [Numeric] decreases chance of action succeeding
18
+ # @return [Boolean] if the action succeeded
19
+ def action_succeeds?(succeed_boost, fail_boost, prng: @prng) =
20
+ prng.rand(20) + (succeed_boost - fail_boost) > 9
21
+ end
22
+ end
data/lib/hlockey/data.rb CHANGED
@@ -1,5 +1,4 @@
1
- require("hlockey/team") # Classes stored in league data
2
- require("yaml")
1
+ require("json")
3
2
 
4
3
  module Hlockey
5
4
  ##
@@ -8,9 +7,11 @@ module Hlockey
8
7
  class << self
9
8
  data_dir = File.expand_path("../../data", __dir__)
10
9
 
11
- Dir.glob("*.yaml", base: data_dir).each do |data_file|
12
- category = File.basename(data_file, ".yaml")
13
- define_method(category) { YAML.unsafe_load_file("#{data_dir}/#{data_file}") }
10
+ Dir.glob("*.json", base: data_dir).each do |data_file|
11
+ # @return [Hash] loaded data
12
+ define_method(File.basename(data_file, ".json")) do
13
+ JSON.parse(File.read("#{data_dir}/#{data_file}"), symbolize_names: true)
14
+ end
14
15
  end
15
16
  end
16
17
  end
@@ -1,5 +1,6 @@
1
- require("hlockey/game/actions")
1
+ require("hlockey/actions")
2
2
  require("hlockey/message")
3
+ require("hlockey/mod/punchy")
3
4
 
4
5
  module Hlockey
5
6
  class Game
@@ -8,30 +9,43 @@ module Hlockey
8
9
  class Fight
9
10
  include(Actions)
10
11
 
11
- # @return [Hash<Symbol => Array<Player>>] the players in the fight
12
+ # @return [Hash<Symbol => Array<Team::Player>>] the players in the fight
12
13
  attr_reader(:players)
13
14
 
14
15
  # @return [Hash<Symbol => Integer>] the amount of successful punches for each team
15
16
  attr_reader(:score)
16
17
 
17
18
  # @param game [Game] the game the fight is a part of
18
- def initialize(game)
19
- @home = game.home
20
- @away = game.away
21
- @prng = game.prng
19
+ # @param starting_player [Team::Player] the player that started the fight, if any
20
+ def initialize(game, starting_player = nil)
21
+ @game = game
22
22
  @actions = 0
23
- @players = {
24
- home: [@home.roster.values.sample(random: @prng)],
25
- away: [@away.roster.values.sample(random: @prng)]
26
- }
23
+ @players = { home: [], away: [] }
24
+ @players.each_key do |team|
25
+ add_player(if @game.send(team).roster.value?(starting_player)
26
+ starting_player
27
+ else
28
+ get_joining_player(team)
29
+ end,
30
+ team)
31
+ end
32
+
27
33
  @score = { home: 0, away: 0 }
28
34
  end
29
35
 
30
- # @return [Message] the message to add to the game stream
31
36
  def next_action
32
37
  @actions += 1
33
38
 
34
- case @prng.rand(@actions)
39
+ # If fight has a single player on one side who is outnumbered,
40
+ # there is a chance that player will withdraw, ending the fight.
41
+ if @players[:home].length == 1
42
+ return if @players[:away].length > 1 && player_withdraws?(@players[:home].first,
43
+ :home)
44
+ elsif @players[:away].length == 1
45
+ return if player_withdraws?(@players[:away].first, :away)
46
+ end
47
+
48
+ case @game.prng.rand(@actions)
35
49
  when 0..3 # attack
36
50
  attack
37
51
  when 4..7 # player joins
@@ -41,62 +55,108 @@ module Hlockey
41
55
  if player_joining.nil?
42
56
  team_joining = opposite(team_joining)
43
57
  player_joining = get_joining_player(team_joining)
44
- return attack if player_joining.nil?
58
+ if player_joining.nil?
59
+ attack
60
+ return
61
+ end
45
62
  end
46
63
 
47
- @players[team_joining] << player_joining
48
-
49
- Message.PlayerJoinedFight(send(team_joining), player_joining)
64
+ add_player(player_joining, team_joining)
50
65
  else # fight ends
51
- Message.FightEnded
66
+ @game.stream << Message.new(:fight_end)
52
67
  end
53
68
  end
54
69
 
55
70
  private
56
71
 
57
- # private readers so #send works
58
- # @return [Team] a team in the fight
59
- attr_reader(:home, :away)
60
-
61
- # @return [Message] returned by #next_action for same purpose
62
72
  def attack
63
73
  attacking_team = rand_team
64
74
  defending_team = opposite(attacking_team)
65
75
 
66
- attacking_player = @players[attacking_team].sample(random: @prng)
67
- defending_player = @players[defending_team].sample(random: @prng)
76
+ attacking_player = @players[attacking_team].sample(random: @game.prng)
77
+ @game.stream << Message.new(:fight_attack, player: attacking_player)
78
+
79
+ defending_player = @players[defending_team].sample(random: @game.prng)
80
+
81
+ if action_succeeds?(defending_player.stats[:defense],
82
+ defending_player.stats[:agility],
83
+ prng: @game.prng)
84
+ # Try to block the punch
85
+ if action_succeeds?(defending_player.stats[:defense],
86
+ attacking_player.stats[:offense],
87
+ prng: @game.prng)
88
+ # Punch sucessfully blocked
89
+ @game.stream << Message.new(:fight_block, player: defending_player)
90
+ return
91
+ end
92
+ # Try to dodge the punch
93
+ elsif action_succeeds?(defending_player.stats[:agility],
94
+ attacking_player.stats[:offense],
95
+ prng: @game.prng)
96
+ # Punch sucessfully dodged
97
+ @game.stream << Message.new(:fight_dodge, player: defending_player)
98
+ return
99
+ end
68
100
 
69
- blocked = action_succeeds?(defending_player.stats[:defense],
70
- attacking_player.stats[:offense])
101
+ # Punch lands
102
+ @game.stream << Message.new(:fight_hit, player: defending_player)
103
+ @score[attacking_team] += 1
104
+ player_withdraws?(defending_player, defending_team)
105
+ end
71
106
 
72
- @score[attacking_team] += 1 unless blocked
107
+ # @param team [:home, :away]
108
+ # @return [Team::Player, nil]
109
+ def get_joining_player(team) =
110
+ (@game.send(team).roster.values - @players[team]).sample(random: @game.prng)
111
+
112
+ # @param player [Team::Player]
113
+ # @param team [:home, :away]
114
+ def add_player(player, team)
115
+ @game.stream << Message.new(:fight_player_join, player:, team: player.team)
116
+
117
+ mods_res = player.mods_do(:on_join_fight)
118
+ if mods_res # Mod would return a joining player to replace them
119
+ @game.stream << Message.new(:fight_player_withdraw, player:)
120
+ player = mods_res
121
+ @game.stream << Message.new(:fight_player_join, player:, team: player.team)
122
+ end
73
123
 
74
- Message.FightAttack(attacking_player, defending_player, blocked)
124
+ @players[team] << player
75
125
  end
76
126
 
127
+ # @param player [Team::Player]
77
128
  # @param team [:home, :away]
78
- # @return [Player, nil]
79
- def get_joining_player(team)
80
- (send(team).roster.values - @players[team]).sample(random: @prng)
129
+ # @return [Boolean] if the player withdrew
130
+ def player_withdraws?(player, team)
131
+ return false unless player.mods.none? { _1.is_a?(Mod::Punchy) } &&
132
+ @game.prng.rand(50).zero?
133
+
134
+ # Player withdraws
135
+ @game.stream << Message.new(:fight_player_withdraw, player:)
136
+ @players[team].delete(player)
137
+
138
+ if @players[team].empty?
139
+ @game.stream << Message.new(:fight_end)
140
+ @score[team] = 0
141
+ @score[opposite(team)] = 10
142
+ end
143
+
144
+ true
81
145
  end
82
146
 
83
147
  # @return [:home, :away] randomly selected based on amount of players in fight
84
- def rand_team
85
- rand_is_home? ? :home : :away
86
- end
148
+ def rand_team = rand_is_home? ? :home : :away
87
149
 
88
150
  # @param team [:home, :away]
89
151
  # @return [:home, :away] :away if `team` is :home, :home if `team` is :away
90
- def opposite(team)
91
- team == :home ? :away : :home
92
- end
152
+ def opposite(team) = team == :home ? :away : :home
93
153
 
94
154
  # @return [Boolean] if randomly selected team is home team
95
155
  def rand_is_home?
96
- home_player_amount = @home.roster.values.length
97
- away_player_amount = @away.roster.values.length
156
+ home_player_amount = @game.home.roster.values.length
157
+ away_player_amount = @game.away.roster.values.length
98
158
 
99
- @prng.rand(home_player_amount + away_player_amount) < home_player_amount
159
+ @game.prng.rand(home_player_amount + away_player_amount) < home_player_amount
100
160
  end
101
161
  end
102
162
  end
@@ -1,5 +1,5 @@
1
1
  require("hlockey/game/weather/weatherable")
2
- require("hlockey/game/actions")
2
+ require("hlockey/actions")
3
3
 
4
4
  module Hlockey
5
5
  class Game
@@ -1,5 +1,5 @@
1
1
  require("hlockey/game/weather/weatherable")
2
- require("hlockey/game/actions")
2
+ require("hlockey/actions")
3
3
  require("hlockey/message")
4
4
 
5
5
  module Hlockey
@@ -29,7 +29,8 @@ module Hlockey
29
29
 
30
30
  @chickened_out[team][pos] = shadows_idx
31
31
 
32
- @game.stream << Message.ChickenedOut(*swap(team, pos, shadows_idx))
32
+ @game.stream << Message.new(:weather_chicken_event,
33
+ **swap(team, pos, shadows_idx))
33
34
  end
34
35
 
35
36
  def on_game_end
@@ -24,7 +24,8 @@ module Hlockey
24
24
  def on_action
25
25
  return unless @incline_changed
26
26
 
27
- @game.stream << Message.InclineFavors(@game.send(@favored_team))
27
+ @game.stream << Message.new(:weather_incline_event,
28
+ team: @game.send(@favored_team))
28
29
  @incline_changed = false
29
30
  end
30
31
 
@@ -15,7 +15,7 @@ module Hlockey
15
15
 
16
16
  team = @game.score.min_by { |_, v| v }.first
17
17
  @game.score[team] += 0.5
18
- @game.stream << Message.StarsAlign(@game.send(team))
18
+ @game.stream << Message.new(:weather_stars_event, team: @game.send(team))
19
19
  end
20
20
  end
21
21
  end
@@ -9,13 +9,11 @@ module Hlockey
9
9
  class Sunset
10
10
  include(Weatherable)
11
11
 
12
- def on_game_start
13
- @score_amt = { home: 0, away: 0 }
14
- end
12
+ def on_game_start = @score_amt = { home: 0, away: 0 }
15
13
 
16
14
  def on_goal(scoring_team)
17
15
  @score_amt[scoring_team] += 1
18
- @game.score[scoring_team] -= @score_amt[scoring_team] * 0.2
16
+ @game.score[scoring_team] -= @score_amt[scoring_team] * 0.3
19
17
  end
20
18
  end
21
19
  end
@@ -1,5 +1,5 @@
1
1
  require("hlockey/game/weather/weatherable")
2
- require("hlockey/game/actions")
2
+ require("hlockey/actions")
3
3
  require("hlockey/message")
4
4
 
5
5
  module Hlockey
@@ -7,7 +7,7 @@ module Hlockey
7
7
  module Weather
8
8
  ##
9
9
  # Waves weather
10
- # Swaps the worst roster player with a random shadow player permanently
10
+ # Swaps a roster player (worst most likely) with a random shadow player permanently
11
11
  class Waves
12
12
  include(Weatherable)
13
13
  include(Actions)
@@ -17,9 +17,13 @@ module Hlockey
17
17
 
18
18
  team_sym = rand_team
19
19
  team = @game.send(team_sym)
20
- @game.stream << Message.WavesWashedAway(*swap(team_sym,
21
- team.worst_player_pos,
22
- @prng.rand(team.shadows.length)))
20
+ player_leaving_pos = if @prng.rand(5).zero?
21
+ team.roster.keys.sample(random: @prng)
22
+ else
23
+ team.worst_player_pos
24
+ end
25
+ swap_res = swap(team_sym, player_leaving_pos, @prng.rand(team.shadows.length))
26
+ @game.stream << Message.new(:weather_waves_event, **swap_res)
23
27
  end
24
28
  end
25
29
  end
@@ -1,4 +1,5 @@
1
1
  require("hlockey/constants")
2
+ require("hlockey/selfdescribable")
2
3
 
3
4
  module Hlockey
4
5
  class Game
@@ -7,6 +8,8 @@ module Hlockey
7
8
  # Module with needed methods for weathers, that every weather includes
8
9
  # All methods starting with "on" represent game events weathers may respond to
9
10
  module Weatherable
11
+ include(SelfDescribable)
12
+
10
13
  def initialize(game)
11
14
  @game = game
12
15
  @home = @game.home
@@ -14,10 +17,6 @@ module Hlockey
14
17
  @prng = @game.prng
15
18
  end
16
19
 
17
- def to_s
18
- self.class.to_s.split("::").last
19
- end
20
-
21
20
  def on_game_start() end
22
21
 
23
22
  def on_game_end() end
@@ -34,7 +33,7 @@ module Hlockey
34
33
  # @param team_sym [:home, :away]
35
34
  # @param pos [Symbol] position of roster player swapped out
36
35
  # @param shadows_idx [Integer] index of shadows player swapped in
37
- # @return [Array<Player>] the players that were swapped
36
+ # @return [Hash<[:prev_player, :next_player] => Team::Player>] the swapped players
38
37
  def swap(team_sym, pos, shadows_idx)
39
38
  team = @game.send(team_sym)
40
39
 
@@ -50,13 +49,14 @@ module Hlockey
50
49
  player_array[player_idx] = next_player unless player_idx.nil?
51
50
  end
52
51
 
53
- [prev_player, next_player]
52
+ prev_player.mods_do(:on_swap, false, shadows_idx, pos)
53
+ next_player.mods_do(:on_swap, true, pos, shadows_idx)
54
+
55
+ { prev_player:, next_player: }
54
56
  end
55
57
 
56
58
  # @return [:home, :away]
57
- def rand_team
58
- @prng.rand(2).zero? ? :home : :away
59
- end
59
+ def rand_team = @prng.rand(2).zero? ? :home : :away
60
60
  end
61
61
  end
62
62
  end