Ok as you said.. I believe.. But It still when option 5 is inputed, it still prints out 'You do not have enough gold' & 'Try again later' statments.. and then loops back to enter the number again.

``````def S():
while True:
global gold
print 'Welcome to the Shipyard!\n'
print 'Here you can buy new Ships.\n'
print 'You currently have',gold,'Gold.\n'

Shiplist = {'1)Sloop':'1500\$', '2)Schooner':'3500\$', '3)Brigantine':'6500\$', '4)Galley': '9500\$'}
print 'The current Ships avaliable:\n'
print Shiplist
print ' '
print 'To Exit type 5'
print 'Type a number to choose the corresponding Ship!\n'

try:
choice = int(raw_input('Enter Number: '))
except ValueError:
print 'Invalid Input! Please input only numbers.\n'

if choice in [1, 2, 3, 4, 5]:
global price
global ship

if choice == 1:
ship = 'Sloop'
price = 1500

elif choice == 2:
ship = 'Schooner'
price = 3500

elif choice == 3:
ship = 'Brigantine'
price = 6500

elif choice == 4:
ship = 'Galley'
price = 9500

if gold >= price:
print 'You bought a new ship!'
gold -= price
print 'You now have:',
print gold,
print 'Gold\n'

elif gold < price:
print 'You do not have enough Gold!'
print 'Try again later!\n'

elif choice == 5:
break``````

I know its something stupid I am not seeing, after this im going to bed, because I am nothing thinking clearly..

That is due to line 24:

``if choice in [1, 2, 3, 4, 5]:``

You allow 5 to execute the 'buying-a-ship' if statement instead of the break one. It should just be:

``if choice in [1, 2, 3, 4]:  # no 5!``

Okay, that fixed it..As said, I am going to bed as I am nothing thinking logic but more idiot right now.. So thank you again. and good nite lol

I will update this tomorrow with some more functions I think you might like...I think I understand the 'if' and 'elif' better now in loops.. and also where I use 'choice in'. Good stuff here..And you also help me learn from my stupid mistakes.. Maybe one day I can get them classes down.

I followed the examples you set last night for 'loops', and things. Today I added a 'Merchant'. So now you can buy a few goods, sell goods you have. the price right now is always the same, I will change this later with a random.randrange so sometimes you may pay more or less, and the items may sell for more or less..

This would rock if it was in a GUI form...maybe not graphics that good, but buttons would be a nice addition sometime..

I got pretty much everything lined out except I get an error, here is the error code..

File "C:\Python25\pirates.py", line 35, in S
if choice in [1, 2, 3, 4]:
UnboundLocalError: local variable 'choice' referenced before assignment

Ok I am not sure why its throwing that up, has not done that before, only dose it when I try and make it error by not typing a number.. You can reference my code I have not changed the way its typed or formatted, just exceptions..

``````try:
choice = int(raw_input('Enter Number: '))
except ValueError:
print 'Invalid Input! Please input only numbers.\n'

if choice in [1, 2, 3, 4]:
global price
global ship

Do I just need to make it 'except' an UnboundLocalError?
if choice == 1:``````

Well if the try ... except block isn't in a while loop, with that else: break segment I posted for you before, then there's your problem.

If you give bad input, it will error and go to the "Invalid Input!..." line, and then continue on down the script to the `if choice in [1,2,3,4]` statement.
But if it threw an error, choice is still undefined, yet it tries to compare it in that if statement. The reason it is still undefined is because it caused an error when trying to assign a value to it, so it stayed undefined.

I showed you a solution before, which was the while loop to get input until it gets good input, in which case it breaks out and continues down the script:

``````while True:
try:
choice = int(raw_input('Enter Number: '))
except ValueError:
print 'Invalid Input! Please input only numbers.\n'
else:  # if the input doesn't cause an error
break

# that 'break' will make it continue along to here... (outside of the loop)
if choice in [1, 2, 3, 4]:
# etc.``````

Well, I thought we had to drop the 'else' statement because I needed all the 'if' and 'elif' functions to be under the loop in order to return to the menu? It was on page 3 when you fixed the indention problem for that to work.. I throw the else statement in there I gotta remove the 'ifs' from the loop in order for it to pass..Which then the menu dose not work.

You're not understanding: the else with the break is attached to the try/except block. That is inside the while loop. Then, outside the loop, on the starting on the same indentation level as your loop, goes all the stuff that happens after the input segment.

No offense, but please, please, please read some books on basic Python or programming in general and do some simple exercises pertaining to that. You need to understand how the code I gave in my previous post actually works.

It's simple: the while loop begins, and asks the user for input. If it's bad (i.e. a non-number), then it goes to the except block, and because of that, it does not execute that else: break section. This means that it asks for input again, and so forth. If it gets good input, then it won't cause an error, so it will go to the else: break part. This break ends the while loop, this allowing the script to continue execution downwards where it encounters the stuff you have dealing with handling the choice the user gave.

I honestly cannot get any more simplistic than that...

I think we are both on two different pages here..

``````try:
choice = int(raw_input('Input a Number! '))
except ValueError:
print 'Invalid Input, Please type a Number!\n'
# this must be where it is at!
if choice in [1, 2, 3]:``````

This above, MUST be in line with the loop/try statement. Otherwise its a waste of time, because it must loop. Doing what you said, puts the 'ifs' outside of the loop, wont work.

You should really check out the tutorial on python.org. Anyway, since you're having trouble wrapping your head around try except, here's a basic outline that handles bad choice slightly differently

``````#a simple class for our user
class Player:
def __init__(self,name):
self.day = 0
self.name = name
def __str__(self):
s = "Player: %s" %(name)
return s

#get the name of the user
player = Player(raw_input('Name: '))

#for pretty formatting, an easy way to separate menus
def bar():
s = "-" * 40
return s

#the main menu, note that it returns a string rather than print it
s = """Welcome %s - Day %d!
%s
(1) Store
(2) Home
(0) Quit
%s""" %(player.name,player.day,bar(),bar())
return s

#same deal as the menu, but this is the store
def store():
s = """Store
%s
(1) Milk
(2) Eggs
%s""" %(bar(),bar())
return s

#another menu type thing, but it's home
def home(player):
s = """%s's home
%s""" %(player.name,bar())

#endless game loop
while 1:
#whenever it loops, it will begin with the menu
#note that we get raw_input
choice = raw_input("Choice: ")
print bar()
if choice == '1': #choice will always be a string!
print store() #note that we print the function call
enter = raw_input("<press enter to cont>")
print bar()
elif choice == '2':
print home(player) #pass the player object to the function
enter = raw_input("<press enter to cont>")
print bar()
elif choice == '3':
print "Advancing a day..."
player.day = player.day + 1 #modify the player object
elif choice == '0':
print "Quitting" #tell them you're quitting...
break #and then break out of the loop
else: #if choice is not equal to a menu option, handle it gracefully
print "Invalid Choice"
print bar()

#any code below me will execute after player "quits"``````

Ok, I finally got the problem resolved, now before I really put alot more work into this, I was wondering of a tutorial, or some help with a save function. I know what I want to save but no idea how to write it.. anyone?

What is it you want to save exactly? This is where classes could come in VERY handy. If you had a player class, and all the stuff you wanted to save were properties of that class (like player.gold, player.name) then you could just pickle the whole class instance to a file. Then when reloading the game, you just make the instance of the player in the game the unpickled instance from that same file.

Example usage:

``````import pickle

# SAVING:
# assuming that 'player' is the class instance you want to save
fh = open('saved_data', 'w')
pickle.dump(player, fh)
fh.close()

# 'player' is now the same as the instance you saved
fh = open('saved_data', 'r')
fh.close()``````

You can read about the pickle module here. It's a very easy way of serializing data for saving and stuff.

I did not make class's as I would have most likely failed, all I want to save is say, gold/level/ship they have/maybe something later I can add to it..

Then you can just invent some simple format for a file to write that to. Say, the file has the values stored, separated by commas, in a specific order, like: `gold,level,ship,name` So you would just need to write those variables to a file like you would anything else. And then you'd need to re-assign them upon reading a file like that.

``````# SAVING:
fh = open('saved_data', 'w')
fh.write('%s,%s,%s,%s' % (gold, level, ship, name))
# or
# fh.write(','.join([gold, level, ship, name]))
fh.close()

fh = open('saved_data', 'r')
fh.close()
data = data.split(',')
gold = int(data[0])
level = int(data[1])
ship = data[2]
name = data[3]``````

If you're making a game you'll soon realize how useful and simple it is to use pickle with the objects you want to save.

ok, I think I see how your doing it, but where is the best place to put a pickle? at the end of my code or at the begining? or is it needed that the 'open' part be at the top?

Well like I was saying, you'd be using pickle for classes and stuff more (or dicts, lists, or tuples).

If you're only wanting to save something like gold, level, ship, then you should only need the basic file I/O like I showed above, not pickle.

And as for placement, you're going to want to put the saving code into a function (saveGame) and the loading code into its own as well (loadGame).

Obviously, you'd want to call the saveGame function when the user wants to quit, so you need to make a call to it, saveGame(), before allowing your script to end.

I tried writing what you put above as kind of a frame for the save/load. It is syntatically correct, I just dont see what it saves or loads anything at all... Then again, I may have it coded totally backwards and just a waste of space lol..

``````def SaveGame():
fh = open('saved_data', 'w')
fh.write(','.join([gold, level, ship]))
fh.close()

fh = open('saved_data', 'r')
fh.close()
data = data.split(',')
gold = int(data[0])
level = int(data[1])
ship = data[2]

print 'Here you can save, and load games\n'
print 'Type: (1 To Load a Game!'
print 'Type: (2 To Save a Game!\n'
try:
choice = int(raw_input('Input a Number! \n'))
except ValueError:
print 'Invalid Input, Please type a Number!\n'
if choice == 1:
elif choice == 2:
SaveGame()``````

I honestly have no idea what I have done here...

Well you've screwed up the try/except thing that I've tried to explain over and over.

You currently have the if statements inside the except block, meaning if there is an error it will print what you've written, and then try to load or save the game. Neither of those will become true anyways because the only reason the except block got fired was because 'choice' was not an integer.

For the last time, I'll fix your try/except part:

``````while True:
try:
choice = int(raw_input('Input a Number! \n'))
except ValueError:
print 'Invalid Input, Please type a Number!\n'
else:
break

if choice == 1:
elif choice == 2:
SaveGame()``````

If you still don't understand the above code, you can find at least 5 posts in this thread where I've explained it.

Also, your LoadGame function won't do anything. You're using global variables for gold, level, etc. so you actually need to declare them as global inside that function in order to modify them:

``````def LoadGame():
global gold, level, ship

fh = open('saved_data', 'r')
fh.close()
data = data.split(',')
gold = int(data[0])
level = int(data[1])
ship = data[2]``````

Ok, I forgot about the 'else' I just kinda slaped it together, I fixed that, but I get an error I dont know, I know what its saying but I do not see an 'int' in this line, unless its making something an 'int'...

``fh.write(','.join([gold, level, ship]))``

TypeError: sequence item 0: expected string, int found

Im not sure what it wants...

Oh damn, I forgot, sorry. The list you pass to join should be strings, so it looks a bit messier but you could change that to this:

``fh.write(','.join([str(i) for i in [gold, level, ship]]))``

Which makes a list of gold, level, and ship converted to strings.

sweet, it works...now if I only understood how it works...but I guess in time I will... Thanks, for the 1 billionth time..lol

This is coming along nicely. Next to do is: Set HP for player based on Level. Set Cargo for ships to a max level. Make a Black Market for selling of illegal items. Make Quest Side Missions. Finally, Set the players level to an EP system for points between levels. Easy enough, just more and more time..

This is coming along nicely. Next to do is: Set HP for player based on Level. Set Cargo for ships to a max level. Make a Black Market for selling of illegal items. Make Quest Side Missions. Finally, Set the players level to an EP system for points between levels. Easy enough, just more and more time..

Yup. Keep in mind that threads that reach this long in length are hard to follow. If you have further questions or need certain things explained in more detail please start a new thread, with the relevant code and your query right there in the first post. Oh and giving it a descriptive title will help too.

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.