UG_RRobots 1.2
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.
- 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
|
+
|