I was wondering how to create a simple high scores form for the Card Sharks game I am creating?
I wish to use the top ten scores in order by name, dollar amount, and date, with the highest accumulated dollar amount being #1 in rank, all the way down to the bottom of the top ten (being the #10 highest score).
The champion's name is identified as gstrChampName. The champion's dollar total will be identified as lngChampWinnings (as it could exceed 5 figure dollar totals). When the game is won, the date (denoted by GameDate) will be recorded as Now. If I were to carry the gstrChampName, lngChampWinnings, and GameDate over to future games, how do I do that in the Leaderboard form I am developing?
The way things are going with the game, I can sense a release of the game to select online buddies by July.
Seeing as this need will span multiple sessions and dates,
it seems to me that you will need a "database" to store
the results, where the database could be a simple text file.
When you app loads, you could "unload" the file into an array.
When appropriate (ie, a current score makes it into the top-10), you'd "insert"
it into the array (score, name, date, etc).
You would then immediately "download" the array the the file (ie, overwrite it).
If deemed necessary, the text file could even be encrypted
Does that work for you?
Can you take if from here?
Spoo, that does sound like a good idea. How do I code this type of form?
I created the text file just now, and its filename is "TopTen".
Here are the contents of the text file:
Player 1,125000,6/12/2010
Player 2,100000,6/11/2010
Player 3,80000,6/10/2010
Player 4,60000,6/9/2010
Player 5,50000,6/8/2010
Player 6,45000,6/7/2010
Player 7,40000,6/6/2010
Player 8,35000,6/5/2010
Player 9,30000,6/4/2010
Player 10,25000,6/3/2010
The player name would appear in the first column, the player's dollar amount would appear in the second column, and the date that high score was achieved appears in the third column.
Also, I plan on using returning champions in this game. How do I save the information (just the player name and the previous winnings amount) so that it can be carried over to the next playing of the game?
This code frag will read your textfile into an array
Code:
Dim aaTop10(10, 3) As String
Dim aaE() As String
Dim fName1 As String
' read from txt file
fName1 = "JonSea.txt" ' change as necessary
Open fName1 For Input As #1
aaE = Split(Input(LOF(1), 1), vbCrLf)
Close #1
' populate Top10 array
For ii = 0 To 9
v0 = Split(aaE(ii), ",")
For jj = 0 To 2
aaTop10(ii + 1, jj + 1) = v0(jj)
Next jj
Next ii
Note: I have elected to dim aaTop10 such that
"row" 1 is the top one. This is a little wasteful, as
"row" 0 remains Empty, and "col" 0 of each row
likewise remains Empty. Modify per your preferences.
A very simple idea is to put data in a database file like .mdb file having fields Name, Amount, Date. Add a new record as per new entry. Sort the data in descending order on Amount after adding a new entry. Check if records are more than 10, if yes, delete extra records after 10th record. in this way always Top 10 records will be there having Top Most Scorer as first record.
Just to clarify, when I use the array of Top10(1,2), for example, does this mean it retrieves the information from row #1 and column #2 and displays it in a text label?
Last edited by JonSea31; Jun 14th, 2010 at 08:18 AM.
Just to clarify, when I use the array of Top10(1,2), for example, does this mean it retrieves the information from row #1 and column #2 and displays it in a text label?
How you reference it depends on how you set it up and how you added data to it. As a rule of thumb, the "rows" are the right side dimension and columns the left side (contrary to your description). Only the far right-side can be resized with a ReDim Preserve statement.
Edited: Think of a 2D array like an Excel spreadsheet: First dimension are columns and 2nd are rows. For a 3D, think again of Excel: 1st dimension are worksheet tabs, 2nd dimension are columns within that tab, and 3rd dimension are rows within that tab. This is how I first associated multidimensional arrays so my mind didn't get foggy.
Last edited by LaVolpe; Jun 14th, 2010 at 01:26 PM.
Insomnia is just a byproduct of, "It can't be done"
All kidding aside, I honestly think it's easier to think of
array dimensions in a similar R1C1 sequence.
EDIT
Could it be one of those different strokes for ... situations?
Spoo
Absolutely.
However, think about it. In majority of the cases, if you are going to resize a 2D array, the number of columns are known in advance, only the rows increase/decrease. Since you can only ReDim Preserve the far right, it is more common to think of it the way I described; adding rows not columns.
FYI: Multidimensional array memory is layed out the way I described too:
col0row0, col1row0, col2row0
col0row1, col1row1, col2row1
col0row2, col1row2, col2row2
This is why you can only ReDim the far right side (rows).
But, different strokes for different folks.
Insomnia is just a byproduct of, "It can't be done"
The code works perfectly, but I get a weird order that shouldn't prevail:
1. Player 2, $100,000
2. Player 3, $80,000
3. Player 4, $60,000
4. Player 5, $50,000
5. Player 6, $45,000
6. Player 7, $40,000
7. Player 1, $125,000 <== highest score, and should be ranked #1.
8. Player 8, $35,000
9. Player 9, $30,000
10. Player 10, $25,000
The highest score in the text file should be ranked #1, not #7. Player 2 through Player 7 (inclusive) should be ranked #2 through #7 respectively. Everything else on the bottom of the Top Ten list is okay.
Is there any way I could arrange the Top Ten list by score (in this case, in descending order from highest score (#1) to lowest score (#10) in the Top Ten list?
Now, re ranking being screwed up. We have entered the
next level. You will need to introduce a sorting algorithm
do deal with the array as it gets modified.
If you do a Search this Forum, you should find a ton of stuff.
The easiest, a Bubble Sort, should be appropriate for such a
small array. Holler if you need some further help
Spoo, here is the code I have thus far for the leaderboard:
Code:
Option Explicit
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" ( _
ByVal hWnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long) As Long
Private Sub Form_Load()
GetInfo
End Sub
Private Sub GetInfo()
Dim i As Integer, j As Integer
Dim v() As String
Dim aaTop10(10, 4) As String
Dim aaE() As String
Dim fName1 As String
' read from txt file
fName1 = "TopTen.txt" ' change as necessary
Open fName1 For Input As #1
aaE = Split(Input(LOF(1), 1), vbCrLf)
Close #1
' populate Top10 array
For i = 0 To 9
v = Split(aaE(i), ",")
For j = 0 To 2
aaTop10(i + 1, j + 1) = v(j)
Next j
Next i
For i = 1 To 10
lblPos(i - 1) = aaTop10(i, 1)
lblName(i - 1) = aaTop10(i, 2)
lblScore(i - 1) = "$" & aaTop10(i, 3)
Date(i - 1) = aaTop10(i, 4)
Next
End Sub
BTW, I added a new field where the rank would display in the lblPos.
Now, I'd like to know, how would I go about sorting the contents of the text file in order by lblPos (from lowest number to highest number)?
OK, I've reconsidered your situation, and now feel
that there is no need to do any sorting. Since you
will be updating the array "on demand" -- that is, with
every new score -- all I think you need to do is just to create a "slot" in the array and stick the new score in
that slot -- assuming, of course, that the new score
even makes it into the top 10.
Let's see if this does the job.
1. Per your post #3, you had this starting situation
Code:
Player 1,125000,6/12/2010
Player 2,100000,6/11/2010
Player 3,80000,6/10/2010
Player 4,60000,6/9/2010
Player 5,50000,6/8/2010
Player 6,45000,6/7/2010
Player 7,40000,6/6/2010
Player 8,35000,6/5/2010
Player 9,30000,6/4/2010
Player 10,25000,6/3/2010
2. So, seems like, per you post #19, the array will be
populated as follows (per Sub GetInfo)
aaTop10(1, 1) = "Player 1"
aaTop10(1, 2) = "125000"
aaTop10(1, 3) = "6/12/2010"
.. all the way to
aaTop10(10, 1) = "Player 10"
aaTop10(10, 2) = "25000"
aaTop10(10, 3) = "6/3/2010"
3. Say you want to "deal with" the following situation:
newName = "Player 11"
newScore = "51000"
newDate= "6/15/2010"
.. so, let's just focus on "col" 2
aaTop10(1, 2) = "125000"
aaTop10(2, 2) = "100000"
aaTop10(3, 2) = "80000"
aaTop10(4, 2) = "60000"
aaTop10(5, 2) = "50000" ... and newScore = "51000" will become (5, 2)
aaTop10(6, 2) = "45000"
aaTop10(7, 2) = "40000"
aaTop10(8, 2) = "35000"
aaTop10(9, 2) = "30000"
aaTop10(10, 2) = "25000" ... will get dropped
You could use some code similar to this:
Code:
in some other sub
Dim cNewName, nNewScore, cNewDate
cNewName = "Player 11"
nNewScore = 51000
cNewDate = "6/15/2010"
' call the new sub to insert the new info
InsertNewScore cNewName, nNewScore, cNewDate
the new sub
Sub InsertNewScore(cNewName, nNewScore, cNewDate)
' 1. test if even in top 10
botScore = Val(aaTop10(10, 2))
If nNewScore < botScore Then
Exit Sub ' ie, do nothing
End If
' 2. find "slot" for new score
For ii = 1 To 10
If nNewScore > Val(aaTop10(ii, 2)) Then
slot = ii
Exit For
End If
Next ii
' 3. create the slot
For ii = 9 To slot Step -1
aaTop10(ii + 1, 1) = aaTop10(ii, 1)
aaTop10(ii + 1, 2) = aaTop10(ii, 2)
aaTop10(ii + 1, 2) = aaTop10(ii, 3)
Next ii
' 4. put new info into the "slot" - overwrite existing info
aaTop10(slot, 1) = cNewName
aaTop10(slot, 2) = Trim(nNewScore)
aaTop10(slot, 3) = cNewDate
End Sub
The above code follows the structure of my
earlier post.
I notice that you have altered things a little,
so you'll need to do a similar alteration to
this new code.
Option Explicit
'~~~ User Defined Type
Private Type ScoreBoard
strName As String
lngScore As Long
strDate As String
End Type
Dim myScores() As ScoreBoard '~~~ Dynamic array
Dim n As Long '~~~ Holds index of the dynamic array
Private Sub Command1_Click()
n = -1
Dim FF As Integer
Dim strTemp As String
'~~~ Reading the scores from file
FF = FreeFile
Open App.Path & "\scores.txt" For Input As #FF
While Not EOF(FF)
Line Input #FF, strTemp '~~~ Eg: Player 1,125000,6/12/2010
'~~~ Increasing size of array
n = n + 1
ReDim Preserve myScores(n)
'~~~ Saving content into the array
myScores(n).strName = Split(strTemp, ",")(0)
myScores(n).lngScore = Val(Split(strTemp, ",")(1))
myScores(n).strDate = Split(strTemp, ",")(2)
Wend
Close #FF
'~~~ Now sorting the scoreboard in descending order(Linear Sort)
Dim i As Long, j As Long
Dim tempScore As ScoreBoard
For i = LBound(myScores) To UBound(myScores) - 1
For j = i + 1 To UBound(myScores)
If myScores(i).lngScore < myScores(j).lngScore Then '~~~ Descending order
tempScore.strName = myScores(i).strName
tempScore.lngScore = myScores(i).lngScore
tempScore.strDate = myScores(i).strDate
myScores(i).strName = myScores(j).strName
myScores(i).lngScore = myScores(j).lngScore
myScores(i).strDate = myScores(j).strDate
myScores(j).strName = tempScore.strName
myScores(j).lngScore = tempScore.lngScore
myScores(j).strDate = tempScore.strDate
End If
Next
Next
'~~~ Displaying the top 10 scores in immediate window
For i = 0 To 9
Debug.Print "Rank " & CStr(i + 1) & ", Score: " & myScores(i).lngScore & " - " & myScores(i).strName
Next
End Sub
....
If my post was helpful to you, then express your gratitude using Rate this Post.
And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video) My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet Social Group:VBForums - Developers from India
Akh, I used the code you supplied, and it works perfectly! Thanks!
I will have to eventually learn how to write the Champion's name and winnings to the Top Ten text file and add it to the Leaderboard form (if it beats any total displayed in the winnings column), but that will be for another thread.
Last edited by JonSea31; Jun 16th, 2010 at 06:43 PM.
If my post helped you in resolving your issue, please consider rating it. It's a way of showing your appreciation...
You can do this by clicking the Rate this post in the post that you want to rate.
Also, consider reading Spoo's method. He took much effort in explaining it to you. I think, his hardwork should be appreciated.
Good luck...
If my post was helpful to you, then express your gratitude using Rate this Post.
And if your problem is SOLVED, then please Mark the Thread as RESOLVED (see it in action - video) My system: AMD FX 6100, Gigabyte Motherboard, 8 GB Crossair Vengance, Cooler Master 450W Thunder PSU, 1.4 TB HDD, 18.5" TFT(Wide), Antec V1 Cabinet Social Group:VBForums - Developers from India