UG_RRobots 1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/rrobots +202 -0
- data/bin/tournament +413 -0
- data/config/rrobots.yml +15 -0
- data/contribs/allbots.rb +0 -0
- data/doc/manual.rdoc +126 -0
- data/doc/manual_fr.rdoc +129 -0
- data/images/explosion00.gif +0 -0
- data/images/explosion01.gif +0 -0
- data/images/explosion02.gif +0 -0
- data/images/explosion03.gif +0 -0
- data/images/explosion04.gif +0 -0
- data/images/explosion05.gif +0 -0
- data/images/explosion06.gif +0 -0
- data/images/explosion07.gif +0 -0
- data/images/explosion08.gif +0 -0
- data/images/explosion09.gif +0 -0
- data/images/explosion10.gif +0 -0
- data/images/explosion11.gif +0 -0
- data/images/explosion12.gif +0 -0
- data/images/explosion13.gif +0 -0
- data/images/explosion14.gif +0 -0
- data/images/red_body000.gif +0 -0
- data/images/red_body010.gif +0 -0
- data/images/red_body020.gif +0 -0
- data/images/red_body030.gif +0 -0
- data/images/red_body040.gif +0 -0
- data/images/red_body050.gif +0 -0
- data/images/red_body060.gif +0 -0
- data/images/red_body070.gif +0 -0
- data/images/red_body080.gif +0 -0
- data/images/red_body090.gif +0 -0
- data/images/red_body100.gif +0 -0
- data/images/red_body110.gif +0 -0
- data/images/red_body120.gif +0 -0
- data/images/red_body130.gif +0 -0
- data/images/red_body140.gif +0 -0
- data/images/red_body150.gif +0 -0
- data/images/red_body160.gif +0 -0
- data/images/red_body170.gif +0 -0
- data/images/red_body180.gif +0 -0
- data/images/red_body190.gif +0 -0
- data/images/red_body200.gif +0 -0
- data/images/red_body210.gif +0 -0
- data/images/red_body220.gif +0 -0
- data/images/red_body230.gif +0 -0
- data/images/red_body240.gif +0 -0
- data/images/red_body250.gif +0 -0
- data/images/red_body260.gif +0 -0
- data/images/red_body270.gif +0 -0
- data/images/red_body280.gif +0 -0
- data/images/red_body290.gif +0 -0
- data/images/red_body300.gif +0 -0
- data/images/red_body310.gif +0 -0
- data/images/red_body320.gif +0 -0
- data/images/red_body330.gif +0 -0
- data/images/red_body340.gif +0 -0
- data/images/red_body350.gif +0 -0
- data/images/red_radar000.gif +0 -0
- data/images/red_radar010.gif +0 -0
- data/images/red_radar020.gif +0 -0
- data/images/red_radar030.gif +0 -0
- data/images/red_radar040.gif +0 -0
- data/images/red_radar050.gif +0 -0
- data/images/red_radar060.gif +0 -0
- data/images/red_radar070.gif +0 -0
- data/images/red_radar080.gif +0 -0
- data/images/red_radar090.gif +0 -0
- data/images/red_radar100.gif +0 -0
- data/images/red_radar110.gif +0 -0
- data/images/red_radar120.gif +0 -0
- data/images/red_radar130.gif +0 -0
- data/images/red_radar140.gif +0 -0
- data/images/red_radar150.gif +0 -0
- data/images/red_radar160.gif +0 -0
- data/images/red_radar170.gif +0 -0
- data/images/red_radar180.gif +0 -0
- data/images/red_radar190.gif +0 -0
- data/images/red_radar200.gif +0 -0
- data/images/red_radar210.gif +0 -0
- data/images/red_radar220.gif +0 -0
- data/images/red_radar230.gif +0 -0
- data/images/red_radar240.gif +0 -0
- data/images/red_radar250.gif +0 -0
- data/images/red_radar260.gif +0 -0
- data/images/red_radar270.gif +0 -0
- data/images/red_radar280.gif +0 -0
- data/images/red_radar290.gif +0 -0
- data/images/red_radar300.gif +0 -0
- data/images/red_radar310.gif +0 -0
- data/images/red_radar320.gif +0 -0
- data/images/red_radar330.gif +0 -0
- data/images/red_radar340.gif +0 -0
- data/images/red_radar350.gif +0 -0
- data/images/red_turret000.gif +0 -0
- data/images/red_turret010.gif +0 -0
- data/images/red_turret020.gif +0 -0
- data/images/red_turret030.gif +0 -0
- data/images/red_turret040.gif +0 -0
- data/images/red_turret050.gif +0 -0
- data/images/red_turret060.gif +0 -0
- data/images/red_turret070.gif +0 -0
- data/images/red_turret080.gif +0 -0
- data/images/red_turret090.gif +0 -0
- data/images/red_turret100.gif +0 -0
- data/images/red_turret110.gif +0 -0
- data/images/red_turret120.gif +0 -0
- data/images/red_turret130.gif +0 -0
- data/images/red_turret140.gif +0 -0
- data/images/red_turret150.gif +0 -0
- data/images/red_turret160.gif +0 -0
- data/images/red_turret170.gif +0 -0
- data/images/red_turret180.gif +0 -0
- data/images/red_turret190.gif +0 -0
- data/images/red_turret200.gif +0 -0
- data/images/red_turret210.gif +0 -0
- data/images/red_turret220.gif +0 -0
- data/images/red_turret230.gif +0 -0
- data/images/red_turret240.gif +0 -0
- data/images/red_turret250.gif +0 -0
- data/images/red_turret260.gif +0 -0
- data/images/red_turret270.gif +0 -0
- data/images/red_turret280.gif +0 -0
- data/images/red_turret290.gif +0 -0
- data/images/red_turret300.gif +0 -0
- data/images/red_turret310.gif +0 -0
- data/images/red_turret320.gif +0 -0
- data/images/red_turret330.gif +0 -0
- data/images/red_turret340.gif +0 -0
- data/images/red_turret350.gif +0 -0
- data/images/toolbox.gif +0 -0
- data/lib/battlefield.rb +102 -0
- data/lib/bullets.rb +39 -0
- data/lib/configuration.rb +26 -0
- data/lib/explosions.rb +20 -0
- data/lib/overloads.rb +10 -0
- data/lib/robot.rb +122 -0
- data/lib/robotrunner.rb +260 -0
- data/lib/tkarena.rb +197 -0
- data/lib/toolboxes.rb +28 -0
- data/robots/BillDuck.rb +92 -0
- data/robots/BotOne.rb +39 -0
- data/robots/DuckBill.rb +384 -0
- data/robots/DuckBill04.rb +330 -0
- data/robots/DuckToEndAllDucks.rb +140 -0
- data/robots/EdgeBot.rb +203 -0
- data/robots/HuntingDuck.rb +74 -0
- data/robots/HyperactiveDuck.rb +15 -0
- data/robots/Killer.rb +58 -0
- data/robots/Kite.rb +193 -0
- data/robots/KoDuck.rb +57 -0
- data/robots/LinearShooter.rb +279 -0
- data/robots/LuckyDuck.rb +83 -0
- data/robots/MoxonoM.rb +85 -0
- data/robots/MsgBot.rb +13 -0
- data/robots/NervousDuck.rb +13 -0
- data/robots/Polisher.rb +15 -0
- data/robots/RomBot.rb +514 -0
- data/robots/RoomPainter.rb +205 -0
- data/robots/Rrrkele.rb +48 -0
- data/robots/Seeker.rb +57 -0
- data/robots/ShootingStation.rb +15 -0
- data/robots/SittingDuck.rb +18 -0
- data/robots/SniperDuck.rb +277 -0
- data/robots/WallPainter.rb +224 -0
- metadata +220 -0
data/robots/MsgBot.rb
ADDED
data/robots/Polisher.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'robot'
|
2
|
+
class Polisher
|
3
|
+
include Robot
|
4
|
+
def tick events
|
5
|
+
@min_distance = (events['robot_scanned'].min || [0]).first
|
6
|
+
@radar_scan ||= 20.0
|
7
|
+
@mid ||= (((x - battlefield_width / 2).abs < 400) and ((y - battlefield_height / 2).abs < 400))
|
8
|
+
accelerate(@mid ? (Math.sin(time*0.1)*2)+0.8 : 1.0)
|
9
|
+
turn(@mid ? 10 : 2)
|
10
|
+
@radar_scan = events['robot_scanned'].empty? ? [40.0,@radar_scan*1.5].min : [15.0,@radar_scan*0.5].max
|
11
|
+
@rt = (@radar_scan > 39.0) ? @radar_scan : @radar_scan*((time % 2)-0.5)
|
12
|
+
turn_gun @rt - (@mid ? 10 : 2)
|
13
|
+
fire 3
|
14
|
+
end
|
15
|
+
end
|
data/robots/RomBot.rb
ADDED
@@ -0,0 +1,514 @@
|
|
1
|
+
require 'robot'
|
2
|
+
|
3
|
+
# utilisation des matrices
|
4
|
+
require 'matrix'
|
5
|
+
|
6
|
+
|
7
|
+
module MathRobot
|
8
|
+
|
9
|
+
def coef_dir(point_1,point_2)
|
10
|
+
x1,y1 = point_1
|
11
|
+
x2,y2 = point_2
|
12
|
+
return (y2-y1)/(x2-x1)
|
13
|
+
end
|
14
|
+
|
15
|
+
def ordonne_origine(a,point)
|
16
|
+
x,y = point
|
17
|
+
return y - a*x
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
# calcule vectoriel pour déterminer l'angle de tir pour le prédicat fait avec la regression lineaire
|
22
|
+
# en utilisant le coeficient directeur a de ma f(x) = ax + b trouvé
|
23
|
+
|
24
|
+
# dfférence de deux vecteur
|
25
|
+
def diff_vecteur(a,b)
|
26
|
+
return a.zip(b).map{|a,b| a - b}
|
27
|
+
end
|
28
|
+
|
29
|
+
# Produit scalaire carré du vecteur
|
30
|
+
def carre_scalaire_du_vecteur(a)
|
31
|
+
return produit_scalaire(a,a)
|
32
|
+
end
|
33
|
+
|
34
|
+
# produit_scalaire
|
35
|
+
def produit_scalaire(a,b)
|
36
|
+
return a.zip(b).map{|a,b| a*b}.inject(0){|a,b| a+b}
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
# On Utilise un régression linéaire pour déterminer le coef dir à suivre f(x) = ax + b
|
41
|
+
def reg_linaire(liste_x,liste_y)
|
42
|
+
somme_des_produits = 0.0
|
43
|
+
somme_des_x_au_carre = 0.0
|
44
|
+
somme_des_x = 0.0
|
45
|
+
somme_des_y = 0.0
|
46
|
+
taille = liste_x.size
|
47
|
+
# ma surcharge de Array va pas suffire
|
48
|
+
somme_des_x = liste_x.sum
|
49
|
+
somme_des_y = liste_y.sum
|
50
|
+
taille.times {|i|
|
51
|
+
somme_des_produits += liste_x[i]*liste_y[i]
|
52
|
+
somme_des_x_au_carre += liste_x[i]*liste_x[i]
|
53
|
+
}
|
54
|
+
# calcule de a et b selon une regression linaire
|
55
|
+
b = (taille*somme_des_produits - somme_des_x*somme_des_y) / (taille*somme_des_x_au_carre - somme_des_x*somme_des_x)
|
56
|
+
a = (somme_des_y - b*somme_des_x) / taille
|
57
|
+
|
58
|
+
raise ListeCoordTropPetite if a.nan? or b.nan? # on leve si a ou b tend vers - l'infini
|
59
|
+
|
60
|
+
return [a,b]
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
# Surcharge de Array pour calcule de Reg Lin
|
68
|
+
class Array
|
69
|
+
def sum
|
70
|
+
sumit = 0
|
71
|
+
self.each do |item|
|
72
|
+
sumit += item
|
73
|
+
end
|
74
|
+
return sumit
|
75
|
+
end
|
76
|
+
def mean
|
77
|
+
return self.sum / self.size
|
78
|
+
end
|
79
|
+
def max
|
80
|
+
self.sort.last
|
81
|
+
end
|
82
|
+
def min
|
83
|
+
self.sort.first
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
# surcharge de Float pour le round
|
89
|
+
|
90
|
+
class Float
|
91
|
+
def round2(precision=2)
|
92
|
+
return ("%01.#{precision}f" %self).to_f
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
class RobotConfig
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
# configuration du RomBot
|
102
|
+
attr_reader :vitesse_max_robot
|
103
|
+
attr_reader :calcul_taux_obux
|
104
|
+
attr_reader :range_correcteur_linaire
|
105
|
+
attr_reader :taux_de_tir_haut
|
106
|
+
attr_reader :taux_de_tir_bas
|
107
|
+
attr_reader :debug
|
108
|
+
attr_reader :critere_crise
|
109
|
+
attr_reader :mode_esquive
|
110
|
+
attr_reader :mode_say
|
111
|
+
attr_reader :critere_crise_vie_perte
|
112
|
+
attr_reader :critere_crise_vie_duree
|
113
|
+
attr_reader :cible_proche
|
114
|
+
attr_reader :cible_loin
|
115
|
+
|
116
|
+
def initialize
|
117
|
+
@vitesse_max_robot = 7 # max 8 min 1
|
118
|
+
@calcul_taux_obux = 30
|
119
|
+
@range_correcteur_linaire = 2 # taille de la range de mon predicteur
|
120
|
+
@taux_de_tir_haut = 0.1
|
121
|
+
@taux_de_tir_bas = 2
|
122
|
+
@debug = true
|
123
|
+
@critere_crise = 10
|
124
|
+
@mode_esquive = false
|
125
|
+
@mode_say = true
|
126
|
+
@critere_crise_vie_perte = 10
|
127
|
+
@critere_crise_vie_duree = 10
|
128
|
+
@cible_proche = 200
|
129
|
+
@cible_loin = 1000
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
|
135
|
+
|
136
|
+
class RomBot
|
137
|
+
|
138
|
+
include MathRobot
|
139
|
+
include Robot
|
140
|
+
|
141
|
+
def tick events
|
142
|
+
config_initiale if time == 0
|
143
|
+
maj_donnees_radar(events)
|
144
|
+
maj_donnees_canon
|
145
|
+
maj_context
|
146
|
+
reglage_taux_de_tir
|
147
|
+
detection_toolboxes(events)
|
148
|
+
if situation_crise?(events) then
|
149
|
+
@botlog.write "Situation de crise : #{@cumul_crise}\n" if @config.debug
|
150
|
+
speed = 0 if @config.mode_esquive
|
151
|
+
@taux_de_tir = @config.taux_de_tir_bas # Forçage de tir de puissance
|
152
|
+
end
|
153
|
+
accelerate 1
|
154
|
+
@botlog.write "vitesse = #{speed}\n" if @config.debug
|
155
|
+
say_msg if @config.mode_say
|
156
|
+
turn_radar(decalage_radar - @vitesse_arme_relative - @vitesse_agulaire)
|
157
|
+
turn_gun(@vitesse_arme_relative - @vitesse_agulaire)
|
158
|
+
turn(@vitesse_agulaire )
|
159
|
+
maj_vie_time
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
def detection_toolboxes(events)
|
164
|
+
unless events['toolbox_scanned'].empty? then
|
165
|
+
@botlog.write "scan toolbox #{events} pour time = #{time}\n"
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
def reglage_taux_de_tir
|
172
|
+
unless @distance_cible_plus_proche.nil?
|
173
|
+
dist = @distance_cible_plus_proche.to_i
|
174
|
+
|
175
|
+
if dist > @config.cible_proche and dist < @config.cible_loin then
|
176
|
+
@taux_de_tir = dist * @coef_dir_taux_de_tir + @ordonne_origine_taux_de_tir
|
177
|
+
@taux_de_tir = @taux_de_tir.round2(1)
|
178
|
+
elsif dist <= @config.cible_proche then
|
179
|
+
@taux_de_tir = @config.taux_de_tir_haut
|
180
|
+
elsif dist >= @config.cible_loin then
|
181
|
+
@taux_de_tir = @config.taux_de_tir_bas
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
def maj_vie_time
|
188
|
+
@botlog.write "energie = #{energy.to_i}\n" if @config.debug
|
189
|
+
if time == @time_derniere + @config.critere_crise_vie_duree then
|
190
|
+
if @check_vie_derniere - energy.to_i >= @config.critere_crise_vie_perte then
|
191
|
+
@cumul_crise += @config.critere_crise unless (@cumul_crise > @config.critere_crise)
|
192
|
+
@botlog.write "energie crise\n" if @config.debug
|
193
|
+
end
|
194
|
+
@check_vie_derniere = energy.to_i
|
195
|
+
@time_derniere = time
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
|
200
|
+
def situation_crise?(events)
|
201
|
+
res = false
|
202
|
+
# @botlog.write("scan cible x : #{@pos_cible_ennemi_x}\t y : #{@pos_cible_ennemi_y}\t pour time = #{time}\n") if @config.debug
|
203
|
+
unless events['got_hit'].empty? then
|
204
|
+
@cumul_crise += events['got_hit'].size
|
205
|
+
else
|
206
|
+
@cumul_crise -= 1 if @cumul_crise > 0
|
207
|
+
end
|
208
|
+
res = true if @cumul_crise > @config.critere_crise
|
209
|
+
return res
|
210
|
+
end
|
211
|
+
|
212
|
+
|
213
|
+
def say_msg
|
214
|
+
chaine = String::new
|
215
|
+
chaine << "X: #{x.to_i} "
|
216
|
+
chaine << "Y: #{y.to_i}\n"
|
217
|
+
chaine <<"DEBUG\n" if @config.debug
|
218
|
+
chaine << "ESQUIVE\n" if @config.mode_esquive
|
219
|
+
chaine << "Energy : #{energy.to_i}\n"
|
220
|
+
chaine << "Critic #{@cumul_crise}"
|
221
|
+
chaine << " !!" if @cumul_crise > @config.critere_crise
|
222
|
+
chaine << "\n"
|
223
|
+
chaine << "Speed : #{speed}\n"
|
224
|
+
chaine << "Fire rate : #{@taux_de_tir}\n"
|
225
|
+
chaine << "Proxy : #{@distance_cible_plus_proche.to_i}" unless @distance_cible_plus_proche.nil?
|
226
|
+
chaine << @msg
|
227
|
+
say chaine
|
228
|
+
end
|
229
|
+
|
230
|
+
|
231
|
+
|
232
|
+
def mode_recherche
|
233
|
+
@vitesse_base_radar = limiteur(@vitesse_base_radar + amplitude_angle_vers_cible_ennemi, 0, 60)
|
234
|
+
|
235
|
+
if @cumul_ticks > 0
|
236
|
+
@cumul_ticks -= 1
|
237
|
+
if @cumul_ticks == 0
|
238
|
+
@radar_direction *= -1
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
def debut_detection(dist)
|
244
|
+
@contexte_prevision_time = beam_center
|
245
|
+
@uptick_dist = dist
|
246
|
+
end
|
247
|
+
|
248
|
+
def cible_verrouille(dist)
|
249
|
+
@uptick_dist = dist
|
250
|
+
end
|
251
|
+
|
252
|
+
def perte_cible
|
253
|
+
@radar_direction *= -1
|
254
|
+
@vitesse_base_radar = limiteur(@vitesse_base_radar * 0.5, amplitude_angle_vers_cible_ennemi, 60)
|
255
|
+
marquage_cible_ennemi(angle_median(angle_median(@contexte_radar_precedant,@plus_vielle_detection_radar),@contexte_prevision_time),@uptick_dist)
|
256
|
+
@cumul_ticks = 8
|
257
|
+
end
|
258
|
+
|
259
|
+
def beam_center
|
260
|
+
angle_median(radar_heading, @contexte_radar_precedant)
|
261
|
+
end
|
262
|
+
|
263
|
+
def tirer_canon(propagation)
|
264
|
+
# je tire tout le temps même quand je suis pas en mode accrochage ou debut accrochage
|
265
|
+
# if propagation < 1
|
266
|
+
fire @taux_de_tir
|
267
|
+
# end
|
268
|
+
end
|
269
|
+
|
270
|
+
|
271
|
+
def maj_donnees_radar(events)
|
272
|
+
if events['robot_scanned'].empty?
|
273
|
+
if @cible_scannee
|
274
|
+
perte_cible
|
275
|
+
@msg = "LOOSE"
|
276
|
+
@botlog.write "perte cible\n" if @config.debug
|
277
|
+
else
|
278
|
+
@msg = "SCAN"
|
279
|
+
@botlog.write "scan cible\n" if @config.debug
|
280
|
+
mode_recherche
|
281
|
+
end
|
282
|
+
@cible_scannee = false
|
283
|
+
else
|
284
|
+
td = events['robot_scanned'].min.first
|
285
|
+
@distance_cible_plus_proche = td
|
286
|
+
if @cible_scannee
|
287
|
+
@msg = "LOCK"
|
288
|
+
@botlog.write "cible locke\n" if @config.debug
|
289
|
+
cible_verrouille(td)
|
290
|
+
else
|
291
|
+
@msg = "SEEK"
|
292
|
+
@botlog.write "acquisition cible\n" if @config.debug
|
293
|
+
debut_detection(td)
|
294
|
+
end
|
295
|
+
@cible_scannee = true
|
296
|
+
end
|
297
|
+
@plus_vielle_detection_radar = @contexte_radar_precedant
|
298
|
+
@contexte_radar_precedant = radar_heading
|
299
|
+
end
|
300
|
+
|
301
|
+
|
302
|
+
def maj_donnees_canon
|
303
|
+
diff = angle_direction(gun_heading, @detecteur.angle_de_tir(x,y,time))
|
304
|
+
@vitesse_arme_relative = limiteur(diff,-30,30)
|
305
|
+
tirer_canon(diff)
|
306
|
+
rescue ListeCoordTropPetite
|
307
|
+
end
|
308
|
+
|
309
|
+
def anti_collision_murs(range)
|
310
|
+
(2**((battlefield_width - range)/50.0))/(2**(battlefield_width/50.0))
|
311
|
+
end
|
312
|
+
|
313
|
+
def maj_context
|
314
|
+
ranges = [x-size, battlefield_height-size-y, battlefield_width-size-x, y-size]
|
315
|
+
normals = [0, 90, 180, 270]
|
316
|
+
forces = ranges.map {|r| anti_collision_murs(r)}
|
317
|
+
|
318
|
+
@xforce = forces[0] - forces[2]
|
319
|
+
@yforce = forces[3] - forces[1]
|
320
|
+
fa = Math.atan2(-@yforce,@xforce).to_deg
|
321
|
+
|
322
|
+
objectif = trajectoire_cible_ennemi + 90
|
323
|
+
unless soustraction_angles(heading, objectif) < 90
|
324
|
+
objectif = (objectif + 180) % 360
|
325
|
+
end
|
326
|
+
|
327
|
+
diff = angle_direction(objectif, fa)
|
328
|
+
objectif += diff*(forces.max)
|
329
|
+
@vitesse_agulaire = limiteur(angle_direction(heading, objectif),-10,10)
|
330
|
+
end
|
331
|
+
|
332
|
+
|
333
|
+
def config_initiale
|
334
|
+
|
335
|
+
@config = RobotConfig.new
|
336
|
+
|
337
|
+
# log file
|
338
|
+
@botlog = File.open("Rombot.log","w") if @config.debug
|
339
|
+
@botlog.write "Démmarrage du RomBot\n" if @config.debug
|
340
|
+
@coef_dir_taux_de_tir = coef_dir([@config.cible_proche,@config.taux_de_tir_bas],[@config.cible_loin,@config.taux_de_tir_haut])
|
341
|
+
@ordonne_origine_taux_de_tir = ordonne_origine( @coef_dir_taux_de_tir, [@config.cible_proche,@config.taux_de_tir_bas])
|
342
|
+
@botlog.write "le taux de tir répond à : f(x) = #{@coef_dir_taux_de_tir}.x + #{@ordonne_origine_taux_de_tir}\n" if @config.debug
|
343
|
+
@msg = "INIT"
|
344
|
+
@touche = false
|
345
|
+
@vitesse_base_radar = 60
|
346
|
+
@radar_direction = 1
|
347
|
+
@contexte_radar_precedant = 0
|
348
|
+
@plus_vielle_detection_radar = 0
|
349
|
+
@cumul_ticks = 0
|
350
|
+
@cumul_crise = 0
|
351
|
+
@taux_de_tir = @config.taux_de_tir_haut
|
352
|
+
@cible_scannee = false
|
353
|
+
@contexte_prevision_time = 0
|
354
|
+
@pos_cible_ennemi_x = @pos_cible_ennemi_y = 0
|
355
|
+
@vitesse_arme_relative = 0
|
356
|
+
@vitesse_agulaire = 0
|
357
|
+
@detecteur = DetecteurPredictif.new
|
358
|
+
@check_vie_derniere = 100
|
359
|
+
@time_derniere = 0
|
360
|
+
@distance_cible_plus_proche = 1800
|
361
|
+
|
362
|
+
@botlog.write "Fin INIT \n" if @config.debug
|
363
|
+
end
|
364
|
+
|
365
|
+
def soustraction_angles(a,b)
|
366
|
+
d = (a % 360 - b % 360).abs
|
367
|
+
d > 180 ? 360 - d : d
|
368
|
+
end
|
369
|
+
|
370
|
+
# définir le décalage positif ou negatif
|
371
|
+
def angle_direction(a,b)
|
372
|
+
azimut = soustraction_angles(a,b)
|
373
|
+
if soustraction_angles(a + 1, b) < azimut
|
374
|
+
azimut
|
375
|
+
else
|
376
|
+
-azimut
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
def decalage_radar
|
381
|
+
@vitesse_base_radar * @radar_direction
|
382
|
+
end
|
383
|
+
|
384
|
+
def angle_median(a,b)
|
385
|
+
(angle_direction(a,b) / 2 + a) % 360
|
386
|
+
end
|
387
|
+
|
388
|
+
def amplitude_angle_vers_cible_ennemi
|
389
|
+
360 * @config.vitesse_max_robot / (2 * Math::PI * distance_cible_ennemi)
|
390
|
+
end
|
391
|
+
|
392
|
+
def trajectoire_cible_ennemi
|
393
|
+
Math.atan2(y- @pos_cible_ennemi_y, @pos_cible_ennemi_x - x).to_deg
|
394
|
+
end
|
395
|
+
|
396
|
+
def distance_cible_ennemi
|
397
|
+
Math.sqrt((@pos_cible_ennemi_x - x)**2 + (@pos_cible_ennemi_y - y)**2)
|
398
|
+
end
|
399
|
+
|
400
|
+
def marquage_cible_ennemi(trajectoire, distance)
|
401
|
+
rads = trajectoire.to_rad
|
402
|
+
@pos_cible_ennemi_y = y - distance * Math.sin(rads)
|
403
|
+
@pos_cible_ennemi_x = x + distance * Math.cos(rads)
|
404
|
+
@detecteur.marquage(@pos_cible_ennemi_x,@pos_cible_ennemi_y,time)
|
405
|
+
@botlog.write("scan cible x : #{@pos_cible_ennemi_x}\t y : #{@pos_cible_ennemi_y}\t pour time = #{time}\n") if @config.debug
|
406
|
+
|
407
|
+
end
|
408
|
+
|
409
|
+
def limiteur(var, min, max)
|
410
|
+
val = 0 + var
|
411
|
+
if val > max
|
412
|
+
max
|
413
|
+
elsif val < min
|
414
|
+
min
|
415
|
+
else
|
416
|
+
val
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
end
|
421
|
+
|
422
|
+
# classe d'exception pour les moindres carrés
|
423
|
+
class ListeCoordTropPetite < RuntimeError; end
|
424
|
+
|
425
|
+
|
426
|
+
class DetecteurPredictif
|
427
|
+
|
428
|
+
|
429
|
+
include MathRobot
|
430
|
+
|
431
|
+
def initialize(taille = 4)
|
432
|
+
@config = RobotConfig.new
|
433
|
+
@taille = taille || @config.range_correcteur_linaire
|
434
|
+
@x = Array.new(@taille,0)
|
435
|
+
@y = Array.new(@taille,0)
|
436
|
+
@t = Array.new(@taille,0)
|
437
|
+
@most_recent = 0
|
438
|
+
@solution = nil
|
439
|
+
end
|
440
|
+
|
441
|
+
|
442
|
+
|
443
|
+
def resoud
|
444
|
+
coef_dir_x, vx = reg_linaire(@t, @x)
|
445
|
+
coef_dir_y, vy = reg_linaire(@t, @y)
|
446
|
+
return [vx,vy,coef_dir_x,coef_dir_y]
|
447
|
+
end
|
448
|
+
|
449
|
+
# predits la position de la cible pour un time donné
|
450
|
+
def predit(time)
|
451
|
+
raise ListeCoordTropPetite unless @solution
|
452
|
+
vx, vy, coef_dir_x, coef_dir_y = @solution
|
453
|
+
[coef_dir_x + vx*time, coef_dir_y + vy*time]
|
454
|
+
end
|
455
|
+
|
456
|
+
|
457
|
+
def marquage(x,y,time)
|
458
|
+
@most_recent = (@most_recent + 1) % @taille
|
459
|
+
@x[@most_recent] = x
|
460
|
+
@y[@most_recent] = y
|
461
|
+
@t[@most_recent] = time
|
462
|
+
@solution = resoud
|
463
|
+
rescue
|
464
|
+
end
|
465
|
+
|
466
|
+
|
467
|
+
|
468
|
+
def point_cible(mon_x, mon_y, time)
|
469
|
+
raise ListeCoordTropPetite unless @solution
|
470
|
+
t = 0
|
471
|
+
loop do
|
472
|
+
x,y = predit(time+t) # on se base sur le dernier prédicat fiable
|
473
|
+
break if carre_scalaire_du_vecteur(diff_vecteur([x,y],[mon_x,mon_y])) < @config.calcul_taux_obux*@config.calcul_taux_obux*t*t
|
474
|
+
t += 1
|
475
|
+
raise ListeCoordTropPetite if t > 100
|
476
|
+
end
|
477
|
+
predit(time+t)
|
478
|
+
end
|
479
|
+
|
480
|
+
# calcule e fonction des coordonné du point cible de l'angle de tir via l'Arctangente du vecteur entre source tank et cible
|
481
|
+
def angle_de_tir(mon_x,mon_y,time)
|
482
|
+
x,y = point_cible(mon_x,mon_y,time)
|
483
|
+
Math.atan2(mon_y-y,x-mon_x).to_deg
|
484
|
+
end
|
485
|
+
|
486
|
+
|
487
|
+
# On Utilise un régression linéaire pour déterminer le coef dir à suivre f(x) = ax + b
|
488
|
+
def reg_linaire(liste_x,liste_y)
|
489
|
+
somme_des_produits = 0.0
|
490
|
+
somme_des_x_au_carre = 0.0
|
491
|
+
somme_des_x = 0.0
|
492
|
+
somme_des_y = 0.0
|
493
|
+
taille = liste_x.size
|
494
|
+
# ma surcharge de Array va pas suffire
|
495
|
+
somme_des_x = liste_x.sum
|
496
|
+
somme_des_y = liste_y.sum
|
497
|
+
taille.times {|i|
|
498
|
+
somme_des_produits += liste_x[i]*liste_y[i]
|
499
|
+
somme_des_x_au_carre += liste_x[i]*liste_x[i]
|
500
|
+
}
|
501
|
+
# calcule de a et b selon une regression linaire
|
502
|
+
b = (taille*somme_des_produits - somme_des_x*somme_des_y) / (taille*somme_des_x_au_carre - somme_des_x*somme_des_x)
|
503
|
+
a = (somme_des_y - b*somme_des_x) / taille
|
504
|
+
|
505
|
+
raise ListeCoordTropPetite if a.nan? or b.nan? # on leve si a ou b tend vers - l'infini
|
506
|
+
|
507
|
+
return [a,b]
|
508
|
+
end
|
509
|
+
|
510
|
+
|
511
|
+
|
512
|
+
end
|
513
|
+
|
514
|
+
|