rubygoal-core 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +18 -0
- data/README.md +85 -0
- data/bin/rubygoal +15 -0
- data/lib/rubygoal.rb +1 -0
- data/lib/rubygoal/ball.rb +60 -0
- data/lib/rubygoal/coach.rb +81 -0
- data/lib/rubygoal/coach_definition.rb +54 -0
- data/lib/rubygoal/coach_loader.rb +55 -0
- data/lib/rubygoal/coaches/coach_definition_away.rb +72 -0
- data/lib/rubygoal/coaches/coach_definition_home.rb +76 -0
- data/lib/rubygoal/configuration.rb +49 -0
- data/lib/rubygoal/coordinate.rb +33 -0
- data/lib/rubygoal/field.rb +134 -0
- data/lib/rubygoal/formation.rb +73 -0
- data/lib/rubygoal/formation/formation_dsl.rb +67 -0
- data/lib/rubygoal/game.rb +162 -0
- data/lib/rubygoal/goal.rb +26 -0
- data/lib/rubygoal/match_data.rb +130 -0
- data/lib/rubygoal/moveable.rb +67 -0
- data/lib/rubygoal/player.rb +87 -0
- data/lib/rubygoal/players/average.rb +16 -0
- data/lib/rubygoal/players/captain.rb +15 -0
- data/lib/rubygoal/players/fast.rb +16 -0
- data/lib/rubygoal/players/goalkeeper.rb +26 -0
- data/lib/rubygoal/players/player_movement.rb +98 -0
- data/lib/rubygoal/recorder.rb +56 -0
- data/lib/rubygoal/simulator.rb +33 -0
- data/lib/rubygoal/team.rb +198 -0
- data/lib/rubygoal/teams/away.rb +15 -0
- data/lib/rubygoal/teams/home.rb +15 -0
- data/lib/rubygoal/util.rb +36 -0
- data/lib/rubygoal/version.rb +3 -0
- data/test/ball_test.rb +56 -0
- data/test/coach_test.rb +49 -0
- data/test/field_test.rb +103 -0
- data/test/fixtures/four_fast_players_coach_definition.rb +27 -0
- data/test/fixtures/less_players_coach_definition.rb +25 -0
- data/test/fixtures/mirror_strategy_coach_definition.rb +42 -0
- data/test/fixtures/more_players_coach_definition.rb +27 -0
- data/test/fixtures/test_away_coach_definition.rb +34 -0
- data/test/fixtures/test_home_coach_definition.rb +34 -0
- data/test/fixtures/two_captains_coach_definition.rb +27 -0
- data/test/fixtures/valid_coach_definition.rb +26 -0
- data/test/formation_test.rb +81 -0
- data/test/game_test.rb +84 -0
- data/test/match_data_test.rb +149 -0
- data/test/player_test.rb +125 -0
- data/test/players/goalkeeper_test.rb +49 -0
- data/test/players/player_movement_test.rb +76 -0
- data/test/recorder_test.rb +118 -0
- data/test/team_test.rb +97 -0
- data/test/test_helper.rb +21 -0
- metadata +158 -0
@@ -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
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'rubygoal/coordinate'
|
2
|
+
|
3
|
+
module Rubygoal
|
4
|
+
class Configuration
|
5
|
+
attr_accessor :average_players_count, :fast_players_count, :captain_players_count,
|
6
|
+
:kick_strength, :kick_again_delay, :distance_control_ball,
|
7
|
+
:deceleration_coef, :initial_player_positions, :game_time,
|
8
|
+
:average_lower_error, :average_upper_error, :average_speed,
|
9
|
+
:fast_lower_error, :fast_upper_error, :fast_speed,
|
10
|
+
:captain_error, :captain_speed, :debug_output, :record_game
|
11
|
+
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
attr_writer :configuration
|
15
|
+
|
16
|
+
def configuration
|
17
|
+
@configuration ||= Configuration.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def configure
|
21
|
+
yield(configuration)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Rubygoal.configure do |config|
|
26
|
+
config.average_players_count = 6
|
27
|
+
config.fast_players_count = 3
|
28
|
+
|
29
|
+
config.kick_strength = 20
|
30
|
+
config.kick_again_delay = 1
|
31
|
+
config.distance_control_ball = 30
|
32
|
+
config.deceleration_coef = 0.95
|
33
|
+
|
34
|
+
config.average_lower_error = 0.1
|
35
|
+
config.average_upper_error = 0.15
|
36
|
+
config.average_speed = 3.5
|
37
|
+
|
38
|
+
config.fast_lower_error = 0.1
|
39
|
+
config.fast_upper_error = 0.15
|
40
|
+
config.fast_speed = 4
|
41
|
+
|
42
|
+
config.captain_error = 0.05
|
43
|
+
config.captain_speed = 4.5
|
44
|
+
|
45
|
+
config.game_time = 120
|
46
|
+
config.debug_output = true
|
47
|
+
config.record_game = false
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'rubygoal/util'
|
2
|
+
|
3
|
+
module Rubygoal
|
4
|
+
class Coordinate < Struct.new(:x, :y)
|
5
|
+
def distance(coordinate)
|
6
|
+
Util.distance(x, y, coordinate.x, coordinate.y)
|
7
|
+
end
|
8
|
+
|
9
|
+
def add(coordinate)
|
10
|
+
self.class.new(x + coordinate.x, y + coordinate.y)
|
11
|
+
end
|
12
|
+
|
13
|
+
def mult(coeficient)
|
14
|
+
self.class.new(x * coeficient, y * coeficient)
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"(#{x}, #{y})"
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_hash
|
22
|
+
{ x: x, y: y }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Position < Coordinate; end
|
27
|
+
|
28
|
+
class Velocity < Coordinate
|
29
|
+
def nonzero?
|
30
|
+
x != 0 || y != 0
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
require 'rubygoal/ball'
|
4
|
+
require 'rubygoal/coach_loader'
|
5
|
+
require 'rubygoal/teams/home'
|
6
|
+
require 'rubygoal/teams/away'
|
7
|
+
module Rubygoal
|
8
|
+
module Field
|
9
|
+
WIDTH = 1394.0
|
10
|
+
HEIGHT = 938.0
|
11
|
+
OFFSET = Position.new(262, 112)
|
12
|
+
GOAL_HEIGHT = 275
|
13
|
+
CLOSE_GOAL_DISTANCE = 275
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def center_position
|
17
|
+
center = Position.new(
|
18
|
+
WIDTH / 2,
|
19
|
+
HEIGHT / 2
|
20
|
+
)
|
21
|
+
OFFSET.add(center)
|
22
|
+
end
|
23
|
+
|
24
|
+
def goal_position(side)
|
25
|
+
position = center_position
|
26
|
+
case side
|
27
|
+
when :home
|
28
|
+
position.x = OFFSET.x
|
29
|
+
when :away
|
30
|
+
position.x = OFFSET.x + WIDTH
|
31
|
+
end
|
32
|
+
|
33
|
+
position
|
34
|
+
end
|
35
|
+
|
36
|
+
def absolute_position(field_position, side)
|
37
|
+
case side
|
38
|
+
when :home
|
39
|
+
OFFSET.add(field_position)
|
40
|
+
when :away
|
41
|
+
OFFSET.add(
|
42
|
+
Position.new(
|
43
|
+
WIDTH - field_position.x,
|
44
|
+
HEIGHT - field_position.y
|
45
|
+
)
|
46
|
+
)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def field_position(absolute_position, side)
|
51
|
+
case side
|
52
|
+
when :home
|
53
|
+
absolute_position.add(
|
54
|
+
Position.new(
|
55
|
+
- OFFSET.x,
|
56
|
+
- OFFSET.y
|
57
|
+
)
|
58
|
+
)
|
59
|
+
when :away
|
60
|
+
Position.new(
|
61
|
+
WIDTH - (absolute_position.x - OFFSET.x),
|
62
|
+
HEIGHT - (absolute_position.y - OFFSET.y)
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def position_from_percentages(position_in_percentages)
|
68
|
+
Position.new(
|
69
|
+
position_in_percentages.x / 100.0 * Field::WIDTH,
|
70
|
+
position_in_percentages.y / 100.0 * Field::HEIGHT
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
def position_to_percentages(position)
|
75
|
+
Position.new(
|
76
|
+
position.x / Field::WIDTH * 100,
|
77
|
+
position.y / Field::HEIGHT * 100
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
def position_side(position)
|
82
|
+
position.x < center_position.x ? :home : :away
|
83
|
+
end
|
84
|
+
|
85
|
+
def out_of_bounds_width?(position)
|
86
|
+
lower_limit = OFFSET.x
|
87
|
+
upper_limit = OFFSET.x + WIDTH
|
88
|
+
!(lower_limit..upper_limit).include?(position.x)
|
89
|
+
end
|
90
|
+
|
91
|
+
def out_of_bounds_height?(position)
|
92
|
+
lower_limit = OFFSET.y
|
93
|
+
upper_limit = OFFSET.y + HEIGHT
|
94
|
+
!(lower_limit..upper_limit).include?(position.y)
|
95
|
+
end
|
96
|
+
|
97
|
+
def goal?(position)
|
98
|
+
if out_of_bounds_width?(position)
|
99
|
+
lower_limit = center_position.y - GOAL_HEIGHT / 2
|
100
|
+
upper_limit = center_position.y + GOAL_HEIGHT / 2
|
101
|
+
|
102
|
+
(lower_limit..upper_limit).include?(position.y)
|
103
|
+
else
|
104
|
+
false
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def close_to_goal?(position, side)
|
109
|
+
goal_position = Field.goal_position(side)
|
110
|
+
goal_position.distance(position) < CLOSE_GOAL_DISTANCE
|
111
|
+
end
|
112
|
+
|
113
|
+
def default_player_field_positions
|
114
|
+
defenders = Field::WIDTH / 6
|
115
|
+
midfielders = Field::WIDTH / 2
|
116
|
+
attackers = Field::WIDTH * 5 / 6
|
117
|
+
|
118
|
+
[
|
119
|
+
Position.new(50, Field::HEIGHT / 2),
|
120
|
+
Position.new(defenders, Field::HEIGHT / 5),
|
121
|
+
Position.new(defenders, Field::HEIGHT * 2 / 5),
|
122
|
+
Position.new(defenders, Field::HEIGHT * 3 / 5),
|
123
|
+
Position.new(defenders, Field::HEIGHT * 4 / 5),
|
124
|
+
Position.new(midfielders, Field::HEIGHT / 5),
|
125
|
+
Position.new(midfielders, Field::HEIGHT * 2 / 5),
|
126
|
+
Position.new(midfielders, Field::HEIGHT * 3 / 5),
|
127
|
+
Position.new(midfielders, Field::HEIGHT * 4 / 5),
|
128
|
+
Position.new(attackers, Field::HEIGHT / 3),
|
129
|
+
Position.new(attackers, Field::HEIGHT * 2 / 3)
|
130
|
+
]
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rubygoal/formation/formation_dsl'
|
2
|
+
|
3
|
+
module Rubygoal
|
4
|
+
class Formation
|
5
|
+
attr_accessor :players_position, :lines_definition
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@players_position = {}
|
9
|
+
|
10
|
+
@lines_definition = {
|
11
|
+
defenders: Field::WIDTH / 6,
|
12
|
+
def_midfielders: Field::WIDTH / 3,
|
13
|
+
midfielders: Field::WIDTH / 2,
|
14
|
+
att_midfielders: Field::WIDTH / 3 * 2,
|
15
|
+
attackers: Field::WIDTH / 6 * 5,
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
def method_missing(method, *args)
|
20
|
+
line_name = method.to_s.chomp('=').to_sym
|
21
|
+
if lines_definition[line_name]
|
22
|
+
set_players_in_custom_line(lines_definition[line_name], args)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def lineup(&block)
|
27
|
+
instance_eval(&block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def errors
|
31
|
+
errors = []
|
32
|
+
|
33
|
+
# TODO Check if we need to count for the goalkeeper as well
|
34
|
+
if players_position.size != 10
|
35
|
+
errors << 'Incorrect number of players, are you missing a name?'
|
36
|
+
end
|
37
|
+
|
38
|
+
errors
|
39
|
+
end
|
40
|
+
|
41
|
+
def valid?
|
42
|
+
errors.empty?
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def lines(&block)
|
48
|
+
CustomLines.apply(self, &block)
|
49
|
+
end
|
50
|
+
|
51
|
+
def custom_position(&block)
|
52
|
+
CustomPosition.apply(self, &block)
|
53
|
+
end
|
54
|
+
|
55
|
+
def set_players_in_custom_line(position_x, players)
|
56
|
+
base_position = Position.new(position_x, 0)
|
57
|
+
separation = line_position_separation(players)
|
58
|
+
|
59
|
+
players.each_with_index do |player, i|
|
60
|
+
next if player == :none
|
61
|
+
|
62
|
+
offset = Position.new(0, separation * (i + 1))
|
63
|
+
position = base_position.add(offset)
|
64
|
+
|
65
|
+
self.players_position[player] = position
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def line_position_separation(players)
|
70
|
+
Field::HEIGHT / (players.size + 1)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Rubygoal
|
2
|
+
class Formation
|
3
|
+
class FormationDSL
|
4
|
+
def self.apply(formation, &block)
|
5
|
+
dsl = self.new(formation)
|
6
|
+
dsl.instance_eval(&block)
|
7
|
+
dsl.apply
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def field_width
|
13
|
+
100.0
|
14
|
+
end
|
15
|
+
|
16
|
+
def field_height
|
17
|
+
100.0
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class CustomLines < FormationDSL
|
22
|
+
def initialize(formation)
|
23
|
+
@formation = formation
|
24
|
+
@lines = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def apply
|
28
|
+
formation.lines_definition.merge!(lines)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :formation, :lines
|
34
|
+
|
35
|
+
def method_missing(method, *args)
|
36
|
+
define_line(method, args.first)
|
37
|
+
end
|
38
|
+
|
39
|
+
def define_line(name, x_position)
|
40
|
+
lines[name] = x_position / 100.0 * Field::WIDTH
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class CustomPosition < FormationDSL
|
45
|
+
def initialize(formation)
|
46
|
+
@formation = formation
|
47
|
+
end
|
48
|
+
|
49
|
+
def apply
|
50
|
+
formation.players_position[player_name] = player_position
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
attr_reader :formation
|
56
|
+
attr_accessor :player_name, :player_position
|
57
|
+
|
58
|
+
def player(name)
|
59
|
+
self.player_name = name
|
60
|
+
end
|
61
|
+
|
62
|
+
def position(x, y)
|
63
|
+
self.player_position = Field.position_from_percentages(Position.new(x, y))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
require 'rubygoal/coordinate'
|
4
|
+
require 'rubygoal/field'
|
5
|
+
require 'rubygoal/goal'
|
6
|
+
require 'rubygoal/recorder'
|
7
|
+
|
8
|
+
module Rubygoal
|
9
|
+
class Game
|
10
|
+
attr_reader :team_home, :team_away, :ball,
|
11
|
+
:time, :goal, :recorder,
|
12
|
+
:coach_home, :coach_away,
|
13
|
+
:score_home, :score_away
|
14
|
+
|
15
|
+
def initialize(coach_home, coach_away)
|
16
|
+
@coach_home = coach_home
|
17
|
+
@coach_away = coach_away
|
18
|
+
|
19
|
+
if debug_output?
|
20
|
+
puts "Home coach: #{@coach_home.name}"
|
21
|
+
puts "Away coach: #{@coach_away.name}"
|
22
|
+
end
|
23
|
+
|
24
|
+
@recorder = Recorder.new(self) if record_game?
|
25
|
+
|
26
|
+
@ball = Ball.new
|
27
|
+
|
28
|
+
@team_home = HomeTeam.new(self, coach_home)
|
29
|
+
@team_away = AwayTeam.new(self, coach_away)
|
30
|
+
|
31
|
+
@goal = Goal.new
|
32
|
+
|
33
|
+
@state = :playing
|
34
|
+
|
35
|
+
@time = Rubygoal.configuration.game_time
|
36
|
+
@score_home = 0
|
37
|
+
@score_away = 0
|
38
|
+
|
39
|
+
reinitialize_players
|
40
|
+
end
|
41
|
+
|
42
|
+
def update
|
43
|
+
return if ended?
|
44
|
+
|
45
|
+
update_elapsed_time
|
46
|
+
|
47
|
+
if celebrating_goal?
|
48
|
+
update_goal
|
49
|
+
else
|
50
|
+
update_remaining_time
|
51
|
+
team_home.update(elapsed_time)
|
52
|
+
team_away.update(elapsed_time)
|
53
|
+
update_ball
|
54
|
+
end
|
55
|
+
|
56
|
+
recorder.update if record_game?
|
57
|
+
|
58
|
+
end_match! if time <= 0
|
59
|
+
end
|
60
|
+
|
61
|
+
def players
|
62
|
+
teams.map(&:players_list).flatten
|
63
|
+
end
|
64
|
+
|
65
|
+
def celebrating_goal?
|
66
|
+
goal.celebrating?
|
67
|
+
end
|
68
|
+
|
69
|
+
def home_players_positions
|
70
|
+
team_home.players_position
|
71
|
+
end
|
72
|
+
|
73
|
+
def away_players_positions
|
74
|
+
team_away.players_position
|
75
|
+
end
|
76
|
+
|
77
|
+
def ball_position
|
78
|
+
ball.position
|
79
|
+
end
|
80
|
+
|
81
|
+
def recorded_game
|
82
|
+
recorder.to_hash if record_game?
|
83
|
+
end
|
84
|
+
|
85
|
+
def ended?
|
86
|
+
state == :ended
|
87
|
+
end
|
88
|
+
|
89
|
+
protected
|
90
|
+
|
91
|
+
attr_writer :time, :score_home, :score_away
|
92
|
+
attr_accessor :state, :last_time, :elapsed_time
|
93
|
+
|
94
|
+
private
|
95
|
+
|
96
|
+
def update_elapsed_time
|
97
|
+
self.last_time ||= Time.now
|
98
|
+
|
99
|
+
self.elapsed_time = Time.now - last_time
|
100
|
+
self.last_time = Time.now
|
101
|
+
end
|
102
|
+
|
103
|
+
def update_remaining_time
|
104
|
+
self.time -= elapsed_time
|
105
|
+
end
|
106
|
+
|
107
|
+
def update_ball
|
108
|
+
ball.update(elapsed_time)
|
109
|
+
if ball.goal?
|
110
|
+
update_score
|
111
|
+
goal.start_celebration
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def update_goal
|
116
|
+
goal.update(elapsed_time)
|
117
|
+
reinitialize_match unless goal.celebrating?
|
118
|
+
end
|
119
|
+
|
120
|
+
def reinitialize_match
|
121
|
+
reinitialize_players
|
122
|
+
reinitialize_ball
|
123
|
+
end
|
124
|
+
|
125
|
+
def update_score
|
126
|
+
if Field.position_side(ball_position) == :home
|
127
|
+
self.score_away += 1
|
128
|
+
else
|
129
|
+
self.score_home += 1
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def reinitialize_players
|
134
|
+
teams.each(&:players_to_initial_position)
|
135
|
+
end
|
136
|
+
|
137
|
+
def reinitialize_ball
|
138
|
+
ball.position = Field.center_position
|
139
|
+
end
|
140
|
+
|
141
|
+
def teams
|
142
|
+
[team_home, team_away]
|
143
|
+
end
|
144
|
+
|
145
|
+
def end_match!
|
146
|
+
self.state = :ended
|
147
|
+
puts_score if debug_output?
|
148
|
+
end
|
149
|
+
|
150
|
+
def puts_score
|
151
|
+
puts "#{coach_home.name} #{score_home} - #{score_away} #{coach_away.name}"
|
152
|
+
end
|
153
|
+
|
154
|
+
def debug_output?
|
155
|
+
Rubygoal.configuration.debug_output
|
156
|
+
end
|
157
|
+
|
158
|
+
def record_game?
|
159
|
+
Rubygoal.configuration.record_game
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|