hlockey 2 → 4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/data/links.yaml ADDED
@@ -0,0 +1,3 @@
1
+ :Website: https://hlockey.onrender.com
2
+ :GitHub: https://github.com/Hlockey
3
+ :Discord: https://discord.gg/2N8VN8Q69E
@@ -0,0 +1,59 @@
1
+ ---
2
+ :vote_amt: 182
3
+ :categories:
4
+ :Bribery (77 votes):
5
+ :Winning bribe:
6
+ :winner: Flavor Text (39 votes)
7
+ :Treasure (65 votes):
8
+ :Vengabus:
9
+ :winner: Pompei Eruptions (1 vote / 16 total)
10
+ :most_votes: Stony Brook Reapers (4 votes)
11
+ :Dave:
12
+ :winner: Orcadas Base Fog (1 vote / 29 total)
13
+ :most_votes: Pompei Eruptions (9 votes)
14
+ :Nice:
15
+ :winner: Kópavogur Seals (1 vote / 15 total)
16
+ :most_votes: Pica Acid (3 votes)
17
+ :Convenient Math Error:
18
+ :winner: Jakarta Architects (1 vote / 5 total)
19
+ :Coaching (40 votes):
20
+ :Antalya Pirates:
21
+ :winner: Please Win Faceoffs (1 vote / 1 total)
22
+ :Baden Hallucinations:
23
+ :winner: Small Gamble (1 vote / 2 total)
24
+ :Kópavogur Seals:
25
+ :winner: Please Block Shots (1 vote / 4 total)
26
+ :Lagos Soup:
27
+ :winner: Big Gamble (4 votes / 8 total)
28
+ :Pica Acid:
29
+ :winner: Please Block Shots (1 vote / 2 total)
30
+ :Dawson City Impostors:
31
+ :winner: Please Win Faceoffs (3 votes / 5 total)
32
+ :Erlangen Ohms:
33
+ :winner: Draft (1 vote / 1 total)
34
+ :Pompei Eruptions:
35
+ :winner: Please Block Shots (1 vote / 1 total)
36
+ :Rio de Janeiro Directors:
37
+ :winner: Please Block Shots (1 vote / 1 total)
38
+ :Wyrzysk Rockets:
39
+ :winner: Please Win Faceoffs (1 vote / 1 total)
40
+ :Cape Town Transplants:
41
+ :winner: Small Gamble (1 vote / 1 total)
42
+ :Manbij Fish:
43
+ :winner: Big Gamble (0 votes / 0 total)
44
+ :Nagqu Paint:
45
+ :winner: Pleaase Win Faceoffs (1 vote / 1 total)
46
+ :Nice Backflippers:
47
+ :winner: Draft (1 vote / 1 total)
48
+ :Orcadas Base Fog:
49
+ :winner: Big Gamble (1 vote / 1 total)
50
+ :Baghdad Abacuses:
51
+ :winner: Small Gamble (0 votes / 0 total)
52
+ :Jakarta Architects:
53
+ :winner: Big Gamble (1 vote / 1 total)
54
+ :Kyoto Payphones:
55
+ :winner: Please Win Faceoffs (1 vote / 2 total)
56
+ :Stony Brook Reapers:
57
+ :winner: Draft (5 votes / 7 total)
58
+ :Sydney Thinkers:
59
+ :winner: Please Block Shots (1 vote / 1 total)
@@ -0,0 +1,4 @@
1
+ module Hlockey
2
+ UPDATE_FREQUENCY_SECONDS = 5
3
+ UPDATES_PER_HOUR = 3600 / UPDATE_FREQUENCY_SECONDS
4
+ end
data/lib/hlockey/data.rb CHANGED
@@ -1,13 +1,17 @@
1
- # frozen_string_literal: true
2
-
3
- require('yaml')
4
-
5
- module Hlockey
6
- # Loads data for the current Hlockey season.
7
- # +category+ can be 'league', 'election', 'information', or 'links'.
8
- # If it is anything else, there will be an error.
9
- def Hlockey.load_data(category)
10
- # If this is only used on data included with the gem, it should be safe
11
- YAML.unsafe_load_file(File.expand_path("data/#{category}.yaml", __dir__))
12
- end
13
- end
1
+ require("hlockey/team") # Class stored in league data
2
+ require("yaml")
3
+
4
+ module Hlockey
5
+ ##
6
+ # Module containing methods to load Hlockey data
7
+ module Data
8
+ class << self
9
+ data_dir = File.expand_path("../../data", __dir__)
10
+
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}") }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ module Hlockey
2
+ class Game
3
+ ##
4
+ # For classes that deal with actions within a Hlockey game.
5
+ # Any class including this must have instance variables indicated by the readers
6
+ module Actions
7
+ # @return [Team] the teams in the game
8
+ attr_reader(:home, :away)
9
+
10
+ # @return [Random] should be the same as the league's
11
+ attr_reader(:prng)
12
+
13
+ # @return [Hash<Symbol => Integer>] the score of each team
14
+ attr_reader(:score)
15
+
16
+ # @return [Boolean] if the sequence of actions is still in progress
17
+ attr_reader(:in_progress)
18
+
19
+ # @param succeed_boost [Numeric] increases chance of action succeeding
20
+ # @param fail_boost [Numeric] decreases chance of action succeeding
21
+ # @return [Boolean] if the action succeeded
22
+ def action_succeeds?(succeed_boost, fail_boost)
23
+ @prng.rand(20) + (succeed_boost - fail_boost) > 9
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,99 @@
1
+ require("hlockey/game/actions")
2
+ require("hlockey/message")
3
+
4
+ module Hlockey
5
+ class Game
6
+ ##
7
+ # A fight within a Hlockey game
8
+ class Fight
9
+ include(Actions)
10
+
11
+ # @return [Hash<Symbol => Array<Player>>] the players in the fight
12
+ attr_reader(:players)
13
+
14
+ # @param game [Game] the game the fight is a part of
15
+ def initialize(game)
16
+ @home = game.home
17
+ @away = game.away
18
+ @prng = game.prng
19
+ @actions = 0
20
+ @players = {
21
+ home: [@home.roster.values.sample(random: @prng)],
22
+ away: [@away.roster.values.sample(random: @prng)]
23
+ }
24
+ @score = { home: 0, away: 0 }
25
+ @in_progress = true
26
+ end
27
+
28
+ # @return [Message] the message to add to the game stream
29
+ def next_action
30
+ @actions += 1
31
+
32
+ case @prng.rand(@actions)
33
+ when 0..3 # attack
34
+ attack
35
+ when 4..7 # player joins
36
+ team_joining = opposite(rand_team)
37
+
38
+ player_joining = get_joining_player(team_joining)
39
+ if player_joining.nil?
40
+ team_joining = opposite(team_joining)
41
+ player_joining = get_joining_player(team_joining)
42
+ return attack if player_joining.nil?
43
+ end
44
+
45
+ @players[team_joining] << player_joining
46
+
47
+ Message.PlayerJoinedFight(send(team_joining), player_joining)
48
+ else # fight ends
49
+ @in_progress = false
50
+
51
+ Message.FightEnded
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ # @return [Message] returned by #next_action for same purpose
58
+ def attack
59
+ attacking_team = rand_team
60
+ defending_team = opposite(attacking_team)
61
+
62
+ attacking_player = @players[attacking_team].sample(random: @prng)
63
+ defending_player = @players[defending_team].sample(random: @prng)
64
+
65
+ blocked = action_succeeds?(defending_player.stats[:defense],
66
+ attacking_player.stats[:offense])
67
+
68
+ @score[attacking_team] += 1 unless blocked
69
+
70
+ Message.FightAttack(attacking_player, defending_player, blocked)
71
+ end
72
+
73
+ # @param team [:home, :away]
74
+ # @return [Player, nil]
75
+ def get_joining_player(team)
76
+ (send(team).roster.values - @players[team]).sample(random: @prng)
77
+ end
78
+
79
+ # @return [:home, :away] randomly selected based on amount of players in fight
80
+ def rand_team
81
+ rand_is_home? ? :home : :away
82
+ end
83
+
84
+ # @param team [:home, :away]
85
+ # @return [:home, :away] :away if `team` is :home, :home if `team` is :away
86
+ def opposite(team)
87
+ team == :home ? :away : :home
88
+ end
89
+
90
+ # @return [Boolean] if randomly selected team is home team
91
+ def rand_is_home?
92
+ home_player_amount = @home.roster.values.length
93
+ away_player_amount = @away.roster.values.length
94
+
95
+ @prng.rand(home_player_amount + away_player_amount) < home_player_amount
96
+ end
97
+ end
98
+ end
99
+ end