1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

How to detect an island?

Discussion in 'Civ6 - Creation & Customization' started by Infixo, Jan 5, 2019.

  1. Infixo

    Infixo Deity

    Joined:
    Jan 9, 2016
    Messages:
    3,785
    Gender:
    Male
    Location:
    Warsaw
    I am looking for a simple algorithm on how to detect that we are on the island. Or generally in a place with “sea” bias. It should be based only on tiles revealed. So, basically a scout is exploring and revealing a map - when and how could he determine that this is an “island” type of land?
     
  2. FearSunn

    FearSunn Warlord

    Joined:
    Dec 10, 2017
    Messages:
    277
    Gender:
    Male
    It is already in the game: GlobalParameters AI_ISLAND_COAST_PERCENTAGE
     
  3. Infixo

    Infixo Deity

    Joined:
    Jan 9, 2016
    Messages:
    3,785
    Gender:
    Male
    Location:
    Warsaw
    I am not sure how is that related to my question? I want to write my own function for that.
    On a separate note, my tests show that this parameter does not affect how the AI detects “being on an island”. Not at all. I noticed only that size of the spawn Area has something to do with that. Smaller areas generate that info faster, i.e. minors detect that fact faste than majors. But the problem is not with speed, rather with accuracy.
    So, any ideas for an algorithm?
     
  4. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    7,212
    Location:
    Illinois, USA
  5. Infixo

    Infixo Deity

    Joined:
    Jan 9, 2016
    Messages:
    3,785
    Gender:
    Male
    Location:
    Warsaw
    Lua. My goal is to determine, based on revealed tiles only, in what situation I am:
    - small island
    - bigger island
    - land, but with lots of coast (like peninsulas, etc.)
    - mostly land, straight line coast
    - pangea, so big land, but barely any seas around
     
  6. cvb

    cvb Prince

    Joined:
    Jun 12, 2017
    Messages:
    446
    Are you allowed to read parameters known at map creation time (eg. map size) or is that considered cheating in this context?

    I think you are looking for 2 distinct things, which will need significantly different numbers of revealed tiles to appoint:
    - differentiate "lacerated/convoluted" or "smooth/straight" coast line will probably need comparably few revealed tiles.
    - small island, bigger island, pangaea ... depend on the ratio of coast-tiles in a closed line to the number of land-tiles in between (area/perimeter) as well as the world size (a 1 tile island has 6 surrounding coast-tiles, ratio = ~0.167 --- --- a "standard city" island with 3 rings has 37 land-tiles and 24 surrounding coast-tiles, ratio = ~1.542) I suppose, you need a lot of revealed tiles and the world size to determine.
     
    Last edited: Jan 12, 2019
  7. Infixo

    Infixo Deity

    Joined:
    Jan 9, 2016
    Messages:
    3,785
    Gender:
    Male
    Location:
    Warsaw
    @cvb Map size yes, known. Human player knows much more, anyway. Just by selecting a map :)
    Anyway, my thinking goes along similar lines, i.e. ratios between coast / land / sea.
    Also, I am thinking about "biggest continous land". That would be e.g. all land tiles that ar at least N tiles away from the sea, The bigger the N (2..4 is enough), the more smooth this part becomes. Comparing this part to the remains should tell about the shape of the coast line.
     
    cvb likes this.
  8. LeeS

    LeeS Imperator

    Joined:
    Jul 23, 2013
    Messages:
    7,212
    Location:
    Illinois, USA
    I believe these are all valid in a GameplayScript

    From the cold war scenario
    Code:
    		-- Reveal the map to all players.
    		local pCurPlayerVisibility = PlayersVisibility[pPlayer:GetID()];
    		if(pCurPlayerVisibility ~= nil) then
    			pCurPlayerVisibility:RevealAllPlots();
    		end
    From the Alexander Scenario (tho it is also for setting visibility of a plot rather than checking for visibility)
    Code:
    local function SetInitialVisibility()
    
    	print ("SetInitialVisibility");
    
    	-- Apply updates to all majors
    	local aPlayers = PlayerManager.GetAliveMajors();
    	for loop, pPlayer in ipairs(aPlayers) do
    		if(pPlayer:IsHuman() == true) then
    			local iPlayer = pPlayer:GetID();
    	
    			local pCurPlayerVisibility = PlayersVisibility[pPlayer:GetID()];
    			if(pCurPlayerVisibility ~= nil) then
    		
    				-- Reveal Balkans and Turkey
    				for iX = 0, 17, 1 do
    					for iY = 25, 36, 1 do
    						local iPlotIndex = Map.GetPlot(iX, iY):GetIndex();
    						pCurPlayerVisibility:ChangeVisibilityCount(iPlotIndex, 1);
    					end
    				end
                .................and a bunch more stuff.......
    This is from WorldViewIconsManager.lua (ie, UI context) so may not be usable in a GameplayScript
    Code:
    	local eObserverID = Game.GetLocalObserver();
    	local pLocalPlayerVis = PlayerVisibilityManager.GetPlayerVisibility(eObserverID);
    
    	if (pLocalPlayerVis ~= nil) then
    		local iCount = Map.GetPlotCount();
    		for plotIndex = 0, iCount-1, 1 do
    
    			local visibilityType = pLocalPlayerVis:GetState(plotIndex);
    			if (visibilityType == RevealedState.HIDDEN) then
    				RemoveAll(plotIndex);
    			else		
    				if (visibilityType == RevealedState.REVEALED) then
    					ChangeToMidFog(plotIndex);
    				else
    					if (visibilityType == RevealedState.VISIBLE) then
    						ChangeToVisible(plotIndex);
    					end
    				end
    			end
    		end
    	end
    end



    From Civ6Common.lua (so "IsVisible" may only be valid in UI context)
    Code:
    		local results:table;
    		if (PlayersVisibility[eAttackingPlayer]:IsVisible(plotX, plotY)) then
    			results = CombatManager.IsAttackChangeWarState(eUnitComponentID, plotX, plotY);
    			if (results ~= nil and #results > 0) then
    				bWillStartWar = true;
    			end
    		end
    We can find how many plots belong to the same "Area" of a plot via Plot:GetArea():GetPlotCount() but this does not tell us if a land area is detached or is part of a series of small continents all jammed together, I don't think. In Civ5 each individual landmass was its own "Area" with an assigned Area ID #, but with the way Civ6 jams multiple continents into the same landmass I am not sure this is true for Civ6 and I have not tested in any way to determine if it is or is not like Civ5.
     
    cvb and Infixo like this.
  9. cvb

    cvb Prince

    Joined:
    Jun 12, 2017
    Messages:
    446
    LeeS, this excursion to PlayersVisibility is great! Exactly what I'm going to need when I'll port some 'Initial views' from civ4 to civ6:

    """Reveal All up to distance 2, Forests & Rivers up to distance 3, Hills & Lakes up to distance 4, Mountains & Oases up to distance 5 and Boni up to distance 6"""

    The reasoning was along the intro "since generations your tribe is wandering around and now finally settles down" ... I always thought: Whow, they wandered around for generations and don't know important resources or Oases behind the next hills or forests?!

    Spoiler :

    civ4, Python
    Code:
    def revealPlots(iUnitX, iUnitY):
       """Reveal All up to distance 2, Forests & Rivers up to distance 3, Hills & Lakes up to distance 4, Mountains & Oases up to distance 5 and Boni up to distance 6"""
    
       for iX in range(iUnitX - 6, iUnitX + 7):
          for iY in range(iUnitY - 6, iUnitY + 7):
             cyPlot = cyMap.plot(iX, iY)
             iabsX, iabsY = abs(iX-iUnitX), abs(iY-iUnitY)
    
             if cyPlot.isRevealed(iTeam, False) or (iabsX==6 and iabsY==6):           # skip corners and already revealed plots
                continue
    
             eBT = cyPlot.getBonusType(iTeam)
    
             if (   (max(iabsX, iabsY) < 3)                                                                        # All
                    or ( (cyPlot.isRiver() or (cyPlot.getFeatureType() == eForest)) and (max(iabsX, iabsY) < 4) )  # Forests & Rivers
                    or ( (cyPlot.isHills() or cyPlot.isLake()) and (max(iabsX, iabsY) < 5) )                       # Hills & Lakes
                    or ( (cyPlot.isPeak() or (cyPlot.getFeatureType() == eOasis)) and (max(iabsX, iabsY) < 6) )    # Mountains & Oases
                    or ( eBT==eBanana or eBT==eClam or eBT==eCorn or eBT==eCow or eBT==eCrab or eBT==eDeer or eBT==eDye or eBT==eFish or eBT==eFur or eBT==eGems or eBT==eGold or eBT==eIncense or eBT==eIvory or eBT==eMarble or eBT==ePig or eBT==eRice or eBT==eSheep or eBT==eSilk or eBT==eSilver or eBT==eSpices or eBT==eStone or eBT==eSugar or eBT==eWhale or eBT==eWheat or eBT==eWine )   ):                                                 # Boni
    
                cyPlot.setRevealed(iTeam, True, False, -1)
    
     
  10. Gedemon

    Gedemon Modder Super Moderator

    Joined:
    Oct 4, 2004
    Messages:
    9,826
    Location:
    France
    AFAIK it's mostly the same as for civ5.

    An area is either a landmass (which could include multiple continents) or a water body.

    Mountains and impassable plots (like ice or some NW) define their own area.
     
  11. isau

    isau Deity

    Joined:
    Jan 15, 2007
    Messages:
    3,071
    Is this part of an AI script?

    I've not done this in Civ 6, but in other ventures, getting a unit to figure out it's on some kind of dead-end structure involves using variations of the A* routine, which you can find examples of online. Basically you would determine you are on an island if the Scout could find no paths to a movable tile, and if the total number of tiles considered was beneath some threshold.

    I don't know how doable A* is with Civ 6 Lua. Presumably some version of it is done in the core DLL files. I can say I have written A* routines in old Flash ActionScript and if done correctly it may not need excessive overhead. It does depend somewhat though on how frequently you need to call this routine.

    Something to think about: is it the unit that knows this, or the AI Player? Both are somewhat different considerations. Especially if you are okay with an AI Player only "realizing" they are on an island every 10-20 turns or so instead of with every move.
     
  12. Infixo

    Infixo Deity

    Joined:
    Jan 9, 2016
    Messages:
    3,785
    Gender:
    Male
    Location:
    Warsaw
    @isau AI Player, and the algorithm doesn't run every turn, no need for that. Rather every 3-5 turns. It is not for operational purposes, but for deciding about high-level strategies.
    As for now I've implemented a very simple yet effective approach that checks for what I call "an extended coast". So, basically if a tile has sea water within N tiles, then it is a CoastN tile. Standard Lua IsCoastalLand() basically checks for Coast1.
    I tested several maps and calculated ratio of Coast2 and Coast3 to the total land, then assigned kind of "how landy or islandy the map is" factor and got a strong correlation (R2>0.99).
     
  13. isau

    isau Deity

    Joined:
    Jan 15, 2007
    Messages:
    3,071
    BTW there may be a way to cheat a litlt

    Sounds like you've got something good going. Congrats.
     
  14. man_in_finance

    man_in_finance Chieftain

    Joined:
    Jan 9, 2019
    Messages:
    48
    Gender:
    Male
    Just read this now, but for what its worth your concept of analysing the ratio of Coast1, Coast2, Coast3 : Total Land I think is a very practical idea and I'm sure will be successful.

    An efficiency you may have is that those ratios are likely to be highly correlated, so you may in fact obtain what you want by reducing your input features to just 1 ratio, e.g. coast2 : Total land.

    Testing on several maps and to obtain some broad ranges was also a good idea. Can't offer improvements!
     
  15. Infixo

    Infixo Deity

    Joined:
    Jan 9, 2016
    Messages:
    3,785
    Gender:
    Male
    Location:
    Warsaw
    Indeed, they are.
    I decided to use Coast2 as it gives best results.
    For Coast1 results tend to be closer to each other, and they got mixed sometimes.
    For Coast3 the trend line is not straight for heavy coasts and islands.
    So, Coast2 it is then.
     

Share This Page