implementation module Highscore /* General utility for reading/writing high scores to Files and displaying current high scores. This module has been written in Clean 2.0 and uses the Object I/O library, version 1.2.2. */ import StdBool, StdEnum, StdFile, StdInt, StdList, StdMisc, StdString, StdTuple import StdId, StdSystem, StdWindow :: HiScores :== [HiScore] :: HiScore = { name :: !String , score :: !Int } // Read in the high scores: readHiScores :: !String !*env -> (!(!*File,!HiScores),!*env) | FileSystem env readHiScores fname env # (exists,file,env) = fopen fpath FReadData env | exists # (highs,file) = readHighs file = ((file,highs),env) | otherwise # (_,create,env) = fopen fpath FWriteData env = ((create,[]),env) where fpath = homepath fname readHighs :: !*File -> (!HiScores,!*File) readHighs file | sfend file = ([],file) # (name, file) = freads file 13 # (ok,hi,file) = freadi file | not ok = ([],file) # (ok,_, file) = freadc file | not ok = ([],file) | otherwise # (rest, file) = readHighs file = ([{name=name,score=hi}:rest],file) // Write the high scores: writeHiScores :: !*File !HiScores !*env -> *env | FileSystem env writeHiScores file highs env # (ok,file) = freopen file FWriteData | not ok = abort "Could not reopen file.\n" | otherwise = snd (fclose (file<< *File (<<<) f {name,score} = f<< String take13 string = (string+++" ")%(0,12) instance <<< [x] | <<< x where (<<<) :: !*File ![x] -> *File | <<< x (<<<) f [x:xs] = f<< Bool itsAHighScore nrOfHiScores score scores | score==0 = False | length scores Bool isItReallyAHighScore score` [{score}:hiscores] = score`>score || isItReallyAHighScore score` hiscores isItReallyAHighScore _ _ = False // Add a HiScore to the current list of high scores: addScore :: !Int !HiScore !HiScores -> HiScores addScore nrOfHighScores hi hiscores = take nrOfHighScores (addscore hi hiscores) where addscore :: !HiScore !HiScores -> HiScores addscore hi` hiscores=:[hi:his] | hi.score>hi`.score = [hi : addscore hi` his] | otherwise = [hi` : hiscores] addscore hi` _ = [hi`] // Display high scores in a modal dialog to the user: showHiScores :: String !HiScores !(PSt *l) -> PSt *l showHiScores header highs pState=:{io} # (okId,io) = openId io # (wId, io) = openId io = snd (openModalDialog undef (dialog wId okId) {pState & io=io}) where dialog id okId = Dialog "High Scores" ( TextControl header [ControlPos (Center,zero)] :+: text :+: ButtonControl "OK" [ControlId okId,ControlPos (Center,zero),ControlFunction (noLS (closeWindow id))] ) [ WindowId id , WindowOk okId ] text= if (isEmpty highs) (ListLS [TextControl "No high scores available." []]) (ListLS [ TextControl (toString hi+++". "+++take13 name+++" "+++toString score) [ControlPos (Left,zero)] \\ (hi,{name,score}) <- zip2 [1..] highs ])