Okay. So I'm writing this snakes and ladders game, and I want to be able to save the scores, but the try/except method seems to be giving me trouble. I feel like it has something to do with the fact that I'm not writing, just reading. But I'm not sure where, or even how, to do this correctly. Any thoughts?

import random

def create_board():
    lst1 = [100, 99, 98, 97, 96, 95, 94, 93, 92, 91]
    lst2 = [90, 89, 88, 87, 86, 85, 84, 83, 82, 81]
    lst3 = [80, 79, 78, 77, 76, 75, 74, 73, 72, 71]
    lst4 = [70, 69, 68, 67, 66, 65, 64, 63, 62, 61]
    lst5 = [60, 59, 58, 57, 56, 55, 54, 53, 52, 51]
    lst6 = [50, 49, 48, 47, 46, 45, 44, 43, 42, 41]
    lst7 = [40, 39, 38, 37, 36, 35, 34, 33, 32, 31]
    lst8 = [30, 29, 28, 27, 26, 25, 24, 23, 22, 21]
    lst9 = [20, 19, 18, 17, 16, 15, 14, 13, 12, 11]
    lst10 = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
    all_lst = lst1 + lst2 + lst3 + lst4 + lst5 + lst6 + lst7 + lst8 + lst9 + lst10
    return all_lst

    
def print_board(board):
    x = 0
    print("-" * 50)
    print("|", end="")
    for number in board:
        print(number, end="|")
        x +=1
        if x == 10:
            print()
            print("-" * 50)
            x = 0
        
def snakes_ladders(board):

    board[board.index(1)] = "L1"
    board[board.index(15)] = "S1"
    board[board.index(19)] = "L2"
    board[board.index(33)] = "L1"
    board[board.index(45)] = "S1"
    board[board.index(48)] = "S2"
    board[board.index(69)] = "L3"
    board[board.index(75)] = "L2"
    board[board.index(78)] = "S3"
    board[board.index(82)] = "S2"
    board[board.index(85)] = "L3"
    board[board.index(98)] = "S3"
        
def roll_die():
    roll1 = random.randrange(1,7)
    total = (roll1)
    return total

def exit_program():
    exit()

def check_snakes(roll_count):
    if roll_count == 98:
        roll_count = 78
    elif roll_count == 82:
        roll_count = 48
    elif roll_count == 45:
        roll_count = 15
    return roll_count

def check_ladders(roll_count):
    if roll_count == 1:
        roll_count = 33
    elif roll_count == 19:
        roll_count = 75
    elif roll_count == 69:
        roll_count = 85
    return roll_count


def save_scores(score):
    try:
        scorefile = open('scores.txt', 'r')
        scores = scorefile.readlines()
        entry = str(score) + "\n"
        scores.append(entry)
        scorefile.close()
        tempo = []
        for entry in scores:
            tempo.append(int(entry))
            tempo.sort()
            new_scores = []
        for entry in tempo:
            entry1 = str(entry) + "\n"
            newscores.append(entry1)
            newscores = newscores[:5]
            scorefile.writelines(new_scores)
            scorefile.close
    except(IOError):
        print("Could not open file for reading")


# main
score = 0
temp = 100
roll_count = 0
check_snakes(roll_count)
check_ladders(roll_count)
board = create_board()
snakes_ladders(board)
save_scores(score)
print_board(board)
while True:
    roll = roll_die()
    roll_quit = input("Type 'r' to roll die, or type 'e' to quit:\n>>>")
    if roll_quit == "r":
        score += 1
        print("You rolled a ", roll,"!")
        if roll_count + roll > 100:
            print("That roll is too high")
            continue
        elif roll_count + roll == 1:
            score -= 11
        elif roll_count + roll == 19:
            score -= 11
        elif roll_count + roll == 69:
            score -= 11
        elif roll_count + roll == 100:
            print("You win! With a score of",score)
            break  
    elif roll_quit == "e":
        break
    else:
        print("That isn't an option.")
        continue
# use negative indexing for the roll number, [-1] = 1
    print("Current score:",score)
    board[-roll_count] = temp
    roll_count = (roll_count) + (roll)
    roll_count = check_snakes(roll_count)
    roll_count = check_ladders(roll_count)
    temp = board[-roll_count]
    board[-roll_count] = "X"
    (print_board(board))

If you want to read and then rewrite the file, you must open the file twice. You could use

def save_scores(score):
    try:
        with open('scores.txt', 'r') as scorefile: # this will automatically close the file
            scores = scorefile.readlines()
    except IOError:
        scores = []
    scores.append(score)
    tempo = sorted(int(line) for line in scores)
    with open('scores.txt', 'w') as scorefile:
        for entry in tempo[:5]: # the five lowest scores ?
            scorefile.write("{e}\n".format(e=entry))

Edited 6 Years Ago by Gribouillis: n/a

Okay. So I didn't get any error messages with that. Which give me hope! But is there anyway to print these scores in a way that I tried in my last 'def save_scores(score):' code? I'd like for it to have the five lowest scores shown in order. Is there a way to do that in this same function?

Okay. So I didn't get any error messages with that. Which give me hope! But is there anyway to print these scores in a way that I tried in my last 'def save_scores(score):' code? I'd like for it to have the five lowest scores shown in order. Is there a way to do that in this same function?

I added a line (forgot to append the score). In principle, this function should store the 5 lowest scores in order. An error in your previous code was the 2 variables new_scores and newscores.

Edited 6 Years Ago by Gribouillis: n/a

So if I wanted to print the lowest five scores would I print(tempo)?

So if I wanted to print the lowest five scores would I print(tempo)?

Yes why not. You could also add a print(entry) in the last for loop (although i'd prefer to separate writing the file and printing because printing is slow).

Edited 6 Years Ago by Gribouillis: n/a

Is the placement of my def save_scores(score) okay? or should it be somewhere different in my program? I feel like placement of these functions are crucial here.

I definitely think placement is off. It seems to not be storing anything for me. I just get back zeros.

I definitely think placement is off. It seems to not be storing anything for me. I just get back zeros.

the placement of the def save_score does not matter as this function does not use any global variable. There must be another problem in your code. The only call to save_score() is at line 102, just after you defined score=0. This is probably the problem.

Edited 6 Years Ago by Gribouillis: n/a

Where would be a better place to call it? I would prefer to have the top scores display at the beginning of the game. Which would mean I need to call save_scores(score) before I call print_board(board).

Where would be a better place to call it? I would prefer to have the top scores display at the beginning of the game. Which would mean I need to call save_scores(score) before I call print_board(board).

Displaying scores and saving scores are 2 different things. You should write 2 functions. The new score must be saved after the game.

Edited 6 Years Ago by Gribouillis: n/a

So write one function for displaying and one function for writing. Should I split up save_scores(score) in terms of reading and writing then? Have it read at the beginning and write after the player wins?

So write one function for displaying and one function for writing. Should I split up save_scores(score) in terms of reading and writing then? Have it read at the beginning and write after the player wins?

Yes, you could have a function read_scores() which returns a list of scores. When a feature is needed in two different places, it is always good to write a function.

Edited 6 Years Ago by Gribouillis: n/a

This sure is giving me a hard time! What should I omit in the print function? Just the .append part?

Edited 6 Years Ago by bwbyron: n/a

It's very easy

def read_scores(score):
    try:
        with open('scores.txt', 'r') as scorefile:
            scores = scorefile.readlines()
    except IOError:
        scores = []
    return [int(s) for s in scores]

def display_scores(): # could be improved
    print("\n".join(str(s) for s in read_scores()))

def save_scores(score):
    scores = read_scores()
    scores.append(score)
    scores.sort()
    with open('scores.txt', "w") as scorefile:
        scorefile.write("\n".join(str(s) for s in scores[:5]))

Edited 6 Years Ago by Gribouillis: n/a

Comments
great

I ended up with this.

def save_scores(score):
    try:
        with open('scores.txt', 'r') as scorefile:
            scores = scorefile.readlines()
    except IOError:
        scores = []
    scores.append(score)
    tempo = sorted(int(line) for line in scores)
    with open('scores.txt', 'w') as scorefile:
        for entry in tempo[:5]:
            scorefile.write("{e}\n".format(e=entry))

def print_scores(score):
    try:
        with open('scores.txt', 'r') as scorefile:
            scores = scorefile.readlines()
    except IOError:
        scores = []
    tempo = sorted(int(line) for line in scores)
    with open('scores.txt', 'w') as scorefile:
        for entry in tempo[:5]:
            scorefile.write("{e}\n".format(e=entry))
            print(entry)
This question has already been answered. Start a new discussion instead.