1-- Dies ist der BlobbyVolley2 Bot "Hyperion" 2-- geschrieben und getestet wurde der Bot mit der SVN-Version 3-- Die Version Blobby0.6 hatte verschiedene Bugs, unter anderem bei der oppx() und der estimate() Funktion 4-- 5-- Hyperion ver. 0.6 6 7-- <Abschnitt 1> - Einige Konstanten die die physikalische Welt in BlobbyVolley2 beschreiben 8 9g=0.28 10g_p=0.88 11v0=14.5 12v_p=4.5 13jb_p=0.44 14r1=31.5 15 16-- </Abschnitt 1> 17 18 19-- <Abschnitt 2> - kleine unkomplizierte Hilfsfunktionen die ich benötige 20 21function max(a,b) 22 if (a>b) then 23 return a 24 else 25 return b 26 end 27end 28 29function min(a,b) 30 if (a<b) then 31 return a 32 else 33 return b 34 end 35end 36 37function y_b(y,vy,t) 38-- Eingabe: Position und Geschwindigkeit des Balles, Zeitpunkt an dem man die y-Koordinate des Balles wissen möchte 39-- Ausgabe: Höhe des Balles nach der Zeit t 40 return y+(vy-g/10)*t-1/2*g*t^2 41end 42 43function peak(y,vy) 44 return vy/g-1/10 45end 46 47function ymax_b(y,vy) 48 return y_b(v,vy,peak(y,vy)) 49end 50 51function move(x) 52 if (posx()<x) and (math.abs(posx()-x)>2.6) then right() 53 elseif (posx()>x) and (math.abs(posx()-x)>2.6) then left() 54 end 55end 56 57function t1_y(y,vy,height) 58-- Eingabe: Position und Geschwindigkeit des Balles, Höhe die der Ball erreichen soll 59-- Ausgabe: Ausgabe der Zeit bis zur Höhe height 60 if (vy^2/g^2-vy/(5*g)+1/100+2*(y-height)/g<0) then 61 return -1 62 else 63 return -1/10+vy/g-math.sqrt( vy^2/g^2-vy/(5*g)+1/100+2*(y-height)/g ) 64 end 65end 66 67function t2_y(y,vy,height) 68-- Eingabe: Position und Geschwindigkeit des Balles, Höhe die der Ball erreichen soll 69-- Ausgabe: Ausgabe der Zeit bis zur Höhe height 70 if (vy^2/g^2-vy/(5*g)+1/100+2*(y-height)/g<0) then 71 return -1 72 else 73 return -1/10+vy/g+math.sqrt( vy^2/g^2-vy/(5*g)+1/100+2*(y-height)/g ) 74 end 75end 76 77function y_p(y,t) 78-- Eingabe: Position und Geschwindigkeit des Players, Zeitpunkt an dem man die y-Koordinate des Players wissen möchte 79-- Ausgabe: Höhe des Players nach der Zeit t 80 return y+(v0+jb_p/2+g_p/10)*t-1/2*(g_p-jb_p)*t^2 81end 82 83tp_peak=(14.5+0.44/2+0.88/10)/(0.88-0.44) 84yp_max=y_p(144.5,tp_peak) 85 86function time(t) 87 return 1/5*math.ceil(5*t) 88end 89 90function t2_yp(y,vy,height) 91y=144.5 92 return (v0+jb_p/2+g_p/10)/(g_p-jb_p)+math.sqrt((v0+jb_p/2+g_p/10)^2/(g_p-jb_p)^2+2*y/(g_p-jb_p)) 93end 94-- </Abschnitt 2> 95 96 97-- <Abschnitt 3> - Komplizierte Funktionen die die Game-Engine nachbilden und so Einschlagpunkte, etc. berechnen. 98 99function collide(x,y,vx,vy,x2,y2,r2) 100-- Berechnet, ob und nach welcher Zeit der Ball im Zustand (x,y,vx,vy) mit der Kugel an (x2,y2) mit Radius r2 kollidiert 101local leftb=x2-r2-r1 102local rightb=x2+r2+r1 103local lowerb=y2-r2-r1 104local upperb=y2+r2+r1 105 106local txlb=time((leftb-x)/vx) -- Zeit zur linken Begrenzung 107local txrb=time((rightb-x)/vx) -- Zeit zur rechten Begrenzung 108local tyla=time(t1_y(y,vy,lowerb)) --untere Grenze steigend (ascending) 109local tyld=time(t2_y(y,vy,lowerb)) --untere Grenze fallend (descending) 110local tyua=time(t1_y(y,vy,upperb)) --obere Grenze steigend (ascending) 111local tyud=time(t2_y(y,vy,upperb)) --obere Grenze fallend (descending) 112local tp=time(vy/g-1/10) -- Zeit bis die Ballkurve auf dem Höhepunkt ist (kann in der Vergangenheit liegen) 113 114local t1,t2,t_coll=0,0,-1 115 116if (vx>0) then 117 t1=max(max(txlb,tyla),0) 118 t2=min(txrb,tyld) 119 else 120 t1=max(max(txrb,tyla),0) 121 t2=min(txlb,tyld) 122end 123 124if (t1<t2) and (t1<300) and (math.abs(t1-t2)<100) then 125 for t=t1,t2,0.2 do 126 local xnew,ynew=x+vx*t,y_b(y,vy,t) 127 if ((xnew-x2)^2+(ynew-y2)^2<(r1+r2)^2) then 128 t_coll=t 129 break 130 end 131 end 132end 133 134return t_coll 135end 136 137function estimate_t(x,y,vx,vy,height) 138-- schätzt den Ort des Balles bei der Höhe height fallend und die Zeit bis dahin 139 140local collision=1 141local t_wall,t_net,t_netsphere=0,0,0 142local t_ret,x_ret,y_ret,vx_ret,vy_ret=0,0,0,0,0 143local t_height=0 144while(collision==1) do 145 t_netsphere=collide(x,y,vx,vy,400,316,7) 146 if (vx>0) 147 then 148 t_wall=time((768.5-x)/vx) 149 t_net=time((361.5-x)/vx) 150 else 151 t_wall=time((31.5-x)/vx) 152 t_net=time((438.5-x)/vx) 153 end 154 local t=10000 155 if ((t_netsphere>0) and (t_netsphere<t)) then t=t_netsphere end 156 if (((t_net>0) and (t_net<t)) and (y_b(y,vy,t_net)<316)) then t=t_net end 157 if ((t_wall>0) and (t_wall<t)) then t=t_wall end 158 t_height=time(t2_y(y,vy,height)) 159 if (t_height>t) then 160 if (t==t_netsphere) then 161 t_ret=t_ret+t 162 vx_ret=0 163 vy_ret=0 164 x_ret=400 165 y_ret=316 166 collision=0 167 end 168 if (t==t_net) or (t==t_wall) then 169 t_ret=t_ret+t 170 x=x+vx*t 171 y=y_b(y,vy,t) 172 vx=-vx 173 vy=vy-g*t 174 collision=1 175 end 176 else 177 t_ret=t_ret+t_height 178 vx_ret=vx 179 vy_ret=vy-g*t_height 180 x_ret=x+vx*t_height 181 y_ret=y_b(y,vy,t_height) 182 collision=0 183 end 184 185 186end -- while Ende 187return x_ret,y_ret,vx_ret,vy_ret,t_ret 188end 189 190 191 192 193function impact(x,y,vx,vy,xpos,ypos) 194-- schätzt den Einschlagsort des Balles wenn er mit dem Blobby an Position xpos kollidiert ist und dann losfliegt. 195-- Funktioniert mit minimalem Fehler 196 197r1=31.5 198r2=25 199--local x,y,vx,vy,t1=estimate_t(x,y,vx,vy,(ypos+19+25)+31.5) Die Wete haben schon nahe genug zu sein 200local t=time(collide(x,y,vx,vy,xpos,ypos+19,25)) 201if(t>0) then 202 x=x+vx*t 203 y=y_b(y,vy,t) 204 dx=x-xpos 205 dy=y-(ypos+19) 206 l=math.sqrt(dx^2+dy^2) 207 vx=dx/l 208 vy=dy/l 209 x=x+vx*3 210 y=y+vy*3 211 vy=vy*13.125 212 vx=vx*13.125 213-- x=x+vx/5 214-- y=y+vy/5 215 x,y,vx,vy,t=estimate_t(x,y,vx,vy,220.5) 216 return x,y,vx,vy,t 217else 218 return -1,-1,-1,-1,-1 219end 220 221end -- Funktionsende 222 223function xtoplayto(target,height) 224 225local x,y,vx,vy,t=estimate_t(ballx(),bally(),bspeedx(),bspeedy(),height+(25+19)+31.5+5) 226local xpos=estimate_t(ballx(),bally(),bspeedx(),bspeedy(),height+(25+19)+31.5) 227local sgn=0 228if (x<target) then sgn=-1 else sgn=1 end 229local imp=0 230local oldimpact=-1000 231 232for pos=xpos,xpos+sgn*30,sgn*2.5 do 233 imp=impact(x,y,vx,vy,pos,height) 234 if (math.abs(imp-target)<math.abs(oldimpact-target)) then 235 oldimpact=imp 236 else 237 xpos=pos-sgn*2.5 238 break 239 end 240end 241 242return xpos 243end 244 245 246-- </Abschnitt 3> 247 248-- <Abschnitt 4> - High-Level Funktionen die bestimmen wo man s 249 250function stellen(tox,height) 251--t2_yp 252--t2_y 253if (tox<390) then 254 255elseif (390<tox) and (tox<410) then 256 257elseif (tox>410) then 258 259end 260 261move(xplayto(tox,posy())) 262end 263 264 265function schmettern() 266 267end 268 269function ueberspielen() 270 271end 272 273 274 275-- </Abschnitt 4> 276 277-- <Abschnitt 5> - Die Hauptfunktionen des Spiels 278function OnOpponentServe() 279end 280 281function OnServe(ballready) 282if (math.abs(math.floor(posx()/4.5)-posx()/4.5)<0.4) 283 then 284 if(math.abs(180-posx())<2) then jump() else moveto(180) end 285 else 286 moveto(400) 287 end 288 old=5 289end 290 291function OnGame() 292 293 294 295 296x1=ballx() 297y1=bally() 298vx1=bspeedx() 299vy1=bspeedy() 300x2=oppx() 301y2=163.5 302r2=25 303 304xe=estimate_t(x1,y1,vx1,vy1,220.5) 305--debug(xe) 306-- debug(x2) 307xr,yr,vxr,vyr,tr=impact(x1,y1,vx1,vy1,x2,144.5) 308 309 310-- debug(xr) 311-- debug(0) 312 313 314if (xe<400) then 315 316 if (touches()==0) then 317 test=xtoplayto(320,144.5) 318 move(test) 319 else 320 test=xtoplayto(400,144.5) 321 move(test-3.1) 322 end 323 324 325elseif (xe==400) then 326 move(180) 327else 328 move(180) 329end 330old=touches() 331end