Apolyton Archive  |  Preserved copy of the Apolyton Civilization Site and its forums as they stood in September 2005. Read-only; nothing here can be posted to or replied to.  |  Forum index |  About this archive |  The 1998–2001 UBB forums
Today on Apolyton WARDELL INTERVIEW PROMO A.C.S. HISTORY CHAPTER 4 GET CIV4 /w FREE PLUS! A.C.S. PHOTO GALLERY GET A.O.M. V1.1
Apolyton Civilization Forums
main| civ2| civ3| civ4| smac| ctp2| ron| moo3| galciv| galciv2| alt| about|
ApolytonPLUS | register | search | faq | new posts | pm (-/-) | upload | members
hall of fame new! | civgroups | civgroups news | interviews | the column | radio | chat | directory | news | store | PLUS
Apolyton Civilization Forums : Powered by vBulletin version 2.0.3 Apolyton Civilization Forums > Miscellaneous > Archive > CtP2-Creation/AI/Mods/Scenarios-Archive > City on same continent
Show a Printable Version | Email This Page to Someone! | Receive updates to this thread | Report this to Apolyton news!

bottom of page
  
Author
Thread    < Last Thread     Next Thread > Post New Thread     Post A Reply
ahenobarb is offline ahenobarb
Prince

Nov 2001
time: 05:28
  Old Post 28-05-2003 21:10
Edit/Delete Message Reply w/Quote
#1 Report this post to a moderator
City on same continent Support Apolyton buy from Amazon

Is there any SLIC function/method to determine if a city is on the same land mass as another object (city, unit, map square)?

Locutus is offline Locutus
ACS CTP1/2 Manager & Civ4 Co-Manager
Hengelo, The Netherlands
Nov 1999
time: 06:28
  Old Post 28-05-2003 21:13 Visit Locutus<br><img src=/forums/images/staff-icon.gif>'s homepage!
Edit/Delete Message Reply w/Quote
#2 Report this post to a moderator
Support Apolyton, buy Alpha Centauri

Nope, I don't think so

Immortal Wombat is offline Immortal Wombat
Prince
in perpetuity
Dec 2000
time: 05:28
  Old Post 28-05-2003 22:08 Visit Immortal Wombat's homepage!
Edit/Delete Message Reply w/Quote
#3 Report this post to a moderator
Suffering from ads?

Unless you can get the IsContinentBiggerThan function to work properly, and your map doesn't have two continents of identical sizes on it.
Probably you could do it the long way, checking each route manually...

Locutus is offline Locutus
ACS CTP1/2 Manager & Civ4 Co-Manager
Hengelo, The Netherlands
Nov 1999
time: 06:28
  Old Post 28-05-2003 23:13 Visit Locutus<br><img src=/forums/images/staff-icon.gif>'s homepage!
Edit/Delete Message Reply w/Quote
#4 Report this post to a moderator
Increase Your PM Length

You can write a function yourself. I was working on this myself but other affairs have been keeping me busy.

The idea is simple: at the start of the game, cycle through the entire map from top-left to bottom-right, row-by-row, and assign a continent ID to every tile. For each tile, check if the tiles above it and left of it happen to be of the same type (where valid types are land and water) and if so, copy their ID. If not, assign a new, unique ID to this tile. Give land continents positive values as ID and 'water continents' negative ones, so that you can easily determine the difference between bodies of water and bodies of land (you may not have an immediate use for it now, but you might in the future).

If several neighbouring tiles are of the same type but have different IDs, then two parts of the same continent were apparently seperated by water (or land, if it's a body of water) and incorrectly got different IDs. So then cycle through the part of the map you already finished again and replace obsolete IDs with the correct ones (e.g. if continent 3 and continent 5 turn out to be the same continent, replace all 5s with 3s (or vice versa)).

The only problem with this code could be that it might add a lot of workload: you'll be doing a *lot* of calls to TerrainType and CreateLocation functions, which may slow down the game quite a bit. Of course, the good thing is that you only have to do this once per game (or rather, once per /reloadslic), after that you can store the 'continent map' and write your own functions to take advantage of it (in case of checking if 2 things are on the same continent, simply check the continent IDs of their tile).
I was actually thinking of combining this continent mapping with other mappings, such a threat mapping and desire mapping, but that's still in the brainstorm phase. It could make it more interesting though: 1 slowdown at the start of the game would give you a whole set of mappings to write AI code on for the rest of the game, without considerable delays (hopefully).

There are a couple of issues I was still working out, but those are details. I probably won't get around to writing this before the end of June, so if you're in a hurry feel free to implement this algorithm in SLIC yourself.

Here's some pseudocode to represent the above (can't guarantee this is functional, but it should be close and apart from replace_all_with_lowest() fairly easy to convert to actual SLIC). Note that you actually need a double loop to cycle through all map tiles (x and y).

code:
current_ID = 1; loop (maptiles) { current_tile = <next tile>; if (is_land(current_tile)) { loop (neighbours) { if (is_land(neighbour)) { continent_ID[current_tile] = continent_ID(neighbour); } if (multiple_land_IDs_found) { replace_all_with_lowest(); } } if (continent_ID[current_tile] = 0) { current_ID++; continent_ID[current_tile] = current_ID; } } else { loop (neighbours) { if (!is_land(neighbour)) { continent_ID[current_tile] = continent_ID(neighbour); } if (multiple_land_IDs_found) { replace_all_with_lowest(); } } if (continent_ID[current_tile] = 0) { current_ID++; continent_ID[current_tile] = -1*current_ID; } } }

Last edited by Locutus on 28-05-2003 at 23:32

Immortal Wombat is offline Immortal Wombat
Prince
in perpetuity
Dec 2000
time: 05:28
  Old Post 29-05-2003 00:20 Visit Immortal Wombat's homepage!
Edit/Delete Message Reply w/Quote
#5 Report this post to a moderator
Support Apolyton buy from Amazon

Well GoodMod does a fair number of calls to CreateLocation, it scans the map four times is it? And this is 8. It would be amazingly useful though.

The only thing I can see that won't work so directly as that would be using the current_tile as an array element, it being a pair of coordinates. I've been using 100*x + y to get two numbers in when using units I think it was for some reason. but the map could be all different sizes, and to do 1000*x + y seems a little large. Is there a better way to do it?

Locutus is offline Locutus
ACS CTP1/2 Manager & Civ4 Co-Manager
Hengelo, The Netherlands
Nov 1999
time: 06:28
  Old Post 29-05-2003 00:35 Visit Locutus<br><img src=/forums/images/staff-icon.gif>'s homepage!
Edit/Delete Message Reply w/Quote
#6 Report this post to a moderator
Support Apolyton

The best way to do it (and how I've always done it in the past), is x + y * g.mapheight (or x * g.mapwidth +y, whatever you prefer). Can't get it more efficient than that...

I was indeed going to look into goodmod as well: maybe this could be merged with Martin's loops to reduce redundancy. But as I said, that's only in the brainstorm phase for now, I don't have anything tangible on that yet.

Martin Gühmann is offline Martin Gühmann
Emperor
Berlin, Germany
Mar 2001
time: 06:28
Post  Old Post 29-05-2003 20:37 Visit Martin Gühmann's homepage!
Edit/Delete Message Reply w/Quote
#7 Report this post to a moderator
Get a bigger avatar today!

quote:
Originally posted by Immortal Wombat
Well GoodMod does a fair number of calls to CreateLocation, it scans the map four times is it? And this is 8. It would be amazingly useful though.


And even the CreateLocation function is not the slowest part of the code. IIRC the slowest part is removing all these help tile improvements. Maybe I should rewrite the code and also modify the tileimprovements so that they can be placed on the terrain without the need that the terrain has to be owned.

-Martin

Martin Gühmann is offline Martin Gühmann
Emperor
Berlin, Germany
Mar 2001
time: 06:28
Post  Old Post 18-10-2003 23:00 Visit Martin Gühmann's homepage!
Edit/Delete Message Reply w/Quote
#8 Report this post to a moderator
Increase Your PM Length

What about this stuff?

code:
//////////////////////////////////////////////////////// //MG_ComputeContinents // // // //Parameter: location_t theLoc // //A location // //Parameter: int_t GetID // //Determinzes what the function returns. // // // //Return Value: // //Returns a continent ID if GetID == 1, that is unique// //for each coherent mass of Land or of water. If the // //continent is a land mass the return value is // //positive, if it is a water mass the return value is // //negative. // //If GetID == 0 it returns the size of the continent // //of that theLoc is part of. // //if GetID == 2 it returns the number of continents on// //the whole map. Else it returns the same value as // //GetID == 1. // // // //Remarks: // //MG_IsLand needs to be modified if you change the // //number of terrains in the terrain.txt. // //////////////////////////////////////////////////////// int_f MG_ComputeContinents(location_t theLoc, int_t GetID){ int_t IsInitialized; int_t i; int_t q; int_t r; int_t MGContinentIDs[];//GetMapWidth() * GetMapHeight() int_t MGContinentSizes[]; int_t MGLastID; location_t MGIDLoc; location_t MGLoc1; location_t MGLoc2; int_t MGGetID; MGGetID = GetID; MGIDLoc = theLoc; if(!IsInitialized){ IsInitialized = 1; MGLastID = 1; for(i = 0; i < GetMapWidth() * GetMapHeight(); i = i + 1){ MGContinentIDs[i] = 0; } location_t MGSameLocs[]; location_t MGDifferentLocs[]; int_t indexS; int_t indexD; indexS = 1; indexD = 1; MakeLocation(MGLoc1, 0, 0); MGDifferentLocs[0] = MGLoc1; q = 0; r = 0; while(q < MGDifferentLocs.#){ MGLoc1 = MGDifferentLocs[q]; q = q + 1; if(MGContinentIDs[MGLoc1.x + MGLoc1.y * GetMapWidth()] == 0){ MGSameLocs[indexS] = MGLoc1; indexS = indexS + 1; while(MGSameLocs.# > r){ MGLoc1 = MGSameLocs[r]; r = r + 1; if(MGContinentIDs[MGLoc1.x + MGLoc1.y * GetMapWidth()] == 0){ if(MG_IsLand(MGLoc1)){ MGContinentIDs[MGLoc1.x + MGLoc1.y * GetMapWidth()] = MGLastID; } else{ MGContinentIDs[MGLoc1.x + MGLoc1.y * GetMapWidth()] = -1 * MGLastID; } for(i = 0; i < 8; i = i + 1){ if(GetNeighbor(MGLoc1, i, MGLoc2)){ if(MGContinentIDs[MGLoc2.x + MGLoc2.y * GetMapWidth()] == 0){ // if(MG_IsLand(MGLoc2) == MG_IsLand(MGLoc1)){ if(MG_IsLand(MGLoc2) == (MGContinentIDs[MGLoc1.x + MGLoc1.y * GetMapWidth()] > 0)){ MGSameLocs[indexS] = MGLoc2; indexS = indexS + 1; } else{ MGDifferentLocs[indexD] = MGLoc2; indexD = indexD + 1; } } } } } } MGLastID = MGLastID + 1; } } MGContinentSizes[MGLastID - 1] = 0; for(i = 0; i < MGContinentIDs.#; i = i + 1){ if(MGContinentIDs[i] > 0){ MGContinentSizes[MGContinentIDs[i]] = MGContinentSizes[MGContinentIDs[i]] + 1; } elseif(MGContinentIDs[i] < 0){ MGContinentSizes[-MGContinentIDs[i]] = MGContinentSizes[-MGContinentIDs[i]] - 1; } } } if(GetID == 1){ return MGContinentIDs[MGIDLoc.x + MGIDLoc.y * GetMapWidth()]; } elseif(GetID == 0){ int_t MGCon; MGCon = MGContinentIDs[MGIDLoc.x + MGIDLoc.y * GetMapWidth()]; if(MGCon > 0){ return MGContinentSizes[MGCon]; } elseif(MGCon < 0){ return MGContinentSizes[-MGCon]; } } elseif(GetID == 2){ return MGContinentSizes.#; } else{ return MGContinentIDs[MGIDLoc.x + MGIDLoc.y * GetMapWidth()]; } } //////////////////////////////////////////////////////// //MG_AreOnSameContinent // // // //Parameter: location_t firstLoc // //A location // //Parameter: location_t secondLoc // //A location // // // //Return Value: // //Returns 1 if both locations are on the same // //continent, otherwise it returns 0. // // // //Remarks: // //MG_IsLand needs to be modified if you change the // //number of terrains in the terrain.txt. // //////////////////////////////////////////////////////// int_f MG_AreOnSameContinent(location_t firstLoc, location_t secondLoc){ location_t MGFirstLoc; location_t MGSecondLoc; MGFirstLoc = firstLoc; MGSecondLoc = secondLoc; return (MG_ComputeContinents(MGFirstLoc, 1) == MG_ComputeContinents(MGSecondLoc, 1)); } //////////////////////////////////////////////////////// //MG_GetContinentID // // // //Parameter: location_t theLoc // // // //Return Value: // //The continent ID of theLoc's continent. // // // //Remarks: // //MG_IsLand needs to be modified if you change the // //number of terrains in the terrain.txt. // //////////////////////////////////////////////////////// int_f MG_GetContinentID(location_t theLoc){ location_t MGLoc; MGLoc = theLoc; return MG_ComputeContinents(MGLoc, 1); } //////////////////////////////////////////////////////// //MG_GetContinentSize // // // //Parameter: location_t theLoc // // // //Return Value: // //The continent size of theLoc's continent. // // // //Remarks: // //MG_IsLand needs to be modified if you change the // //number of terrains in the terrain.txt. // //////////////////////////////////////////////////////// int_f MG_GetContinentSize(location_t theLoc){ location_t MGLoc; MGLoc = theLoc; return MG_ComputeContinents(MGLoc, 0); } //////////////////////////////////////////////////////// //MG_GetNumberOfContinents // // // //Parameter: none // // // //Return Value: // //The number of continents on the map. // // // //Remarks: // //MG_IsLand needs to be modified if you change the // //number of terrains in the terrain.txt. // //////////////////////////////////////////////////////// int_f MG_GetNumberOfContinents(){ location_t MGLoc; MakeLocation(MGLoc, 0, 0); return MG_ComputeContinents(MGLoc, 2); }


-Martin

The Big Mc is offline The Big Mc
King
Of the universe / England
Oct 2001
time: 05:28
  Old Post 19-10-2003 01:14 Visit The Big Mc's homepage!
Edit/Delete Message Reply w/Quote
#9 Report this post to a moderator
Increase the size of your Attachments

looks like some poor poor person got some work to do

Martin the Dane is offline Martin the Dane
Prince
Aarhus, Denmark
Feb 2000
time: 06:28
  Old Post 19-10-2003 13:24 Visit Martin the Dane's homepage!
Edit/Delete Message Reply w/Quote
#10 Report this post to a moderator
Support Apolyton buy from Amazon

Martin,

I just scanned through your code and noticed that you used GetMapWidth() and GetMapHeight() several times within a loop.

Depending on the implementation of these functions this might be OK, but as we do not know how this is implemented (yet), you could most likey speed up the process considerabely by reading these values once and placing them in variables.

The same goes for the "for(i = 0; i < GetMapWidth() * GetMapHeight(); i = i + 1)" here "GetMapWidth() * GetMapHeight()" is (most likely) calculated once for every map-square.

Some (probably most) modern compilers takes this into account but I doubth that the slic-script engine does that.

When I learned to program (back in the days where I was one of a select few that had a 486DX with 4 MB of RAM - 386DX with 1MB was considered a fast computer) I learnd a very usefull rule: "Never put any line of code within a loop that can in any way be placed outside it" in other words "put as little code as possible into loops."

Martin Gühmann is offline Martin Gühmann
Emperor
Berlin, Germany
Mar 2001
time: 06:28
Post  Old Post 19-10-2003 19:40 Visit Martin Gühmann's homepage!
Edit/Delete Message Reply w/Quote
#11 Report this post to a moderator
Support Apolyton, buy GURPS/ Alpha Centauri

quote:
Originally posted by The Big Mc
looks like some poor poor person got some work to do


That is not much I just posted less then 200 lines of a script that contains nearly 3000 lines, well including comments. And this script just contains a lot of function.

Well Martin I replaced the GetMapWidth and GetMapHeight functions by integers. But the function still needs one or two seconds on a 70*140 map to calculate all the stuff. That is not faster than the original function. And actual I don't care to much about it, because the function is selfreinitializing. That means if all the stuff is calculated the whole data is stored in the MGContinentIDs array until the next /reloadslic and IsInitialized is 1 until the next /reloadslic as well.

Well I would rather worry about memory usage and redundancy. I know for example that MGDifferentLocs[] can be filled with a lot of location.

-Martin

  < Last Thread     Next Thread > Post New Thread     Post A Reply
All times are GMT. The time now is 05:28.
Apolyton Time is 00:28.
    top of page
Rate This Thread:
archivepost
Forum Jump:
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is ON
vB code is ON
Smilies are ON
[IMG] code is ON
 




Contact Us - Apolyton Civilization Site - Support Us!

Building a better Apolyton through better information. Click here and take our poll!
Non-US visitors, click here!

Powered by: vBulletin Version 2.0.3
Copyright ©2000, 2001, Jelsoft Enterprises Limited.

Page generated in 0.0495 seconds (89.71% PHP - 10.29% MySQL) with 31 queries
Page Loading Time:

Support Apolyton: Amazon USA | Amazon UK | Amazon DE | Amazon FR |
Support Apolyton and get FREE PLUS, Buy from Chips&Bits: Galactic Civilizations | Galactic Civilizations: Deluxe Edition | Call to Power 2 | Civilization: The Boardgame | GURPS/ Alpha Centauri | Alpha Centauri | Civilization IV | Civilization III: Complete |


Front Page | Civilization IV | Civilization III | Civilization II | Call to Power II | Alpha Centauri | Master of Orion III
Rise of Nations | Galactic Civilizations | Galactic Civilizations II | Misc
Alt.Civs | Civ I | C:CtP I | About | News | Directory | Apolyton Store | Forums | Chat | Columns | Interviews | Newsletter
Scenario League | CSC | Clash of Civs | Spanish Site | CtP Maps | Cradle of Civ | WesW's Ctp1/2 Site | Civ3 Haven

apolyton.net | apolyton.com | civilization2.net | civilization3.net | civilization4.net | civilizationiv.info | calltopower.net | galciv.net | galciv2.net | moo3.net