Making a high score

danter

Member
Joined
Mar 24, 2010
Messages
13
Programming Experience
Beginner
hi Guys,
Just quick querry,
Can you give me some advice how can i save a high score in toolstrip textbox or listbox?

thanks a lot

daniel
 
You're going to have to provide more details as the question as stated doesn't mean a lot. A ToolStripTextBox is quite different to a ListBox, so that doesn't really indicate the format of the data. Where is the data coming from? Are you saying that you want the data persisted between sessions? Please provide a FULL and CLEAR description of what you've got, how it fits into your project and what you want to happen.
 
I am working on the small game where gamers have to give a name to enter in. So the name shows up on the title of mothers form and have to be kept in a file as txt. Every new player have to be on the same list in the same file. In addition to this I want to keep the name in the file.toolstrip in the same way as some programs keep the latest used file.
Using records As StreamWriter = New StreamWriter(applicationstartup"record.txt")
 
Any reason this can't be in an xml file as that would greatly simplify adding/updating users and pulling the correct data.

Base Xml file I started with:

VB.NET:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root>
</Root>

Here's some code showing how to Load/Read/Insert/Update an Xml file.

For testing I have it using a TextBox for the UserName, a Label to show the high Score, and 2 buttons to simulate starting/stopping a game.

VB.NET:
Public Class Form1

    'Random to fake a score
    Dim rnd As New Random
    Dim userName As String
    Dim scoresDoc As XDocument
    Dim userData As XElement
    Dim highScore As Integer = 0

    Private Sub btnStartGame_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStartGame.Click
        userName = txtUserName.Text
        scoresDoc = XDocument.Load("C:\Temp\HighScores.xml")

        'Load User
        userData = (From node In scoresDoc.Descendants("User")
                       Where node.Attribute("name").Value = userName
                       Select node).FirstOrDefault

        'Set High Score if User is returning
        If userData IsNot Nothing Then
            highScore = CInt(userData.<HighScore>.Value)
            lblHighScore.Text = highScore
        End If
    End Sub

    Private Sub btnEndGame_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEndGame.Click
        Dim currentScore = rnd.Next(1, 1001)

        'Check if User exists
        If userData IsNot Nothing Then
            If currentScore > highScore Then
                'Update HighScore element
                userData.SetElementValue("HighScore", currentScore)
                MessageBox.Show("New High Score of " & currentScore.ToString() & "!")
                highScore = currentScore
                lblHighScore.Text = highScore
            End If
        Else
            'Create a user
            Dim newUser = <User name=<%= userName %>>
                              <HighScore><%= currentScore %></HighScore>
                          </User>
            scoresDoc.Element("Root").Add(newUser)
        End If

        scoresDoc.Save("C:\Temp\HighScores.xml")
    End Sub
End Class

Resulting XML file after some testing.

VB.NET:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root>
  <User name="MattP">
    <HighScore>694</HighScore>
  </User>
  <User name="JaneD">
    <HighScore>912</HighScore>
  </User>
  <User name="BillyB">
    <HighScore>481</HighScore>
  </User>
</Root>
 
If that's the case I'd suggest making a user class to keep track of Users and High scores since you'll need to rewrite the entire text file each time a high score is made. Then use a TextFieldParser to split up delimited fields in the file.

VB.NET:
Public Class User

    Private _userName As String
    Public Property UserName() As String
        Get
            Return _userName
        End Get
        Set(ByVal value As String)
            _userName = value
        End Set
    End Property

    Private _highScore As Integer
    Public Property HighScore() As Integer
        Get
            Return _highScore
        End Get
        Set(ByVal value As Integer)
            _highScore = value
        End Set
    End Property

End Class

Simplistic example using TextFieldParser to create a List(Of User) from the file and a StreamWriter to update the file whenever a user gets a new high score.

VB.NET:
Public Class Form1

    Dim rnd As New Random
    Dim highScore As Integer = 0
    Dim users As List(Of User)
    Dim curUser As User
    Const scoresFile As String = "C:\Temp\userScores.csv"

    Private Sub LoadUsersFromFile(ByVal filePath As String)
        Dim tfp As New FileIO.TextFieldParser(filePath)
        tfp.TextFieldType = FileIO.FieldType.Delimited
        tfp.Delimiters = {","}
        users = New List(Of User)
        While Not tfp.EndOfData
            Dim fields() = tfp.ReadFields
            users.Add(New User With {.UserName = fields(0), .HighScore = CInt(fields(1))})
        End While
    End Sub

    Private Sub SaveHighScoreData(ByVal filePath As String)
        Using sw As New IO.StreamWriter(filePath)
            For Each User In users
                sw.WriteLine(String.Join(",", {User.UserName, User.HighScore.ToString}))
            Next
        End Using
    End Sub

    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
        LoadUsersFromFile(scoresFile)
        curUser = (From cu In users _
                      Where cu.UserName = txtCurUser.Text
                      Select cu).FirstOrDefault

        If curUser IsNot Nothing Then
            lblHighScore.Text = curUser.HighScore
        Else
            curUser = New User With {.UserName = txtCurUser.Text, .HighScore = 0}
            users.Add(curUser)
            lblHighScore.Text = 0
        End If
    End Sub

    Private Sub btnEnd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEnd.Click
        'Fake score for game
        highScore = rnd.Next(1, 1001)
        MessageBox.Show(highScore)
        If highScore > curUser.HighScore Then
            lblHighScore.Text = highScore
            curUser.HighScore = highScore
            SaveHighScoreData(scoresFile)
        End If
    End Sub
End Class

The high scores file after a couple of run throughs.

VB.NET:
BillyB,893
JoeS,827
MattP,746
 
Hi Matt,
That is great code,
but I had a problem with:
sw.WriteLine(String.Join(",", {User.UserName, User.HighScore.ToString}))
It looks like something is missing. My compiler shows:Error 2 Comma, ')', or a valid expression continuation expected..

Thanks a lot daniel
 
Oops Visual Studio 2010 lets you shorthand it.

Try

VB.NET:
sw.WriteLine(String.Join(",", New String() {User.UserName, User.HighScore.ToString}))
 
Back
Top