Question

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.

Was it helpful?

Solution

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.

OTHER TIPS

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.

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

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.

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]]

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()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top