Login Register
Frontpage Code library Pastebin

HiScores

Author: VesQ
Added: 11. huhtikuuta 2011 kello 4.03
Edited: 15. huhtikuuta 2011 kello 22.19
Category: Käyttöliittymä

Description

Funktiokokoelma "turvallista" ennätyslistaa varten. Koittaa pitää ennätykset räpelöimisen ulkopuolella käyttämällä apuna Bagardin MD5-funktiota. Tarvitset siis tämän: http://www.cbrepository.com/codes/code/35/

Code

Select all
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
//==================================================================
// Funktiokokoelma ennätyslistaa varten. [ VesQ ]
// -----------------------------
// Funktioiden käyttämät vakiot:
//  * HISCORES_PASSPHRASE
//	  > Hashausta varten tarvittava merkkijono
//  * HISCORES_FILE
//    > Ennätyslistan tiedostonimi
//  * HISCORES_AMOUNT
//    > Ennätysten määrä
//  * HISCORES_MAXLENGTH
//    > Nimimerkin maksimipituus
//
// Funktiot käyttävät kaksiulotteista HISCORES-taulukkoa:
//    > (x, 0) -> Sisältää nimen
//    > (x, 1) -> Sisältää pisteet
//    > (x, 2) -> Sisältää MD5-hashin
//
// Funktiot:
//  * SetHiScore
//    > Lisää uuden nimen ja tuloksen ennätyslistaan.
//	  > Parametrit:
//      - 1: Nimimerkki (merkkijono)
//      - 2: Pisteet (kokonaisluku)
//  * SaveHiScores
//    > Tallentaa ennätykset tiedostoon
//    > Ei parametreja, tallennustiedosto on määritelty vakiossa
//  * LoadHiScores
//    > Lataa ennätykset tiedostosta
//    > Jos tiedosto on korruptoitunut -> MakeErrorilla virhe
//    > Parametrit:
//      - 1: Oletusnimimerkki tyhjille tuloksille (valinnainen, 
//           oletuksena "Nobody")
//  * PrintHiScores
//    > Tulostaa ennätyslistan näytölle niin, että joka toinen rivi
//      on erivärinen.
//    > Parametrit:
//      -      1: vasemman laidan x-koordinaatti tekstille
//      -      2: ensimmäisen rivin y-koordinaatti
//      -      3: monennesta ennätyksestä aletaan tulostamaan tekstiä
//                (oletuksena alusta)
//      -      4: kuinka monta ennätystä tulostetaan (ol. loppuun asti)
//      -  5,6,7: Ensimmäinen väri (oletuksena cbWhite; 255,255,255)
//      - 8,9,10: Toinen väri (oletuksena cbGreen; 128,168,4)
//  * SortHiScores
//    > Järjestää ennätyslistataulukon bubblesort-algoritmilla
//==================================================================


//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// TARVITTAVA OSA
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

Include "MD5.CB" // MD5-hash merkkijonosta by Bagard (http://www.cbrepository.com/codes/code/35/)

Const HISCORES_PASSPHRASE = "H#s&_;?€{vH"  // Hashausta varten tarvittava merkkijono
Const HISCORES_FILE       = "hiscores.dat" // Ennätysten tiedosto
Const HISCORES_AMOUNT     = 30             // Ennätysten määrä
Const HISCORES_MAXLENGTH  = 20             // Nimen maksimipituus

Dim HISCORES(HISCORES_AMOUNT, 3) As String
// (x, 0) = nimi
// (x, 1) = pisteet
// (x, 2) = hash

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// TARVITTAVA OSA
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// ESIMERKKIOHJELMA
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv

    SCREEN 500, 500
    
    // Ota alla olevan rivin kommentointi pois nähdäksesi miten tallennus sujuu
    'LoadHiScores("Nimetön") // Ladataan ennätykset, tyhjät ennätykset asetetaan nimelle Nimetön
    
    For i=1 To HISCORES_AMOUNT
        // Asetetaan maksimimäärä nimiä ennätyslistaan
        SetHiScore( "Heppu-"+i, Rand(10000) )
    Next i
    
    SaveHiScores() // Tallennetaan lista HISCORES_FILE tiedostoon
    
    Color cbBlue // Ohjetekstien väri
    
    SetWindow "esim. 1"
    Repeat
        Text 0, 0, "Paina ENTER tai SPACE siirtyäksesi seuraavaan esimerkkiin"
    
        Text 0, 470, "Tulostetaan lista loopissa, käytetään oletusarvoja."
        Text 0, 483, "x-koord: 20, y-koord: 40"
        PrintHiScores( 20, 40 )
        
        DrawScreen
    Until KeyHit(cbKeyReturn) Or KeyHit(cbKeySpace)
    
    SetWindow "esim. 2"
    Repeat
        Text 0, 0, "Paina ENTER tai SPACE siirtyäksesi viimeiseen esimerkkiin"
        
        Text 0, 470, "Tulostetaan 10 ensimmäistä ennätystä käyttäen väreinä"
        Text 0, 483, "hopeaa ja magentaa (RGB: 192,192,192 ja 255,0,255)."
        PrintHiScores( 20, 40, 0, 10, 192,192,192, 255,0,255 )
        
        DrawScreen
    Until KeyHit(cbKeyReturn) Or KeyHit(cbKeySpace)
    
    currentHS=0 // tarvittava apumuuttuja
    SetWindow "esim. 3"
    Repeat
        Text 0, 0, "Selaa ennätyksiä ylös- ja alas-nuolinäppäimillä."
        Text 0, 13, "ESC/ENTER/SPACE lopettaa esimerkin."
        
        // Siirrytään 5 nimeä eteen/taaksepäin nuolinäppäimillä
        If KeyHit(cbKeyDown) Then currentHS + 5
        If KeyHit(cbKeyUp) Then currentHS - 5
        
        // Pidetään muuttujan arvot rajojen sisällä
        If currentHS < 0 Then currentHS = 0
        If currentHS > HISCORES_AMOUNT-10 Then currentHS = HISCORES_AMOUNT-10
        
        Text 0, 470, "Tulostetaan 10 arvoa lähtien muuttujan currentHS kohdasta."
        Text 0, 483, "Väreinä cbLightBlue ja cbPink, x-koord: 20, y-koord:40"
        PrintHiScores( 20, 40, currentHS, 10, cbLightBlue, cbPink )
        
        DrawScreen
    Until KeyHit(cbKeyReturn) Or KeyHit(cbKeySpace)
    End

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// ESIMERKKIOHJELMA
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

//==================================================================
// FUNKTIOT
//==================================================================

//------------------------------------------------------------------
// Viimeiseen (ylimääräiseen) soluun lisätään uusi tulos
// ja sitten järjestetään taulukko.
//------------------------------------------------------------------

Function SetHiScore(_nickname$, _score)
    If Len(_nickname$) > HISCORES_MAXLENGTH Then 
        // Rajoitetaan nimen pituus
        _nickname$ = Left( _nickname$, HISCORES_MAXLENGTH )
    EndIf
    hash$ = MD5(_nickname + _score + HISCORES_PASSPHRASE)
    HISCORES( HISCORES_AMOUNT, 0 ) = _nickname
    HISCORES( HISCORES_AMOUNT, 1 ) = Str(_score)
    HISCORES( HISCORES_AMOUNT, 2 ) = hash

    SortHiScores()
    
    // Asetetaan viimeinen paikka tyhjäksi
    HISCORES( HISCORES_AMOUNT, 0 ) = ""
    HISCORES( HISCORES_AMOUNT, 1 ) = ""
    HISCORES( HISCORES_AMOUNT, 2 ) = ""
EndFunction

//------------------------------------------------------------------
// Tallentaa hiscoret tiedostoon. Huomaa, että viimeinen solu,
// joka on varattu uusille ennätyksille, ei tule tiedostoon mukaan.
//------------------------------------------------------------------

Function SaveHiScores()
    If FileExists(HISCORES_FILE) Then DeleteFile HISCORES_FILE
    f = OpenToWrite(HISCORES_FILE)
        For i=0 To HISCORES_AMOUNT-1
            WriteString f, HISCORES(i, 0)
            WriteString f, HISCORES(i, 1)
            WriteString f, HISCORES(i, 2)
        Next i
    CloseFile f
EndFunction

//------------------------------------------------------------------
// Lataa hiscore-taulukon HISCORES_FILE tiedostosta. Jos tiedosto
// on korruptoitunut (esim. joku on muuttanut tekstieditorilla
// pisteitänsä käsin) niin heitetään MakeErrorilla virhe muotoa:
//    Korruptoitunut ennätystiedosto! (ennätystiedosto.dat)
//    Poista se päästäksesi eroon tästä viestistä.
//------------------------------------------------------------------

Function LoadHiScores(_defname$ = "Nobody")
    If Not FileExists(HISCORES_FILE) Or IsDirectory(HISCORES_FILE) Then
        For i=0 To HISCORES_AMOUNT-1
            HISCORES(i, 0) = _defname$
            HISCORES(i, 1) = "0"
            HISCORES(i, 2) = MD5( _defname$ + "0" + HISCORES_PASSPHRASE )
        Next i
        Return False
    EndIf
    
    f = OpenToRead(HISCORES_FILE)
        For i=0 To HISCORES_AMOUNT-1
            If Not EOF(f) Then
                name$  = ReadString(f)
                If EOF(f) Then MakeError "Korruptoitunut ennätystiedosto! ("+HISCORES_FILE+")"+Chr(10)+Chr(13)+"Poista se päästäksesi eroon tästä viestistä."
                score$ = ReadString(f)
                If EOF(f) Then MakeError "Korruptoitunut ennätystiedosto! ("+HISCORES_FILE+")"+Chr(10)+Chr(13)+"Poista se päästäksesi eroon tästä viestistä."
                hash$  = ReadString(f)
                check$ = MD5(name + score + HISCORES_PASSPHRASE)
                If( hash$ <> MD5(name + score + HISCORES_PASSPHRASE) ) Then
                    MakeError "Korruptoitunut ennätystiedosto! ("+HISCORES_FILE+")"+Chr(10)+Chr(13)+"Poista se päästäksesi eroon tästä viestistä."+Chr(10)+Chr(13)+Chr(10)+Chr(13)+hash$+Chr(10)+Chr(13)+check$
                EndIf
                
                HISCORES(i, 0) = name
                HISCORES(i, 1) = score
                HISCORES(i, 2) = hash
            Else
                HISCORES(i, 0) = _defname$
                HISCORES(i, 1) = "0"
                HISCORES(i, 2) = MD5( _defname$ + "0" + HISCORES_PASSPHRASE )
            EndIf
        Next i
    CloseFile f
    
    SortHiScores()
    
    Return True
EndFunction

//------------------------------------------------------------------
// Tulostaa hiscore-listan näytölle. Funktio säilyttää nykyisen
// piirtovärin. Parametrit:
//      _X: vasemman laidan x-koordinaatti tekstille
//      _Y: ensimmäisen rivin y-koordinaatti
//   _from: monennesta ennätyksestä aletaan tulostamaan tekstiä
//          (oletuksena alusta)
// _amount: kuinka monta ennätystä tulostetaan (ol. loppuun asti)
// _r-g-b1: Ensimmäinen väri (oletuksena cbWhite; 255,255,255)
// _r-g-b2: Toinen väri (oletuksena cbGreen; 128,168,4)
//------------------------------------------------------------------

Function PrintHiScores( _X, _Y, _from=0, _amount=-1, _r1=255, _g1=255, _b1=255, _r2=128, _g2=168, _b2=4 )
    oldr=getRGB(RED):oldg=getRGB(GREEN):oldb=getRGB(BLUE)
    height = TextHeight("I")
    If _from < 0 Then _from=0 : ElseIf _from > HISCORES_AMOUNT-1 Then _from = HISCORES_AMOUNT-1
    If _amount = -1 Or (_from+_amount)>(HISCORES_AMOUNT) Then _amount = HISCORES_AMOUNT
    j=0
    x2 = _X + TextWidth("99. ")
    x3 = x2 + TextWidth( String("#", HISCORES_MAXLENGTH) )
    For i=_from To _from+_amount-1
        j=j+1
        If(j Mod 2) Then Color _r1,_g1,_b1 Else Color _r2,_g2,_b2
        
        Text _X, _Y + height*j, (i+1)+"."
        Text x2, _Y + height*j, HISCORES(i, 0)
        Text x3, _Y + height*j, HISCORES(i, 1)
    Next i
    Color oldr, oldg, oldb
EndFunction

//------------------------------------------------------------------
// Järjestää hiscore-listan suurimmasta pienimpään 
// bubblesort-nimisellä algoritmilla.
//------------------------------------------------------------------

Function SortHiScores()
    For i = 0 To HISCORES_AMOUNT Step 1
        For o = i-1 To 0 Step -1
            If Int(HISCORES(o, 1)) < Int(HISCORES(o+1, 1))
                For lokero=0 To 2
                    temp$ = HISCORES(o, lokero)
                    HISCORES(o, lokero) = HISCORES(o+1, lokero)
                    HISCORES(o+1, lokero) = temp
                Next lokero
            EndIf
        Next o
    Next i
EndFunction 

Comments

No comments. You can be first!

Leave a comment

You must be logged in to comment.