Changeset 67 for trunk


Ignore:
Timestamp:
Sep 28, 2014, 12:47:34 PM (10 years ago)
Author:
chronos
Message:
  • Modified: Computer now move all available inner power to borders. This greatly improved computer attack potential.
  • Modified: Computer attack with all available power not just 2 units more then defender.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UGame.pas

    r66 r67  
    4848    MovesTo: TUnitMoves;
    4949    Neighbors: TObjectList; // TList<TCell>
     50    Mark: Boolean;
    5051    procedure Assign(Source: TCell);
    5152    function IsVisible(View: TView): Boolean;
     
    204205    Game: TGame;
    205206    Targets: TObjectList;
    206     procedure Attack;
     207    procedure AttackNeutral;
     208    procedure AttackPlayers;
    207209    procedure InnerMoves;
     210    procedure IncreaseMoves;
    208211    procedure Process;
    209212  end;
     
    11251128end;
    11261129
    1127 procedure TComputer.Attack;
     1130function CellCompareDescending(Item1, Item2: Pointer): Integer;
     1131begin
     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;
     1135end;
     1136
     1137procedure TComputer.AttackNeutral;
    11281138var
    11291139  AllCells: TObjectList;
     
    11471157  for C := 0 to AllCells.Count - 1 do
    11481158  with TCell(AllCells[C]) do begin
    1149     if (Terrain <> ttVoid) and (Player <> Game.CurrentPlayer) then begin
     1159    if (Terrain <> ttVoid) and (Player = nil) then begin
    11501160      Cells := Game.Map.GetCellNeighbors(TCell(AllCells[C]));
    11511161      CanAttack := 0;
     
    11591169
    11601170  // Sort ascending to attack cells with lower power first
     1171  // Low power cells are better for expanding our teritorry
    11611172  TargetCells.Sort(CellCompare);
    11621173
     
    11891200end;
    11901201
     1202procedure TComputer.AttackPlayers;
     1203var
     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;
     1214const
     1215  AttackDiff = 2;
     1216begin
     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;
     1265end;
     1266
    11911267procedure TComputer.InnerMoves;
    11921268var
     
    11961272  C: Integer;
    11971273  CanAttack, CanAttack2: Integer;
    1198 begin
     1274  TargetCells: TCells;
     1275  NewTargetCells: TCells;
     1276begin
     1277  // We need to move available power to borders to be available for attacks
     1278  // or defense
    11991279  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
    12001286  for C := 0 to AllCells.Count - 1 do
    12011287  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
    12061289      Cells := Game.Map.GetCellNeighbors(TCell(AllCells[C]));
    12071290      CanAttack := 0;
     
    12101293        Inc(CanAttack);
    12111294      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]);
    12321320      end;
    12331321    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;
     1331end;
     1332
     1333procedure TComputer.IncreaseMoves;
     1334var
     1335  I: Integer;
     1336begin
     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;
    12341342  end;
    12351343end;
     
    12371345procedure TComputer.Process;
    12381346begin
    1239   Attack;
     1347  AttackPlayers;
     1348  AttackNeutral;
    12401349  InnerMoves;
     1350  IncreaseMoves;
    12411351end;
    12421352
Note: See TracChangeset for help on using the changeset viewer.