Skip to content

Commit

Permalink
Fix: [AI] AI now considers states with broadcast permission for anten…
Browse files Browse the repository at this point in the history
…na spots. Report: Nalindir

Fixes #115
  • Loading branch information
GWRon committed Dec 31, 2019
1 parent 4c0e1cc commit b498683
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 16 deletions.
35 changes: 25 additions & 10 deletions res/ai/DefaultAIPlayer/TaskStationMap.lua
Expand Up @@ -332,11 +332,14 @@ function JobBuyStation:GetBestAntennaOffer()
-- 2) fill list up to X (eg. 50) with random spots
-- 3) add Y random spots (10) so that even with >50 existing antennas
-- we still try to find some random ones
-- 3) add Z random spots (10) in states we have broadcast permissions
-- so that we try to keep prices low even with high budget
-- 4) lookup at _similar_ positions (add some random...)

local stationPositions = {}
local maxToCheck = 50 -- +some random
local minimumRequiredRandoms = 10
local minimumRequiredRandomsWithPermission = 10

-- 1)
for playerKey, playerStations in pairs(self.Task.knownAntennaPositions) do
Expand All @@ -357,6 +360,14 @@ function JobBuyStation:GetBestAntennaOffer()
stationPositions[newKey] = {x, y}
end

for i = 1, minimumRequiredRandomsWithPermission do
local vec = TVT.of_GetRandomAntennaCoordinateInPlayerSections()
if vec ~= nil then
local newKey = x .. "_" .. y
stationPositions[newKey] = {x, y}
end
end


-- 4)
--for i = 1, 50 do
Expand All @@ -370,25 +381,25 @@ function JobBuyStation:GetBestAntennaOffer()
if table.count(value) > 2 then otherOwner = value[3] end
local tempStation = TVT.of_GetTemporaryAntennaStation(x, y)

-- if tempStation ~= nil then
-- debugMsg(" - Station " .. tablePos .. " at " .. x .. "," .. y .. ". owner: " .. otherOwner .. " reach: " .. tempStation.GetReach() .. " exclusive/increase: " .. tempStation.GetExclusiveReach() .. " price: " .. tempStation.GetBuyPrice() .. " (incl.fees: " .. tempStation.GetTotalBuyPrice() ..") F: " .. (tempStation.GetExclusiveReach() / tempStation.GetPrice()) .. " buyPrice: " .. tempStation.GetBuyPrice() )
-- end

--filter criterias
--0) skip checks if there is no tempstation
if tempStation == nil then
-- debugMsg("tempStation is nil!")

--1) outside
elseif tempStation.GetPrice() < 0 then
-- debugMsg(" -> outside of map")
-- debugMsg(" - Station " .. tablePos .. " at " .. x .. "," .. y .. ". owner: " .. otherOwner .. " reach: " .. tempStation.GetReach() .. " exclusive/increase: " .. tempStation.GetExclusiveReach() .. " price: " .. tempStation.GetBuyPrice() .. " (incl.fees: " .. tempStation.GetTotalBuyPrice() ..") F: " .. (tempStation.GetExclusiveReach() / tempStation.GetPrice()) .. " buyPrice: " .. tempStation.GetBuyPrice() .. " -> outside of map!")
tempStation = nil

--2) price to high
elseif tempStation.GetPrice() > self.Task.CurrentBudget then
-- debugMsg(" -> too expensive")
debugMsg(" - Station " .. tablePos .. " at " .. x .. "," .. y .. ". owner: " .. otherOwner .. " reach: " .. tempStation.GetReach() .. " exclusive/increase: " .. tempStation.GetExclusiveReach() .. " price: " .. tempStation.GetBuyPrice() .. " (incl.fees: " .. tempStation.GetTotalBuyPrice() ..") F: " .. (tempStation.GetExclusiveReach() / tempStation.GetPrice()) .. " buyPrice: " .. tempStation.GetBuyPrice() .. " -> too expensive!")
tempStation = nil
--3) relative increase to low (at least 30% required)
elseif tempStation.GetRelativeExclusiveReach() < 0.30 then
-- debugMsg(" -> not enough reach increase")

--3) relative increase to low (at least 35% required)
elseif tempStation.GetRelativeExclusiveReach() < 0.35 then
debugMsg(" - Station " .. tablePos .. " at " .. x .. "," .. y .. ". owner: " .. otherOwner .. " reach: " .. tempStation.GetReach() .. " exclusive/increase: " .. tempStation.GetExclusiveReach() .. "(" .. tempStation.GetRelativeExclusiveReach()..")" .. " price: " .. tempStation.GetBuyPrice() .. " (incl.fees: " .. tempStation.GetTotalBuyPrice() ..") F: " .. (tempStation.GetExclusiveReach() / tempStation.GetPrice()) .. " buyPrice: " .. tempStation.GetBuyPrice() .. " -> not enough reach increase!")
tempStation = nil

--4) absolute increase too low
Expand All @@ -397,8 +408,11 @@ function JobBuyStation:GetBestAntennaOffer()

--5) reach to low (at least 75.000 required)
elseif tempStation.GetReach() < 75000 then
-- debugMsg(" -> not enough absolute reach")
debugMsg(" - Station " .. tablePos .. " at " .. x .. "," .. y .. ". owner: " .. otherOwner .. " reach: " .. tempStation.GetReach() .. " exclusive/increase: " .. tempStation.GetExclusiveReach() .. " price: " .. tempStation.GetBuyPrice() .. " (incl.fees: " .. tempStation.GetTotalBuyPrice() ..") F: " .. (tempStation.GetExclusiveReach() / tempStation.GetPrice()) .. " buyPrice: " .. tempStation.GetBuyPrice() .. " -> not enough absolute reach!")
tempStation = nil

else
debugMsg(" - Station " .. tablePos .. " at " .. x .. "," .. y .. ". owner: " .. otherOwner .. " reach: " .. tempStation.GetReach() .. " exclusive/increase: " .. tempStation.GetExclusiveReach() .. " price: " .. tempStation.GetBuyPrice() .. " (incl.fees: " .. tempStation.GetTotalBuyPrice() ..") F: " .. (tempStation.GetExclusiveReach() / tempStation.GetPrice()) .. " buyPrice: " .. tempStation.GetBuyPrice() .. " -> OK!")
end


Expand All @@ -417,7 +431,8 @@ function JobBuyStation:GetBestAntennaOffer()
if otherOwner > 0 then attraction = attraction * 1.10 end
-- raise attraction (even further) if AI's enemy is there
if otherOwner == player:GetArchEnemyId() then attraction = attraction * 1.06 end
-- debugMsg(" -> attraction: " .. attraction .. " | ".. pricePerViewer .. " - (" .. priceDiff .. " / currentBudget: " .. self.Task.CurrentBudget)

debugMsg(" -> attraction: " .. attraction .. " | ".. pricePerViewer .. " - (" .. priceDiff .. " / currentBudget: " .. self.Task.CurrentBudget .. ")")

if bestOffer == nil then
bestOffer = tempStation
Expand Down
21 changes: 20 additions & 1 deletion source/game.ai.bmx
Expand Up @@ -912,8 +912,27 @@ endrem


'=== OFFICE ===
'players bureau
'player's office

Method of_GetRandomAntennaCoordinateInPlayerSections:TVec2D()
If Not _PlayerInRoom("office") Then Return Null
Return GetStationMap(Self.ME, True).GetRandomAntennaCoordinateInPlayerSections()
End Method

Method of_GetRandomAntennaCoordinateInSections:TVec2D(sectionNames:string[])
If Not _PlayerInRoom("office") Then Return Null
Return GetStationMap(Self.ME, True).GetRandomAntennaCoordinateInSections(sectionNames)
End Method

Method of_GetRandomAntennaCoordinateInSection:TVec2D(sectionName:string)
If Not _PlayerInRoom("office") Then Return Null
Return GetStationMap(Self.ME, True).GetRandomAntennaCoordinateInSection(sectionName)
End Method

Method of_GetRandomAntennaCoordinateOnMap:TVec2D(checkBroadcastPermission:Int=True, requiredBroadcastPermissionState:Int=True)
If Not _PlayerInRoom("office") Then Return Null
Return GetStationMap(Self.ME, True).GetRandomAntennaCoordinateOnMap(checkBroadcastPermission, requiredBroadcastPermissionState)
End Method

Method of_GetTemporaryCableNetworkUplinkStation:TStationBase(cableNetworkIndex:Int)
If Not _PlayerInRoom("office") Then Return Null
Expand Down
99 changes: 94 additions & 5 deletions source/game.stationmap.bmx
Expand Up @@ -1668,6 +1668,27 @@ endrem
End Method


Method GetSectionsFiltered:TStationMapSection[](channelID:Int=-1, checkBroadcastPermission:Int=True, requiredBroadcastPermissionState:Int=True, stationType:Int=-1)
Local count:int = sections.Count()
Local sections:TStationMapSection[] = new TStationMapSection[count]
Local used:Int = 0
For Local section:TStationMapSection = EachIn sections
If (checkBroadcastPermission and section.NeedsBroadcastPermission(channelID, stationType))
If section.HasBroadcastPermission(channelID, stationType) <> requiredBroadcastPermissionState Then Continue
EndIf
sections[used] = section

used :+ 1
Next

if used <> count
return sections[.. used]
else
return sections
endif
End Method


'returns sections "nearby" a station (connection not guaranteed as
'check of a circle-antenna is based on two rects intersecting or not)
Method GetSectionsConnectedToStation:TStationMapSection[](station:TStationBase)
Expand Down Expand Up @@ -2010,13 +2031,20 @@ Type TStationMap extends TOwnedGameObject {_exposeToLua="selected"}

'returns all stations of a player in a given section
Method GetStationsBySectionName:TStationBase[](sectionName:string, stationType:int=0) {_exposeToLua}
local result:TStationBase[]
local result:TStationBase[5]
Local found:int = 0
For local station:TStationBase = EachIn stations
if stationType >0 and station.stationType <> stationType then continue
if station.sectionName = sectionName then result :+ [station]
if station.sectionName = sectionName
result[found] = station
found :+ 1
if found > result.length then result = result[.. result.length + 5]
endif
Next

Return result
if found <> result.length
result = result[.. found]
endif
return result
End Method


Expand Down Expand Up @@ -2083,6 +2111,67 @@ Type TStationMap extends TOwnedGameObject {_exposeToLua="selected"}
End Method



Method GetRandomAntennaCoordinateOnMap:TVec2D(checkBroadcastPermission:Int=True, requiredBroadcastPermissionState:Int=True)
Local x:int = Rand(35, 560)
Local y:int = Rand(1, 375)
Local station:TStationBase = GetTemporaryAntennaStation(x, y)
if station.GetPrice() < 0 then return Null

if checkBroadcastPermission and GetStationMapCollection().GetSection(x,y).HasBroadcastPermission(owner, TVTStationType.ANTENNA) <> requiredBroadcastPermissionState Then Return Null

Return new TVec2D.Init(x,y)
End Method


Method GetRandomAntennaCoordinateInPlayerSections:TVec2D()
local sections:TStationMapSection[] = GetStationMapCollection().GetSectionsFiltered(owner, True, True, TVTStationType.ANTENNA)
if sections.length = 0 Then Return Null

Local sectionName:String = sections[ Rand(0, sections.length-1) ].name
Return GetRandomAntennaCoordinateInSection(sectionName)
End Method


Method GetRandomAntennaCoordinateInSections:TVec2D(sectionNames:string[])
if sectionNames.length = 0 Then return Null

local sectionName:String = sectionNames[ Rand(0, sectionNames.length-1) ]
Return GetRandomAntennaCoordinateInSection(sectionName)
End Method


'specific section
Method GetRandomAntennaCoordinateInSection:TVec2D(sectionName:string)
Local section:TStationMapSection = GetStationMapCollection().GetSectionByName( sectionName)
If not section then return Null

Local found:Int = False
Local x:Int = 0
Local y:Int = 0
Local tries:int = 0
Repeat
x = rand(section.rect.GetIntX(), section.rect.GetIntX2())
y = rand(section.rect.GetIntY(), section.rect.GetIntY2())
If section.GetShapeSprite().PixelIsOpaque(Int(x-section.rect.GetX()), Int(y-section.rect.GetY())) > 0
found = True
EndIf
tries :+ 1
Until found or tries > 1000

If tries > 1000
print "Failed to find a valid random section point in < 1000 tries."
Return Null
EndIf

If found
Return new TVec2D.Init(x,y)
EndIf

Return Null
End Method


Method CheatMaxAudience:int()
local oldReachLevel:int = GetReachLevel(GetReach())
cheatedMaxReach = true
Expand Down Expand Up @@ -2584,7 +2673,7 @@ Type TStationBase Extends TOwnedGameObject {_exposeToLua="selected"}


'get the relative reach increase of that station
Method GetRelativeExclusiveReach:Int(refresh:Int=False) {_exposeToLua}
Method GetRelativeExclusiveReach:Float(refresh:Int=False) {_exposeToLua}
Local r:Float = GetReach(refresh)
If r = 0 Then Return 0

Expand Down

0 comments on commit b498683

Please sign in to comment.