rubygoal 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rubygoal +12 -2
  3. data/lib/rubygoal.rb +1 -18
  4. data/lib/rubygoal/ball.rb +60 -0
  5. data/lib/rubygoal/coach.rb +81 -0
  6. data/lib/rubygoal/coach_definition.rb +54 -0
  7. data/lib/rubygoal/coach_loader.rb +55 -0
  8. data/lib/rubygoal/coaches/coach_definition_away.rb +72 -0
  9. data/lib/rubygoal/coaches/coach_definition_home.rb +76 -0
  10. data/lib/rubygoal/configuration.rb +49 -0
  11. data/lib/rubygoal/coordinate.rb +33 -0
  12. data/lib/rubygoal/field.rb +134 -0
  13. data/lib/rubygoal/formation.rb +73 -0
  14. data/lib/rubygoal/formation/formation_dsl.rb +67 -0
  15. data/lib/rubygoal/game.rb +162 -0
  16. data/lib/rubygoal/goal.rb +26 -0
  17. data/lib/rubygoal/match_data.rb +130 -0
  18. data/lib/rubygoal/moveable.rb +68 -0
  19. data/lib/rubygoal/player.rb +87 -0
  20. data/lib/rubygoal/players/average.rb +16 -0
  21. data/lib/rubygoal/players/captain.rb +15 -0
  22. data/lib/rubygoal/players/fast.rb +16 -0
  23. data/lib/rubygoal/players/goalkeeper.rb +26 -0
  24. data/lib/rubygoal/players/player_movement.rb +98 -0
  25. data/lib/rubygoal/recorder.rb +53 -0
  26. data/lib/rubygoal/simulator.rb +33 -0
  27. data/lib/rubygoal/team.rb +198 -0
  28. data/lib/rubygoal/teams/away.rb +15 -0
  29. data/lib/rubygoal/teams/home.rb +15 -0
  30. data/lib/rubygoal/util.rb +36 -0
  31. data/lib/rubygoal/version.rb +3 -0
  32. metadata +35 -23
  33. data/lib/rubygoal/gui.rb +0 -20
  34. data/lib/rubygoal/gui/ball.rb +0 -26
  35. data/lib/rubygoal/gui/field.rb +0 -21
  36. data/lib/rubygoal/gui/game.rb +0 -166
  37. data/lib/rubygoal/gui/goal.rb +0 -23
  38. data/lib/rubygoal/gui/players.rb +0 -28
  39. data/lib/rubygoal/gui/version.rb +0 -5
  40. data/media/average_away.png +0 -0
  41. data/media/average_home.png +0 -0
  42. data/media/background.png +0 -0
  43. data/media/ball.png +0 -0
  44. data/media/captain_away.png +0 -0
  45. data/media/captain_home.png +0 -0
  46. data/media/fast_away.png +0 -0
  47. data/media/fast_home.png +0 -0
  48. data/media/goal.png +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a9f36e4a9184d9837b4834ab1449995676e02ca
4
- data.tar.gz: 6c5e76bef10ba32174430b6ffd68e175eebdb463
3
+ metadata.gz: d155a0a59d614e49e7832da9ca8fc4c02273d179
4
+ data.tar.gz: de24cb2ef8982d53a277e5bc3f6bd0f7334d9058
5
5
  SHA512:
6
- metadata.gz: 256936663d874aeb3a2c9a690af37da3bc43811c98442d3f73b2321ccc9eb9ea52d3f4466b5964e6d84fa15f5c5398399fe4e8fc47053db2c58a7fd5e87538a9
7
- data.tar.gz: 135a5704aea61868d8286e619821a56db2e7c923ead040dd1c97d2aa0d5b73b9e2f9067897df4f624e74e4e9ff19d095d71f6b06301bc7201e6fa31921bb86d4
6
+ metadata.gz: 3885e0a61ac501bb8507758a3e133015a338a01079333f9b41973e452f5e7310c49941c722702a7dbc6753553729945b8120cfcab325a679b46e23d955e3170c
7
+ data.tar.gz: 42685daf89b6fb6c45bab128e121199db7a8cc0e3725e9cf245e3485d87c02f9b892aa495237a2d7b81a2bab9082169a2317ce07be5bf440683653acb1f8203b
@@ -1,5 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
  # -*- mode: ruby -*-
3
3
 
4
- require 'rubygoal/gui'
5
- Rubygoal::Gui.start
4
+ require 'rubygoal/simulator'
5
+
6
+ simulator = Rubygoal::Simulator.new
7
+ simulator.simulate
8
+
9
+ timestamp = Time.now.strftime("%Y%m%d%H%M%S")
10
+ file = File.new("recorded_game_#{timestamp}.json", 'w')
11
+ JSON.dump(simulator.recorded_game, file)
12
+
13
+ p "Match recorded in #{file.path}"
14
+
15
+
@@ -1,18 +1 @@
1
- require 'rubygoal-core'
2
- require 'rubygoal/gui/game'
3
-
4
- module Rubygoal
5
- class << self
6
- def start
7
- game = Game.new(load_coach(:home), load_coach(:away))
8
- gui = Gui::Game.new(game)
9
- gui.show
10
- end
11
-
12
- private
13
-
14
- def load_coach(side)
15
- CoachLoader.new(side).coach
16
- end
17
- end
18
- end
1
+ require 'rubygoal/game'
@@ -0,0 +1,60 @@
1
+ require 'rubygoal/util'
2
+ require 'rubygoal/field'
3
+ require 'rubygoal/moveable'
4
+
5
+ module Rubygoal
6
+ class Ball
7
+ include Moveable
8
+
9
+ def initialize
10
+ super
11
+ reinitialize_position
12
+ end
13
+
14
+ def goal?
15
+ Field.goal?(position)
16
+ end
17
+
18
+ def move(direction, speed)
19
+ self.velocity = Velocity.new(
20
+ Util.offset_x(direction, speed),
21
+ Util.offset_y(direction, speed)
22
+ )
23
+ end
24
+
25
+ def reinitialize_position
26
+ self.position = Field.center_position
27
+ end
28
+
29
+ def update(elapsed_time)
30
+ super
31
+
32
+ prevent_out_of_bounds
33
+ decelerate(elapsed_time)
34
+ end
35
+
36
+ private
37
+
38
+ def prevent_out_of_bounds
39
+ if Field.out_of_bounds_width?(position)
40
+ velocity.x *= -1
41
+ end
42
+ if Field.out_of_bounds_height?(position)
43
+ velocity.y *= -1
44
+ end
45
+ end
46
+
47
+ def decelerate(elapsed_time)
48
+ coef = deceleration_coef(elapsed_time)
49
+
50
+ self.velocity = velocity.mult(coef)
51
+ end
52
+
53
+ def deceleration_coef(elapsed_time)
54
+ custom_frame_rate = 1 / 60.0
55
+ time_coef = elapsed_time / custom_frame_rate
56
+
57
+ Rubygoal.configuration.deceleration_coef ** time_coef
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,81 @@
1
+ require 'forwardable'
2
+
3
+ module Rubygoal
4
+ class Coach
5
+ extend Forwardable
6
+
7
+ def_delegators :coach_definition, :players, :name, :formation
8
+
9
+ def initialize(coach_definition)
10
+ @coach_definition = coach_definition
11
+ end
12
+
13
+ def errors
14
+ [].tap do |errors|
15
+ check_unique_captain(errors)
16
+ check_players_count(:average, errors)
17
+ check_players_count(:fast, errors)
18
+ end
19
+ end
20
+
21
+ def valid?
22
+ errors.empty?
23
+ end
24
+
25
+ def players_by_type(type)
26
+ players.select { |p| p.type == type }
27
+ end
28
+
29
+ def captain_player
30
+ players_by_type(:captain).first
31
+ end
32
+
33
+ def fast_players
34
+ players_by_type(:fast)
35
+ end
36
+
37
+ def average_players
38
+ players_by_type(:average)
39
+ end
40
+
41
+ def initial_formation
42
+ average_names = average_players.map(&:name)
43
+ fast_names = fast_players.map(&:name)
44
+ captain_name = captain_player.name
45
+
46
+ formation = Formation.new
47
+
48
+ formation.lineup do
49
+ defenders average_names[0], average_names[2], :none, average_names[3], average_names[4]
50
+ midfielders average_names[1], fast_names[0], :none, fast_names[1], average_names[5]
51
+ attackers :none, captain_name, :none, fast_names[2], :none
52
+ end
53
+
54
+ formation
55
+ end
56
+
57
+ private
58
+
59
+ attr_reader :coach_definition
60
+
61
+ def game_config
62
+ Rubygoal.configuration
63
+ end
64
+
65
+ def check_unique_captain(errors)
66
+ captain_count = players_by_type(:captain).size
67
+
68
+ if captain_count != 1
69
+ errors << "The number of captains is #{captain_count}"
70
+ end
71
+ end
72
+
73
+ def check_players_count(type, errors)
74
+ players_count = players_by_type(type).size
75
+
76
+ if players_count != game_config.send("#{type}_players_count")
77
+ errors << "The number of #{type} players is #{players_count}"
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,54 @@
1
+ module Rubygoal
2
+ class CoachDefinition
3
+ PlayerDefinition = Struct.new(:name, :type)
4
+
5
+ class << self
6
+ attr_reader :team_name
7
+
8
+ def team(&block)
9
+ instance_eval(&block)
10
+ end
11
+
12
+ def name(team_name)
13
+ @team_name = team_name
14
+ end
15
+
16
+ def players(&block)
17
+ @team_players = []
18
+ instance_eval(&block)
19
+ end
20
+
21
+ def method_missing(method, *args)
22
+ name = args.first.to_sym
23
+ @team_players << PlayerDefinition.new(name, method.to_sym)
24
+ end
25
+
26
+ def team_players
27
+ @team_players || [
28
+ PlayerDefinition.new(:captain, :captain),
29
+ PlayerDefinition.new(:fast1, :fast),
30
+ PlayerDefinition.new(:fast2, :fast),
31
+ PlayerDefinition.new(:fast3, :fast),
32
+ PlayerDefinition.new(:average1, :average),
33
+ PlayerDefinition.new(:average2, :average),
34
+ PlayerDefinition.new(:average3, :average),
35
+ PlayerDefinition.new(:average4, :average),
36
+ PlayerDefinition.new(:average5, :average),
37
+ PlayerDefinition.new(:average6, :average),
38
+ ]
39
+ end
40
+ end
41
+
42
+ def players
43
+ self.class.team_players
44
+ end
45
+
46
+ def name
47
+ self.class.team_name
48
+ end
49
+
50
+ def formation(match)
51
+ raise NotImplementedError
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,55 @@
1
+ require 'rubygoal/coach'
2
+ require 'rubygoal/coaches/coach_definition_home'
3
+ require 'rubygoal/coaches/coach_definition_away'
4
+
5
+ module Rubygoal
6
+ class CoachLoader
7
+ DEFAULT_COACH_DEFINITIONS = {
8
+ home: CoachDefinitionHome,
9
+ away: CoachDefinitionAway
10
+ }
11
+
12
+ def initialize(side)
13
+ @side = side
14
+ end
15
+
16
+ def coach
17
+ Coach.new(load_definition_coach)
18
+ end
19
+
20
+ private
21
+
22
+ attr_reader :side
23
+
24
+ def default_definition_class
25
+ DEFAULT_COACH_DEFINITIONS[side]
26
+ end
27
+
28
+ def load_definition_coach
29
+ if filename && File.exists?(filename)
30
+ load filename
31
+
32
+ class_name = camelize(File.basename(filename, ".rb"))
33
+ Rubygoal.const_get(class_name).new
34
+ else
35
+ if filename && Rubygoal.configuration.debug_output
36
+ puts "File `#{filename}` doesn't exist. Using #{default_definition_class.name}."
37
+ end
38
+
39
+ default_definition_class.new
40
+ end
41
+ end
42
+
43
+ def filename
44
+ side == :home ? ARGV[0] : ARGV[1]
45
+ end
46
+
47
+ def camelize(term)
48
+ string = term.to_s
49
+ string = string.sub(/^[a-z\d]*/) { $&.capitalize }
50
+ string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
51
+ string.gsub!('/', '::')
52
+ string
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,72 @@
1
+ require 'rubygoal/coach_definition'
2
+ require 'rubygoal/formation'
3
+
4
+ module Rubygoal
5
+ class CoachDefinitionAway < CoachDefinition
6
+
7
+ team do
8
+ name "Argentina"
9
+ end
10
+
11
+ def formation(match)
12
+ formation = Formation.new
13
+
14
+ if match.me.winning?
15
+ formation.lineup do
16
+ defenders :average1, :fast1, :none, :fast3, :average5
17
+ midfielders :average2, :none, :captain, :none, :average6
18
+ att_midfielders :average3
19
+ attackers :none, :none, :fast2, :average4, :none
20
+ end
21
+ elsif match.me.draw?
22
+ formation.lineup do
23
+ lines do
24
+ defenders 13
25
+ midfielders 40
26
+ attackers 65
27
+ end
28
+
29
+ defenders :average1, :fast1, :none, :average3, :average5
30
+ midfielders :average2, :none, :none, :none, :average6
31
+ attackers :none, :fast2, :none, :average4, :none
32
+
33
+ custom_position do
34
+ player :fast3
35
+ position 30, 10
36
+ end
37
+ custom_position do
38
+ player :captain
39
+ position match.ball.x, match.ball.y
40
+ end
41
+ end
42
+ elsif match.me.losing?
43
+ if match.time < 30
44
+ formation.lineup do
45
+ defenders :none, :average2, :average4, :average5, :none
46
+ midfielders :average1, :none, :none, :fast2, :average6
47
+ attackers :none, :average3, :none, :fast3, :none
48
+
49
+ custom_position do
50
+ player :fast1
51
+ position 33, 50
52
+ end
53
+ custom_position do
54
+ player :captain
55
+ position 67, 50
56
+ end
57
+ end
58
+ else
59
+ formation.lineup do
60
+ defenders :none, :average2, :fast1, :average5, :none
61
+ def_midfielders :average4
62
+ midfielders :average1, :none, :none, :captain, :average6
63
+ att_midfielders :fast2
64
+ attackers :none, :average3, :none, :fast3, :none
65
+ end
66
+ end
67
+ end
68
+
69
+ formation
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,76 @@
1
+ require 'rubygoal/coach_definition'
2
+ require 'rubygoal/formation'
3
+
4
+ module Rubygoal
5
+ class CoachDefinitionHome < CoachDefinition
6
+
7
+ team do
8
+ name "Uruguay"
9
+
10
+ players do
11
+ captain :godin
12
+
13
+ fast :cavani
14
+ fast :rolan
15
+ fast :suarez
16
+
17
+ average :pereira
18
+ average :gimenez
19
+ average :arevalo
20
+ average :lodeiro
21
+ average :cacerez
22
+ average :rodriguez
23
+ end
24
+ end
25
+
26
+ def formation(match)
27
+ formation = Formation.new
28
+
29
+ if match.me.winning?
30
+ formation.defenders :pereira, :cacerez, :gimenez, :godin, :rodriguez
31
+ formation.midfielders :lodeiro, :none, :rolan, :none, :arevalo
32
+ formation.attackers :none, :cavani, :none, :suarez, :none
33
+ elsif match.time < 20
34
+ formation.defenders :none, :rolan, :cacerez, :gimenez, :none
35
+ formation.midfielders :arevalo, :lodeiro, :godin, :none, :pereira
36
+ formation.attackers :suarez, :none, :none, :cavani, :rodriguez
37
+ elsif match.time < 20 && match.me.winning?
38
+ # Mirror opponent players
39
+
40
+ opponent = match.other.positions
41
+ my_players = players
42
+
43
+ opponent.each_with_index do |(opponent_name, opponent_pos), index|
44
+ formation.lineup do
45
+ custom_position do
46
+ player my_players[index].name
47
+ position opponent_pos.x, 100.0 - opponent_pos.y
48
+ end
49
+ end
50
+ end
51
+ else
52
+ formation.lineup do
53
+ if match.ball.x < 50
54
+ lines do
55
+ defenders 10
56
+ midfielders 30
57
+ attackers 50
58
+ end
59
+ else
60
+ lines do
61
+ defenders 30
62
+ midfielders 50
63
+ attackers 70
64
+ end
65
+ end
66
+
67
+ defenders :pereira, :cacerez, :gimenez, :godin, :rodriguez
68
+ midfielders :lodeiro, :none, :rolan, :none, :arevalo
69
+ attackers :none, :cavani, :none, :suarez, :none
70
+ end
71
+ end
72
+
73
+ formation
74
+ end
75
+ end
76
+ end