- Timestamp:
- Sep 28, 2014, 12:47:34 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/UGame.pas
r66 r67 48 48 MovesTo: TUnitMoves; 49 49 Neighbors: TObjectList; // TList<TCell> 50 Mark: Boolean; 50 51 procedure Assign(Source: TCell); 51 52 function IsVisible(View: TView): Boolean; … … 204 205 Game: TGame; 205 206 Targets: TObjectList; 206 procedure Attack; 207 procedure AttackNeutral; 208 procedure AttackPlayers; 207 209 procedure InnerMoves; 210 procedure IncreaseMoves; 208 211 procedure Process; 209 212 end; … … 1125 1128 end; 1126 1129 1127 procedure TComputer.Attack; 1130 function CellCompareDescending(Item1, Item2: Pointer): Integer; 1131 begin 1132 if TCell(Item1).Power > TCell(Item2).Power then Result := -1 1133 else if TCell(Item1).Power < TCell(Item2).Power then Result := 1 1134 else Result := 0; 1135 end; 1136 1137 procedure TComputer.AttackNeutral; 1128 1138 var 1129 1139 AllCells: TObjectList; … … 1147 1157 for C := 0 to AllCells.Count - 1 do 1148 1158 with TCell(AllCells[C]) do begin 1149 if (Terrain <> ttVoid) and (Player <> Game.CurrentPlayer) then begin1159 if (Terrain <> ttVoid) and (Player = nil) then begin 1150 1160 Cells := Game.Map.GetCellNeighbors(TCell(AllCells[C])); 1151 1161 CanAttack := 0; … … 1159 1169 1160 1170 // Sort ascending to attack cells with lower power first 1171 // Low power cells are better for expanding our teritorry 1161 1172 TargetCells.Sort(CellCompare); 1162 1173 … … 1189 1200 end; 1190 1201 1202 procedure TComputer.AttackPlayers; 1203 var 1204 AllCells: TObjectList; 1205 Cells, Cells2: TCellArray; 1206 TotalPower: Integer; 1207 AttackPower: Integer; 1208 TotalAttackPower: Integer; 1209 I, J: Integer; 1210 C: Integer; 1211 CanAttack, CanAttack2: Integer; 1212 TargetCells: TCells; 1213 S: string; 1214 const 1215 AttackDiff = 2; 1216 begin 1217 AllCells := Game.Map.Cells; 1218 TargetCells := TCells.Create; 1219 TargetCells.OwnsObjects := False; 1220 1221 // Get list of all attack target cells 1222 for C := 0 to AllCells.Count - 1 do 1223 with TCell(AllCells[C]) do begin 1224 if (Terrain <> ttVoid) and (Player <> Game.CurrentPlayer) and (Player <> nil) then begin 1225 Cells := Game.Map.GetCellNeighbors(TCell(AllCells[C])); 1226 CanAttack := 0; 1227 for I := 0 to Length(Cells) - 1 do 1228 if (Cells[I].Player = Game.CurrentPlayer) then begin 1229 Inc(CanAttack); 1230 end; 1231 if CanAttack > 0 then TargetCells.Add(AllCells[C]); 1232 end; 1233 end; 1234 1235 // Sort descending to attack cells with higher power first 1236 // Higher power enemy cells grow faster and is more dangerous 1237 TargetCells.Sort(CellCompareDescending); 1238 1239 for C := 0 to TargetCells.Count - 1 do 1240 with TCell(TargetCells[C]) do begin 1241 // Attack to not owned cell yet 1242 // Count own possible power 1243 Cells := Game.Map.GetCellNeighbors(TCell(TargetCells[C])); 1244 TotalPower := 0; 1245 for I := 0 to Length(Cells) - 1 do 1246 if (Cells[I].Player = Game.CurrentPlayer) then begin 1247 TotalPower := TotalPower + Cells[I].GetAvialPower; 1248 end; 1249 // Attack if target is weaker 1250 if TotalPower >= (Power + AttackDiff) then begin 1251 TotalAttackPower := 0; 1252 for I := 0 to Length(Cells) - 1 do 1253 if (Cells[I].Player = Game.CurrentPlayer) then begin 1254 // Use only necessary power 1255 AttackPower := Power - TotalAttackPower + AttackDiff; 1256 if Cells[I].GetAvialPower < AttackPower then 1257 AttackPower := Cells[I].GetAvialPower; 1258 Game.SetMove(Cells[I], TCell(TargetCells[C]), AttackPower); 1259 TotalAttackPower := TotalAttackPower + AttackPower; 1260 end; 1261 end; 1262 end; 1263 1264 TargetCells.Free; 1265 end; 1266 1191 1267 procedure TComputer.InnerMoves; 1192 1268 var … … 1196 1272 C: Integer; 1197 1273 CanAttack, CanAttack2: Integer; 1198 begin 1274 TargetCells: TCells; 1275 NewTargetCells: TCells; 1276 begin 1277 // We need to move available power to borders to be available for attacks 1278 // or defense 1199 1279 AllCells := Game.Map.Cells; 1280 TargetCells := TCells.Create; 1281 TargetCells.OwnsObjects := False; 1282 NewTargetCells := TCells.Create; 1283 NewTargetCells.OwnsObjects := False; 1284 1285 // Get list of all our cells which can attack 1200 1286 for C := 0 to AllCells.Count - 1 do 1201 1287 with TCell(AllCells[C]) do begin 1202 if (Terrain <> ttVoid) and (Player = Game.CurrentPlayer) then begin 1203 // Inner moves 1204 // We need to move available power to borders to be available for attacks 1205 // or defense 1288 if (Player = Game.CurrentPlayer) then begin 1206 1289 Cells := Game.Map.GetCellNeighbors(TCell(AllCells[C])); 1207 1290 CanAttack := 0; … … 1210 1293 Inc(CanAttack); 1211 1294 end; 1212 if CanAttack = 0 then begin 1213 // We cannot attack and should do move 1214 // For simplicty just try to balance inner area cells power 1215 for I := 0 to Length(Cells) - 1 do 1216 if (Cells[I].Player = Game.CurrentPlayer) and (Cells[I].Power < TCell(AllCells[C]).GetAvialPower) then begin 1217 Game.SetMove(TCell(AllCells[C]), Cells[I], (TCell(AllCells[C]).GetAvialPower - Cells[I].Power) div 2); 1218 end; 1219 end else begin 1220 // Is enemy border cell, try to absorb all units from inner neighbours 1221 for I := 0 to Length(Cells) - 1 do 1222 if (Cells[I].Player = Game.CurrentPlayer) and (Cells[I].GetAvialPower > 0) then begin 1223 Cells2 := Game.Map.GetCellNeighbors(TCell(Cells[I])); 1224 CanAttack2 := 0; 1225 for J := 0 to Length(Cells2) - 1 do 1226 if (Cells2[J].Player <> Game.CurrentPlayer) and (Cells2[J].Terrain <> ttVoid) then begin 1227 Inc(CanAttack2); 1228 end; 1229 if CanAttack2 = 0 then 1230 Game.SetMove(Cells[I], TCell(AllCells[C]), Cells[I].GetAvialPower); 1231 end; 1295 if CanAttack > 0 then TargetCells.Add(AllCells[C]); 1296 end; 1297 end; 1298 1299 // Unset mark for all cells 1300 for C := 0 to AllCells.Count - 1 do 1301 TCell(AllCells[C]).Mark := False; 1302 1303 while TargetCells.Count > 0 do begin 1304 // Set mark for selected border cells 1305 for C := 0 to TargetCells.Count - 1 do 1306 TCell(TargetCells[C]).Mark := True; 1307 1308 // Move all power from unmarked cells and mark them 1309 NewTargetCells.Count := 0; 1310 for C := 0 to TargetCells.Count - 1 do 1311 with TCell(TargetCells[C]) do begin 1312 // 1313 Cells := Game.Map.GetCellNeighbors(TCell(TargetCells[C])); 1314 for I := 0 to Length(Cells) - 1 do 1315 if (Cells[I].Player = Game.CurrentPlayer) and (Cells[I].Terrain <> ttVoid) 1316 and (not Cells[I].Mark) then begin 1317 Game.SetMove(Cells[I], TCell(TargetCells[C]), Cells[I].GetAvialPower); 1318 TCell(TargetCells[C]).Mark := True; 1319 NewTargetCells.Add(Cells[I]); 1232 1320 end; 1233 1321 end; 1322 1323 // Use source cells NewTargetCells as new TargetCells 1324 TargetCells.Count := NewTargetCells.Count; 1325 for C := 0 to TargetCells.Count - 1 do 1326 TargetCells[C] := NewTargetCells[C]; 1327 end; 1328 1329 TargetCells.Free; 1330 NewTargetCells.Free; 1331 end; 1332 1333 procedure TComputer.IncreaseMoves; 1334 var 1335 I: Integer; 1336 begin 1337 // If available power remains then use all for existed unit moves 1338 for I := 0 to Game.Moves.Count - 1 do 1339 with TUnitMove(Game.Moves[I]) do begin 1340 if CellFrom.GetAvialPower > 0 then 1341 CountOnce := CountOnce + CellFrom.GetAvialPower; 1234 1342 end; 1235 1343 end; … … 1237 1345 procedure TComputer.Process; 1238 1346 begin 1239 Attack; 1347 AttackPlayers; 1348 AttackNeutral; 1240 1349 InnerMoves; 1350 IncreaseMoves; 1241 1351 end; 1242 1352
Note:
See TracChangeset
for help on using the changeset viewer.