hedgewars/uAIAmmoTests.pas
changeset 2948 3f21a9dc93d0
parent 2695 ed789a7ef68d
child 2973 b51a0f57cd43
equal deleted inserted replaced
2947:803b277e4894 2948:3f21a9dc93d0
    22 interface
    22 interface
    23 uses SDLh, uGears, uConsts, uFloat;
    23 uses SDLh, uGears, uConsts, uFloat;
    24 const amtest_OnTurn = $00000001;
    24 const amtest_OnTurn = $00000001;
    25 
    25 
    26 type TAttackParams = record
    26 type TAttackParams = record
    27 			Time: Longword;
    27             Time: Longword;
    28 			Angle, Power: LongInt;
    28             Angle, Power: LongInt;
    29 			ExplX, ExplY, ExplR: LongInt;
    29             ExplX, ExplY, ExplR: LongInt;
    30 			AttackPutX, AttackPutY: LongInt;
    30             AttackPutX, AttackPutY: LongInt;
    31 			end;
    31             end;
    32 
    32 
    33 function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    33 function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    34 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    34 function TestGrenade(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    35 function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    35 function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    36 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    36 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    38 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    38 function TestBaseballBat(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    39 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    39 function TestFirePunch(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    40 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    40 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    41 
    41 
    42 type TAmmoTestProc = function (Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    42 type TAmmoTestProc = function (Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
    43 	TAmmoTest = record
    43     TAmmoTest = record
    44 			proc: TAmmoTestProc;
    44             proc: TAmmoTestProc;
    45 			flags: Longword;
    45             flags: Longword;
    46 			end;
    46             end;
    47 
    47 
    48 const AmmoTests: array[TAmmoType] of TAmmoTest =
    48 const AmmoTests: array[TAmmoType] of TAmmoTest =
    49 			(
    49             (
    50 			(proc: nil;              flags: 0), // amNothing
    50             (proc: nil;              flags: 0), // amNothing
    51 			(proc: @TestGrenade;     flags: 0), // amGrenade
    51             (proc: @TestGrenade;     flags: 0), // amGrenade
    52 			(proc: nil;              flags: 0), // amClusterBomb
    52             (proc: nil;              flags: 0), // amClusterBomb
    53 			(proc: @TestBazooka;     flags: 0), // amBazooka
    53             (proc: @TestBazooka;     flags: 0), // amBazooka
    54 			(proc: nil;              flags: 0), // amUFO
    54             (proc: nil;              flags: 0), // amUFO
    55 			(proc: @TestShotgun;     flags: 0), // amShotgun
    55             (proc: @TestShotgun;     flags: 0), // amShotgun
    56 			(proc: nil;              flags: 0), // amPickHammer
    56             (proc: nil;              flags: 0), // amPickHammer
    57 			(proc: nil;              flags: 0), // amSkip
    57             (proc: nil;              flags: 0), // amSkip
    58 			(proc: nil;              flags: 0), // amRope
    58             (proc: nil;              flags: 0), // amRope
    59 			(proc: nil;              flags: 0), // amMine
    59             (proc: nil;              flags: 0), // amMine
    60 			(proc: @TestDesertEagle; flags: 0), // amDEagle
    60             (proc: @TestDesertEagle; flags: 0), // amDEagle
    61 			(proc: nil;              flags: 0), // amDynamite
    61             (proc: nil;              flags: 0), // amDynamite
    62 			(proc: @TestFirePunch;   flags: 0), // amFirePunch
    62             (proc: @TestFirePunch;   flags: 0), // amFirePunch
    63 			(proc: nil;              flags: 0), // amWhip
    63             (proc: nil;              flags: 0), // amWhip
    64 			(proc: @TestBaseballBat; flags: 0), // amBaseballBat
    64             (proc: @TestBaseballBat; flags: 0), // amBaseballBat
    65 			(proc: nil;              flags: 0), // amParachute
    65             (proc: nil;              flags: 0), // amParachute
    66 			(proc: @TestAirAttack;   flags: amtest_OnTurn), // amAirAttack
    66             (proc: @TestAirAttack;   flags: amtest_OnTurn), // amAirAttack
    67 			(proc: nil;              flags: 0), // amMineStrike
    67             (proc: nil;              flags: 0), // amMineStrike
    68 			(proc: nil;              flags: 0), // amBlowTorch
    68             (proc: nil;              flags: 0), // amBlowTorch
    69 			(proc: nil;              flags: 0), // amGirder
    69             (proc: nil;              flags: 0), // amGirder
    70 			(proc: nil;              flags: amtest_OnTurn), // amTeleport
    70             (proc: nil;              flags: amtest_OnTurn), // amTeleport
    71 			(proc: nil;              flags: 0), // amSwitch
    71             (proc: nil;              flags: 0), // amSwitch
    72 			(proc: @TestMortar;      flags: 0), // amMortar
    72             (proc: @TestMortar;      flags: 0), // amMortar
    73 			(proc: nil;              flags: 0), // amKamikaze
    73             (proc: nil;              flags: 0), // amKamikaze
    74 			(proc: nil;              flags: 0), // amCake
    74             (proc: nil;              flags: 0), // amCake
    75 			(proc: nil;              flags: 0), // amSeduction
    75             (proc: nil;              flags: 0), // amSeduction
    76 			(proc: nil;              flags: 0), // amBanana
    76             (proc: nil;              flags: 0), // amBanana
    77 			(proc: nil;              flags: 0), // amHellishBomb
    77             (proc: nil;              flags: 0), // amHellishBomb
    78 			(proc: nil;              flags: 0), // amNapalm
    78             (proc: nil;              flags: 0), // amNapalm
    79 			(proc: nil;              flags: 0), // amDrill
    79             (proc: nil;              flags: 0), // amDrill
    80 			(proc: nil;              flags: 0), // amBallgun
    80             (proc: nil;              flags: 0), // amBallgun
    81 			(proc: nil;              flags: 0), // amRCPlane
    81             (proc: nil;              flags: 0), // amRCPlane
    82 			(proc: nil;              flags: 0), // amLowGravity
    82             (proc: nil;              flags: 0), // amLowGravity
    83 			(proc: nil;              flags: 0), // amExtraDamage
    83             (proc: nil;              flags: 0), // amExtraDamage
    84 			(proc: nil;              flags: 0), // amInvulnerable
    84             (proc: nil;              flags: 0), // amInvulnerable
    85 			(proc: nil;              flags: 0), // amExtraTime
    85             (proc: nil;              flags: 0), // amExtraTime
    86 			(proc: nil;              flags: 0), // amLaserSight
    86             (proc: nil;              flags: 0), // amLaserSight
    87 			(proc: nil;              flags: 0), // amVampiric
    87             (proc: nil;              flags: 0), // amVampiric
    88 			(proc: nil;              flags: 0), // amSniperRifle
    88             (proc: nil;              flags: 0), // amSniperRifle
    89 			(proc: nil;              flags: 0),  // amJetpack
    89             (proc: nil;              flags: 0),  // amJetpack
    90 			(proc: nil;              flags: 0)  // amMolotov
    90             (proc: nil;              flags: 0)  // amMolotov
    91 			);
    91             );
    92 
    92 
    93 const BadTurn = Low(LongInt) div 4;
    93 const BadTurn = Low(LongInt) div 4;
    94 
    94 
    95 implementation
    95 implementation
    96 uses uMisc, uAIMisc, uLand;
    96 uses uMisc, uAIMisc, uLand;
   214 const tDelta = 24;
   214 const tDelta = 24;
   215 var Vx, Vy: hwFloat;
   215 var Vx, Vy: hwFloat;
   216     Score, EX, EY, valueResult: LongInt;
   216     Score, EX, EY, valueResult: LongInt;
   217     TestTime: Longword;
   217     TestTime: Longword;
   218 
   218 
   219 	function CheckTrace: LongInt;
   219     function CheckTrace: LongInt;
   220 	var x, y, dY: hwFloat;
   220     var x, y, dY: hwFloat;
   221 		value: LongInt;
   221         value: LongInt;
   222 	begin
   222     begin
   223 		x:= Me^.X;
   223         x:= Me^.X;
   224 		y:= Me^.Y;
   224         y:= Me^.Y;
   225 		dY:= -Vy;
   225         dY:= -Vy;
   226 
   226 
   227 		repeat
   227         repeat
   228 			x:= x + Vx;
   228             x:= x + Vx;
   229 			y:= y + dY;
   229             y:= y + dY;
   230 			dY:= dY + cGravity;
   230             dY:= dY + cGravity;
   231 			EX:= hwRound(x);
   231             EX:= hwRound(x);
   232 			EY:= hwRound(y);
   232             EY:= hwRound(y);
   233 		until TestCollExcludingMe(Me, EX, EY, 5) or (EY > 1000);
   233         until TestCollExcludingMe(Me, EX, EY, 5) or (EY > 1000);
   234 
   234 
   235 		if (EY < 1000) and not dY.isNegative then
   235         if (EY < 1000) and not dY.isNegative then
   236 			begin
   236             begin
   237 			value:= RateExplosion(Me, EX, EY, 91);
   237             value:= RateExplosion(Me, EX, EY, 91);
   238 			if (value = 0) then
   238             if (value = 0) then
   239 				if (dY > _0_15) then
   239                 if (dY > _0_15) then
   240 					value:= - abs(Targ.Y - EY) div 32
   240                     value:= - abs(Targ.Y - EY) div 32
   241 				else
   241                 else
   242 					value:= BadTurn
   242                     value:= BadTurn
   243 			else if (value < 0) then value:= BadTurn
   243             else if (value < 0) then value:= BadTurn
   244 			end
   244             end
   245 		else
   245         else
   246 			value:= BadTurn;
   246             value:= BadTurn;
   247 
   247 
   248 		CheckTrace:= value;
   248         CheckTrace:= value;
   249 	end;
   249     end;
   250 
   250 
   251 	function Solve: LongWord;
   251     function Solve: LongWord;
   252 	var A, B, D, T: hwFloat;
   252     var A, B, D, T: hwFloat;
   253 		C: LongInt;
   253         C: LongInt;
   254 	begin
   254     begin
   255 		A:= hwSqr(cGravity) * _0_25;
   255         A:= hwSqr(cGravity) * _0_25;
   256 		B:= - cGravity * (Targ.Y - hwRound(Me^.Y)) - _1;
   256         B:= - cGravity * (Targ.Y - hwRound(Me^.Y)) - _1;
   257 		C:= sqr(Targ.Y - hwRound(Me^.Y)) + sqr(Targ.X - hwRound(Me^.X));
   257         C:= sqr(Targ.Y - hwRound(Me^.Y)) + sqr(Targ.X - hwRound(Me^.X));
   258 		D:= hwSqr(B) - (A * C * 4);
   258         D:= hwSqr(B) - (A * C * 4);
   259 		if D.isNegative = false then
   259         if D.isNegative = false then
   260 			begin
   260             begin
   261 			D:= ( - B + hwSqrt(D)) * _0_5 / A;
   261             D:= ( - B + hwSqrt(D)) * _0_5 / A;
   262 			if D.isNegative = false then
   262             if D.isNegative = false then
   263 				T:= hwSqrt(D)
   263                 T:= hwSqrt(D)
   264 			else
   264             else
   265 				T:= _0;
   265                 T:= _0;
   266 			Solve:= hwRound(T)
   266             Solve:= hwRound(T)
   267 			end else Solve:= 0
   267             end else Solve:= 0
   268 	end;
   268     end;
   269 
   269 
   270 begin
   270 begin
   271 valueResult:= BadTurn;
   271 valueResult:= BadTurn;
   272 ap.ExplR:= 0;
   272 ap.ExplR:= 0;
   273 
   273 
   275 
   275 
   276 TestTime:= Solve;
   276 TestTime:= Solve;
   277 
   277 
   278 if TestTime = 0 then exit(BadTurn);
   278 if TestTime = 0 then exit(BadTurn);
   279 
   279 
   280 	Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime);
   280     Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime);
   281 	Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime);
   281     Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime);
   282 
   282 
   283 	Score:= CheckTrace;
   283     Score:= CheckTrace;
   284 	if valueResult < Score then
   284     if valueResult < Score then
   285 		begin
   285         begin
   286 		ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   286         ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level));
   287 		ap.Power:= 1;
   287         ap.Power:= 1;
   288 		ap.ExplR:= 100;
   288         ap.ExplR:= 100;
   289 		ap.ExplX:= EX;
   289         ap.ExplX:= EX;
   290 		ap.ExplY:= EY;
   290         ap.ExplY:= EY;
   291 		valueResult:= Score
   291         valueResult:= Score
   292 		end;
   292         end;
   293 
   293 
   294 TestMortar:= valueResult;
   294 TestMortar:= valueResult;
   295 end;
   295 end;
   296 
   296 
   297 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   297 function TestShotgun(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   383 ap.Time:= 0;
   383 ap.Time:= 0;
   384 ap.Power:= 1;
   384 ap.Power:= 1;
   385 ap.Angle:= 0;
   385 ap.Angle:= 0;
   386 if (Abs(hwRound(Me^.X) - Targ.X) > 25)
   386 if (Abs(hwRound(Me^.X) - Targ.X) > 25)
   387 or (Abs(hwRound(Me^.Y) - 50 - Targ.Y) > 50) then
   387 or (Abs(hwRound(Me^.Y) - 50 - Targ.Y) > 50) then
   388 	begin
   388     begin
   389 	if TestColl(hwRound(Me^.Y), hwRound(Me^.Y) - 16, 6)
   389     if TestColl(hwRound(Me^.Y), hwRound(Me^.Y) - 16, 6)
   390 	and (RateShove(Me, hwRound(Me^.X) + 10 * hwSign(Me^.dX), hwRound(Me^.Y) - 40, 30, 30) = 0) then
   390     and (RateShove(Me, hwRound(Me^.X) + 10 * hwSign(Me^.dX), hwRound(Me^.Y) - 40, 30, 30) = 0) then
   391 		valueResult:= Succ(BadTurn)
   391         valueResult:= Succ(BadTurn)
   392 	else
   392     else
   393 		valueResult:= BadTurn;
   393         valueResult:= BadTurn;
   394 	exit(valueResult)
   394     exit(valueResult)
   395 	end;
   395     end;
   396 
   396 
   397 valueResult:= 0;
   397 valueResult:= 0;
   398 for i:= 0 to 4 do
   398 for i:= 0 to 4 do
   399 	valueResult:= valueResult + RateShove(Me, hwRound(Me^.X) + 10 * hwSign(int2hwFloat(Targ.X) - Me^.X),
   399     valueResult:= valueResult + RateShove(Me, hwRound(Me^.X) + 10 * hwSign(int2hwFloat(Targ.X) - Me^.X),
   400                                     hwRound(Me^.Y) - 20 * i - 5, 10, 30);
   400                                     hwRound(Me^.Y) - 20 * i - 5, 10, 30);
   401 if valueResult <= 0 then
   401 if valueResult <= 0 then
   402 	valueResult:= BadTurn
   402     valueResult:= BadTurn
   403 else
   403 else
   404 	inc(valueResult);
   404     inc(valueResult);
   405 
   405 
   406 TestFirePunch:= valueResult;
   406 TestFirePunch:= valueResult;
   407 end;
   407 end;
   408 
   408 
   409 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;
   409 function TestAirAttack(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt;