Using Generics in Delphi

When it comes to “new” language features in Delphi (which usually have been in Free Pascal for years) I’m always willing to give them a shot. I’m using the for..in loop a lot, and also tend to shorten my code with things like ifthen (the poor mans ? operator, but sadly without any compiler magic). And I also use the with statment a lot, though it doesn’t have the best reputation amongst Delphi coders due to it’s scope problems.

One thing I always liked about FPC where the generics, allowing you do e.g. create TLists with your own types saving you lots of typecasts. And as far as I’m aware generics were included with Delphi 2009, so XE2 allows me to implement them into my code too. So while working on the AI for “Phase 2” I decided to give them a shot and implemented them in a function that generates random data for counter espionage :

[delphi]…
TmpType : TBuildingType;
BuildingTypeList : TList<TBuildingType>;
BuildingTypeListSpecial : TList<TBuildingType>;

// Fake building data
if CounterIntelligence.FakeDataType = AgentFakeDataBuilding then
begin
BuildingTypeList := TList<TBuildingType>.Create;
BuildingTypeListSpecial := TList<TBuildingType>.Create;

// Gather available building types
for TmpType in BuildingTypePool.BuildingType do
if Owner.TechnologyTree.IsTechnologyResearched(TmpType.NeededTechID) then
if TmpType.Category = BuildingCatSpecial then
BuildingTypeListSpecial.Add(TmpType)
else
BuildingTypeList.Add(TmpType);

// Generate random fake data
CounterIntelligence.FakeStructure.TurnUpdated := CurrentTurn;
for x := Low(Region.Building) to High(Region.Building) do
for y := Low(Region.Building[x]) to High(Region.Building[x]) do
if Region.Building[x,y].IsSpecial then
CounterIntelligence.FakeStructure.BuildingID[x,y] := BuildingTypeListSpecial[Random(BuildingTypeListSpecial.Count)].ID
else
CounterIntelligence.FakeStructure.BuildingID[x,y] := BuildingTypeList[Random(BuildingTypeList.Count)].ID;

BuildingTypeList.Free;
BuildingTypeListSpecial.Free;
end;
…[/delphi]

Usually I’d use dynamic arrays in such a function and adding element after element via SetLength, but with a generic list using my own types the code looks cleaner and I don’t have to care about resizing arrays myself.

So what do you guys think about using generics in Delphi? Do you use them all the time, sometimes or never? I’ve heard the implementation still has it’s share of bugs and generics seem to be pretty slow compared to normal lists or dynamic arrays.

Using Generics in Delphi

Updating the AI

Now that the beta is out in the wild (and up until now I haven’t heard any big complaints) it’s time to finally bring the AI in line with all the changes in “Phase 2. In the last beta, roughly 90% of the AI code was the same as in “Phase 1” and so the current AI isn’t much of a challenge.

So I just started rewriting most of the AI code for the next beta, and one of the areas the AI was always lacking (already in “Phase 1”) was building construction. Today I did a complete rewrite of how the AI handles construction inside of regions and the new version is much better, more dynamic and produces results that look much more human than the old one which would produce the same cityscapes over and over again.

Here are the changes for the new AI builder :

  • Buildings will be upgraded
  • This was one of the biggest problems of the old AI builder. Once a building was finished, it would never change (unless it was replaced to e.g. counter high pollution). This was a huge drawback for the AI, as the human player would constantly upgrade it’s buildings while the AI had to life with the buildings that were available at the time of construction (i.e. mostly the basic buildings). So I implemented a list of upgrades for each building type that can be set in the game’s editor (screenshot of the current WeltEdit version). The AI will now randomly select upgrades from that list when no other buildings are in construction and (random) factors are met. This is an important improvment, making the AI much more competitive and also adding more dynamics to the AI.

  • Construction spots are now selected at random
  • The old version always started populating the region starting from spot position 0/0, generating the same city scapes over and over again.

  • Differntiating between normal and coastal building spots
  • The old AI couldn’t tell the difference between a normal and a coastal building spot, so in the last beta it would just construct normal buildings on coastal spots. That’s something the human player can’t and something I fixed. So the AI will now populate coastal spots with coastal buildings only.

  • Redundant buildings are demolished
  • The new AI builder will finally demolish buildings that aren’t required (anymore). So if a region had high pollution and the AI placed buildings to counter that, the new AI builder will now demolish them once pollution levels are fine again and pollution increase is at a low pace. This opens up space for other buildings.

  • Added some fuziness
  • To add further dynamics to the city scapes generated by the AI I added some fuziness. So contrary to the old AI, that always selected the building with the highest primary effect in a category (e.g. energy output for power plants), the new one won’t always select the perfectly fitting building but may instead go for a less perfect choice. Together with the random buildings spot selection and random upgrade selection this adds further to the human-like behaviour of the AI.

  • Take a look at the the (small) screencaps below to see the difference :
  • All three shots show the same region after 50 turns. The one on the left is from the old AI builder code (also lacking coastal spots), the two on the right are from the new code. With the old code, the same region always looked like on the first shot after 50 turns, and with the new code you can clearly see how the two city scapes for the same region differ after 50 turns. Not only are the buildings placed more randomly, but you can also spot different buildings to to more random choosing of buildings as well as the new upgrade paths.

Together with some other small changes, addditions and fixes, this adds a lot the game. The AI is now competitive and the city scapes it creates spread much more in variety than with the old builder AI. The added dynamics now also allow the AI to better react to emergency situations like high pollution or low loyalty, so it’s now less likely to loose regions.

In the next step I’m going to teach the AI on how to do espionage and sabotage. Currently the AI won’t even hire agents, so stuff like counter espionage and sabotage won’t happen to you in a singleplayer game, and that’s a shame. So stay tuned for more AI updates!

Updating the AI