Jump to content
IGNORED

How do we keep a high score?


Random Terrain

Recommended Posts

The bB page has this:

 

 dim sc1 = score
 dim sc2 = score+1
 dim sc3 = score+2

 

 

But I've seen people post this:

 

 dim sc0 = score
 dim sc1 = score+1
 dim sc2 = score+2

 

 

I tried both and no matter what I try, I can't get a game to remember the high score. I thought the following would work, but it doesn't:

 

   if sc1 > High_Score01 then High_Score01=sc1 : High_Score02=sc2 : High_Score03=sc3 : goto Skip_High_Score

  if sc2 > High_Score02 then High_Score01=sc1 : High_Score02=sc2 : High_Score03=sc3 : goto Skip_High_Score

  if sc3 > High_Score03 then High_Score01=sc1 : High_Score02=sc2 : High_Score03=sc3

Skip_High_Score

 

 

I even reversed the order in case sc1 is on the right instead of the left and that doesn't work either.

 

 

What do I need to do?

 

 

Thanks.

 

 

Update

 

The problem has been solved:

 

http://www.atariage.com/forums/topic/168926-how-do-we-keep-a-high-score/page__view__findpost__p__2089754

Edited by Random Terrain
Link to comment
Share on other sites

For a 24 bit comparison you need to start with the high order byte first and work your way down. It'll end up with something like this :-

 

if sc3>hs3&&sc2>hs2&&sc1>hs1 hs3=sc2:hs2=sc2:hs1=sc1

 

Where :-

 

sc3=score bits 16 to 23

sc2=score bits 8 to 15

sc1=score bits 0 to 7

 

Not tested but it should work.

Link to comment
Share on other sites

if sc3> hs3 && sc2 > hs2 && sc1 > hs1 then hs3=sc3 : hs2=sc2 : hs1=sc1

Thanks. Nope, doesn't work. I even tried this:

 

if sc3 >= High_Score03 && sc2 >= High_Score02 && sc1 >= High_Score01 then High_Score03=sc3 : High_Score02=sc2 : High_Score01=sc1

 

Since we are using AND, everything has to be greater than or equal, so if my high score is 60, then I get a high score of 110, although 110 is greater than 60, 10 is not greater than 60, so it doesn't get recorded.

 

 

I modified the reverse of what I posted and this seems to work:

 

  if sc3 > 0 && sc3 > High_Score03 then New_High_Score

  if sc2 > 0 && sc2 > High_Score02 then New_High_Score

  if sc1 > 0 && sc1 > High_Score01 then New_High_Score

  goto Skip_High_Score

New_High_Score

  High_Score01=sc1 : High_Score02=sc2 : High_Score03=sc3

Skip_High_Score

 

[The code I posted above is crap. See my next post.]

 

When I tested starting with sc3 and working down to sc1, it wasn't working because I didn't use sc3 > 0 &&. It's always some simple thing that screws everything up.

 

Unless somebody has a more crunched down version of what I posted, I'll just use it as it is.

Edited by Random Terrain
Link to comment
Share on other sites

Forget what I posted about sc3 > 0 &&, now it seems to be working without it:

 

   if sc3 > High_Score03 then New_High_Score

  if sc2 > High_Score02 then New_High_Score

  if sc1 > High_Score01 then New_High_Score

  goto Skip_High_Score

New_High_Score

  High_Score01=sc1 : High_Score02=sc2 : High_Score03=sc3

Skip_High_Score

 

 

I don't get it. It wasn't working, but now it is. Maybe I was using >= in my test before and I forgot about it. That has to be what happened. :dunce:

 

If someone else tests this and it seems to work for them too, I can put a version of this on the bB page to help new users who want to record a high score too.

Edited by Random Terrain
Link to comment
Share on other sites

   if sc3 > High_Score03 then New_High_Score

  if sc2 > High_Score02 then New_High_Score

  if sc1 > High_Score01 then New_High_Score

  goto Skip_High_Score

New_High_Score

  High_Score01=sc1 : High_Score02=sc2 : High_Score03=sc3

Skip_High_Score

I am interested too!

Then, how do I display the high score?

score=???????

Link to comment
Share on other sites

I am interested too!

Then, how do I display the high score?

score=???????

Here's part of the code from my program:

 

 

rem ****************************************************************

rem * Setup for the restart loop.

rem *

 

Master_Counter=0 : Frame_Counter=0 : Flip_Score=0 : Debounce_Reset{1}=1

 

RS01=sc1 : RS02=sc2 : RS03=sc3

 

 

 

Loop_Ready_to_Restart

 

 

 

rem ****************************************************************

rem * Set sprite color, color of top playfield row,

rem * background color, turn on side borders, and

rem * flip sprite if necessary.

rem *

 

COLUP0=10 : COLUPF = $CE : COLUBK=$80 : PF0 = %11110000 : REFP0=Flip_P0

 

 

 

 

rem ****************************************************************

rem * Go to title screen after 30 seconds if player does nothing.

rem * Also shows high score every 2 seconds.

rem *

 

Master_Counter=Master_Counter+1

 

if Master_Counter < 60 then Skip_30_Counter

 

Frame_Counter=Frame_Counter+1 : Flip_Score=Flip_Score+1 : Master_Counter = 0

 

if Frame_Counter = 30 then Game_Over{0} = 0 : goto Start_Restart bank1

 

if Flip_Score = 2 then Flip_Score=0 : Swap_Scores{2}=!Swap_Scores{2}

 

if !Swap_Scores{2} then scorecolor = $AE : sc1=High_Score01 : sc2=High_Score02 : sc3=High_Score03 : goto Skip_30_Counter

 

scorecolor = $1C : sc1=RS01 : sc2=RS02 : sc3=RS03

 

Skip_30_Counter

 

You just copy the score, then flip between the high score and the copy of the score.

 

I'll try to get that demo program working. I don't understand what is wrong with it, so I'll start over and I hope whatever I did to screw it up the first time will be gone.

Edited by Random Terrain
Link to comment
Share on other sites


dim sc1=score
dim sc2=score+1
dim sc3=score+2

dim hisc1=a
dim hisc2=c
dim hisc3=x

...


restart

if sc3 > 0 && sc3 > hisc3 then highscore
if sc2 > 0 && sc2 > hisc2 then highscore
if sc1 > 0 && sc1 > hisc1 then highscore

goto skiphighscore

highscore
hisc1=sc1:hisc2=sc2:hisc3=sc3
 
skiphighscore

sc1=hisc1:sc2=hisc2:sc3=hisc3
goto titlescreen bank2

 

Surely I am doing something wrong...

Link to comment
Share on other sites

An efficient multi-byte comparison requires use of the carry flag for multi-precision arithmetic; a three-byte comparison can be done with six instructions totaling 12 bytes to get the result into the carry flag. If multi-precision arithmetic is not available, the logic should be:

 if score_top > highscore_top then YEP
 if score_top < highscore_top then NOPE
 if score_mid > highscore_mid then YEP
 if score_mid < highscore_mid then NOPE
 if score_bot > highscore_bot then YEP
 if score_bot < highscore_bot then NOPE

Otherwise, optimal 6502 code would be:

 lda highscore_bot
 cmp score_bot
 lda highscore_mid
 sbc score_mid
 lda highscore_top
 sbc score_top
; Carry will be clear if score > highscore

The CMP will clear the carry if score_bot > highscore_bot and set it otherwise. Each SBC will clear the carry if the corresponding byte of score is greater than the corresponding byte of highscore, set it if the corresponding byte of score is less than the corresponding byte of highscore, and leave it alone if they're equal. Thus, the state of the flag after earlier comparisons is relevant only if later bytes are equal.

  • Like 1
Link to comment
Share on other sites

An efficient multi-byte comparison requires use of the carry flag for multi-precision arithmetic; a three-byte comparison can be done with six instructions totaling 12 bytes to get the result into the carry flag. If multi-precision arithmetic is not available, the logic should be:

 if score_top > highscore_top then YEP
 if score_top < highscore_top then NOPE
 if score_mid > highscore_mid then YEP
 if score_mid < highscore_mid then NOPE
 if score_bot > highscore_bot then YEP
 if score_bot < highscore_bot then NOPE

I think the following should be sufficiently optimized for bB:

 

  if score_top < highscore_top then NOPE
  if score_mid < highscore_mid then NOPE
  if score_bot < highscore_bot then NOPE
  score_top = highscore_top : score_mid = highscore_mid : score_bot = highscore_bot
NOPE
  rem * continue

Michael

Link to comment
Share on other sites

I think the following should be sufficiently optimized for bB:

 

  if score_top < highscore_top then NOPE
  if score_mid < highscore_mid then NOPE
  if score_bot < highscore_bot then NOPE
  score_top = highscore_top : score_mid = highscore_mid : score_bot = highscore_bot
NOPE
  rem * continue

Michael

So instead of this:

 

  if sc3 > High_Score03 then New_High_Score

  if sc2 > High_Score02 then New_High_Score

  if sc1 > High_Score01 then New_High_Score

  goto Skip_High_Score

New_High_Score

  High_Score01=sc1 : High_Score02=sc2 : High_Score03=sc3

Skip_High_Score

 

 

We'd use this:

 

  if sc3 < High_Score03 then No_High_Score

  if sc2 < High_Score02 then No_High_Score

  if sc1 < High_Score01 then No_High_Score

  High_Score01=sc1 : High_Score02=sc2 : High_Score03=sc3

No_High_Score

 

Problem is that doesn't work. A lower part will win over a higher part if the number is larger. So we are back to this:

 

  if sc3 > High_Score03 then New_High_Score

  if sc2 > High_Score02 then New_High_Score

  if sc1 > High_Score01 then New_High_Score

  goto Skip_High_Score

New_High_Score

  High_Score01=sc1 : High_Score02=sc2 : High_Score03=sc3

Skip_High_Score

 

Problem is that it doesn't always work in the little demo program I'm trying to get working.

Link to comment
Share on other sites

A highscore is possible when digits are EQUAL as well as greater-than. 1001 is higher than 1000. The above is just checking if any of the 3 BCD's are greater than their highscore counterpart...which is why it doesn't work. Aside from that, you need abandon and skip to the next comparison if the scores are equal.

 

This is simple in asm using a loop. I dunno how to translate that to bB.

 

;check high score subroutine
      ldy    #$00             ;2
Check_Score_Loop:
      lda.wy Score,y          ;4
      cmp.wy HiScore,y        ;4 compare the high byte
      beq    Next_Digit       ;2 branch if the same (and check next)
      bcc    No_High_Score    ;2 branch if lower (and end)
      bcs    Set_HiScore      ;2 higher...new high score
Next_Digit:
      iny                     ;2 bump pointer
      cpy    #$03             ;2 at the end of 3 bytes?
      bne    Check_Score_Loop ;2 branch if not
No_High_Score:
      rts                     ;2 fell through...no high score
Set_HiScore:
      lda    Score            ;3 New high score...transfer ram
      sta    HiScore          ;3
      lda    Score+1          ;3
      sta    HiScore+1        ;3
      lda    HiScore+2        ;3
      sta    HiScore+2        ;3
      rts                     ;6

Link to comment
Share on other sites

BTW since bBasic is interpreting...couldn't you just...

 

  IF (sc1*10000+sc2*100+sc3) < (High_Score01*10000+High_Score02*100+High_Score03) then No_High_Score

 

...or is that too complex?

I'm not using the beta version of bB, so it might be able to handle that. The regular version can't do math in an if-then. We'd have to do this:

 

  temp5 = (sc1*10000+sc2*100+sc3)
  temp6 = (High_Score01*10000+High_Score02*100+High_Score03)
  
  if temp5 < temp6 then No_High_Score

  High_Score01=sc1 : High_Score02=sc2 : High_Score03=sc3

No_High_Score

 

I just tried it and it seems to be working great so far. That seems to be the best solution. Thanks!

Edited by Random Terrain
Link to comment
Share on other sites

It's still overthinking the solution. SeaG's example is still better. Why didn't it work? Falling through each if-then should only be possible if the scores are at least equal :?

 

Were you checking from high to low?

No matter which way I try his example (from sc1 to sc3 or from sc3 to sc1), it doesn't work correctly. So far your last example is the only one that seems to work consistently.

 

Speaking of high to low, the bB page says:

 

If you plan to check the score, you will need to break out its 6 digits into 3 sets of two digits and check each one. One way to pull out the score digits is:

 

dim sc1=score

dim sc2=score+1

dim sc3=score+2

 

sc1 will contain the first two digits, sc2 the 3rd and 4th, and sc3 the last two.

 

I'm not clear about which ones are the first two digits. Are we going from left to right or right to left?

Link to comment
Share on other sites

First = left, last = right. sc1 holds the 100&10 thousands digits, sc2 holds the thousands and hundreds, sc3 holds the tens and ones.

 

How about:

 

  if sc1 > High_Score01 then YEP
 if sc1 < High_Score01 then NOPE
;first byte equal...do the next test...
 if sc2 > High_Score02 then YEP
 if sc2 < High_Score02 then NOPE
;second byte equal...do the next test...
 if sc3 > High_Score03 then YEP
 if sc3 < High_Score03 then NOPE
;all bytes equal
 goto NOPE
YEP:
 High_Score01 = sc1
 High_Score02 = sc2
 High_Score03 = sc3
NOPE:

 

goto NOPE isn't needed if you aren't worried about resetting the high score when it's totally equal to the score. You'd need to use it if the game is doing something to signify that the high score was made, tho (such as playing a sound effect).

Edited by Nukey Shay
  • Like 1
Link to comment
Share on other sites

First = left, last = right. sc1 holds the 100&10 thousands digits, sc2 holds the thousands and hundreds, sc3 holds the tens and ones.

Thanks. I'll add that to the bB page tonight.

 

 

How about:

 

  if sc1 > High_Score01 then YEP
 if sc1 < High_Score01 then NOPE
;first byte equal...do the next test...
 if sc2 > High_Score02 then YEP
 if sc2 < High_Score02 then NOPE
;second byte equal...do the next test...
 if sc3 > High_Score03 then YEP
 if sc3 < High_Score03 then NOPE
;all bytes equal
 goto NOPE
YEP:
 High_Score01 = sc1
 High_Score02 = sc2
 High_Score03 = sc3
NOPE:

 

goto NOPE isn't needed if you aren't worried about resetting the high score when it's totally equal to the score. You'd need to use it if the game is doing something to signify that the high score was made, tho (such as playing a sound effect).

That works better than your last one. I tried 530 against 120 and 530 was the new high score. I'll test some more crazy numbers, but it looks like we might be done:

 

  if sc1 > High_Score01 then New_High_Score
  if sc1 < High_Score01 then Skip_High_Score

  rem first byte equal...do the next test...

  if sc2 > High_Score02 then New_High_Score
  if sc2 < High_Score02 then Skip_High_Score

  rem second byte equal...do the next test...

  if sc3 > High_Score03 then New_High_Score
  if sc3 < High_Score03 then Skip_High_Score

  rem all bytes equal

  goto Skip_High_Score

New_High_Score

  High_Score01 = sc1
  High_Score02 = sc2
  High_Score03 = sc3

Skip_High_Score

 

 

Thanks again. So far no problems. Now I can get the little demo program finished.

Edited by Random Terrain
Link to comment
Share on other sites

Exactly the same as what supercat posted above...I just changed the variable names to be sure that the tests were being done in the proper order ;)

Oh yeah, it is. You sanded it and put a coat of paint on it, though. Thanks goes to supercat and Nukey Shay. :thumbsup:

Link to comment
Share on other sites

The bB page has been updated:

 

http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#score

 

 

Below is an example program that shows how to save the high score until the game is turned off. Move the joystick up to increase the score. Press the fire button to leave the main loop and the score will flip between the current score and the high score every 2 seconds. Press the fire button or reset switch to go back to the main loop.

 

 

Here's the .bin file to use with an emulator:

 

ex_save_high_score_2010y_09m_08d_0323t.bin

 

 

Here's the bB code:

 

ex_save_high_score_2010y_09m_08d_0323t.bas

Edited by Random Terrain
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...