rubygoal 0.0.2 → 2.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.
- checksums.yaml +4 -4
- data/LICENSE +18 -0
- data/README.md +51 -28
- data/bin/rubygoal +2 -2
- data/lib/rubygoal/gui/ball.rb +26 -0
- data/lib/rubygoal/gui/field.rb +21 -0
- data/lib/rubygoal/gui/game.rb +166 -0
- data/lib/rubygoal/gui/goal.rb +23 -0
- data/lib/rubygoal/gui/players.rb +28 -0
- data/lib/rubygoal/gui/version.rb +5 -0
- data/lib/rubygoal/gui.rb +20 -0
- data/lib/rubygoal.rb +14 -3
- data/media/background.png +0 -0
- data/media/goal.png +0 -0
- metadata +28 -51
- data/MIT-LICENSE +0 -24
- data/lib/rubygoal/ball.rb +0 -41
- data/lib/rubygoal/coach.rb +0 -11
- data/lib/rubygoal/coach_loader.rb +0 -32
- data/lib/rubygoal/coaches/coach_away.rb +0 -52
- data/lib/rubygoal/coaches/coach_home.rb +0 -28
- data/lib/rubygoal/coaches/template.rb +0 -198
- data/lib/rubygoal/config.rb +0 -64
- data/lib/rubygoal/config_definitions.rb +0 -77
- data/lib/rubygoal/coordinate.rb +0 -25
- data/lib/rubygoal/field.rb +0 -84
- data/lib/rubygoal/field_metrics.rb +0 -85
- data/lib/rubygoal/formation.rb +0 -69
- data/lib/rubygoal/game.rb +0 -179
- data/lib/rubygoal/goal.rb +0 -43
- data/lib/rubygoal/match.rb +0 -52
- data/lib/rubygoal/moveable.rb +0 -55
- data/lib/rubygoal/player.rb +0 -86
- data/lib/rubygoal/players/average.rb +0 -20
- data/lib/rubygoal/players/captain.rb +0 -20
- data/lib/rubygoal/players/fast.rb +0 -20
- data/lib/rubygoal/team.rb +0 -217
- data/lib/rubygoal/version.rb +0 -3
- data/test/formation_test.rb +0 -66
- data/test/random.txt +0 -788
- data/test/record.txt +0 -432000
- data/test/test.rb +0 -104
data/lib/rubygoal/coach.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
module Rubygoal
|
2
|
-
module CoachLoader
|
3
|
-
class << self
|
4
|
-
def get(default)
|
5
|
-
file = ARGV.shift
|
6
|
-
|
7
|
-
if file && File.exists?(file)
|
8
|
-
load file
|
9
|
-
|
10
|
-
class_name = camelize(File.basename(file, ".rb"))
|
11
|
-
Rubygoal.const_get(class_name).new
|
12
|
-
else
|
13
|
-
if file
|
14
|
-
puts "File `#{file}` doesn't exist. Using #{default.name}."
|
15
|
-
end
|
16
|
-
|
17
|
-
default.new
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def camelize(term)
|
24
|
-
string = term.to_s
|
25
|
-
string = string.sub(/^[a-z\d]*/) { $&.capitalize }
|
26
|
-
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
|
27
|
-
string.gsub!('/', '::')
|
28
|
-
string
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'rubygoal/coach'
|
2
|
-
require 'rubygoal/formation'
|
3
|
-
|
4
|
-
module Rubygoal
|
5
|
-
class CoachAway < Coach
|
6
|
-
def name
|
7
|
-
"Danubio"
|
8
|
-
end
|
9
|
-
|
10
|
-
def formation(match)
|
11
|
-
formation = Formation.new
|
12
|
-
|
13
|
-
if match.me.winning?
|
14
|
-
formation.lineup = [
|
15
|
-
[:average, :none, :average, :none, :none],
|
16
|
-
[:fast, :none, :none, :average, :none],
|
17
|
-
[:none, :none, :captain, :none, :fast],
|
18
|
-
[:fast, :none, :none, :none, :average],
|
19
|
-
[:average, :none, :average, :none, :none],
|
20
|
-
]
|
21
|
-
elsif match.me.draw?
|
22
|
-
formation.lineup = [
|
23
|
-
[:average, :none, :average, :none, :none],
|
24
|
-
[:fast, :none, :none, :none, :fast],
|
25
|
-
[:none, :fast, :none, :captain, :none],
|
26
|
-
[:average, :none, :none, :none, :average],
|
27
|
-
[:average, :none, :average, :none, :none],
|
28
|
-
]
|
29
|
-
elsif match.me.losing?
|
30
|
-
if match.time < 30
|
31
|
-
formation.lineup = [
|
32
|
-
[:none, :none, :average, :none, :none],
|
33
|
-
[:average, :none, :none, :none, :average],
|
34
|
-
[:average, :fast, :none, :captain, :none],
|
35
|
-
[:average, :none, :fast, :none, :fast],
|
36
|
-
[:none, :none, :average, :none, :none],
|
37
|
-
]
|
38
|
-
else
|
39
|
-
formation.lineup = [
|
40
|
-
[:none, :none, :average, :none, :none],
|
41
|
-
[:average, :none, :none, :none, :average],
|
42
|
-
[:fast, :average, :none, :fast, :none],
|
43
|
-
[:average, :none, :captain, :none, :fast],
|
44
|
-
[:none, :none, :average, :none, :none],
|
45
|
-
]
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
formation
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'rubygoal/coach'
|
2
|
-
require 'rubygoal/formation'
|
3
|
-
|
4
|
-
module Rubygoal
|
5
|
-
class CoachHome < Coach
|
6
|
-
def name
|
7
|
-
"Wanderers"
|
8
|
-
end
|
9
|
-
|
10
|
-
def formation(match)
|
11
|
-
formation = Formation.new
|
12
|
-
|
13
|
-
if match.me.winning?
|
14
|
-
formation.defenders = [:average, :average, :average, :captain, :average]
|
15
|
-
formation.midfielders = [:average, :none, :fast, :none, :average]
|
16
|
-
formation.attackers = [:none, :fast, :none, :fast, :none]
|
17
|
-
elsif match.time < 20
|
18
|
-
formation.defenders = [:none, :fast, :average, :average, :none]
|
19
|
-
formation.midfielders = [:average, :average, :captain, :none, :average]
|
20
|
-
formation.attackers = [:fast, :none, :none, :fast, :average]
|
21
|
-
else
|
22
|
-
formation.lineup = match.other.formation.lineup
|
23
|
-
end
|
24
|
-
|
25
|
-
formation
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,198 +0,0 @@
|
|
1
|
-
# RubyGoal - Fútbol para Rubistas
|
2
|
-
#
|
3
|
-
# Este documento contiene varias implementaciones mínimas de un entrenador de RubyGoal.#
|
4
|
-
#
|
5
|
-
# Esta clase debe implementar, como mínimo, los métodos `name` y `formation(match)`
|
6
|
-
# Esta clase debe ser implementada dentro del módulo Rubygoal
|
7
|
-
|
8
|
-
module Rubygoal
|
9
|
-
class MyCoach < Coach
|
10
|
-
# Indica el nombre del equipo
|
11
|
-
# Debe retornar un string
|
12
|
-
def name
|
13
|
-
"My team name"
|
14
|
-
end
|
15
|
-
|
16
|
-
# Este método debe devolver una instancia de Formation indicando como
|
17
|
-
# se tienen que parar los jugadores en la cancha
|
18
|
-
#
|
19
|
-
# Este método es invocado constantemente (varias veces por segundo)
|
20
|
-
# proporcionando información de como va el partido utilizando el
|
21
|
-
# parámetro match
|
22
|
-
def formation(match)
|
23
|
-
formation = Formation.new
|
24
|
-
|
25
|
-
# La clase Formation tiene varios helpers para ayudar a definir la
|
26
|
-
# formación del equipo
|
27
|
-
#
|
28
|
-
# La cancha se divide en una matriz de 5 por 5
|
29
|
-
#
|
30
|
-
# ------------------------------
|
31
|
-
# | N N N N N |
|
32
|
-
# | |
|
33
|
-
# | N N N N N |
|
34
|
-
# A | | A
|
35
|
-
# R | N N N N N | R
|
36
|
-
# C | | C
|
37
|
-
# O | N N N N N | O
|
38
|
-
# | |
|
39
|
-
# | N N N N N |
|
40
|
-
# ------------------------------
|
41
|
-
#
|
42
|
-
# Esto es un ejemplo que posiciona jugadores en columnas de la matriz
|
43
|
-
#
|
44
|
-
# Los tipos de jugadores válidos son :average, :fast, :captain
|
45
|
-
# Se usa :none para las posiciones que no se usen en la línea
|
46
|
-
#
|
47
|
-
# Restricciones:
|
48
|
-
# Exactamente un :captain
|
49
|
-
# Exactamente tres :fast
|
50
|
-
# Exactamente seis :average
|
51
|
-
#
|
52
|
-
# :captain -> Este jugador es el más rápido y preciso del equipo
|
53
|
-
# :fast -> Estos jugadores son más rápidos que los demás (aunque más lentos que
|
54
|
-
# el capitán del equipo)
|
55
|
-
# :average -> Estos jugadores completan el equipo
|
56
|
-
#
|
57
|
-
# El arquero no hay que especificarlo, ya viene incluido por defecto
|
58
|
-
formation.defenders = [:none, :average, :average, :average, :none]
|
59
|
-
formation.midfielders = [:average, :fast, :captain, :none, :average]
|
60
|
-
formation.attackers = [:none, :fast, :none, :fast, :average]
|
61
|
-
|
62
|
-
# Esto produce la siguiente alineación
|
63
|
-
#
|
64
|
-
# ------------------------------
|
65
|
-
# | N N A N N |
|
66
|
-
# | |
|
67
|
-
# | A N F N F |
|
68
|
-
# A | | A
|
69
|
-
# R | A N C N N | R
|
70
|
-
# C | | C
|
71
|
-
# O | A N N N F | O
|
72
|
-
# | |
|
73
|
-
# | N N A N A |
|
74
|
-
# ------------------------------
|
75
|
-
|
76
|
-
formation
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# Lo siguiente es otra implementación posible de una instancia de Coach
|
81
|
-
|
82
|
-
class AnotherCoach < Coach
|
83
|
-
def name
|
84
|
-
"Maeso FC"
|
85
|
-
end
|
86
|
-
|
87
|
-
# El método formation debe devolver una instancia de Formation
|
88
|
-
# El siguiten ejemplo muestra como controlar la posición de los jugadores
|
89
|
-
# de una forma más fina, usando el método `lineup`
|
90
|
-
#
|
91
|
-
def formation(match)
|
92
|
-
formation = Formation.new
|
93
|
-
|
94
|
-
# Por defecto el valor de formation.lineup es
|
95
|
-
#
|
96
|
-
# [
|
97
|
-
# [:none, :none, :none, :none, :none],
|
98
|
-
# [:none, :none, :none, :none, :none],
|
99
|
-
# [:none, :none, :none, :none, :none],
|
100
|
-
# [:none, :none, :none, :none, :none],
|
101
|
-
# [:none, :none, :none, :none, :none],
|
102
|
-
# ]
|
103
|
-
#
|
104
|
-
# Este valor DEBE sobreescribirse con una formación que incluya las
|
105
|
-
# cantidades correctas de :average, :fast y :captain
|
106
|
-
#
|
107
|
-
# Para este tipo de estrategias es importante siempre considerar que el arco
|
108
|
-
# que atacas es el de la derecha.
|
109
|
-
#
|
110
|
-
# En el siguiente ejemplo, la formación 4322 puede interpretarse
|
111
|
-
# de la siguiente manera
|
112
|
-
# | |
|
113
|
-
# defensa | medio campo | delantera
|
114
|
-
# [ | |
|
115
|
-
# [ :average, | :none, :average, :none, | :none ],
|
116
|
-
# [ :fast, | :none, :none, :average, | :none ],
|
117
|
-
# [ :none, | :none, :captain, :none, | :fast ],
|
118
|
-
# [ :fast, | :none, :none, :average, | :average ],
|
119
|
-
# [ :average, | :none, :average, :none, | :none ],
|
120
|
-
# ] | |
|
121
|
-
# | |
|
122
|
-
#
|
123
|
-
# Usando `lineup`, la línea mas defensiva son los primeros elementos de
|
124
|
-
# cada uno de los arrays (:average, :fast, :none, :fast, :average)
|
125
|
-
#
|
126
|
-
# La segunda línea (entre la defensa y los mediocampistas) no tiene jugadores
|
127
|
-
# (son todos :none)
|
128
|
-
#
|
129
|
-
# La tercer línea, la que corresponde a los mediocampistas, son el tercer
|
130
|
-
# elemento de cada array (:average, :none, :captain, :none, :average)
|
131
|
-
#
|
132
|
-
# La cuarta línea está ubicada entre los mediocampistas y delanteros
|
133
|
-
# (:none, :average, :none, :average, :none)
|
134
|
-
#
|
135
|
-
# Los últimos elementos de los arrays corresponden a la línea de
|
136
|
-
# delanteros (:none, :none, :fast, :average, :none)
|
137
|
-
formation.lineup = [
|
138
|
-
[:average, :none, :average, :none, :none],
|
139
|
-
[:fast, :none, :none, :average, :none],
|
140
|
-
[:none, :none, :captain, :none, :fast],
|
141
|
-
[:fast, :none, :none, :average, :average],
|
142
|
-
[:average, :none, :average, :none, :none],
|
143
|
-
]
|
144
|
-
|
145
|
-
formation
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
# Otra implementación posible de una instancia de Coach
|
150
|
-
|
151
|
-
# Gran parte de la gracia de este juego está en hacer cambios en la formación
|
152
|
-
# a medida que va transcurriendo el partido
|
153
|
-
#
|
154
|
-
# La instancia de `match` que recibe el método `formation` contiene información
|
155
|
-
# sobre el partido y el rival de turno
|
156
|
-
#
|
157
|
-
# Veamos un ejemplo
|
158
|
-
|
159
|
-
class MyCoach < Coach
|
160
|
-
def name
|
161
|
-
"Villa Pancha"
|
162
|
-
end
|
163
|
-
|
164
|
-
def formation(match)
|
165
|
-
formation = Formation.new
|
166
|
-
|
167
|
-
# El método `me` trae información sobre mi equipo en el partido
|
168
|
-
#
|
169
|
-
# me.winning? indica si estoy ganando
|
170
|
-
# me.losing? y me.draw? son análogos al anterior :)
|
171
|
-
# me.score me indica la cantidad exacta de goles que marcó mi equipo
|
172
|
-
if match.me.winning?
|
173
|
-
formation.defenders = [:average, :average, :average, :captain, :average]
|
174
|
-
formation.midfielders = [:average, :none, :fast, :none, :average]
|
175
|
-
formation.attackers = [:none, :fast, :none, :fast, :none]
|
176
|
-
#
|
177
|
-
# El método `time` indica cuanto tiempo (segundos) le queda al partido.
|
178
|
-
# Devuelve un número entre 120 y 0 (120 cuando comienza el partido)
|
179
|
-
elsif match.time < 10
|
180
|
-
formation.defenders = [:none, :average, :average, :average, :none]
|
181
|
-
formation.midfielders = [:average, :average, :captain, :none, :average]
|
182
|
-
formation.attackers = [:fast, :fast, :none, :fast, :average]
|
183
|
-
else
|
184
|
-
#
|
185
|
-
# El método `other` devuelve información básica del rival. Tiene los mismos
|
186
|
-
# métodos que `me`.
|
187
|
-
#
|
188
|
-
# En particular, se puede acceder a la formación definida por el equipo
|
189
|
-
# contrario. En la siguiente linea, a modo de ejemplo, se estableció
|
190
|
-
# una táctica `espejo` con respecto al rival (posiciono mis jugadores en forma
|
191
|
-
# simétrica)
|
192
|
-
formation.lineup = match.other.formation.lineup
|
193
|
-
end
|
194
|
-
|
195
|
-
formation
|
196
|
-
end
|
197
|
-
end
|
198
|
-
end
|
data/lib/rubygoal/config.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'rubygoal/config_definitions'
|
2
|
-
require 'rubygoal/coordinate'
|
3
|
-
|
4
|
-
module Rubygoal
|
5
|
-
module Config
|
6
|
-
field.width = 1392
|
7
|
-
field.height = 934
|
8
|
-
field.offset = Position.new(262, 114)
|
9
|
-
field.goal_height = 275
|
10
|
-
field.close_to_goal_distance = 275
|
11
|
-
field.background_image_file = File.dirname(__FILE__) + '/../../media/background.png'
|
12
|
-
|
13
|
-
team.initial_player_positions = [
|
14
|
-
[50, 466],
|
15
|
-
[236, 106],
|
16
|
-
[236, 286],
|
17
|
-
[236, 646],
|
18
|
-
[236, 826],
|
19
|
-
[436, 106],
|
20
|
-
[436, 286],
|
21
|
-
[436, 646],
|
22
|
-
[436, 826],
|
23
|
-
[616, 436],
|
24
|
-
[616, 496]
|
25
|
-
]
|
26
|
-
team.average_players_count = 7
|
27
|
-
team.fast_players_count = 3
|
28
|
-
team.captain_players_count = 1
|
29
|
-
|
30
|
-
|
31
|
-
ball.width = 20
|
32
|
-
ball.height = 20
|
33
|
-
ball.image_file = File.dirname(__FILE__) + '/../../media/ball.png'
|
34
|
-
|
35
|
-
|
36
|
-
player.time_to_kick_again = 60
|
37
|
-
player.distance_control_ball = 30
|
38
|
-
player.kick_strength = 20
|
39
|
-
|
40
|
-
|
41
|
-
player.captain_home_image_file = File.dirname(__FILE__) + '/../../media/captain_home.png'
|
42
|
-
player.captain_away_image_file = File.dirname(__FILE__) + '/../../media/captain_away.png'
|
43
|
-
player.fast_home_image_file = File.dirname(__FILE__) + '/../../media/fast_home.png'
|
44
|
-
player.fast_away_image_file = File.dirname(__FILE__) + '/../../media/fast_away.png'
|
45
|
-
player.average_home_image_file = File.dirname(__FILE__) + '/../../media/average_home.png'
|
46
|
-
player.average_away_image_file = File.dirname(__FILE__) + '/../../media/average_away.png'
|
47
|
-
|
48
|
-
|
49
|
-
goal.image_file = File.dirname(__FILE__) + '/../../media/goal.png'
|
50
|
-
|
51
|
-
|
52
|
-
game.time = 120
|
53
|
-
game.goal_image_position = Position.new(596, 466)
|
54
|
-
game.time_label_position = Position.new(870, 68)
|
55
|
-
game.score_home_label_position = Position.new(1150, 68)
|
56
|
-
game.score_away_label_position = Position.new(1220, 68)
|
57
|
-
game.max_name_length = 20
|
58
|
-
game.default_font_size = 48
|
59
|
-
game.team_label_font_size = 64
|
60
|
-
game.team_label_width = 669
|
61
|
-
game.home_team_label_position = Position.new(105, 580)
|
62
|
-
game.away_team_label_position = Position.new(1815, 580)
|
63
|
-
end
|
64
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
module Rubygoal
|
2
|
-
module Config
|
3
|
-
class Field < Struct.new(:width,
|
4
|
-
:height,
|
5
|
-
:offset,
|
6
|
-
:goal_height,
|
7
|
-
:close_to_goal_distance,
|
8
|
-
:background_image_file)
|
9
|
-
end
|
10
|
-
|
11
|
-
class Team < Struct.new(:initial_player_positions,
|
12
|
-
:average_players_count,
|
13
|
-
:fast_players_count,
|
14
|
-
:captain_players_count)
|
15
|
-
end
|
16
|
-
|
17
|
-
class Ball < Struct.new(:width,
|
18
|
-
:height,
|
19
|
-
:image_file)
|
20
|
-
end
|
21
|
-
|
22
|
-
class Player < Struct.new(:time_to_kick_again,
|
23
|
-
:distance_control_ball,
|
24
|
-
:kick_strength,
|
25
|
-
:average_home_image_file,
|
26
|
-
:average_away_image_file,
|
27
|
-
:fast_home_image_file,
|
28
|
-
:fast_away_image_file,
|
29
|
-
:captain_home_image_file,
|
30
|
-
:captain_away_image_file)
|
31
|
-
end
|
32
|
-
|
33
|
-
class Goal < Struct.new(:image_file,
|
34
|
-
:sound_file)
|
35
|
-
end
|
36
|
-
|
37
|
-
class Game < Struct.new(:time,
|
38
|
-
:goal_image_position,
|
39
|
-
:time_label_position,
|
40
|
-
:score_home_label_position,
|
41
|
-
:score_away_label_position,
|
42
|
-
:max_name_length,
|
43
|
-
:default_font_size,
|
44
|
-
:team_label_font_size,
|
45
|
-
:team_label_width,
|
46
|
-
:home_team_label_position,
|
47
|
-
:away_team_label_position,
|
48
|
-
:background_sound_file)
|
49
|
-
end
|
50
|
-
|
51
|
-
class << self
|
52
|
-
def field
|
53
|
-
@field ||= Field.new
|
54
|
-
end
|
55
|
-
|
56
|
-
def team
|
57
|
-
@team ||= Team.new
|
58
|
-
end
|
59
|
-
|
60
|
-
def ball
|
61
|
-
@ball ||= Ball.new
|
62
|
-
end
|
63
|
-
|
64
|
-
def player
|
65
|
-
@player ||= Player.new
|
66
|
-
end
|
67
|
-
|
68
|
-
def goal
|
69
|
-
@goal ||= Goal.new
|
70
|
-
end
|
71
|
-
|
72
|
-
def game
|
73
|
-
@game ||= Game.new
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
data/lib/rubygoal/coordinate.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'gosu'
|
2
|
-
|
3
|
-
module Rubygoal
|
4
|
-
class Coordinate < Struct.new(:x, :y)
|
5
|
-
def distance(coordinate)
|
6
|
-
Gosu.distance(x, y, coordinate.x, coordinate.y)
|
7
|
-
end
|
8
|
-
|
9
|
-
def add(coordinate)
|
10
|
-
Coordinate.new(x + coordinate.x, y + coordinate.y)
|
11
|
-
end
|
12
|
-
|
13
|
-
def to_s
|
14
|
-
"(#{x}, #{y})"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class Position < Coordinate; end
|
19
|
-
|
20
|
-
class Velocity < Coordinate
|
21
|
-
def nonzero?
|
22
|
-
x != 0 && y != 0
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/rubygoal/field.rb
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'forwardable'
|
2
|
-
require 'gosu'
|
3
|
-
|
4
|
-
require 'rubygoal/ball'
|
5
|
-
require 'rubygoal/coach_loader'
|
6
|
-
require 'rubygoal/team'
|
7
|
-
require 'rubygoal/field_metrics'
|
8
|
-
require 'rubygoal/match'
|
9
|
-
require 'rubygoal/coaches/coach_home'
|
10
|
-
require 'rubygoal/coaches/coach_away'
|
11
|
-
|
12
|
-
module Rubygoal
|
13
|
-
class Field
|
14
|
-
attr_reader :ball, :team_home, :team_away
|
15
|
-
|
16
|
-
extend Forwardable
|
17
|
-
def_delegators :ball, :goal?
|
18
|
-
|
19
|
-
def initialize(game_window)
|
20
|
-
@game_window = game_window
|
21
|
-
@background_image = Gosu::Image.new(game_window, Config.field.background_image_file, true)
|
22
|
-
|
23
|
-
@ball = Ball.new(game_window, FieldMetrics.center_position)
|
24
|
-
|
25
|
-
coach_home = CoachLoader.get(CoachHome)
|
26
|
-
coach_away = CoachLoader.get(CoachAway)
|
27
|
-
|
28
|
-
puts "Home coach: #{coach_home.class.name}"
|
29
|
-
puts "Away coach: #{coach_away.class.name}"
|
30
|
-
|
31
|
-
@team_home = Team.new(game_window, :home, coach_home)
|
32
|
-
@team_away = Team.new(game_window, :away, coach_away)
|
33
|
-
end
|
34
|
-
|
35
|
-
def reinitialize
|
36
|
-
team_home.players_to_initial_position
|
37
|
-
team_away.players_to_initial_position
|
38
|
-
ball.position = FieldMetrics.center_position
|
39
|
-
end
|
40
|
-
|
41
|
-
def team_names
|
42
|
-
{
|
43
|
-
home: team_home.name,
|
44
|
-
away: team_away.name
|
45
|
-
}
|
46
|
-
end
|
47
|
-
|
48
|
-
def update
|
49
|
-
team_home.update(game_data(:home))
|
50
|
-
team_away.update(game_data(:away))
|
51
|
-
ball.update
|
52
|
-
end
|
53
|
-
|
54
|
-
def draw
|
55
|
-
background_image.draw(0, 0, 0);
|
56
|
-
ball.draw
|
57
|
-
team_home.draw
|
58
|
-
team_away.draw
|
59
|
-
end
|
60
|
-
|
61
|
-
private
|
62
|
-
|
63
|
-
def game_data(side)
|
64
|
-
case side
|
65
|
-
when :home
|
66
|
-
Match.new(
|
67
|
-
game_window.score_home,
|
68
|
-
game_window.score_away,
|
69
|
-
game_window.time,
|
70
|
-
team_away.formation
|
71
|
-
)
|
72
|
-
when :away
|
73
|
-
Match.new(
|
74
|
-
game_window.score_away,
|
75
|
-
game_window.score_home,
|
76
|
-
game_window.time,
|
77
|
-
team_home.formation
|
78
|
-
)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
attr_reader :background_image, :game_window
|
83
|
-
end
|
84
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
require 'rubygoal/config'
|
2
|
-
require 'rubygoal/coordinate'
|
3
|
-
require 'rubygoal/field_metrics'
|
4
|
-
|
5
|
-
module Rubygoal
|
6
|
-
module FieldMetrics
|
7
|
-
class << self
|
8
|
-
def center_position
|
9
|
-
center = Position.new(
|
10
|
-
Config.field.width / 2,
|
11
|
-
Config.field.height / 2
|
12
|
-
)
|
13
|
-
Config.field.offset.add(center)
|
14
|
-
end
|
15
|
-
|
16
|
-
def goal_position(side)
|
17
|
-
position = center_position
|
18
|
-
case side
|
19
|
-
when :home
|
20
|
-
position.x = Config.field.offset.x
|
21
|
-
when :away
|
22
|
-
position.x = Config.field.offset.x + Config.field.width
|
23
|
-
end
|
24
|
-
position
|
25
|
-
end
|
26
|
-
|
27
|
-
def initial_player_positions(side)
|
28
|
-
Config.team.initial_player_positions.map do |pos|
|
29
|
-
case side
|
30
|
-
when :home
|
31
|
-
Position.new(
|
32
|
-
Config.field.offset.x + pos[0],
|
33
|
-
Config.field.offset.y + pos[1]
|
34
|
-
)
|
35
|
-
when :away
|
36
|
-
Position.new(
|
37
|
-
Config.field.offset.x + Config.field.width - pos[0],
|
38
|
-
Config.field.offset.y + Config.field.height - pos[1]
|
39
|
-
)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def goalkeeper_position(side)
|
45
|
-
initial_player_positions(side).first
|
46
|
-
end
|
47
|
-
|
48
|
-
def position_side(position)
|
49
|
-
if position.x < FieldMetrics.center_position.x
|
50
|
-
:home
|
51
|
-
else
|
52
|
-
:away
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def out_of_bounds_width?(position)
|
57
|
-
lower_limit = Config.field.offset.x
|
58
|
-
upper_limit = Config.field.offset.x + Config.field.width
|
59
|
-
!(lower_limit..upper_limit).include?(position.x)
|
60
|
-
end
|
61
|
-
|
62
|
-
def out_of_bounds_height?(position)
|
63
|
-
lower_limit = Config.field.offset.y
|
64
|
-
upper_limit = Config.field.offset.y + Config.field.height
|
65
|
-
!(lower_limit..upper_limit).include?(position.y)
|
66
|
-
end
|
67
|
-
|
68
|
-
def goal?(position)
|
69
|
-
if out_of_bounds_width?(position)
|
70
|
-
lower_limit = center_position.y - Config.field.goal_height / 2
|
71
|
-
upper_limit = center_position.y + Config.field.goal_height / 2
|
72
|
-
|
73
|
-
(lower_limit..upper_limit).include?(position.y)
|
74
|
-
else
|
75
|
-
false
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def close_to_goal?(position, side)
|
80
|
-
goal_position = FieldMetrics.goal_position(side)
|
81
|
-
goal_position.distance(position) < Config.field.close_to_goal_distance
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|