rubygoal-core 1.0.0

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.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +18 -0
  3. data/README.md +85 -0
  4. data/bin/rubygoal +15 -0
  5. data/lib/rubygoal.rb +1 -0
  6. data/lib/rubygoal/ball.rb +60 -0
  7. data/lib/rubygoal/coach.rb +81 -0
  8. data/lib/rubygoal/coach_definition.rb +54 -0
  9. data/lib/rubygoal/coach_loader.rb +55 -0
  10. data/lib/rubygoal/coaches/coach_definition_away.rb +72 -0
  11. data/lib/rubygoal/coaches/coach_definition_home.rb +76 -0
  12. data/lib/rubygoal/configuration.rb +49 -0
  13. data/lib/rubygoal/coordinate.rb +33 -0
  14. data/lib/rubygoal/field.rb +134 -0
  15. data/lib/rubygoal/formation.rb +73 -0
  16. data/lib/rubygoal/formation/formation_dsl.rb +67 -0
  17. data/lib/rubygoal/game.rb +162 -0
  18. data/lib/rubygoal/goal.rb +26 -0
  19. data/lib/rubygoal/match_data.rb +130 -0
  20. data/lib/rubygoal/moveable.rb +67 -0
  21. data/lib/rubygoal/player.rb +87 -0
  22. data/lib/rubygoal/players/average.rb +16 -0
  23. data/lib/rubygoal/players/captain.rb +15 -0
  24. data/lib/rubygoal/players/fast.rb +16 -0
  25. data/lib/rubygoal/players/goalkeeper.rb +26 -0
  26. data/lib/rubygoal/players/player_movement.rb +98 -0
  27. data/lib/rubygoal/recorder.rb +56 -0
  28. data/lib/rubygoal/simulator.rb +33 -0
  29. data/lib/rubygoal/team.rb +198 -0
  30. data/lib/rubygoal/teams/away.rb +15 -0
  31. data/lib/rubygoal/teams/home.rb +15 -0
  32. data/lib/rubygoal/util.rb +36 -0
  33. data/lib/rubygoal/version.rb +3 -0
  34. data/test/ball_test.rb +56 -0
  35. data/test/coach_test.rb +49 -0
  36. data/test/field_test.rb +103 -0
  37. data/test/fixtures/four_fast_players_coach_definition.rb +27 -0
  38. data/test/fixtures/less_players_coach_definition.rb +25 -0
  39. data/test/fixtures/mirror_strategy_coach_definition.rb +42 -0
  40. data/test/fixtures/more_players_coach_definition.rb +27 -0
  41. data/test/fixtures/test_away_coach_definition.rb +34 -0
  42. data/test/fixtures/test_home_coach_definition.rb +34 -0
  43. data/test/fixtures/two_captains_coach_definition.rb +27 -0
  44. data/test/fixtures/valid_coach_definition.rb +26 -0
  45. data/test/formation_test.rb +81 -0
  46. data/test/game_test.rb +84 -0
  47. data/test/match_data_test.rb +149 -0
  48. data/test/player_test.rb +125 -0
  49. data/test/players/goalkeeper_test.rb +49 -0
  50. data/test/players/player_movement_test.rb +76 -0
  51. data/test/recorder_test.rb +118 -0
  52. data/test/team_test.rb +97 -0
  53. data/test/test_helper.rb +21 -0
  54. metadata +158 -0
@@ -0,0 +1,103 @@
1
+ require 'test_helper'
2
+
3
+ require 'rubygoal/field'
4
+
5
+ module Rubygoal
6
+ class FieldTest < Minitest::Test
7
+ def test_center_position
8
+ assert_equal Position.new(959, 581), Field.center_position
9
+ end
10
+
11
+ def test_home_goal_position
12
+ assert_equal Position.new(262, 581), Field.goal_position(:home)
13
+ end
14
+
15
+ def test_away_goal_position
16
+ assert_equal Position.new(1656, 581), Field.goal_position(:away)
17
+ end
18
+
19
+ def test_home_position_side
20
+ assert_equal :home, Field.position_side(Position.new(958, 0))
21
+ end
22
+
23
+ def test_away_position_side
24
+ assert_equal :away, Field.position_side(Position.new(960, 0))
25
+ end
26
+
27
+ def test_left_out_of_bounds_width
28
+ assert Field.out_of_bounds_width?(Position.new(261, 0))
29
+ end
30
+
31
+ def test_inside_left_bounds_width
32
+ refute Field.out_of_bounds_width?(Position.new(262, 0))
33
+ end
34
+
35
+ def test_inside_right_bounds_width
36
+ refute Field.out_of_bounds_width?(Position.new(1656, 0))
37
+ end
38
+
39
+ def test_right_out_of_bounds_width
40
+ assert Field.out_of_bounds_width?(Position.new(1657, 0))
41
+ end
42
+
43
+ def test_up_out_of_bounds_height
44
+ assert Field.out_of_bounds_height?(Position.new(0, 111))
45
+ end
46
+
47
+ def test_inside_upper_bounds_height
48
+ refute Field.out_of_bounds_height?(Position.new(0, 112))
49
+ end
50
+
51
+ def test_inside_bottom_bounds_height
52
+ refute Field.out_of_bounds_height?(Position.new(0, 1050))
53
+ end
54
+
55
+ def test_down_out_of_bounds_width
56
+ assert Field.out_of_bounds_height?(Position.new(0, 1051))
57
+ end
58
+
59
+ def test_middle_goal
60
+ assert Field.goal?(Position.new(261, 581))
61
+ end
62
+
63
+ def test_upper_goal
64
+ assert Field.goal?(Position.new(261, 718))
65
+ end
66
+
67
+ def test_bottom_goal
68
+ assert Field.goal?(Position.new(261, 444))
69
+ end
70
+
71
+ def test_upper_missed_goal
72
+ refute Field.goal?(Position.new(261, 719))
73
+ end
74
+
75
+ def test_bottom_missed_goal
76
+ refute Field.goal?(Position.new(261, 443))
77
+ end
78
+
79
+ def test_close_to_goal_straight
80
+ assert Field.close_to_goal?(Position.new(536, 581), :home)
81
+ end
82
+
83
+ def test_not_close_to_goal_straight
84
+ refute Field.close_to_goal?(Position.new(537, 581), :home)
85
+ end
86
+
87
+ def test_close_to_goal_upper_diagonal
88
+ assert Field.close_to_goal?(Position.new(456, 775), :home)
89
+ end
90
+
91
+ def test_not_close_to_goal_upper_diagonal
92
+ refute Field.close_to_goal?(Position.new(457, 776), :home)
93
+ end
94
+
95
+ def test_close_to_goal_lower_diagonal
96
+ assert Field.close_to_goal?(Position.new(456, 387), :home)
97
+ end
98
+
99
+ def test_not_close_to_goal_lower_diagonal
100
+ refute Field.close_to_goal?(Position.new(457, 386), :home)
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,27 @@
1
+ module Rubygoal
2
+ class FourFastPlayersCoachDefinition < CoachDefinition
3
+ team do
4
+ name "FourFastPlayers"
5
+
6
+ players do
7
+ captain :captain
8
+
9
+ fast :fast1
10
+ fast :fast2
11
+ fast :fast3
12
+ fast :fast4
13
+
14
+ average :average1
15
+ average :average2
16
+ average :average3
17
+ average :average4
18
+ average :average5
19
+ average :average6
20
+ end
21
+ end
22
+
23
+ def formation(match)
24
+ Formation.new
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,25 @@
1
+ module Rubygoal
2
+ class LessPlayersCoachDefnition < CoachDefinition
3
+ team do
4
+ name "LessPlayers"
5
+
6
+ players do
7
+ captain :captain
8
+
9
+ fast :fast1
10
+ fast :fast2
11
+ fast :fast3
12
+
13
+ average :average2
14
+ average :average3
15
+ average :average4
16
+ average :average5
17
+ average :average6
18
+ end
19
+ end
20
+
21
+ def formation(match)
22
+ Formation.new
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,42 @@
1
+ module Rubygoal
2
+ class MirrorStrategyCoachDefinition < CoachDefinition
3
+ team do
4
+ name "Mimic Team"
5
+
6
+ players do
7
+ average :average1
8
+ average :average2
9
+ average :average3
10
+ average :average4
11
+ average :average5
12
+ average :average6
13
+
14
+ fast :fast1
15
+ fast :fast2
16
+ fast :fast3
17
+
18
+ captain :captain
19
+ end
20
+ end
21
+
22
+ def formation(match)
23
+ # Mirror opponent players
24
+
25
+ formation = Formation.new
26
+
27
+ opponent = match.other.positions
28
+ my_players = players
29
+
30
+ opponent.each_with_index do |(_, opponent_pos), index|
31
+ formation.lineup do
32
+ custom_position do
33
+ player my_players[index].name
34
+ position opponent_pos.x, 100.0 - opponent_pos.y
35
+ end
36
+ end
37
+ end
38
+
39
+ formation
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,27 @@
1
+ module Rubygoal
2
+ class MorePlayersCoachDefinition < CoachDefinition
3
+ team do
4
+ name "MorePlayers"
5
+
6
+ players do
7
+ captain :captain
8
+
9
+ fast :fast1
10
+ fast :fast2
11
+ fast :fast3
12
+
13
+ average :average1
14
+ average :average2
15
+ average :average3
16
+ average :average4
17
+ average :average5
18
+ average :average6
19
+ average :average7
20
+ end
21
+ end
22
+
23
+ def formation(match)
24
+ Formation.new
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,34 @@
1
+ module Rubygoal
2
+ class TestAwayCoachDefinition < CoachDefinition
3
+ team do
4
+ name "Test Away Team"
5
+
6
+ players do
7
+ captain :away_captain
8
+
9
+ fast :away_fast1
10
+ fast :away_fast2
11
+ fast :away_fast3
12
+
13
+ average :away_average1
14
+ average :away_average2
15
+ average :away_average3
16
+ average :away_average4
17
+ average :away_average5
18
+ average :away_average6
19
+ end
20
+ end
21
+
22
+ def formation(match)
23
+ formation = Formation.new
24
+
25
+ formation.lineup do
26
+ defenders :away_average1, :away_fast1, :none, :away_fast3, :away_average5
27
+ midfielders :away_average2, :away_average3, :away_captain, :away_average4, :away_average6
28
+ attackers :away_fast2
29
+ end
30
+
31
+ formation
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ module Rubygoal
2
+ class TestHomeCoachDefinition < CoachDefinition
3
+ team do
4
+ name "Test Home Team"
5
+
6
+ players do
7
+ captain :home_captain
8
+
9
+ fast :home_fast1
10
+ fast :home_fast2
11
+ fast :home_fast3
12
+
13
+ average :home_average1
14
+ average :home_average2
15
+ average :home_average3
16
+ average :home_average4
17
+ average :home_average5
18
+ average :home_average6
19
+ end
20
+ end
21
+
22
+ def formation(match)
23
+ formation = Formation.new
24
+
25
+ formation.lineup do
26
+ defenders :home_average1, :home_fast1, :none, :home_fast3, :home_average5
27
+ midfielders :home_average2, :none, :home_captain, :none, :home_average6
28
+ attackers :none, :home_average3, :home_fast2, :home_average4, :none
29
+ end
30
+
31
+ formation
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,27 @@
1
+ module Rubygoal
2
+ class TwoCaptainsCoachDefinition < CoachDefinition
3
+ team do
4
+ name "TwoCaptains"
5
+
6
+ players do
7
+ captain :captain
8
+ captain :captain2
9
+
10
+ fast :fast1
11
+ fast :fast2
12
+ fast :fast3
13
+
14
+ average :average1
15
+ average :average2
16
+ average :average3
17
+ average :average4
18
+ average :average5
19
+ average :average6
20
+ end
21
+ end
22
+
23
+ def formation(match)
24
+ Formation.new
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ module Rubygoal
2
+ class ValidCoachDefinition < CoachDefinition
3
+ team do
4
+ name "ValidTeam"
5
+
6
+ players do
7
+ captain :captain
8
+
9
+ fast :fast1
10
+ fast :fast2
11
+ fast :fast3
12
+
13
+ average :average1
14
+ average :average2
15
+ average :average3
16
+ average :average4
17
+ average :average5
18
+ average :average6
19
+ end
20
+ end
21
+
22
+ def formation(match)
23
+ Formation.new
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,81 @@
1
+ require 'test_helper'
2
+
3
+ require 'rubygoal/formation'
4
+
5
+ module Rubygoal
6
+ class TestFormation < Minitest::Test
7
+ def setup
8
+ @formation = Formation.new
9
+ @formation.lineup do
10
+ defenders :average1, :average2, :none, :average3, :average4
11
+ midfielders :average5, :fast1, :none, :fast2, :average6
12
+ attackers :none, :captain, :none, :fast3, :none
13
+ end
14
+ end
15
+
16
+ def test_default_formation_is_valid
17
+ assert @formation.valid?
18
+ assert_empty @formation.errors
19
+ end
20
+
21
+ def test_player_default_positions
22
+ expected_positions = {
23
+ average1: Position.new(232, 156),
24
+ average2: Position.new(232, 312),
25
+ average3: Position.new(232, 625),
26
+ average4: Position.new(232, 782),
27
+ average5: Position.new(697, 156),
28
+ average6: Position.new(697, 782),
29
+ captain: Position.new(1162, 312),
30
+ fast1: Position.new(697, 312),
31
+ fast2: Position.new(697, 625),
32
+ fast3: Position.new(1162, 625)
33
+ }
34
+
35
+ expected_positions.each do |name, pos|
36
+ assert_in_delta pos, @formation.players_position[name], 1
37
+ end
38
+ end
39
+
40
+ def test_custom_default_positions
41
+ @formation.lineup do
42
+ lines do
43
+ defenders 13
44
+ midfielders 43
45
+ attackers 65
46
+ end
47
+
48
+ defenders :average1, :average2, :none, :average3, :average4
49
+ midfielders :none, :fast1, :none, :fast2, :average6
50
+ attackers :none, :captain, :none, :none, :none
51
+
52
+ custom_position do
53
+ player :fast3
54
+ position 30, 10
55
+ end
56
+ custom_position do
57
+ player :average5
58
+ position 60, 50
59
+ end
60
+ end
61
+
62
+ expected_positions = {
63
+ average1: Position.new(181, 156),
64
+ average2: Position.new(181, 312),
65
+ average3: Position.new(181, 625),
66
+ average4: Position.new(181, 781),
67
+ average6: Position.new(600, 781),
68
+ captain: Position.new(906, 312),
69
+ fast1: Position.new(600, 312),
70
+ fast2: Position.new(600, 625),
71
+
72
+ fast3: Position.new(418, 94),
73
+ average5: Position.new(836, 469)
74
+ }
75
+
76
+ expected_positions.each do |name, pos|
77
+ assert_in_delta pos, @formation.players_position[name], 1
78
+ end
79
+ end
80
+ end
81
+ end
data/test/game_test.rb ADDED
@@ -0,0 +1,84 @@
1
+ require 'test_helper'
2
+ require 'timecop'
3
+
4
+ module Rubygoal
5
+ class GameTest < Minitest::Test
6
+ def setup
7
+ home_coach = Coach.new(TestHomeCoachDefinition.new)
8
+ away_coach = Coach.new(TestAwayCoachDefinition.new)
9
+ @game = Game.new(home_coach, away_coach)
10
+ end
11
+
12
+ def test_initial_score
13
+ assert_equal 0, @game.score_home
14
+ assert_equal 0, @game.score_away
15
+ end
16
+
17
+ def test_score_after_home_team_goal
18
+ goal_position = Field::goal_position(:away).add(Position.new(1, 0))
19
+ @game.ball.position = goal_position
20
+
21
+ @game.update
22
+
23
+ assert_equal 1, @game.score_home
24
+ end
25
+
26
+ def test_score_after_away_team_goal
27
+ goal_position = Field::goal_position(:home).add(Position.new(-1, 0))
28
+ @game.ball.position = goal_position
29
+
30
+ @game.update
31
+
32
+ assert_equal 1, @game.score_away
33
+ end
34
+
35
+ def test_celebrating_goal_after_init
36
+ refute @game.celebrating_goal?
37
+ end
38
+
39
+ def test_celebrating_goal_after_away_team_goal
40
+ goal_position = Field::goal_position(:home).add(Position.new(-1, 0))
41
+ @game.ball.position = goal_position
42
+
43
+ @game.update
44
+
45
+ assert @game.celebrating_goal?
46
+ end
47
+
48
+ def test_initial_time
49
+ assert_equal Rubygoal.configuration.game_time, @game.time
50
+ end
51
+
52
+ def test_time_pass
53
+ # Begin game with an initial update call
54
+ @game.update
55
+
56
+ # Simulate time passing
57
+ elapsed_time = 70
58
+ Timecop.travel(Time.now + elapsed_time)
59
+
60
+ @game.update
61
+
62
+ remaining_time = Rubygoal.configuration.game_time - elapsed_time
63
+ assert_in_delta remaining_time, @game.time, 0.05
64
+ end
65
+
66
+ def test_players
67
+ assert_equal 22, @game.players.size
68
+ end
69
+
70
+ def test_recorded_game
71
+ Rubygoal.configuration.record_game = true
72
+ home_coach = Coach.new(TestHomeCoachDefinition.new)
73
+ away_coach = Coach.new(TestAwayCoachDefinition.new)
74
+ game = Game.new(home_coach, away_coach)
75
+
76
+ expected_teams = {
77
+ home: 'Test Home Team',
78
+ away: 'Test Away Team'
79
+ }
80
+
81
+ assert_equal expected_teams, game.recorded_game[:teams]
82
+ end
83
+ end
84
+ end