Saving the highscore for a game?
Asked Answered
K

6

10

I have made a very simple game in python using pygame. The score is based on whatever level the player reached. I have the level as a variable called score. I want to display the top level at the start or end of the game.

I would be even more happy to display more than one score, but all of the other threads I have seen were too complicated for me to understand, so please keep it simple: I'm a beginner, only one score is necessary.

Killdeer answered 24/5, 2013 at 1:17 Comment(4)
Python 2 or Python 3?Reahard
what is your problem? what keeps you from doing print(score)?Denotative
2.7.4 and my problem is that i want to be able to display the score again after the program has been closedKilldeer
In other words you want to be able to load scores from past sessions?Ice
D
11

I recommend you use shelve. For example:

import shelve
d = shelve.open('score.txt')  # here you will save the score variable   
d['score'] = score            # thats all, now it is saved on disk.
d.close()

Next time you open your program use:

import shelve
d = shelve.open('score.txt')
score = d['score']  # the score is read from disk
d.close()

and it will be read from disk. You can use this technique to save a list of scores if you want in the same way.

Denotative answered 24/5, 2013 at 2:4 Comment(4)
i think i got it, my only problem is how do i define something with a "key" can you post a quick line or two of what the .txt file should look like?Killdeer
@KevinKlute, There is nothing to define, it just works, try it out! The key name 'score' is choosen by you. I could have used d['saved_score']. Of course to retrieve it later you need to use the same name you used to save. The file is automatically created but it is not a text format, is a special python format to save variables.Denotative
i ran you code, except i subsituted my file name and i got the error 'db type could not be determined' sorry for being such a pain but i really just cant figure this outKilldeer
got it thanks for the help, i figure out that i needed d.closeKilldeer
R
8

You can use the pickle module to save variables to disk and then reload them.

Example:

import pickle

# load the previous score if it exists
try:
    with open('score.dat', 'rb') as file:
        score = pickle.load(file)
except:
    score = 0

print "High score: %d" % score

# your game code goes here
# let's say the user scores a new high-score of 10
score = 10;

# save the score
with open('score.dat', 'wb') as file:
    pickle.dump(score, file)

This saves a single score to disk. The nice thing about pickle is that you can easily extend it to save multiple scores - just change scores to be an array instead of a single value. pickle will save pretty much any type of variable you throw at it.

Reahard answered 24/5, 2013 at 1:27 Comment(1)
Except pygame Surfaces. For some reason, I've had a lot of trouble pickling surfaces. not sure why...Ice
C
2

You can use a dict to hold your highscore and simply write it into a file:

def store_highscore_in_file(dictionary, fn = "./high.txt", top_n=0):
    """Store the dict into a file, only store top_n highest values."""
    with open(fn,"w") as f:
        for idx,(name,pts) in enumerate(sorted(dictionary.items(), key= lambda x:-x[1])):
            f.write(f"{name}:{pts}\n")
            if top_n and idx == top_n-1:
                break

def load_highscore_from_file(fn = "./high.txt"):
    """Retrieve dict from file"""
    hs = {}
    try:
        with open(fn,"r") as f:
            for line in f:
                name,_,points = line.partition(":")
                if name and points:
                    hs[name]=int(points)
    except FileNotFoundError:
        return {}
    return hs

Usage:

# file does not exist
k = load_highscore_from_file()
print(k)

# add some highscores to dict
k["p"]=10
k["a"]=110
k["k"]=1110
k["l"]=1022 
print(k)

# store file, only top 3
store_highscore_in_file(k, top_n=3)

# load back into new dict
kk = load_highscore_from_file()
print(kk)

Output:

{} # no file
{'p': 10, 'a': 110, 'k': 1110, 'l': 1022} # before storing top 3 
{'k': 1110, 'l': 1022, 'a': 110} # after loading the top 3 file again
Chanell answered 8/12, 2018 at 16:50 Comment(0)
F
0

First create a highscore.txt with a value zero initially. Then use the following code:

hisc=open("highscore.txt","w+")
highscore=hisc.read()
highscore_in_no=int(highscore)
if current_score>highscore_in_no:
                hisc.write(str(current_score))
                highscore_in_no=current_score
                     .
                     .
#use the highscore_in_no to print the highscore.
                     .

                     .
hisc.close()

I could make a permanent highscore storer with this simple method, no need for shelves or pickle.

Fonseca answered 17/8, 2015 at 14:49 Comment(0)
V
0

I usually store the player names and high-scores as a list of lists (e.g. [['Joe', 50], ['Sarah', 230], ['Carl', 120]]), because you can sort and slice them (for example if there should be a maximum of 10 entries). You can save and load the list with the json module (json.dump and json.load) or with pickle.

import json
from operator import itemgetter

import pygame as pg
from pygame import freetype


pg.init()
BG_COLOR = pg.Color('gray12')
BLUE = pg.Color('dodgerblue')
FONT = freetype.Font(None, 24)


def save(highscores):
    with open('highscores.json', 'w') as file:
        json.dump(highscores, file)  # Write the list to the json file.


def load():
    try:
        with open('highscores.json', 'r') as file:
            highscores = json.load(file)  # Read the json file.
    except FileNotFoundError:
        return []  # Return an empty list if the file doesn't exist.
    # Sorted by the score.
    return sorted(highscores, key=itemgetter(1), reverse=True)


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    highscores = load()  # Load the json file.

    while True:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                return
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_s:
                    # Save the sorted the list when 's' is pressed.
                    # Append a new high-score (omitted in this example).
                    # highscores.append([name, score])
                    save(sorted(highscores, key=itemgetter(1), reverse=True))

        screen.fill((30, 30, 50))
        # Display the high-scores.
        for y, (hi_name, hi_score) in enumerate(highscores):
            FONT.render_to(screen, (100, y*30+40), f'{hi_name} {hi_score}', BLUE)

        pg.display.flip()
        clock.tick(60)


if __name__ == '__main__':
    main()
    pg.quit()

The highscores.json file would then look like this:

[["Sarah", 230], ["Carl", 120], ["Joe", 50]]
Vladamar answered 9/12, 2018 at 4:3 Comment(0)
E
-3

I would suggest:

def add():
input_file=open("name.txt","a")#this opens up the file 
name=input("enter your username: ")#this input asks the user to enter their username
score=input("enter your score: ")#this is another input that asks user for their score
print(name,file=input_file)
print(number,file=input_file)#it prints out the users name and is the commas and speech marks is what is also going to print before the score number is going to print
input_file.close()
Esau answered 26/4, 2016 at 10:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.