471,071 Members | 1,340 Online

# Python and Highscore.

Hello! I have been making a "guess what number the computer thinks of"-game in python (text-only) for educational reasons. Now, i want to implement a highscore in the code, which writes the best three players with names and number of attempts. First, I'll just show you my game, but nevermind the code in that one:

Expand|Select|Wrap|Line Numbers
1. #Importere modulen random:
2. import random
3. #thenumber tilsvarer nå random.randint(0, 100) som er et tilfeldig tall mellom 0 og 100)
4. thenumber = random.randint(0, 100)
5. # Et tappert forsøk på en loop.
6. loop = 1
7.
8. #Definerer choice.
9. choice = 0
10. forsøk = 0
11.
12. #Så til selve gjettedelen av scriptet :)
13.
14. print "It is a number between 0 and 100. Can you guess it?"
15. print "Guess-the-number-game made by CromogliC"
16. print "Just type in a number of your own choice and press enter!"
17.
18. yourname = raw_input("Please type in your name here: ")
19.
20. while loop == 1:
21.     choice = input("What number do you think is is?: ")
22.     if choice == thenumber:
23.         forsøk = forsøk +1
24.         print "Amazing," + " " + yourname + "!"
25.         print "You have guessed the right number!"
26.         print "You are victorious!"
27.         print "Tries used:"
28.         print forsøk
29.         wins = forsøk
30.         loop = 0
31.         print "Restart? y for yes. n for no."
32.         restart = raw_input("Do you want to restart?: ")
33.         if restart == "y":
34.             forsøk = 0
35.             #User restart!
36.             loop = 1
37.         elif restart == "n":
38.             loop = 0
39.             print "Game Over!"
40.             exit()
41.     elif choice < thenumber:
42.         print "Nope, you have got to go higher!"
43.         forsøk = forsøk +1
44.         loop = 1
45.     elif choice > thenumber:
46.         print "Nope, you have got to go lower!"
47.         forsøk = forsøk +1
48.         loop = 1
49.     elif choice > 100:
50.         print "I am sorry, but you cannot pick a number above 100!"
51.         loop = 1
52.
Explanation: The notes are just explaining what the different sections does. nevermind those at all - they are in norwegian because i am a norwegian^^
Forsøk (in english attempts/tries) indicates how many attempts the user have used on guessing the right number. I did not plan on getting a highscore for this game, but now I've changed my mind. However, the integration of the actual highscore-code might be a little harder then. (Am I right?:P)

Now, to the actual highscore-code. I found a highscore from a previous post in here, but I am rather new to Python, and therefore had some trouble using it. Well, here is it (a little bit modifyed, as i tried to make it work on my own):

Expand|Select|Wrap|Line Numbers
1. def hasHighScore(score):
2. #opens guessnumberhighscore.txt
3.     infile = open("guessnumberhighscore.txt",'r')
4.     scores = [0,0,0]
5.     names = ["","",""]
6.
7. #reads in scores from guessnumberhighscore.txt
8. i=0
9. for line in infile.readlines():
10.     scores[i],names[i] = string.split(line,"\t")
11.     names[i]=string.rstrip(names[i])
12.     i += 1
13.     infile.close()
14.
15. #compares player's score with those in guessnumberhighscore.txt
16. i=0
17. for i in range(0,len(scores)):
18.     if(score in(scores[i])):
19.         return True
20.     else:
21.         return False
22.
23. def setHighScores(score,name):
24. #opens guessnumberhighscore.txt
25.     infile = open("guessnumberhighscore.txt",'r')
26.     scores = [0,0,0]
27.     names = ["","",""]
28.
29. scores = [0,0,0]
30. #reads in scores from guessnumberhighscore.txt
31. i=0
32. for line in infile.readlines():
33.     scores[i],names[i] = string.split(line,"\t")
34.     scores[i]=int(scores[i])
35.     names[i]=string.rstrip(names[i])
36.     i += 1
37.     infile.close()
38.
39. #shuffles thru the guessnumberhighscore.txt and inserts player's score if
40. #higher than those in file
41. i=len(scores)
42. while(score == scores[i-1] and i>0):
43.     i -= 1
44. scores.insert(i,score)
45. names.insert(i,name)
46. scores.pop(len(scores)-1)
47. names.pop(len(names)-1)
48.
49. #writes new guessnumberhighscore.txt
50. outfile = open("guessnumberhighscore.txt","w")
51.
52. outfile.write (" High Score Name \n")
53. outfile.write ("-------------------------------------------------\n")
54.
55. i=0
56. for i in range(0,len(scores)):
57.     outfile.write("\t" + str(scores[i]) + "\t\t\t" + names[i] + "\n")
58.     outfile.close()
59.
60.
61. #adds player's score to high score list if high enough
62. if(hasHighScore(wins) == True):
63.     setHighScores(wins,yourname(wins))
64.
65.
Can anyone help me out a little?;)
Mar 28 '08 #1
21 5021
jlm699
314 100+
Expand|Select|Wrap|Line Numbers
2.     #opens guesshighscores.txt
3.     infile = open("guesshighscores.txt",'r')
4.     scores = [0,0,0]
5.     names = ["","",""]
6.
7.     #reads in scores from guesshighscores.txt
8.     for idx, line in enumerate(infile):
9.         scores[idx],names[idx] = tuple(line.strip().split())
10.     infile.close()
11.
12.     return scores, names
13.
14.
15. def hasHighScore(score):
16.     #opens guesshighscores.txt
17.     scores, names = readHighScores()
18.
19.     #compares player's score with those in guesshighscores.txt
20.     for elem in scores:
21.         if int(score) < int(elem):
22.             return True
23.     return False
24.
25. def setHighScores(score, name):
26.     #opens guesshighscores.txt
27.     scores, names = readHighScores()
28.
29.     # re-writes the list of highscores
30.     for idx, elem in enumerate(scores):
31.         if score > elem:
32.             continue
33.         scores.insert(idx, score)
34.         names.insert(idx, name)
35.         scores.pop()
36.         names.pop()
37.         break
38.
39.     #writes new guesshighscores.txt
40.     outfile = open("guesshighscores.txt","w")
41.
42.     i=0
43.     for i in range(0,len(scores)):
44.         outfile.write("\t" + str(scores[i]) + "\t\t\t" + names[i] + "\n")
45.     outfile.close()
46.     outfile = open('guesshighscores.txt', 'r')
48.     outfile.close()
49.
What was it that gave you trouble? I've posted some general fixes above (just a few things I noticed off the bat). But please let us know how you were having trouble.. was it syntax errors? Just wasn't doing what was expected? Elaborate...
Mar 28 '08 #2
Thank you:) Well, first of all i need a variable that writes to file after each successfully ended game. How do I do this? Can I just modify the game script, renaming all my score and name variables so they match with the variables for score and names in the HighScore code?

About the code: Yeah, last time i got some syntax errors (blocks and stuff, which I fixed easily, and one syntax error for "while score scores[i-1] and...", cant remember the exact error, but it was a syntax error caused by the word "scores". Might have been "scores is not defined", although one of the first lines defines scres by: scores = [0,0,0]. Anyways, your fixes seems to have fixed the problem.
Mar 28 '08 #3
jlm699
314 100+
Can I just modify the game script, renaming all my score and name variables so they match with the variables for score and names in the HighScore code?
Not necessary, since the high score code is all functions. As long as you're passing the correct values, you will achieve the desired result
Mar 28 '08 #4
Hmm. My problem, at the moment, is making the highscore-code to read from my game-code. I'll post all of it here:

Expand|Select|Wrap|Line Numbers
1.
2. #Importere modulen random:
3. import random
4. #thenumber tilsvarer nå random.randint(0, 100) som er et tilfeldig tall mellom 0 og 100)
5. thenumber = random.randint(0, 100)
6. # Et tappert forsøk på en loop.
7. loop = 1
8.
9. #Definerer choice.
10. choice = 0
11. forsøk = 0
12.
13. #Så til selve gjettedelen av scriptet :)
14.
15. print "It is a number between 0 and 100. Can you guess it?"
16. print "Guess-the-number-game made by CromogliC"
17. print "Just type in a number of your own choice and press enter!"
18.
19. yourname = raw_input("Please type in your name here: ")
20.
21. while loop == 1:
22.     choice = input("What number do you think is is?: ")
23.     if choice == thenumber:
24.         forsøk = forsøk +1
25.         print "Amazing," + " " + yourname + "!"
26.         print "You have guessed the right number!"
27.         print "You are victorious!"
28.         print "Tries used:"
29.         print forsøk
30.         wins = forsøk
31.         loop = 0
32.         print "Restart? y for yes. n for no."
33.         restart = raw_input("Do you want to restart?: ")
34.         if restart == "y":
35.             thenumber = random.randint(0, 100)
36.             forsøk = 0
37.             #User restart!
38.             loop = 1
39.         elif restart == "n":
40.             loop = 0
41.             print "Game Over!"
42.             exit()
43.     elif choice < thenumber:
44.         print "Nope, you have got to go higher!"
45.         forsøk = forsøk +1
46.         loop = 1
47.     elif choice > thenumber:
48.         print "Nope, you have got to go lower!"
49.         forsøk = forsøk +1
50.         loop = 1
51.     elif choice > 100:
52.         print "I am sorry, but you cannot pick a number above 100!"
53.         loop = 1
54.
56.     #opens guesshighscores.txt
57.     infile = open("guesshighscores.txt",'r')
58.     scores = [0,0,0]
59.     names = ["","",""]
60.
61.     #reads in scores from guesshighscores.txt
62.     for idx, line in enumerate(infile):
63.         scores[idx],names[idx] = tuple(line.strip().split())
64.     infile.close()
65.
66.     return scores, names
67.
68.
69. def hasHighScore(score):
70.     #opens guesshighscores.txt
71.     scores, names = readHighScores()
72.
73.     #compares player's score with those in guesshighscores.txt
74.     for elem in scores:
75.         if int(score) < int(elem):
76.             return True
77.     return False
78.
79. def setHighScores(score, name):
80.     #opens guesshighscores.txt
81.     scores, names = readHighScores()
82.
83.     # re-writes the list of highscores
84.     for idx, elem in enumerate(scores):
85.         if score > elem:
86.             continue
87.         scores.insert(idx, score)
88.         names.insert(idx, name)
89.         scores.pop()
90.         names.pop()
91.         break
92.
93.     #writes new guesshighscores.txt
94.     outfile = open("guesshighscores.txt","w")
95.
96.     i=0
97.     for i in range(0,len(scores)):
98.         outfile.write("\t" + str(scores[i]) + "\t\t\t" + names[i] + "\n")
99.     outfile.close()
100.     outfile = open('guesshighscores.txt', 'r')
102.     outfile.close()
103.
104.
Mar 28 '08 #5
jlm699
314 100+
Well what do you mean read from your code? You never call any of the highschore functions, so obviously nothing is going to happen. Basically all you need to do is check if the player's score is the high score when they win. If it returns true then call the set high score function with their name and score.
Mar 28 '08 #6
so if i add something similiar to
while forsøk < 0:

and then the highscore-code it should work? Then, it will check the txt-file as long as my result is greater than 0
Mar 28 '08 #7
jlm699
314 100+
No. Do you know what calling a function is?
You would want something more like this (which is when you have determined the player has won...):
Expand|Select|Wrap|Line Numbers
1. forsøk = forsøk +1
2. print "Amazing," + " " + yourname + "!"
3. print "You have guessed the right number!"
4. print "You are victorious!"
5. print "Tries used:", forsøk
6. wins = forsøk
7. if hasHighScore(wins):
8.      setHighScores(wins, yourname)
9.
Mar 28 '08 #8
Hmm, I thought "commands" such as "if" and "while" etc. were calling commands. Bare in mind that I started with python a week ago:P I will try your suggestion, thank you:)
Mar 28 '08 #9
Well, i tried to add the code you gave me, with the result of setHighScores etc. not being defined - easy enough, I just put the highscorepart over the actual game-part. Now, i get this error when I've guessed the right number:

Traceback (most recent call last):
File "C:\Documents and Settings\Omni Potent\Desktop\Python scripting\Guessnumbergame\guessnumber.py", line 82, in ?
if hasHighScore(wins):
File "C:\Documents and Settings\Omni Potent\Desktop\Python scripting\Guessnumbergame\guessnumber.py", line 29, in hasHighScore
scores, names = readHighScores()
File "C:\Documents and Settings\Omni Potent\Desktop\Python scripting\Guessnumbergame\guessnumber.py", line 15, in readHighScores
infile = open("guesshighscores.txt",'r')
IOError: [Errno 2] No such file or directory: 'guesshighscores.txt'

The highscorecode is supposed to write a new guesshighscores.txt, but as it didnt, I made a textfile with that name manually. The error persists. I found out that I had called the file i made guesshighscores.txt, which results in the full name: guesshighscores.txt.txt (as the file extension is added). When I fixed this, the "game" runs without errors, but it doesnt write anything to my file. It seems like the call-function or the highscore-codepart does not work properly/isnt configured properly, but I cant see whats wrong. Help me?:D
Mar 28 '08 #10
jlm699
314 100+
It would seem to me that if the file is empty, then the hasHighScore function will never have anything to compare the score to; thereby never being able to return True.

In your txt file make entries with a score of 100 and a random name like CPU1, 2 and 3 or similar.

Similarly, if you're looking to learn good programming practices, at the initialization of your program you could do the following:
Expand|Select|Wrap|Line Numbers
1. import os
2.
3. if not os.path.exists('guesshighscores.txt'):
4.      fh = open('guesshighscores.txt', 'w')
5.      fh.write('100     CPU1\n100     CPU2\n100     CPU3\n')
6.      fh.close()
7.
That way you can be sure that you won't get a file does not exist error, as well as there being default scores... HTH
Mar 28 '08 #11
Thank you, you have been really helpful :)
Could you explain the bit about CPU/n? I did not understand that part:P (just for learning)
Mar 28 '08 #12
Oh, by the way, the code prevents errors from appearing, but the program still wont write to file.
Mar 28 '08 #13
jlm699
314 100+
\n is what's known as an escape character... any character that has a \ in front of it is an escape character (\n is the escape character for "new line".. so it's like pressing enter in a text editor... it creates a "new line").
Expand|Select|Wrap|Line Numbers
1. fh.write('100    CPU1\n100    CPU2\n100    CPU3\n')
2.
is simply shorter than writing
Expand|Select|Wrap|Line Numbers
1. fh.write('100    CPU1\n')
2. fh.write('100    CPU2\n')
3. fh.write('100    CPU3\n')
4.
So when you say it's not writing to file .. are you sure you're checking the correct file? Does it print out the correct high scores ? I'm thinking that the file is in a different location than where you imagine it to be. A quick " print os.getcwd() " at the beginning of your program will tell you the current working directory, which is where the highscore file is being read/written
Mar 28 '08 #14
Yes, I've learnt that the working directory usually is where the actual script is saved. To be sure, i tried your command, which proved that i was right about the directory. However, when i tried to delete the txt-file i manually created earlier, it worked. Now, it looks damn messy, so I'll start working on the "layout" now;) Thank you alot for your help:)!

By the way, will I be able to make line at the top containing for instance PlayersName Score

which will stand the "for ever" by adding a /n at the beginning of the fh.write('100 CPU1\n100 CPU2\n100 CPU3\n')-line?

now, I am starting to get this error:

Traceback (most recent call last):
File "C:\Documents and Settings\Omni Potent\Desktop\Python scripting\Guessnumbergame\guessnumber.py", line 92, in ?
if hasHighScore(wins):
File "C:\Documents and Settings\Omni Potent\Desktop\Python scripting\Guessnumbergame\guessnumber.py", line 39, in hasHighScore
scores, names = readHighScores()
File "C:\Documents and Settings\Omni Potent\Desktop\Python scripting\Guessnumbergame\guessnumber.py", line 31, in readHighScores
scores[idx],names[idx] = tuple(line.strip().split())
ValueError: too many values to unpack

Even though i didnt touch anything:P For me, it seems like this occurs every time my score is above 9, but I could be wrong:P
Mar 28 '08 #15
jlm699
314 100+
By the way, will I be able to make line at the top containing for instance PlayersName Score

which will stand the "for ever" by adding a /n at the beginning of the fh.write('100 CPU1\n100 CPU2\n100 CPU3\n')-line?
I don't know what you mean by "for ever" and adding /n .... The escape characters are \ not / ... But if you add a line to the beginning of the file you must account for that and skip over it when reading from the file... which leads me into the second part of your post:
Traceback (most recent call last):
File "C:\Documents and Settings\Omni Potent\Desktop\Python scripting\Guessnumbergame\guessnumber.py", line 92, in ?
if hasHighScore(wins):
File "C:\Documents and Settings\Omni Potent\Desktop\Python scripting\Guessnumbergame\guessnumber.py", line 39, in hasHighScore
scores, names = readHighScores()
File "C:\Documents and Settings\Omni Potent\Desktop\Python scripting\Guessnumbergame\guessnumber.py", line 31, in readHighScores
scores[idx],names[idx] = tuple(line.strip().split())
ValueError: too many values to unpack
Basically this means that there is more than just two items in the line. One way to debug this is to split that line up in the following way:
Expand|Select|Wrap|Line Numbers
1.     scores[idx],names[idx] = tuple(line.strip().split())
2. # Split the above line into the following lines for debug purposes
3. line = line.strip().split()
4. print line # This will show you what the script is reading from the file line by line
5. if len(line) == 2:
6.     scores[idx] = line[0]
7.     names[idx] = line[1]
8. else:
9.     print 'This line is not formatted correctly: %s' % line
10.
Before the suspect line of code was assuming that only two things were on each line... score and name, however if for some reason that goes sour you'll see the above error. Basically it is cause by assigning two variables to something when there is more than two thing to be assigned... example from IDLE:
Expand|Select|Wrap|Line Numbers
1. >>> tupp = ('1a', '1b')
2. >>> a, b = tupp
3. >>> a
4. '1a'
5. >>> b
6. '1b'
7. >>> tupp = ('2a', '2b', '2c')
8. >>> a, b = tupp
9. Traceback (most recent call last):
10.   File "<input>", line 1, in ?
11. ValueError: too many values to unpack
12. >>> a, b, c = tupp
13. >>> tupp
14. ('2a', '2b', '2c')
15. >>>
Get it? So try to debug your code by seeing which line is causing this error and then try to solve the problem with your wits! ;)
Mar 28 '08 #16
well, here is what I did:

Expand|Select|Wrap|Line Numbers
1.
2. #reads in scores from guesshighscores.txt
3.     for idx, line in enumerate(infile):
4.         line = line.strip().split()
5.         print line # This will show you what the script is reading from the file line by line
6.         if len(line) == 2:
7.             scores[idx] = line[0]
8.             names[idx] = line[1]
9.         else:
10.             print 'This line is not formatted correctly: %s' % line
11.     infile.close()
12.
Len len(line) is obviously not equal to 2, because i get the This line is not formatted correctly blablabla-message.

the result of the highscore is like this:

0
5 Lars
100 CPU1

(first of all, it is not possible to get 0, and also, a name should appear^^)

the "error" i get now is:

['8', 'The', 'Lars']
This line is not formatted correctly: ['8', 'The', 'Lars']
['100', 'CPU1']
['100', 'CPU2']
['8', 'The', 'Lars']
This line is not formatted correctly: ['8', 'The', 'Lars']
['100', 'CPU1']
['100', 'CPU2']
0
5 Lars
100 CPU1

for me, it seems like the highscore cant handle me putting in a double name in the raw_input called yourname.
Mar 28 '08 #17
jlm699
314 100+
it seems like the highscore cant handle me putting in a double name in the raw_input called yourname.
That's correct. When reading from file your code only performs a split() and then assumes that item[0] is score and item[1] is name. Since split() simply splits at white space you'll want to modify it so that it only splits at tabs (ie, split('\t'), see there's another escape character \t which is for tab). Then when writing to file make sure you put \t between your score and your names. This should allow you to take a "multiple word" name and read/write in the same manner.
Mar 28 '08 #18
fh.write('100 CPU1\t\n100 CPU2\t\n100 CPU3\t\n')
works, now I can use double names properly, but the other errors are still there:

['0']
This line is not formatted correctly: ['0']
['5', 'Lars']
['100', 'CPU1']
['0']
This line is not formatted correctly: ['0']
['5', 'Lars']
['100', 'CPU1']
0
6 The Lars
5 Lars

I do not get this. Can you help me out?^^
Mar 28 '08 #19
jlm699
314 100+
Post the contents of your high score text file and maybe it'll be a little clearer
Mar 31 '08 #20
Well, the contents of the textfile looks like this:

0
6 The Lars
5 Lars
Mar 31 '08 #21
jlm699
314 100+
Your problem is that you have a line with only a 0... The code is telling you that it's not formatted correctly, so that should've given you a hint.
Mar 31 '08 #22