CyGame().getSorenRandNum(len(list)) not quite doing what i want.

naf4ever

Dread Lord
Joined
Feb 8, 2003
Messages
405
Location
Southeast Washington State
My program gets all cities in range of the the player then if certain ones meet a criteria it appends them to a list. I then want to pick a random city off that list. So far Ive done this:

Code:
iRandCity = CyGame().getSorenRandNum(len(listpTowns), "Bob")

It doesnt give me any errors but it doesnt quite return a random city either. It seems to always return back the first city i founded which i guess means an integar value of 0. Then if that one stops meeting the criteria and gets bumped off the list it will always return back the second city i founded, then the third,,, etc... How can i make it choose a random city off my list and not go in order?
 
Are you sure the length of listpTowns isn't 1?
Post more code. getSorenRandNum returns an integer between 0 and arg1 - 1.
 
Yeah, I've done the same thing (well, I use gc.getGame().getMapRand(), but same effect), and it works fine. Try posting the code that creates your list, maybe the bug is there.

Bh
 
Hmm, ya maybe the problem is in the list then. To sum up my code: It sorts down the cities based on a new specialist im making. If the empire-wide total of this new specialist is less than half of the total empire population it then makes a list of the individual cities that meet this criteria then picks one at random:

Code:
listTowns = []
totalPop = 0
totalSpec = 0
for i in range(pPlayer.getNumCities()):
	listTowns.append(i)
	totalPop += (pPlayer.getCity(i).getPopulation()) 
	totalSpec += pPlayer.getCity(i).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW"))
	if totalSpec < int(totalPop / 2):
		for i in range(len(listTowns)):
		cityPop = pPlayer.getCity(i).getPopulation()
		listpTowns = []
		if pPlayer.getCity(i).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW")) < int(cityPop / 2):
			listpTowns.append(i)
			iRandCity = CyGame().getSorenRandNum(len(listpTowns), "Bob")
                        then execute function blah on iRandCity,,,,,,,
 
Well, I'm hoping the spacing is messed up on that code, because it's a bit messy the way it is now. But I think the main problem is that you constantly reset "listpTowns" within your for loop.

There are a few more minor errors you made as well (such as using i instead of listTowns).

This should work:
Code:
listTowns = []
totalPop = 0
totalSpec = 0
for i in range(pPlayer.getNumCities()):
	listTowns.append(i)
	totalPop += (pPlayer.getCity(i).getPopulation()) 
	totalSpec += pPlayer.getCity(i).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW"))
if totalSpec < int(totalPop / 2):
	listpTowns = []
	for i in range(len(listTowns)):
		cityPop = pPlayer.getCity(listTowns[i]).getPopulation()
		if pPlayer.getCity(listTowns[i]).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW")) < int(cityPop / 2):
			listpTowns.append(listTowns[i])
	iRandCity = listpTowns[CyGame().getSorenRandNum(len(listpTowns), "Bob")]

Bh
 
That did it. Thanks Bhuric.
Well, I'm hoping the spacing is messed up on that code, because it's a bit messy the way it is now.

Well,,, thats cause im not really a programmer and am not too sure how everything works exactly. Your solution did highlight something thats been on my mind, and that is: What is the main difference between:
Code:
for i in range(pPlayer.getNumCities()):
	listTowns.append(i)
	totalPop += (pPlayer.getCity(i).getPopulation()) 
	totalSpec += pPlayer.getCity(i).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW"))
if totalSpec < int(totalPop / 2):
Which is the correct way. And my goofy way of doing it:
Code:
for i in range(pPlayer.getNumCities()):
	listTowns.append(i)
	totalPop += (pPlayer.getCity(i).getPopulation()) 
	totalSpec += pPlayer.getCity(i).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW"))
        if totalSpec < int(totalPop / 2):
Where i have the If statement tabbed over.
 
naf4ever said:
What is the main difference between:
Which is the correct way. And my goofy way of doing it:
Where i have the If statement tabbed over.

In Python, tabs are considered to be 'section blocks'. So in my code, the 'for' loop only ecompasses the following 3 lines. In your example, your entire code is within the for loop. That means that it is all looping, which is going to cause an incredible mess to your function.

I don't know if you've have and experience with other languages, but consider tabs to be the equivalent of "BEGIN" and "END" from something like Pascal, or the { } from C/C++/etc.

edit: If it helps, try and mentally look at it that way. Every time you do a loop, or a conditional, mentally think "begin" to yourself. Once you are finished with what that loop/conditional is supposed to do, mentally think "end". And then stop tabbing. ;)

edit2: To illustrate the answer to your question, however, let's assume there are 3 cities. My code would look like:
Code:
listTowns.append(0)
totalPop += (pPlayer.getCity(0).getPopulation()) 
totalSpec += pPlayer.getCity(0).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW"))
listTowns.append(1)
totalPop += (pPlayer.getCity(1).getPopulation()) 
totalSpec += pPlayer.getCity(1).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW"))
listTowns.append(2)
totalPop += (pPlayer.getCity(2).getPopulation()) 
totalSpec += pPlayer.getCity(2).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW"))
if totalSpec < int(totalPop / 2):
	<do if stuff here>
where yours would look like:
Code:
listTowns.append(0)
totalPop += (pPlayer.getCity(0).getPopulation()) 
totalSpec += pPlayer.getCity(0).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW"))
if totalSpec < int(totalPop / 2):
	<do if stuff here>
listTowns.append(1)
totalPop += (pPlayer.getCity(1).getPopulation()) 
totalSpec += pPlayer.getCity(1).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW"))
if totalSpec < int(totalPop / 2):
	<do if stuff here>
listTowns.append(2)
totalPop += (pPlayer.getCity(2).getPopulation()) 
totalSpec += pPlayer.getCity(2).getFreeSpecialistCount(gc.getInfoTypeForString("SPECIALIST_NEW"))
if totalSpec < int(totalPop / 2):
	<do if stuff here>

See the difference?

Bh
 
DUDE,,, do you know how huge this is for me... I cant even go into how many hours ive spent trying to figure out why the heck my function is being implemented like 20 times. Thanks a ton! Coincidently i also figured out today that I dont have to restart civ everytime i make a change in a python file that im working on but that it will just reload automatically,, oh man... Its been a productive day!
 
Back
Top Bottom