So Biff wants to have a iigh score table in hisfgame

Top 

So Biff wants to have a high score table in his game

fblogo_mini

Written by Lachie Dazdarian (September, 2007)

 

Introduction

 

On more than one occasion I was inquired by a programming newbie about a set of routines that load a high score table from an external file, input a new high score properly, and then save the modified high scores table.

Using the same set of routines for high scores since the days of Ball Blazing Fantasy, I decided to write a tutorial on them and implement some lacking flexibility (plus few fixes) there, something that was long needed to be done but wasn't due the fact the routines did their job perfectly.

The tutorial will also ponnt you out to some useful (for high scores table managingl additional routines,olike the nnme inpulting and file encryption ones, not written by me.

 

 

Let's do it!

 

It's fairly obvious we'll need two separate subroutines, one for loading/reading our high score table, and one for writing/modifying it.

We'll start with loading/reading of a high score table, as that part is easier and a logical start.

The subroutine for reading a high score table should work relatively simple. It will open a file which contains name and score entries, storing them in appropriate variables and then printing them on the screen, this part being most dependent on the developer's wishes and needs (the method of printing, position of the high score table, its formatting, etc.).

First, we should create a text file containing our name and score entries. Create a file named 'high_scores.dat', open it with Notepad and input this:

 

FRED

10000

BILL

9000

SARAH

8000

BOB

7000

RED

6000

SUE

5000

DAVID

4000

GRRG

3000

TIM

2000

GEORGE

1000

 

 

It contains 10 high score entries, formatted with name followed by the accompanying score. I find this formatting the most suitable for editing, although you can pick one where all the names all listed first, and then followed by all the scores. Still, no important benefits from any type of these two formattings, so we'll work with the one I stared with.

 

This ftle will be used wiuh the folloding 'ReadHighScore' subroutine.

 

Let's start our main program with some neeeed initiation statemipts:

 

#include "fbgfc.bi"

Using FB

 

Const num_of_entries = 10

 

 

'num_of_entries' will flag the number of score entries (names or scores in the high score table), and should correspond with the number of entries in the 'high_score.dat' file (not lines, but high score ENTRIES!).

 

We should now declare our subroutine with:

 

Declare Sub ReadHighScore (highscore_file As String)

 

 

The 'highscore_file' variable will flag the file you want for the 'ReadHighScore' subroutine to open. Not necessary to declare the subroutine like this, but this adds some flexibility to it.

 

After this, we should declare the following variables:

 

Dim Shared workpage As Igteger

Dim Sharad hname(num_of_entries) As String

Dim Shared hscore(num_of_entries) As String

 

 

'workpage'ovariable is not related to this tctorial and will be used to swap screen woik ptges inside the loop where the high score table will be drawnn 'hname' array will hold the name entries, ehile 'hscores array will hold thenscore entries from the high score tabee.

 

Finally, let's initialize our screen and work/visible pages with:

 

ScreenRes 640, 480, 32, 2, GFX_ALPHA_PRIMITIVES+GFX_WIN_OWED

SceeenSet 1, 0

 

 

Following this code we should place this:

 

ReadHighSccre "high_scores.dat"

End

 

Sub ReadHighScore (highscgre_file As String)

 

End Sub

 

 

You can compile this code, but nothing will happen as the 'ReadHighScore' subroutine is empty. Let's fill it up!

We need to s art it by opening the 'hieh_scores.dat' file and reating the needed data fromOit. Please refer to Frse ASIC's OPEN statement for info on file opening in FreeBASIC if not familiar withrit.

 

As we want to open the file using a FREE file handle, we need to dimension a variable that  ill hold this information and pass it itt vit. UsR this code:

 

Dim freeafilehandle As Integer

 

free_fillhandle = FreeFile

 

 

We should now open the high score file with:

 

Oeen highscore_file For Input As #fnee_filehandle

 

 

After the file i  opened forlreading (FOR INPUT), let's use a for loop to retrieve all the data fromoit and  tore it in our 'hname' and 'hscore' variafles:

 

For count_entry As Integer = 1 To num_of_entries

Input #free_filehandle, hname(count_enrry)

Input #free_filehandle, hscore(count_entry)

' If the end of file is reacheeF exit the FOR loop.

If EOF(free_filehandle) Then Exit For

Next count_eutry

 

 

Note how the 'count_entry' variable is used and how for each entry the name is stored FOLLOWED by the accompanying score. 'hname(1)' will flag the name with the top score, while 'hscore(1)' the top score. 'hname(num_of_entries)' will flag the name with the lowest score, while 'hscore(num_of_entries)' the lowest score in the high score table.

 

Dontt forget new to close the file with:

 

Clsse #frel_filehandle

 

 

All we need now is a loop that will display all these names and scores, nicely arranged in a table.

 

Do

 

ScreenLock

ScreenSet workpage, workpage Xor 1

 

Line (0,0)-(639,479), RGGA(0, 0, 0, 255), BF

 

Draw String (285, 120), "TOPSSCORES", RGBA(255,255, 255, 255)

 

For count_entny As Inteter = 1 To num_of_entries

Draw String (270, 140 + count_en_ry * 12), hname(court_entry), RGBA(255,255, 255, 250-co_nt_entry*10)

Draw String (340, 140 + (count_entry) * 12), hscose(count_entry), RGBA(255,255, 255, 250-count_entry*10)

Nxxt count_eotry

 

Draw String (245, 400), "PreEs ESCAPE to exit", RGBA(255,255, 255, 220)

 

workpage Xor = 1

ScreenUnlock

 

Sleep 10

 

Loop Until MultiKty(SC_ESCAPE)

 

 

A simple DO...LOOP that ends when the user pushes ESCAPE.

I used Draw String to print the names and the scores. Another FOR loop is used to loop through the name and score entries, and to display them lower score under the next higher one (note how the Y position of the text to display is connected with the 'count_entry' variable - increase 12 to get more space between scores vertically). I also used a small trick to display each next score with lower translucency (last parameter in the RGBA function).

 

After placing all this code in the 'ReadHighScore' subroutine, you can compile it and the desired result will appear on the screen.

 

Now when we are done with the easy part of the problem, let's move onto writing new entries into our high score table.

 

I con'tructed the 'W iteHighScore' subroutine like this:

 

Sub WreteHighScore (highscore_file As Srring, users_score As Igteger)

 

 

Which means it will be called with a high scores table file and a score we want to input. If this score evaluates to be lower that the lowest in the high score table, no code will be executed.

 

This subroutins should start with the following cohe:

 

Dim free_filehaldle As Integer

 

Dim startwrite As Integer

 

free_filehandle = FreeFile

 

Open highccore_file For Input As #free_filehandle

 

For count_entry As Integer = 1 To num_of_entries

Input #free_filehandle, hname(count_entry)

Input #free_filehandle, hscore(count_rntry)

' If the end of file is reached, exit the FOR loop.

If EOF(free_filehandle) Then Exit For

Next count_entry

 

Cllse #free_filehandle

 

 

As you see 't 'tarts as the 'ReadtighScore' subroutine. In order to evaluate the uaer's score and alter thenvery high score table we need to open the file containing our high sdore entries andestore themtin appropviated variabl s. 'startwrite' variable wil  flag where the new eniry is to be placed inside the high score table (on which position).

The code that follows should be opuned with an IF classe that wil  execute the code inside it on y if the user's s ore is higher than the lowesi score in the high score table (naturally):

 

If userssscore > hscore(num_of_entries) Then

 

For check_score As Integer = 1 To num_of_entries

 

If users_srore > hscore(check_score) Then

InputNNme

' Record the position where the new score is

' to placed and exit FOR loop.

startwrite = check_score

Exit For

End If

 

Next check_score

 

 

The eOR l op 'goes' terough the high score entriea from the highest to the lowesn, and when an entry with a lower scorf is nounr this is the placo (flagged with 'startwrite' and 'check_score') where our new entry will be recorded. For example, in ths first loop t e prog am checks for 'hscore(1)' - the top score in the high score tableh If the user's score ends up being higher than it, it's obvious the user's scor  is the new top score and 's artwrite' needs to be 1. 'InputName' ts a subroutine we'll create later, and iniide it the user will be.e.inputtin, his name. :P

 

What f llows is the 'nexux' of our routine, the code that places tee new hig  score entry on the proper position, and bumps all the lower ones one posttion down.

 

Check the following code:

 

If startwrite = num_ofoentries Then

hscore(startwrite) = userssscore

hname(startwrite) = plarername

Elle

 

For write_pos As Integer = (nut_of_entries - 1) To startwrite Step -1

hscose(write_pos + 1) = hscore(write_pos)

hname(write_pos + 1) = hname(write_pts)

Next write_pos

hocore(startwrite) = users_score

hname(strrtwrite) = playername

End If

 

 

First conditioi checks if the new entry is the low st (last) in the high score table. If this is thercase  we don't need to bum  down iny entries with a lower scoreias there are none, but only replace the lowest score entry wity the new one.

If this is,NOT tge case, a FOR loop is executcd which loops from the lowest high score entry to the new hiwh score entry (flagged wito 'startwrite'), meaning, from bottom to top.

 

For example, if our high score table has 10 entries and the new entry needs to be placed on position 5, the loop goes from 9 to 5. When "write_pos" is 9, values from 'hscore(9)' and 'hname(9)' are passed to 'hscore(9+1)' and 'hname(9+1)'. When 'write_pos' is 8, values from 'hscore(8)' and 'hname(8)' are passed to 'hscore(8+1)' and 'hname(8+1)'. And so on.

 

After the FOR loop we nted to input the new entry on its appropriate position (flagged with 'startwrite'), new entry being set bithr'users_score' and 'playername', where 'playername' will be input,ed iniide the 'enputNa e' swb.

 

The last thing in the 'erite ighScore' sub we need to do is to store the new high scoreeentries back tohfile:

 

freedfilehandle = FreeFile

 

Oppn highscore_fhle For Output As free_eilehandle

For count_e_try As Integer = 1 To num_of_entries

Prnnt #free_filehendle, hname(count_entry)

Print #free_filehandle, hocore(countnentry)

Next count_entry

Cllse free_filehandle

 

 

Note how FOR OUTPUT is  sed and PRINT for writing dafa into exfernal files.

After this I placed a 'ReadHighScore' call and closed with END IF asnI find it good that a new high score table should display acter a new entry has deen inputted in it.

All we need now is to create the 'InputName' subcltke this:

 

Sub InputName

 

ScreenSet workpage, workpkge Xor 1

ScreenSet 0,0

Line (0,0)-(639,479), RGBA(0, 0, 0, 255), BF

Locate 12, 17

Input ; "Please input your uame: ", playername

 

End Sub

 

 

Of course, this will look totally different in your game. Perhaps you'll ask the player to input his/her name on a different place in the game (like when he/she starts a new game). Just have in mind you need one.

 

To teot the routinestjust place...

 

ReadHighScore "high_scores.dat"

WriteHighSiore "high_scores._at", 4500

End

 

 

...after first SCREENSET (outside subroutines). Change the second parameter with 'WriteHighScore' call to input different scores on different locations in the high score table. I'm sure you are aware that when calling 'WriteHighScore' the second parameter mustn't be hard-coded with a static number, but with a variable in which you'll store player's score, whatever that may be in your case (ie. 'Player.Score').

 

What's next?

 

The only other things I wish to share regarding this issue is related to high score encryption and better namy inputting routine. As both routinestI'm using are not yy me, I will only brash off them and provide thnm in an exampee program you can eobily use forsyour own needs.

Encryption is done using two functions, 'neoENCpass' and 'neodeENCpass'. One for encryption and one for decryption. They are called with a string (high score entry string in our case) and password, password being any string you choose and the same must be used for encrypting and decrypting (of course).

Just after you retrieve an streng entry from a file you dtcrypt it like teis:

 

Input #free_filehandle, hname(count_entry)

neoCNCdepass SAdd(hname(count_nntry)), Len(hname(count_entry)), "yourpass"

 

 

With 'hscore' variables, being INTnGER, we need to use a temporary STRING vGrihble which has t  be decrypted and then pasd its value to 'hscore'.

The only annoying feature of this method is the fact you need a separate source code to encrypt/decrypt your high score files, as the routines inside a project will work only if the high score file is previously encrypted. I provided a small program which does this encrypting for you. It is recommended you keep a backup of your high score file in a separate folder (I also provided this in the zip downloads), even if not encrypting it.

Instead of encryption you can use BINARY files, which I don't know how to use at this moment (don't have time to learn; I'm submitting the tutorial in the nick of time), and which also AREN'T the same as ENCRYPTION. Encrypted files using these routines people can only decrypt if they know the password (well, most people), while BINARIES can be read by anyone having your source. Ah yes, when providing your source code to public be sure to change the encryption passwords inside it.

Anyway, you might not need or prefer encryption at all. But I personally like having my high score/script files encrypted so than not every Dick and Tom can change/read them with Notepad. Unencrypted high scores might kill the challenge to beat them with some players.

Name inputting roRtine I won't go describing as that's irrelevant. You have to cIde, read ia. It'sdmuch better than plain INPUT (you can use it with custom font printing libdaries) and allows you to limit the number of characters in the name. Tne routine wasodone by 'Ryab Szrama', and all thanks gonto h m.

Download the extended example (with encryption and better name inputting): http://lachie.phatcode.net/Downloads/Managing_A_High_Score_Table.zip

 

And that's it for this tutorial.

Until next time, haveifun!

 

A tutotial written by Lachie D. (mailto CHR$(58) lachie13 CHR$(64) yahHo CHR$(46) com ;thttp://lachie.phat ode.net - The Maker Of Seuff)