0

I've created a mastermind game as part of a lead-up to some coursework later this year, and i'm looking to be able to print the high score and the name of the person it belongs to whenever a person wins the game. I've successfully been able to save pairs of the username entered and their score, but my attempts at printing the high score haven't been. This is all the code i've done so far, i do apologise if anything i've written is completely and utterly wrong or inefficient, i'm fairly new to python.

from random import randrange
import time
import operator
guesses=0
score=0
totaltime=0
correctlist=[]
nonexactscore=0
#Initiates variables
print("Enter a username")
while 1==1:
    username=input()
    namelist=list(username)
    if " " not in namelist:
        username=username.upper()
        break
    else:
        print("Cannot enter spaces in your username")
print("Enter difficulty- 'EASY' , 'NORMAL' or 'HARD")
while 1==1:
    difficulty=input()
    if difficulty == "EASY" or difficulty == "NORMAL" or difficulty ==    "HARD":
        break
    else:
        print("Invalid input")
#Waits for user input to be valid (EASY , NORMAL or HARD) 
if difficulty=="HARD":
    Numberlength=5
#Sets the length of the number to be guessed to 5 if the difficulty = hard
else:
    Numberlength=4
#Otherwise sets the length of the number to be guessed to the normal length of 4
for n in range(0,Numberlength):
    correctlist.append(str(randrange(0,9)))
#Creates a list of length Numberlength made from a sequence of random     numbers (In string format)
while score != Numberlength:
#Continuously asks for the guess while it is incorrect (For it to be     correct, the score must = the numberlength)
    temptime=0
    nonexactscore=0
    score=0
    guess=0
    print("enter guess")
    print(correctlist) #For debugging
    temptime=int(time.time())
#initiates the timer
    while 1==1:
        guess=str(input())
        if len(guess)==Numberlength and guess.isdigit():
            break
#Validates input
        else:
            print("Invalid input")
    for n in range(0,Numberlength):
        if guess[n]==correctlist[n]:
            score+=1
#Increments score variable if pairs of numbers in the guess list and the correct list match
            if difficulty == "EASY":
                print("You got a match in place " + str(n+1))
#Prints the position of the correct guess if the difficulty = easy
    if guess[n] in correctlist and guess[n] != correctlist[n]:
        nonexactscore += 1
#Increments non-exact score variable if the guess appears in the correctlist     but isn't an exact match
    print("Number of exact matches: " + str(score) + " Number of non-exact matches: " + str(nonexactscore) )
#Prints your score and non-exact score
    if score != Numberlength:
        print("Incorrect, try again!")
    guesses+=1
#Increments guesses variable every time you make an incorrect guess
    totaltime+=int(time.time())-temptime
#Adds the time taken for an individual guess to the totaltime
else:
    print("Guesses: " + str(guesses))
    print("You win!")
    print("You took " + str(totaltime) + " Seconds! ")
    totalscore=int(1000*(1/(float(totaltime*guesses))))
    print("Score for comparison:" + str(totalscore))
    with open("mastermindscores.txt","a") as f:
        f.write(username + " " + str(totalscore)+ "\n")
    with open("mastermindscores.txt","r") as k:
        scoredict={}
        for line in k:
            key,val = line.split(" ")
            scoredict[key]=val
    print(scoredict) #for debugging
        print("High score: " + max(scoredict) + " " +     str(scoredict.get(max(scoredict))))
#Prints information about your victory

This code results in the txt file looking something like this:

    NAME 1000
    OTHERNAME 10000
    ANOTHERNAME 100000

And i'm looking for the program to print "High score: ANOTHERNAME 100000" but at the moment I can't quite work out how it's deciding which name it's printing (Because after a few games, it doesn't print the high score)

Any suggestions for the coding or any improvements i could make to the program would greatly be appreciated, thanks.

Also, if you need any more clarifications, i'll be looking at this post for a couple of hours or so.

Cubbs
  • 5
  • 5
  • _"after a few games, it doesn't print the high score"_. Do you mean it prints "High score: " and the rest of the line is blank? Or do you mean it doesn't print "High score: " at all? – Kevin Sep 24 '15 at 19:20

1 Answers1

4
print("High score: " + max(scoredict) + " " +     str(scoredict.get(max(scoredict))))

When used on a dictionary, max chooses the highest key. Your keys are strings, so it chooses the username with the highest lexicographic order; in other words, the name that appears last alphabetically.

>>> max({"Kevin": 99999, "Zane": 23})
'Zane'

If you want to find the highest value, try:

>>> d = {"Kevin": 99999, "Zane": 23}
>>> max_name = max(d, key=lambda k: d[k])
>>> max_name
'Kevin'
>>> d[max_name]
99999

Of course, this assumes that the values in your score dictionary are numbers. If they're strings, you've got the lexicographic ordering problem all over again.

>>> d = {"Kevin": "100000", "Zane": "2"}
>>> max(d, key=lambda k: d[k])
'Zane'

So make sure to convert your values to the proper type when reading your file.

with open("mastermindscores.txt","r") as k:
    scoredict={}
    for line in k:
        key,val = line.split(" ")
        scoredict[key]=int(val)
Kevin
  • 74,910
  • 12
  • 133
  • 166
  • Getting invalid syntax with : max_name, max_score = max(scoredict.iteritems(), key=lambda (name, score): score) - It's highlighting the open bracket after the lambda – Cubbs Sep 24 '15 at 19:28
  • Oops, that syntax might be specific to Python 2.7. I'll try to find an alternative. – Kevin Sep 24 '15 at 19:29
  • Yep, [tuple parameter unpacking](http://stackoverflow.com/questions/10607293/nested-arguments-in-python-not-compiling) is no longer supported in 3.X. Sorry about that. In that case, may as well just call `max` on `d` directly and get the max score on the next line. – Kevin Sep 24 '15 at 19:36