# Jools -- a graphical puzzle game in the Tetris tradition # # Copyright (C) 2002-2003 Paul Pelzl # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # highscore.py # # Display or add people to the high score list. # import os, pickle import pygame from initialize import * from globals import * import options # Load the high scores from disk. The high score file has the format: # [ , [ [timedname1,timedlevel1,timedscore1], [timedname2,timedlevel2,timedscore2], ... ], # [ [untimedname1,untimedlevel1,untimedscore1], ...] ] def loadScores(): dummyFile = "~/.jools/scores" scoreFile = os.path.expanduser(dummyFile) # catch for OS's that don't implement $HOME if scoreFile == dummyFile: scoreFile = ".jools/scores" scoreFile = os.path.normpath(scoreFile) scores = [VERSION, [], []] # Check for existence of the jools high score file if os.path.exists(scoreFile): try: f = open(scoreFile, "r") scores = pickle.load(f) f.close() except: scores = [VERSION, [], []] # If the high score file is from a previous jools version, wipe it. if scores[0] != VERSION: scores = [VERSION, [], []] return (scores[1], scores[2]) # Save the high scores to disk. def saveScores(scoreLists): dummyFile = "~/.jools/scores" scoreFile = os.path.expanduser(dummyFile) # catch for OS's that don't implement $HOME if scoreFile == dummyFile: scoreFile = ".jools/scores" scoreFile = os.path.normpath(scoreFile) dummyDir = "~/.jools" scoreDir = os.path.expanduser(dummyDir) # catch for OS's that don't implement $HOME if scoreDir == dummyDir: scoreDir = ".jools" scoreDir = os.path.normpath(scoreDir) # Check for existence of the directory if not os.path.isdir(scoreDir): os.mkdir(scoreDir) try: f = open(scoreFile, "w") try: pickle.dump([VERSION, scoreLists[0], scoreLists[1]], f) except: print "Error: Unable to serialize high score file." f.close() except IOError: print "Error: Unable to open high score file for writing." # Check whether an entry belongs in the high score list. def isHighScore(score, timeTrial): if score <= 0: return 0 else: if timeTrial: scoreList = loadScores()[0] else: scoreList = loadScores()[1] if len(scoreList) >= 5: if score > scoreList[len(scoreList)-1][2]: return 1 else: return 0 else: return 1 # Compare two entries of a score list to determine their relative # magnitude. (Used within a sort() routine.) def scoreCmp(entry1, entry2): if entry1[2] > entry2[2]: return -1 elif entry1[2] < entry2[2]: return 1 else: return 0 # Add a score to the high score list. Return the rank # of this score. # "not timeTrial" is a shortcut. If timeTrial == 1, # then we want to look at the first scoreLists entry, # i.e. 0. (and vice versa.) def addScore(name, level, points, timeTrial): thisScore = [name, level, points] scoreLists = loadScores() scoreLists[not timeTrial].append(thisScore) scoreLists[not timeTrial].sort(scoreCmp) rank = -1 for i in range(len(scoreLists[not timeTrial])): if scoreLists[not timeTrial][i] == thisScore: rank = i break croppedScores = [scoreLists[0][:5], scoreLists[1][:5]] saveScores(croppedScores) return rank # Display the high scores. If the optional arguments are provided, then that # number entry will be highlighted for the proper timed or untimed section. def showScores(highlight=None, timeTrial=None): pygame.mouse.set_visible(1) # move the logo out of the way screen.blit(logoEraser, ((SCREENW-logoRect.width)/2, 0)) screen.blit(logoImage, (0,0)) color = (0, 80, 255) specialColor = (40, 238, 252) titleText = highScoreTitleFont.render("High Scores", 1, (180, 180, 180), (1, 1, 1) ) labelText = highScoreFont1.render( "Name Level Score", 1, color, (1, 1, 1) ) highScoreFont2.set_italic(1) timeText = highScoreFont2.render("Time Trial", 1, color, (1, 1, 1) ) notimeText= highScoreFont2.render("No Timer", 1, color, (1, 1, 1) ) highScoreFont2.set_italic(0) clickText = highScoreFont2.render("(Click to Continue)", 1, (180, 180, 180), (1, 1, 1) ) screen.blit(background, (0,100), (0,100,640,380)) screen.blit(titleText, (220, 100)) screen.blit(labelText, (160, 140)) screen.blit(timeText, (30, 220)) screen.blit(notimeText, (35, 350)) screen.blit(clickText, (240, 450)) pygame.draw.line(screen, color, (10, 170), (630, 170), 5) pygame.draw.line(screen, color, (10, 300), (630, 300), 5) pygame.draw.line(screen, color, (10, 430), (630, 430), 5) pygame.draw.line(screen, color, (140, 170),(140, 430), 5) timedScores, untimedScores = loadScores() # time trial section for i in range(len(timedScores)): if i == highlight and timeTrial: c = specialColor else: c = color nameTemp = timedScores[i][0] if len(nameTemp) < 1: nameTemp = "" nameText = highScoreFont2.render(nameTemp, 1, c, (1, 1, 1) ) screen.blit(nameText, (160, 180+20*i)) levelText = highScoreFont2.render(str(timedScores[i][1]), 1, c, (1, 1, 1) ) screen.blit(levelText, (440, 180+20*i)) scoreText = highScoreFont2.render(str(timedScores[i][2]), 1, c, (1, 1, 1) ) screen.blit(scoreText, (595-scoreText.get_width(), 180+20*i)) # untimed section for i in range(len(untimedScores)): if i == highlight and not timeTrial: c = specialColor else: c = color nameTemp = untimedScores[i][0] if len(nameTemp) < 1: nameTemp = "(anonymous)" nameText = highScoreFont2.render(nameTemp, 1, c, (1, 1, 1) ) screen.blit(nameText, (160, 310+20*i)) levelText = highScoreFont2.render(str(untimedScores[i][1]), 1, c, (1, 1, 1) ) screen.blit(levelText, (440, 310+20*i)) scoreText = highScoreFont2.render(str(untimedScores[i][2]), 1, c, (1, 1, 1) ) screen.blit(scoreText, (595-scoreText.get_width(), 310+20*i)) pygame.display.update() pygame.display.flip() # Mouse button must be released, then pressed, then released again. pygame.event.pump() clickable = 0 oldButtonPressed = 0 while 1: if clickable: if oldButtonPressed: if not pygame.mouse.get_pressed()[0]: # center the logo again screen.blit(logoEraser, (0,0)) screen.blit(logoImage, ((SCREENW-logoRect.width)/2, 0)) return elif pygame.mouse.get_pressed()[0]: oldButtonPressed = 1 else: if not pygame.mouse.get_pressed()[0]: clickable = 1 pygame.event.pump() if pygame.event.wait().type == QUIT: options.saveOptions() pygame.quit() sys.exit("Exiting Jools...") # arch-tag: high scores