borderAndreaVB free resources for Visual Basic developersborder

borderAndreaVB Visual Basic and VB.NET source code resources - Copyright © 1999-2008 Andrea Tincaniborder

AndreaVB | Forum | News | Downloads | Register | Help | Member List | Statistics | Search | PM | Profile

Print This Topic
Next Topic (Progress Bar, Datagrid, Chart) New Topic New Poll Post Reply
AndreaVB Forum : VB.Net : Loops pls help
Poster Message
oakkie25
Level: Protégé

Registered: 13-03-2008
Posts: 4

icon Loops pls help

I am a newbie and having some problems with loops

I have to create a board with 16 cells in 4 regions in 2x2 grids
Which I already have, it is like a mini sudoku game, I was trying to put random numbers in 3 of the cells (the other 13 are pre-populated) everytime you hit the new game button, currently progamhas all cells blank and only randomly places 3-4 numbers in the boards.......so
since the assignment says I only need five valid boards with 13 cells pre-populated and 3 blanks I was thinking to pre-create the 5 boards and somehow loop them everytime the new game button hit it would put up one of the 5 boards... I have no idea how I would do this... any help would be greatly appreciated.
code below for random numbers in the cells but none are prepopulated....
#Region "Declared Variables"


#End Region

    Private Sub Reset()
        Dim board(4, 4) As Integer
        NewGame = board
        Button1.Text = ""
        Button2.Text = ""
        Button3.Text = ""
        Button4.Text = ""
        Button5.Text = ""
        Button6.Text = ""
        Button7.Text = ""
        Button8.Text = ""
        Button9.Text = ""
        Button10.Text = ""
        Button11.Text = ""
        Button12.Text = ""
        Button13.Text = ""
        Button14.Text = ""
        Button15.Text = ""
        Button16.Text = ""


    End Sub

    Private Sub NewGamebtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NewGamebtn.Click

        Dim RandomNumber As Integer
        Dim x As Integer
        Dim y As Integer

        Reset()
        For x = 1 To 4

            RandomNumber = 1 + CInt(Rnd() * 16)
            Select Case RandomNumber
                Case 1
                    If Button1.Text = "" Then
                        Button1.Text = x.ToString
                        NewGame(0, 1) = x

                    Else
                        x = x + 1
                        y = y + 1
                    End If
                Case 2
                    If Button2.Text = "" Then
                        Button2.Text = x.ToString
                        NewGame(0, 2) = x

                    Else
                        x = x + 1
                    End If
                Case 3
                    If Button3.Text = "" Then
                        Button3.Text = x.ToString
                        NewGame(0, 3) = x

                    Else
                        x = x - 1
                    End If
                Case 4
                    If Button4.Text = "" Then
                        Button4.Text = x.ToString
                        NewGame(0, 4) = x

                    Else
                        x = x - 1
                    End If
                Case 5
                    If Button5.Text = "" Then
                        Button1.Text = x.ToString
                        NewGame(1, 1) = x

                    Else
                        x = x - 1
                    End If
                Case 6
                    If Button6.Text = "" Then
                        Button6.Text = x.ToString
                        NewGame(1, 2) = x

                    Else
                        x = x - 1
                    End If
                Case 7
                    If Button7.Text = "" Then
                        Button7.Text = x.ToString
                        NewGame(1, 3) = x

                    Else
                        x = x - 1
                    End If
                Case 8
                    If Button8.Text = "" Then
                        Button8.Text = x.ToString
                        NewGame(1, 4) = x
                    Else
                        x = x - 1
                    End If
                Case 9
                    If Button9.Text = "" Then
                        Button9.Text = x.ToString
                        NewGame(2, 1) = x
                    Else
                        x = x - 1
                    End If
                Case 10
                    If Button10.Text = "" Then
                        Button10.Text = x.ToString
                        NewGame(2, 2) = x
                    Else
                        x = x - 1
                    End If
                Case 11
                    If Button11.Text = "" Then
                        Button11.Text = x.ToString
                        NewGame(2, 3) = x
                    Else
                        x = x - 1
                    End If
                Case 12
                    If Button12.Text = "" Then
                        Button12.Text = x.ToString
                        NewGame(2, 4) = x
                    Else
                        x = x - 1
                    End If
                Case 13
                    If Button13.Text = "" Then
                        Button13.Text = x.ToString
                        NewGame(3, 1) = x
                    Else
                        x = x - 1
                    End If
                Case 14
                    If Button14.Text = "" Then
                        Button14.Text = x.ToString
                        NewGame(3, 2) = x
                    Else
                        x = x - 1
                    End If
                Case 15
                    If Button15.Text = "" Then
                        Button15.Text = x.ToString
                        NewGame(3, 3) = x
                    Else
                        x = x - 1
                    End If
                Case 16
                    If Button16.Text = "" Then
                        Button16.Text = x.ToString
                        NewGame(3, 4) = x
                    Else
                        x = x - 1
                    End If
            End Select
        Next x
    End Sub
End Class

13-03-2008 at 03:19 PM
View Profile Send Email to User Show All Posts | Quote Reply
stickleprojects
Level: Moderator


Registered: 09-09-2002
Posts: 1015
icon Re: Loops pls help

Just to clarify:
You have supplied code that populates 3 of 16 squares based on a random number.
You have stated that you need to randomly place 3-4 numbers on the board.
Can you rephrase what your problem is please? Start the sentence like:

I need to do xxx under these yyyy conditions.

Also,
your problem is not loop-specific - I read this thinking you wanted help in how to create a loop in vb.net, so change the subject too

Regards


____________________________
Build it better, faster, quicker, easier.. then fix it (non-offical MS mission statement)

17-03-2008 at 06:36 PM
View Profile Send Email to User Show All Posts | Quote Reply
oakkie25
Level: Protégé

Registered: 13-03-2008
Posts: 4
icon VB.NET help with code

The code I supplied only fills in 3 squares randomly each time I hit the new game button
I need the program to fill in 13 cells and leave 3 blank.
Each time the new game button is pushed a new board appears. It also has to be a valid board each time.
Remember this is not a 9x9 grid it is meant for us beginners so it is only a 4x4 grid.

I was thinking of pre generating 5 valid bds, maybe using arrays, But running into problems with that also.

oakkie

18-03-2008 at 01:01 AM
View Profile Send Email to User Show All Posts | Quote Reply
stickleprojects
Level: Moderator


Registered: 09-09-2002
Posts: 1015
icon Re: Loops pls help

HI,
Lets break the problem down into pieces and deal with those.

1. Hold 16 integer values between 0 and 9
2. Display 16 integer values in a 4x4 grid
3. Each integer value adheres to a valid rule (to be defined as Sudoku rule or some such)
4. Only values that adhere to the Sudoku rules can be stored.
5. Allow the user to enter an integer value for any of the 16 positions, providing that rule 4 is still enforced.

Looking at the plural nouns in this explanation, there appear to be more than one VALUE (rules 1 & 2), but each is to be treated seperately (as implied by rules 3 & 4), therefore we need many VALUE items.
Many of 1 thing = Array

There is only 1 rule for the display (rule 2) so ignore display for the moment, but we're probably dealing with an Array type structure anyway for display.

The code to create an array in VB is:

Dim any_old_name() as data_Type


Start a new EXE project
Add a single textbox to the default form, and name it "txtValue"
change it's index to 0
Copy and paste this textbox 16 times, to give you 16 textboxes
Position the textboxes in a grid so that they are numbered 1-4 in the first row, 5-8 in the second, and so forth
Set the visible property of txtValue with index of 0 to false
view the code designer for the default form.

In the form declarations section enter the following:

Dim m_Values(16) as Integer

Rule 1 states that it must hold 16 integers, hence the numbers 16 (places to hold information) and Integer (what type of information to hold).


Rule 3 indicates that some business logic will be needed to determine what values may be stored where within our array, so lets put a skeleton function that will check this rule for us. Enter the following code into the form:

private function SudokuRuleOk (intNewValue as Integer, intPosition as integer) as boolean
' Returns TRUE if the business rule has been satisfied
' Until we find out the full rules, just return True
' intNewValue is the value to put into the values array
' intPosition is where to put the value

    SudokuRuleOk = true
end function


.. and in good modular programming style, a function to check the business rule before setting the value...

private function SetValue (intNewValue as Integer, intPosition as integer) as boolean
' Rule 1 indicates what range of values are allowed
    if intNewValue < 0 or intNewValue > 9 then
        SetValue = false
    else
    if SudokuRuleOk (intNewvalue, intPosition) then
m_Values(intPosition) = intNewValue
SetValue = True
    else
SetValue = false
    end if
    end if
end function


.. and more good practice to add a GetValue routine too ...

Private Function GetValue(intPosition As Integer) As Integer
    GetValue = m_Values(intPosition)
    
End Function


At the moment, your project doesn't do very much, but there is not much left to complete (as usual, the difficulty is in the details).

Add the following skeleton functions to the form:

private sub ClearValues()
end sub
private sub GenerateValues()
end sub
private sub DisplayValues()
end sub



Now in the form_load, add the following to call these routines:

private sub Form_Load
   ClearValues
   GenerateValues
   DisplayValues
end sub



ClearValues is a small routine that initialises the values back to -1 (-1 is invalid), key in the revised code:

private sub ClearValues
   dim intIndex as integer
  
   for intIndex = 1 to 16
   ClearValue(intIndex)
   next intIndex
end sub
Private Sub ClearValue(intIndex As Integer)
    m_Values(intIndex) = -1
End Sub
Private Function ValueIsClear(intIndex As Integer) As Boolean
    If m_Values(intIndex) = -1 Then ValueIsClear = True
End Function


DisplayValues lets the user "see" the grid and quite straightforward, key in the revised code

Private Sub DisplayValues()
   Dim intIndex As Integer
   Dim intTextBoxIndex As Integer
  
   For intIndex = 1 To 16
        intTextBoxIndex = GetTextBoxIndexFromValueIndex(intIndex)
        
        If ValueIsClear(intIndex) = False Then
            Me.txtValue(intTextBoxIndex).Text = m_Values(intIndex)
        Else
            Me.txtValue(intTextBoxIndex).Text = ""
        End If
   Next intIndex
End Sub

Private Function GetTextBoxIndexFromValueIndex(intIndex As Integer) As Integer
    GetTextBoxIndexFromValueIndex = intIndex
End Function
Private Function GetValueIndexFromTextBoxIndex(intIndex As Integer) As Integer
    GetValueIndexFromTextBoxIndex = intIndex
End Function



The DisplayValues will not display invalid values, so our initial grid will be blank on screen until we generate values for it. I've also added the helper functinos to convert between the array index and the textbox on screen.
These are trivial helper functions at the moment, but we'll get to that later.. suffice to say, it's good practice

The following implementation of GenerateValues tries random valid numbers against the business rule (sudoku) and if successful, stores the value in the array

private sub GenerateValues
dim intIndex as integer
dim intValue as integer
dim intNumberOfTries as integer

Randomize

' Loop through the positions in the array
for intindex = 1 to 16

' Make sure we don't have an infinite loop, by counting the number of times
' we tried to put a value in
intNumberOfTries = 0
do

' Get the next value to try (between 0 and 9)
intValue = GetRandomValue(0,9)

' Increment the number of times we've tried
intNumberOfTries = intNumberOfTries +1

' Repeat the loop until SetValue succeeds, or we run out of tries
loop until (SetValue (intValue, intIndex) = True) or intNumberOfTries > 100

if intNumberOfTries >= 100 then
msgbox "GenerateValues aborted. Couldn't find a value for position " & intIndex
exit sub
end if
next

end sub

Private Function GetRandomValue(intMin As Integer, intMax As Integer) As Integer
    Dim intValue As Integer
    

    intValue = CInt((intMax - intMin) * Rnd + intMin)
    
    GetRandomValue = intValue
End Function


TIP: I've put some code in (intNumberOfTries) to stop the loop continuing forever. You should always do this if your loop doesn't have a fixed number of execution times

If you run your project now, you should see your form, with 16 textboxes on it with numbers in between 0 and 9 (ish).

Now, part of the spec was to randomly clear out some of these values for the user to complete.

so add the following function, and modify the form_load to call it before display
private sub RandomlyClearSomeValues (intHowManyToClear as integer)
dim intIndex as Integer
dim intNumberCleared as integer
dim intNumberOfTries as integer

intNumberCleared=0
do while (intNumberCleared < intHowManyToClear) and (intNumberOfTries < 100)

' Get a  random number between 0 and 16
intIndex = GetRandomValue (1,16)

' If its not already cleared
if ValueIsClear(intIndex)=false then

ClearValue (intIndex)
intNumberCleared = intNumberCleared+1
intNumberOfTries = 0
else
intNumberOfTries = intNumberOfTries+1
end if


loop

if intNumberOfTries >= 100 then
msgbox "RandomlyClearSomeVAlues aborted. infinite loop!
end if

end sub

Private Function ValueIsClear(intIndex As Integer) As Boolean
    If m_Values(intIndex) = -1 Then ValueIsClear = True
End Function

Private Sub Form_Load()
   ClearValues
   GenerateValues
   RandomlyClearSomeValues 3
   DisplayValues
End Sub



At the moment, the user can type any old number/text into each text box, so we should tell them when something is wrong.
To detect when a user has changed a value you should use the validate event on the textbox, so add the following code, to check the value and tell the user if they are incorrect:


Private Sub txtValue_Validate(Index As Integer, Cancel As Boolean)
    Dim intValue As Integer
    Dim strUserText As String
    Dim intIndex As Integer
    
    strUserText = Me.txtValue(Index).Text
    
    ' Translate the index of the textbox into the position in the array
    intIndex = GetValueIndexFromTextBoxIndex(index)
    
    ' If the user has entered some text
    If Len(strUserText) > 0 Then
        
        If IsNumeric(strUserText) Then
            intValue = CInt(strUserText)
        Else
            MsgBox "You must enter a number"
            Cancel = True
            Exit Sub
        End If
        
        
        ' Tell them if they are wrong
        If SetValue(intValue, Index) = False Then
            MsgBox "You cannot put that value there!"
            Cancel = True
        End If
    Else
        ClearValue (intIndex)
    End If
    
    
    
    
End Sub


Nearly there. The only remaining implementation is to populate the empty function SudokuRuleOk

The following functions should help:

Private Function GetRowIndexFromArrayIndex(ByVal intIndex As Integer, ByVal intColsPerRow As Integer) As Integer
    Dim intRow As Integer
    Dim intRemainder As Integer
    
    intIndex = intIndex - 1
    
    ' Get the remainder after the division
    intRemainder = intIndex Mod intColsPerRow
    ' Remove the remainder, means that index is now in "rows"
    intIndex = intIndex - intRemainder
    
    intRow = intIndex / intColsPerRow
    
    GetRowIndexFromArrayIndex = intRow
End Function

Private Function GetColIndexFromArrayIndex(ByVal intIndex As Integer, ByVal intColsPerRow As Integer) As Integer
    Dim intCol As Integer
    Dim intRow As Integer
        
    intRow = GetRowIndexFromArrayIndex(intIndex, intColsPerRow)
    intCol = intIndex - (intColsPerRow * intRow) - 1
    
    
    GetColIndexFromArrayIndex = intCol
End Function


They return a zero-based number to indicate the row or col (ie. the first row is rowindex 0, first col is colindex 0)

You should be able to use these functions from within the SudokuRuleOk routine to determine whether the value is correct or not.
I've implemented 1 of the rules for you.

Private Function SudokuRuleOk(intNewValue As Integer, intPosition As Integer) As Boolean
' Returns TRUE if the business rule has been satisfied
' Until we find out the full rules, just return True
' intNewValue is the value to put into the values array
' intPosition is where to put the value

    Dim intRow As Integer
    Dim intCol As Integer
    Dim blnOk As Boolean
    
    intRow = GetRowIndexFromArrayIndex(intPosition, 4)
    intCol = GetColIndexFromArrayIndex(intPosition, 4)
    blnOk = True
    
    ' First rule, value cannot already be in row or col
    ' Find the value in the array
    Dim intValueFound As Integer
    Dim intFRow As Integer
    Dim intFCol As Integer
    Dim intIndex As Integer
    
    If blnOk Then
        For intIndex = 1 To 16
            intValueFound = GetValue(intIndex)
            If intNewValue = intValueFound Then
                intFRow = GetRowIndexFromArrayIndex(intIndex, 4)
                intFCol = GetColIndexFromArrayIndex(intIndex, 4)
                
                If intFRow = intRow Or intFCol = intCol Then
                    blnOk = False
                    Exit For
                End If
                
            End If
        Next
    End If
    
    If blnOk Then
        ' Check another rule
    End If
    
    SudokuRuleOk = blnOk
    
End Function



Hope this helps
Kieron


____________________________
Build it better, faster, quicker, easier.. then fix it (non-offical MS mission statement)

19-03-2008 at 09:15 AM
View Profile Send Email to User Show All Posts | Quote Reply
oakkie25
Level: Protégé

Registered: 13-03-2008
Posts: 4
icon Re: Loops pls help

Yes this helps alot, thanks!
I was going about it a totally different way since my last code didn't work, I was trying to use arrays to pregenerate 5 boards with 13 cells filled in and 3 blank and everytime the "new game" button was  hit a new pregenerated bd pops up! I am going to check out the code you showed me because I am not having much luck with the arrays either.

Thanks again you were a big help!

oakkie

19-03-2008 at 08:03 PM
View Profile Send Email to User Show All Posts | Quote Reply
oakkie25
Level: Protégé

Registered: 13-03-2008
Posts: 4
icon Re: Loops pls help

I do have 2 questions can I use buttons instead of Textboxes?
I tried naming it btnValue instead of textValue and it gives error stating it is not part of the form?

and also how do I incorporate the "new game button" in the code so when I hit the new game button a new game pops up with 13 pre-populated cells and 3 blank ones

note: my game only calls for numbers 1- 4 which I already changed in the code

21-03-2008 at 12:34 AM
View Profile Send Email to User Show All Posts | Quote Reply
AndreaVB Forum : VB.Net : Loops pls help
Next Topic (Progress Bar, Datagrid, Chart) New Topic New Poll Post Reply
Surf To:


Not Logged In? Username: Password: Lost your password?
Partners: Il portale per lui e lei | Download Actual Software | Free Software Download
borderAndreaVB free resources for Visual Basic developersborder

borderAndreaVB Visual Basic and VB.NET source code resources - Copyright © 1999-2008 Andrea Tincaniborder