62 Angle, Power, Score, ExplX, ExplY, ExplR: integer; |
62 Angle, Power, Score, ExplX, ExplY, ExplR: integer; |
63 i: integer; |
63 i: integer; |
64 a, aa: TAmmoType; |
64 a, aa: TAmmoType; |
65 begin |
65 begin |
66 for i:= 0 to Pred(Targets.Count) do |
66 for i:= 0 to Pred(Targets.Count) do |
67 if Targets.ar[i].Score >= 0 then |
67 if (Targets.ar[i].Score >= 0) then |
68 begin |
68 begin |
69 with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do |
69 with CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog] do |
70 a:= Ammo[CurSlot, CurAmmo].AmmoType; |
70 a:= Ammo[CurSlot, CurAmmo].AmmoType; |
71 aa:= a; |
71 aa:= a; |
72 repeat |
72 repeat |
102 until (a = aa) or (CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].AttacksNum > 0) |
102 until (a = aa) or (CurrentTeam.Hedgehogs[CurrentTeam.CurrHedgehog].AttacksNum > 0) |
103 end |
103 end |
104 end; |
104 end; |
105 |
105 |
106 procedure Walk(Me: PGear); |
106 procedure Walk(Me: PGear); |
107 const FallTicksForBranching = cHHRadius * 2 + 8; |
107 const FallPixForBranching = cHHRadius * 2 + 8; |
108 cBranchStackSize = 8; |
108 cBranchStackSize = 12; |
109 |
109 |
110 type TStackEntry = record |
110 type TStackEntry = record |
111 WastedTicks: Longword; |
111 WastedTicks: Longword; |
112 MadeActions: TActions; |
112 MadeActions: TActions; |
113 Hedgehog: TGear; |
113 Hedgehog: TGear; |
116 var Stack: record |
116 var Stack: record |
117 Count: Longword; |
117 Count: Longword; |
118 States: array[0..Pred(cBranchStackSize)] of TStackEntry; |
118 States: array[0..Pred(cBranchStackSize)] of TStackEntry; |
119 end; |
119 end; |
120 |
120 |
121 procedure Push(Ticks: Longword; const Actions: TActions; const Me: TGear; Dir: integer); |
121 function Push(Ticks: Longword; const Actions: TActions; const Me: TGear; Dir: integer): boolean; |
122 begin |
122 begin |
123 if Stack.Count < cBranchStackSize then |
123 Result:= (Stack.Count < cBranchStackSize) and (Actions.Count < MAXACTIONS - 5); |
|
124 if Result then |
124 with Stack.States[Stack.Count] do |
125 with Stack.States[Stack.Count] do |
125 begin |
126 begin |
126 WastedTicks:= Ticks; |
127 WastedTicks:= Ticks; |
127 MadeActions:= Actions; |
128 MadeActions:= Actions; |
128 Hedgehog:= Me; |
129 Hedgehog:= Me; |
145 |
146 |
146 var Actions: TActions; |
147 var Actions: TActions; |
147 ticks, maxticks, steps: Longword; |
148 ticks, maxticks, steps: Longword; |
148 BaseRate, BestRate, Rate: integer; |
149 BaseRate, BestRate, Rate: integer; |
149 GoInfo: TGoInfo; |
150 GoInfo: TGoInfo; |
|
151 CanGo: boolean; |
|
152 AltMe: TGear; |
150 begin |
153 begin |
151 Actions.Count:= 0; |
154 Actions.Count:= 0; |
152 Actions.Pos:= 0; |
155 Actions.Pos:= 0; |
153 Actions.Score:= 0; |
156 Actions.Score:= 0; |
154 Stack.Count:= 0; |
157 Stack.Count:= 0; |
155 |
158 |
156 Push(0, Actions, Me^, aia_Left); |
159 Push(0, Actions, Me^, aia_Left); |
157 Push(0, Actions, Me^, aia_Right); |
160 Push(0, Actions, Me^, aia_Right); |
158 |
161 |
159 if (Me.State and gstAttacked) = 0 then maxticks:= TurnTimeLeft - 5000 |
162 if (Me.State and gstAttacked) = 0 then maxticks:= max(0, integer(TurnTimeLeft) - 10000) |
160 else maxticks:= TurnTimeLeft; |
163 else maxticks:= TurnTimeLeft; |
161 |
164 |
162 if (Me.State and gstAttacked) = 0 then TestAmmos(Actions, Me); |
165 if (Me.State and gstAttacked) = 0 then TestAmmos(Actions, Me); |
163 BestRate:= RatePlace(Me); |
166 BestRate:= RatePlace(Me); |
164 BaseRate:= max(BestRate, 0); |
167 BaseRate:= max(BestRate, 0); |
169 AddAction(Actions, Me.Message, aim_push, 250); |
172 AddAction(Actions, Me.Message, aim_push, 250); |
170 AddAction(Actions, aia_WaitX, round(Me.X), 0); |
173 AddAction(Actions, aia_WaitX, round(Me.X), 0); |
171 AddAction(Actions, Me.Message, aim_release, 0); |
174 AddAction(Actions, Me.Message, aim_release, 0); |
172 steps:= 0; |
175 steps:= 0; |
173 |
176 |
174 while HHGo(Me, GoInfo) do |
177 while true do |
175 begin |
178 begin |
|
179 CanGo:= HHGo(Me, @AltMe, GoInfo); |
176 inc(ticks, GoInfo.Ticks); |
180 inc(ticks, GoInfo.Ticks); |
177 if ticks > maxticks then break; |
181 if ticks > maxticks then break; |
|
182 if GoInfo.JumpType = jmpHJump then // hjump support |
|
183 if Push(ticks, Actions, AltMe, Me^.Message) then |
|
184 with Stack.States[Pred(Stack.Count)] do |
|
185 begin |
|
186 AddAction(MadeActions, aia_HJump, 0, 305); |
|
187 AddAction(MadeActions, aia_HJump, 0, 350); |
|
188 end; |
|
189 if GoInfo.JumpType = jmpLJump then // ljump support |
|
190 if Push(ticks, Actions, AltMe, Me^.Message) then |
|
191 with Stack.States[Pred(Stack.Count)] do |
|
192 AddAction(MadeActions, aia_LJump, 0, 305); |
|
193 if not CanGo then break; |
178 inc(steps); |
194 inc(steps); |
179 Actions.actions[Actions.Count - 2].Param:= round(Me.X); |
195 Actions.actions[Actions.Count - 2].Param:= round(Me.X); |
180 Rate:= RatePlace(Me); |
196 Rate:= RatePlace(Me); |
181 if Rate > BestRate then |
197 if Rate > BestRate then |
182 begin |
198 begin |
185 Me.State:= Me.State or gstAttacked // we have better place, go there and don't use ammo |
201 Me.State:= Me.State or gstAttacked // we have better place, go there and don't use ammo |
186 end |
202 end |
187 else if Rate < BestRate then break; |
203 else if Rate < BestRate then break; |
188 if ((Me.State and gstAttacked) = 0) |
204 if ((Me.State and gstAttacked) = 0) |
189 and ((steps mod 4) = 0) then TestAmmos(Actions, Me); |
205 and ((steps mod 4) = 0) then TestAmmos(Actions, Me); |
190 if GoInfo.FallTicks >= FallTicksForBranching then |
206 if GoInfo.FallPix >= FallPixForBranching then |
191 Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right |
207 Push(ticks, Actions, Me^, Me^.Message xor 3); // aia_Left xor 3 = aia_Right |
192 if StopThinking then exit |
208 if StopThinking then exit |
193 end; |
209 end; |
194 |
210 |
195 if BestRate > BaseRate then exit |
211 if BestRate > BaseRate then exit |
233 if ((Me.State and gstAttacking) <> 0) or isInMultiShoot then exit; |
249 if ((Me.State and gstAttacking) <> 0) or isInMultiShoot then exit; |
234 Me.State:= Me.State or gstHHThinking; |
250 Me.State:= Me.State or gstHHThinking; |
235 StopThinking:= false; |
251 StopThinking:= false; |
236 ThinkingHH:= Me; |
252 ThinkingHH:= Me; |
237 FillTargets; |
253 FillTargets; |
|
254 if Targets.Count = 0 then |
|
255 begin |
|
256 OutError('AI: no targets!?'); |
|
257 exit |
|
258 end; |
238 FillBonuses((Me.State and gstAttacked) <> 0); |
259 FillBonuses((Me.State and gstAttacked) <> 0); |
239 for a:= Low(TAmmoType) to High(TAmmoType) do |
260 for a:= Low(TAmmoType) to High(TAmmoType) do |
240 CanUseAmmo[a]:= Assigned(AmmoTests[a]) and HHHasAmmo(PHedgehog(Me.Hedgehog), a); |
261 CanUseAmmo[a]:= Assigned(AmmoTests[a]) and HHHasAmmo(PHedgehog(Me.Hedgehog), a); |
241 {$IFDEF DEBUGFILE}AddFileLog('Enter Think Thread');{$ENDIF} |
262 {$IFDEF DEBUGFILE}AddFileLog('Enter Think Thread');{$ENDIF} |
242 ThinkThread:= SDL_CreateThread(@Think, Me) |
263 ThinkThread:= SDL_CreateThread(@Think, Me) |