;==================== begin high-scores.nls ==================================== ; high-scores - Load/save/manipulate high scores in a file. ; ; By Rik Blok, 2013 ; ; This is free and unencumbered software released into the public domain. ; ; Anyone is free to copy, modify, publish, use, compile, sell, or ; distribute this software, either in source code form or as a compiled ; binary, for any purpose, commercial or non-commercial, and by any ; means. ; ; Provides: ; ; add-high-score ; Adds a new high score to the list and saves to file. Asks for player name. ; high-scores-list ; Reports formatted list of high scores. ; is-high-score? ; Reports true if a score makes the list. ; read-high-scores ; Read the high scores from file. ; write-high-scores ; Save the high scores to file. ; ; ; Usage: ; ; ; Reads high scores from _filename_ and remembers to keep _count_ highest. ; read-high-scores _filename_ _count_ ; ; ; Reports true if _score_ should be in the high scores. ; is-high-score? _score_ ; ; ; Adds _score_ and user-entered name to high score list. ; add-high-score _score_ _prompt_ ; ; ; Prints a formatted high score list with specified _width_. ; output-print high-scores-list _width_ ; ; Example: ; ; to setup ; read-high-scores "high-scores.txt" 10 ; end ; to go ; assume 'go' is a forever button ; ; ...do stuff and keep score... ; if is-game-over? ; check if game over ; [ if is-high-score? score ; [ add-high-score score "You got a high score! What is your name?" ; ] ; output-print "High scores:" ; output-print high-scores-list 25 ; stop ; stop forever button ; ] ; end ; ; Known limitations: ; ; 2013-09-05 - File write operations probably don't work in applet so ; most functionality disabled. ; 2013-09-02 - Assumes scores are non-negative integers. ; ; Revisions: ; ; 2013-09-05 - disable functionality if running in an applet ; 2013-09-02 - initial release by Rik Blok ;------------------------------------------------------------------------------- globals [ high-scores-data high-scores-file high-scores-count ] to read-high-scores ; Read high scores from file. ; Parameters: [ hs-file ; high scores file hs-count ; number of high scores to keep ] if not is-string? hs-file [ error "Parameter hs-file must be a filename." ] if not is-number? hs-count or hs-count < 1 [ error "Parameter hs-count must be an integer >= 1." ] set high-scores-file hs-file set high-scores-count hs-count set high-scores-data [ ["" 0] ] if file-exists? high-scores-file [ file-open high-scores-file set high-scores-data file-read file-close ] ; keep high scores sorted set high-scores-data sort-by [ last ?1 > last ?2 ] high-scores-data end to write-high-scores ; Write high scores to file. if not is-string? high-scores-file [ error "You must read-high-scores before calling write-high-scores." ] ; Replace file. if file-exists? high-scores-file [ file-delete high-scores-file ] file-open high-scores-file file-write high-scores-data file-close end to-report is-high-score? ; Reports whether passed score belongs on high-score list. ; Automatically reports false if running in an applet. ; Parameters: [ hs-score ; Score to check. ] if netlogo-applet? [ report false ] if not is-list? high-scores-data [ error "You must read-high-scores before calling is-high-score?." ] if high-scores-count <= 0 [ set high-scores-count 10 ] ; default report ( length high-scores-data < high-scores-count ) or ( hs-score > last last high-scores-data ) end to add-high-score ; Asks for name and adds to high score list. Saves to file. ; Parameters: [ hs-score ; Score to be added. hs-prompt ; Prompt for user name. ] if not is-list? high-scores-data [ error "You must read-high-scores before calling add-high-score." ] if high-scores-count <= 0 [ set high-scores-count 10 ] ; default let hs-name user-input hs-prompt set high-scores-data lput (list hs-name hs-score ) high-scores-data ; keep high scores sorted set high-scores-data sort-by [ last ?1 > last ?2 ] high-scores-data ; keep highest set high-scores-data sublist high-scores-data 0 min (list high-scores-count length high-scores-data) write-high-scores end to-report high-scores-list ; Reports formatted high score list, restricted to specified width. ; Parameters: [ hs-width ; column width ] if not is-list? high-scores-data [ error "You must read-high-scores before calling high-scores-list." ] ; calculate number of characters required for rank, name, and score let hs-rank-width ceiling log ( high-scores-count + 1 ) 10 ; assume high-score-list already sorted so biggest score is first let hs-score-width ceiling log ( last first high-scores-data + 1 ) 10 let hs-name-width hs-width - hs-rank-width - hs-score-width - 2 if hs-name-width < 1 [ set hs-name-width 1 ] ; loop through list let hs-rank 0 let hs-list "" foreach high-scores-data [ set hs-rank hs-rank + 1 ; pad rank, name, and score with spaces to line up columns let hs-rank-str (word hs-rank) while [ length hs-rank-str < hs-rank-width ] [ set hs-rank-str word " " hs-rank-str ] let hs-name first ? while [ length hs-name < hs-name-width ] [ set hs-name word hs-name " " ] let hs-score ( word last ? ) while [ length hs-score < hs-score-width ] [ set hs-score word " " hs-score ] ; add line to output set hs-list ( word hs-list hs-rank-str " " hs-name " " hs-score "\n" ) ] report hs-list end ;==================== end high-scores.nls ======================================