首页 > 解决方案 > Python将排行榜从最高到最低分数和前5名排序(外部文件)

问题描述

请原谅措辞非常糟糕的标题!

对于我的计算机科学 GCSE,我得到了一个 20 小时的项目。其中大部分已经完成并且功能齐全,但是我正在努力完成最后一步。

我已经做到了,因此用户可以将他们的最终分数存储到外部文件中,并且该文件的内容会在游戏结束时打印出来。但是,我希望它只打印前 5 名得分者,并将得分从高到低排列。

每个位置旁边的数字表明他们在棋盘上的位置会很酷,但如果这很难做到,我可以跳过它。

这是定义排行榜的代码部分:

    def leaderboard():
  print ("\n")
  print ("⬇ Check out the leaderboard ⬇") #LEADERBOARD SECTION
  f = open('H_Highscore.txt', 'r')
  leaderboard = [line.replace('\n','') for line in f.readlines()]
  for i in leaderboard:
      print(i)
  f.close()
  time.sleep(10)
  sys.exit()

这是写入排行榜的代码:

user = str(input("Enter a name to save your highscore: "))
                    file = open ("H_Highscore.txt", "a")
                    file.write("\n")
                    file.write(user)
                    file.write(",")
                    file.write(str(score)) # (int(x)) can not be written
                    file.write("pts")
                    file.write("\n")
                    file.close()
                    time.sleep(0.5)
                    leaderboard()
                    sys.exit()

如果需要,这里是整个程序:

#Casey_Neale
import sys
import random
import time
import math
import csv
import time, sys
import datetime
newaccounts=True   #DEVELOPMENT
loggedIn=False     #PURPOSES
yn=True            #ONLY
from threading import Timer

TIMELIMIT = 5.0 #Timer in secs, lowered for development and testing
time_ran_out = False #Global 

'''
Known bugs and needed improvements are stored in G_Bugs.txt
The report for this project is entitled "D_ProjectReportTemplate.docx
Songs stored externally to F_Songs.txt
'''

def tutorial(): #Games introduction
  slow_print("Your aim is to get as many points as possible...\n")
  #print("\n")
  time.sleep(1.5)
  slow_print("You need to guess the name of each song to gain points...\n")
#  print("\n")
  time.sleep(1.5)
  slow_print("You have two guesses for each song...\n")
 # print("\n")
  time.sleep(1.5)
  slow_print ("The artist name is provided for you...\n")
  time.sleep(1.5)
  slow_print("There is an ingame timer, so good luck!")
  time.sleep(1.5)
  print("\n")
  print("\n")

def slow_print(s):
  for c in s:
    sys.stdout.write( '%s' % c )
    sys.stdout.flush()
    time.sleep(0.03)

def timeout():
    global time_ran_out

    time_ran_out = True

def leaderboard():
  print ("\n")
  print ("⬇ Check out the leaderboard ⬇") #LEADERBOARD SECTION
  f = open('H_Highscore.txt', 'r')
  leaderboard = [line.replace('\n','') for line in f.readlines()]
  for i in leaderboard:
      print(i)
  f.close()
  time.sleep(10)
  sys.exit()

def loginsys():
  doublecheck=True
  while doublecheck == True:
    slow_print("➡Welcome | Are you a registered user?\n[Y/N]: ")
    verifyRegister = input()
    print (" ")
    if verifyRegister == "n" or verifyRegister == "N":  #If the user is not already registered
      if newaccounts == True:
        loop=True
        while loop == True:
            username = input ("Please enter a username\n[User]: ")#Prompts the user to provide a desired username
            print (" ")#Prompts for username
            checkusername = input ("Please retype your username\n[Verify]: ")#Verifys username
            print (" ")#Prompts to verify username
            if checkusername != username:
              print ("Invalid, please try again")
              loop=True
            else:
              loop=False       
              time.sleep(0.5)
              passloop=True
              while passloop == True:
                      password = input ("Please enter a password\n[Password]: ") #Prompts the user to provide a desired password
                      print (" ")#Prompts for password
                      checkpassword = input ("Please retype your password\n[Verify]: ") #Verifys password
                      print (" ")#Prompts to verify password
                      if checkpassword != password:
                        print ("Invalid, please try again")
                        print (" ")
                        passloop=True
                      else:
                        passloop=False
                        file = open("C_AccountData.txt","a") #Opens the file C_AccountData.txt in write mode/opens connection
                        file.write("USRN:") #Prefix Username to make the file easier to read
                        file.write(username) #Writes the username 
                        file.write("|") #Partition for visual ease to make the file easier to read
                        file.write("PSWD:") #Prefix Password to make the file easier to read
                        file.write(password)#Writes the password
                        file.write("\n") #New line to make the file easier to read
                        file.close() #Closes file/ends connection
                        print ("✓Your account has been created") #Verifies that the account has been made to the user
                        time.sleep(2)
                        print ("\n")
                        doublecheck=True #Loop

    if verifyRegister == "Y" or verifyRegister == "y":
      loop=True
      if loop == True:
          user = input("[User]: ")
          passw = input("[Password]: ")
          if passw == (""):
            print("You did not enter a password")
            loop=True
            time.sleep(2)
            sys.exit() #If the end user does not enter a password, the program will terminate. This is to prevent a security concern where users can freely login to existing accounts by leaving the password field empty
            break
          f = open("C_AccountData.txt", "r")
          for line in f.readlines():
            uspwd = line.split("|")
            us = uspwd[0]
            pw = uspwd[1]
            if (user in us) and (passw in pw):
              loop=False
              print("Login successful, welcome",user)
              print("\n")
              doublecheck=False
          else:
            if loop == True:
                  print ("\n")
                  print ("Sorry, your account details were not recognised. ") #Reject

    else:
      if verifyRegister != "Y" or verifyRegister != "y" or verifyRegister != "N" or verifyRegister != "n" or verifyRegister !="backup":
        print("\n")
        doublecheck=True

def pickSong_random():
    global time_ran_out

    score = 0
    lives = 5
    songFile = open("F_Songs.txt", "r")
    songList = songFile.readlines() # Reads from the bridged file
    songFile.close()

    while True:
        chosenSong = random.choice(songList)
        chosenSong = chosenSong.strip("\n")
        artistAndSong = chosenSong.split(":") # Defines song split

        toDisplay = ""
        toDisplay += artistAndSong[0] + ": "
        songTitleWords = artistAndSong[1].split(" ")

        for word in songTitleWords:
            # loop through
            toDisplay += word[0] + " "
        print(toDisplay)
        # print("2" +toDisplay)
        toDisplay = toDisplay.strip("None")

        guesses = 0
        timer = Timer(TIMELIMIT, timeout)  # Create a timer thread object.
        time_ran_out = False  # Initialize the variable the callback modifies.

        timer.start()  # Start the background timer.
        while guesses < 2:
            if time_ran_out:
                print('Times up!')
                time.sleep(3)
                print ("You managed to score",score,"point(s)")
                time.sleep(3)
                print("\n")
                slow_print("Would you like to play again?")
                playAgain = input("\n[Y/N]: ")
                if playAgain == ("n") or playAgain == ("N"):
                    print("\n")
                    # user variable is not saved from the login system as it is
                    # defined as a function separately
                    user = str(input("Enter a name to save your highscore: "))
                    file = open ("H_Highscore.txt", "a")
                    file.write("\n")
                    file.write(user)
                    file.write(",")
                    file.write(str(score)) # (int(x)) can not be written
                    file.write("pts")
                    file.write("\n")
                    file.close()
                    time.sleep(0.5)
                    leaderboard()
                    sys.exit()
                if playAgain == ("Y") or playAgain == ("y"):
                    print("Your last score was", score,", lets see if you can beat it this time...")
                    time.sleep(1)
                    print("\n")
                    pickSong_random()
                time.sleep(2)
                break

            guesses += 1
            guess = input("[Enter your guess]: ")

            # Guess checking
            if guess.lower() == artistAndSong[1].lower():
                print("✓Correct! The song was '" + artistAndSong[1]
                        + "' by " + artistAndSong[0])
                print("It took you", guesses, "guess(es)!")
                if guesses == 1:
                    print("\n")
                    print("↑(+3 points)↑")
                    print("\n")
                    score += 3
                    break
                elif guesses == 2:
                    print("\n")
                    print("↑(+1 point)↑")
                    print("\n")
                    score += 1
                    break
            else:
                print("╳The song name isn't", guess, "\n")
                lives = lives-1
                if guesses == 2:
                    print("Sorry, you couldn't guess the song.")
                    print("\n")
            if lives == 0:
                print("You have no more lives to continue! Your score was:", score)
                time.sleep(3)
                print("\n")
                slow_print("Would you like to play again?")
                playAgain = input("\n[Y/N]: ")
                if playAgain == ("n") or playAgain == ("N"):
                    print("\n")
                    # user variable is not saved from the login system as it is
                    # defined as a function separately
                    user = str(input("Enter a name to save your highscore: "))
                    file = open ("H_Highscore.txt", "a")
                    file.write(user)
                    file.write(",")
                    file.write(str(score)) # (int(x)) can not be written
                    file.write("pts")
                    file.write("\n")
                    file.close()
                    time.sleep(0.5)
                    leaderboard()
                    sys.exit()
                if playAgain == ("Y") or playAgain == ("y"):
                    print("Your last score was", score,", lets see if you can beat it this time...")
                    time.sleep(1)
                    print("\n")
                    pickSong_random()

#if __name__ == '__main__':


print(" ___|)________________________________________________________")
print("|___/____________________________|___________________________||")
print("|__/|_______/|____/|_____/|______|___________________________||")
print("|_/(|,\____/_|___/_|____/_|______|___________________________||")
print("|_\_|_/___|__|__|__|___|__|___|__|___________________________||")
print("|   |     | ()  | ()   | ()   |  |                           ||")
print("| (_|   -()-  -()-   -()-   -()- | -()-  -()-  -()-   -()-   ||")
print("|________________________________|__|__()_|__()_|__()__|_____||")
print("|__/___\_._______________________|__|__|__|__|__|__|___|_____||")
print("|__\___|_._______________________|___\_|___\_|___\_|___|_____||")
print("|_____/__________________________|____\|____\|____\|_________||")
print("|____/___________________________|___________________________||")
print("             This project was developed by Casey Neale")
clockTime = time.asctime( time.localtime(time.time()) )
print ("                   ",clockTime) #Displays the current time and date. No real reason, just to look pleasing
print("\n")
print("\n")

loginsys() #LOGIN PROTOCOL
time.sleep(3)
#print("\n")
tutorial() #TUTORIAL PROTOCOL
slow_print ("\nPrepare yourself! The game will begin in...\n") #COUNTDOWN TO GAME TIME
time.sleep(0.5)
print("\n")
slow_print("5...")
time.sleep(0.5)
print("\n")
slow_print("4...")
time.sleep(0.5)
print("\n")
slow_print ("3...")
time.sleep(0.5)
print("\n")
slow_print ("2...")
time.sleep(0.5)
print("\n")
slow_print ("1...")
time.sleep(0.5)
print("\n")
print("\n")
print("\n")
print(" ________  _________  ________  ________  _________ ") 
print("|\   ____\|\___   ___\\   __  \|\   __  \|\___   ___\ ")
print("\ \  \___|\|___ \  \_\ \  \|\  \ \  \|\  \|___ \  \_|")
print(" \ \_____  \   \ \  \ \ \   __  \ \   _  _\   \ \  \ ")
print("  \|____|\  \   \ \  \ \ \  \ \  \ \  \\  \|   \ \  \ ")
print("    ____\_\  \   \ \__\ \ \__\ \__\ \__\\ _\    \ \__\ ")
print("   |\_________\   \|__|  \|__|\|__|\|__|\|__|    \|__|")
print("    \|_________|                                       ")

print("\n")
print("\n")
pickSong_random() #GAME PROTOCOL
sec
sys.exit() #EXIT PROTOCOL

显然,这是一件苦差事,所以如果你懒得去尝试,那完全没问题!感谢您的光临,祝您有美好的一天!

标签: pythonleaderboard

解决方案


我建议将排行榜字符串列表转换为 (str, int) 元组列表,对列表进行排序并打印前 5 名,如下所示:

leaderboard_tuples = [tuple(x.split(',')) for x in leaderboard]
leaderboard_tuples.sort(key=lambda tup: tup[1])

推荐阅读