range of plots

isenchine

Empress
Joined
Oct 18, 2010
Messages
1,774
Location
Brussels, Belgium
If I have a Python code like below (indentation should be OK but might not display properly:

Code:
	x = homecity.getX()
	y = homecity.getY()
	xrange = range(x-1, x+1)
	yrange = range(y-1, y+1)
	for i in xrange:
		for j in yrange:
			nearplot = cyMap.plot(i, j)
etc...

Would it return me a range of 5 plots ("homecity", above, below, left, right) or 9 plots (a square surrounding the city)?

If it returns 5 plots, how can I make it 9?

Is it easy to return the Big Fat Cross or not?

Thanks in advance!
 
What I use for the -2/+2 BFC range is:
PHP:
                        iX=city.getX()
                        iY=city.getY()                                                    
			for iXLoop in range(iX - 2, iX + 3, 1):
				for iYLoop in range(iY - 2, iY + 3, 1):
                                        pPlot = CyMap().plot(iXLoop, iYLoop)
Edit: Yeah, the indentation looks wrong, I know.

An addendum from platyping to prevent the corners:
PHP:
if abs(iXLoop - iX) != 2 or abs(iYLoop - iY) != 2:
 
Thank You The_J for your answer but ... now you are confusing me :confused:

I'm really not a Python expert and I was trying to understand what the code does so can we try to go slowly...

1) What would "my" code return (even if it's not my code at all) ?

2) how come in your code "for iXLoop in range(iX - 2, iX + 3, 1):" you are using iX + 3, and not iX + 2?

3) same code: what does the ", 1" do in the end?

4) the If statement from Platyping, does it come just after your code? (for the time being, I'm not even starting to understand what it does though!)

Thanks for answering those questions from a noob in Python!
 
1) would only return the plots to the bottom and the left. Also cyMap is wrong, should be CyMap() -> would give an error.

2) The top border is where it stops, and not where the last calculation is made.
for i in range(0,10): will give you i from 0 to 9, not to 10.
Yes, that's confusing.

3) That's the step between the numbers in the loop.
for i in range(0,10,2) will give you every second number between 0 and 9, beginning with 0 (0, 2, 4, 6, 8).
for i in range(0,10,3) will give you every third number between 0 and 9, beginning with 0 (0,3,6,9)
etc.

Giving a step of 1 is not really necessary, because that will be used as default if nothing is given.

4) That would come after the second loop.
An easier version is maybe:
PHP:
if not (abs(iXLoop - iX) == 2 and abs(iYLoop - iY) == 2):

abs will give you...er...forgot the name of that math function...the absolute positive value (2 -> 2, 3 -> 3, -2 -> 2, -3 -> 3, etc; I think in school you learn it like |-3| = 3, or so). It will prevent that you get the edges of the -2/+2 grid around the city.
 
Thanks a lot for this detailed answer, now I understand better! :)

So, for "my" code, should

nearplot = cyMap.plot(i, j) be replaced by

nearplot = CyMap().plot(i, j) ?

(I never got an error for that, I just thought that it was not working properly!).

I'm just asking for the sake of it because I will probably replace it with your code anyway. Thanks again.
 
Thanks a lot for this detailed answer, now I understand better! :)

You're welcome :).

So, for "my" code, should

nearplot = cyMap.plot(i, j) be replaced by

nearplot = CyMap().plot(i, j) ?

:yup:


(I never got an error for that, I just thought that it was not working properly!).

Are Python Exceptions enabled?
If not, or you don't know, then take a look at your main BtS ini file (Documents\My games\BtS\Civ4.ini).
 
Are Python Exceptions enabled?

Yes (and I do receive error messages from time to time).

Edit 2: the reason is that it is defined on top of the file as "cyMap = CyMap()"!

Edit 1: and to apply my newly learned lessons, I changed in my code
xrange = range(x-1, x+1) to x+2
and
yrange = range(y-1, y+1) to y+2

and now it works properly!
 
Just a follow up necromancy post:

i want to place an improvement but only if it is within the BFC of an owned city. so far my code works with one exeption: i can not cut the corners, i.e. if the city is 2 tiles diagonally away the improvement is still placed.

here is the relevant code:

PHP:
pPlot = caster.plot()

<snip>

iX = pPlot.getX()
iY = pPlot.getY()
iCityRange = 0
for iiX in range(iX-2, iX+3, 1):
	for iiY in range(iY-2, iY+3, 1):
		if not abs(iiX - iX) == 2 or abs(iiY - iY) == 2: 
			pPlot2 = CyMap().plot(iiX,iiY)
			if pPlot2.isCity():
				pCity = pPlot2.getPlotCity()
				if pCity.getOwner() == caster.getOwner():
					iCityRange = 1
<snip>
 
Code:
for i in range(21):
	pPlot = pCity.getCityIndexPlot(i)
 
What happens if the plot is a one plot island?
there is a lot more code that handles water, peaks, improvements, features and so on, i just posted the relevant part.

Code:
for i in range(21):
	pPlot = pCity.getCityIndexPlot(i)

i changed the my code to:
PHP:
pPlot = caster.plot()
iPlayer = caster.getOwner()
pPlayer = gc.getPlayer(iPlayer)

<snip>

iCityRange = 0
for pyCity in PyPlayer(iPlayer).getCityList():
	for i in range(21):
		pCity = pyCity.GetCy()
		pPlot2 = pCity.getCityIndexPlot(i)
		if pPlot == pPlot2:
			iCityRange = 1

but it still does not work (iCityRange = 0)
 
I not sure what you wanna do with iCityRange or what is the purpose of it.
After those 2 lines, just do what you want like checking if the plot is a peak/water/city etc and then place your improvements accordingly.

Code:
for i in xrange(CyMap().numPlots()):
	pPlot = CyMap().plotByIndex(i)
	pPlot.setBonusType(2)

For instance, this will place copper in each of the city plot.
 
pPlot is the plot where the unit that builds the improvement is
pPlot2 are the plots withing the BFC of the cities of the player of the unit

therefore if the unit is on a plot that is within any of the players city BFC the improvement gets placed where the unit is. iCityRange is just an integer that i use later to determine if this is the case, i.e. iCityRange = 0 if it is outside the BFC and iCityRange = 1 if it is inside the BFC.


edit: it is basically just the if statement that is not working, i.e.
PHP:
if pPlot == pPlot2:
but i don't know why :'(

using commands such as pPlot.setBonusType(2) or pPlot2.setBonusType(2) work fine, but why can't it compare the plot coordinates?
 
Hmm so, pPlot is the plot of the unit.
If pPlot is within BFC of a city owned by the player, place improvement there right.

Then...
Code:
pPlot = caster.plot()
if pPlot.isPlayerCityRadius(caster.getOwner()):
          do what you want
Wouldn't this do the job?

This will check if pPlot is within BFC of any city owned by the player, but it does not check ownership of the plot itself.
If you want that, add another ownership check thats all.

Plot Ownership check:
if pPlot.getOwner() == caster.getOwner():
 
PHP:
iCityRange = 0
if pPlot.isPlayerCityRadius(caster.getOwner()):
		iCityRange = 1

works perfectly :)

thank you! ownership is not need because the ability can only be used within your borders (via xml)
 
Top Bottom