rubygoal-core 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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