15 CONSTANT MAXNAME
5 CONSTANT NUMNAMES

MAXNAME STRING NEWHIGH
NUMNAMES ARRAY HIGHSCORES

NUMNAMES MAXNAME STRING[] HIGHTABLE

: STORENAME ( POS / STRADDR )
   >R HIGHTABLE R> STRCPY
   ;

: INITHIGHTABLE
   NUMNAMES 0 DO
      I HIGHTABLE STRCPY" ROB TURNER"
      300 I HIGHSCORES !
   LOOP
   ;

: PRINTHIGHTABLE.OLD
   CR CR CR CR
   2 COLOUR1
   14 SPACES ." HIGH SCORES" CR CR
   3 COLOUR1
   NUMNAMES 0 DO
      10 SPACES
      I HIGHTABLE DUP .STR
      MAXNAME 1+ SWAP STRLEN - SPACES
      I HIGHSCORES ? CR
   LOOP
   ;

: PRINTHIGHTABLE
   3 COLOUR1
   NUMNAMES 0 DO
      30 I 20 + TAB2 DROP ( TAB2 LEAVES 30 STACKED! )
      I HIGHTABLE DUP .STR
      MAXNAME 1+ SWAP STRLEN - SPACES
      I HIGHSCORES ?
   LOOP
   ;

: HIGHTABLEPOS ( SCORE -> POS )
   0 ( A FLAG ) NUMNAMES 0 DO
      DROP
      DUP I HIGHSCORES @ > IF
         DROP I 1 LEAVE
      ELSE
         0
      THEN
   LOOP
   IF ( HIGHER SCORE )
   ELSE
      DROP -1
   THEN
   ;

: INSERTNAME ( POS / NAME STRING )
   SWAP DUP ( NAME / POS / POS )
   NUMNAMES 1- <> IF ( NAME / POS )
      DUP ( NAME / POS / POS )
      NUMNAMES 1- DUP ROT
      ( NAME / POS / END / END / START ) DO
         ( NAME / POS / END )
         2DUP 1- I - +
         ( NAME / POS / END / END-I+POS )
         DUP
         1+ HIGHTABLE SWAP HIGHTABLE STRCPY
      LOOP DROP
   ELSE
   THEN
   HIGHTABLE SWAP STRCPY ( INSERT NEW NAME )
   ;

: INSERTSCORE ( SCORE / POS )
   DUP ( SCORE / POS / POS )
   NUMNAMES 1- <> IF ( SCORE / POS )
      DUP ( SCORE / POS / POS )
      NUMNAMES 1- DUP ROT
      ( SCORE / POS / END / END / START ) DO
         ( SCORE / POS / END )
         2DUP 1- I - +
         ( SCORE / POS / END / END-I+POS )
         DUP
         HIGHSCORES @ SWAP 1+ HIGHSCORES !
      LOOP DROP
   ELSE
   THEN
   HIGHSCORES ! ( INSERT NEW SCORE )
   ;

: READSTRING ( ADDR OF STRING CHARS / MAXLEN )
   >R DUP R> EXPECT DUP
   0 ( ST ADDR / ST ADDR / LENGTH COUNT )
   BEGIN
      SWAP DUP ( ST ADDR / CNT / C ADDR / C ADDR )
      C@ 0= IF ( ST ADDR / CNT / C ADDR )
         DROP
         SWAP 4 - ! EXIT
      ELSE
         1+ SWAP 1+ ( ST ADDR / C ADDR+1 / CNT+1 )
      THEN
   AGAIN
   ;

: GETNAME ( STRING )
   4 COLOUR1
   CR CR 13 SPACES ." HIGH SCORE!" CR CR CR
   5 COLOUR1
   6 SPACES ." Enter Your Name: "
   6 COLOUR1
   4 + MAXNAME 2 - READSTRING
   ;

: UPDATEHIGHTABLE ( SCORE )
   DUP
   HIGHTABLEPOS ( SCORE / POS )
   DUP 0< IF ( SCORE / POS )
      2DROP EXIT
   ELSE
      DUP ( SCORE / POS / POS )
      NEWHIGH GETNAME
      NEWHIGH INSERTNAME
      INSERTSCORE
   THEN
   ;

INITHIGHTABLE
