Building a road from one city to another in python

gautam

Chieftain
Joined
Dec 13, 2005
Messages
24
Hi,

I am trying to build a road from one city to another if there is more than 1 city for a civilization. However it seems like I am doing something wrong. Firstly I would like to ask if this even possible. Secondly I am doing it this way :-

Code:
	def buildRoads(self, iPlayer):
		print "Build Roads called"
		player = gc.getPlayer(iPlayer)
		iWorker = gc.getInfoTypeForString("UNIT_FARM_WORKER")
		pWorker = player.getUnit(iWorker)

		pGroup = pWorker.getGroup()
		iCities = player.getNumCities()
		pyPlayer = PyPlayer(iPlayer)

		print "Num Cities"
		print iCities

		pCapitalCity = player.getCapitalCity()
		print pCapitalCity.getName()

		if(iCities > 1):
			cityList = pyPlayer.getCityList()
			for apCityLoop in cityList:
				for iCityLoop in range(iCities):
					apCityLoop = pyPlayer.getCity(iCityLoop)
					print "In Build roads loop"
					print apCityLoop
					pGroup.generatePath(pCapitalCity.plot(), apCityLoop.getPlot(), False, 10)

However it doesn't seem to be going into the iCityLoop for loop.

Thanks
 
You have a loop variable apCityLoop and then you change that variable inside the loop! That's a red flag the size of a bedsheet going off right there, you'll want to change that. I don't know how Python deals with that, it may well be the cause of the problem.

Either way, as it is you're not using the outer loop for anything, you're generating paths from all your cities to the capital x times, where x is the number of times the outer loop is run. Are you trying to link all cities with each other or just all cities to the capital? If the latter is the case, you don't need a double loop to begin with, a single one will do. If you want to link every city with every other city you do need the double loop, but you'll need to change the variable name of apCityLoop inside the loop and change pCapitalCity to apCityLoop.
 
Hi,

You are right, on looking through the code this is a fatal mistake. I modified this to the following

Code:
def buildRoads(self, iPlayer):
		print "Build Roads called"
		player = gc.getPlayer(iPlayer)
		iWorker = gc.getInfoTypeForString("UNIT_FARM_WORKER")
		pWorker = player.getUnit(iWorker)

		pGroup = pWorker.getGroup()
		iCities = player.getNumCities()
		pyPlayer = PyPlayer(iPlayer)

		print "Num Cities"
		print iCities

		pCapitalCity = player.getCapitalCity()
		print pCapitalCity.getName()

		if(iCities > 1):
			for iCityLoop in range(iCities):
				print "In Build roads loop"
				pCity = player.getCity(iCityLoop)
				print pCity.getName()
				pGroup.generatePath(pCapitalCity.plot(), pCity.getPlot(), False, 10)

Which should take care of the for loop. I am trying to build a road from capital to all other cities. Also I have modified the XML to use a unique unit called farm worker that will only build farms. Does this have any effect on this. However even then it should go into the for loop. Not sure why its not going into the loop.
 
Hi,

I managed to get it going into the loop but it still doesn't seem to build any roads. Should I be doing anything else in order to do this.

Thanks
 
gautam said:
I managed to get it going into the loop but it still doesn't seem to build any roads. Should I be doing anything else in order to do this.

Ah, wait, you thought generate path meant generate a road network? It doesn't. What it does do I don't know for sure, the C++ of the generatePath function calls very low-level A* pathfinding code that's not in the SDK. It probably sets a movement path for the group, but it might not. But if it does, it only sets a move path, it doesn't create a road network. I'm not sure you can do what I think you're trying to do.

To build a road from one city to the next, you'll have to write your own pathfinding algorithm to determine the best route between the cities and to return the list of plots on which you can then apply CyPlot().setRouteType() to actually create the road. This can get a bit technical, you'll probably want to make it an A* algorithm, much like the one Firaxis used internally (but didn't expose to Python AFAIK). You can find a description of how A* works here (or google for it, whole books have been written on the subject). It can be a bit of work if you've never done anything like this before but it'll make you a better programmer if you do...
 
You might be able to get access to the path, if inefficiently:

Call CvSelectionGroup.generatePath() to create a path
Call getPathFirstPlot() - if this returns the first place you move *into*, you're set:
Move there
Build a route segment
Repeat

But yes, it'd be nice if the paths were more exposed.

On your bug, are you sure that pWorker.getGroup() is returning a valid value? I had some problems using that function that led me to back off on some AI work of my own. (If you know where there's decent documentation for SelectionGroup, I'd love to see it.)
 
Back
Top Bottom