Go Back  Xtreme Visual Basic Talk > Visual Basic .NET (2002/2003/2005/2008, including Express editions) > .NET Game Programming > Pig Dice game


Reply
 
Thread Tools Display Modes
  #1  
Old 04-18-2012, 03:55 PM
ndegner ndegner is offline
Newcomer
 
Join Date: Apr 2012
Posts: 4
Default Pig Dice game


Hello, Trying to help my son on programming assignment without having any real experience in vb. I guess I don't understand subroutines that well. When the program runs it never goes to the computer's turn and does not update the users score either. This assignment is already in but would like to know what is going wrong. Using VB 2010, and this is windows application. Thanks.
Code:
Public Class Form1
    Dim Myturn As Integer
    Dim Computerturn As Integer
    Dim Dice1 As New Random
    Dim Dice2 As New Random
    Dim Die1 As Integer
    Dim Die2 As Integer
    Dim Mycount As Integer = 0
    Dim Computercount As Integer = 0
    Dim Rollagain As Integer
    Dim ComRoll As New Random
    Dim ComRoll2 As Integer

    Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged

    End Sub

    Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles xTurn.TextChanged
        Myturn = Val(xTurn.Text)
        If Myturn = 1 Then Myroll()
        If Myturn = 0 Then Computersroll()

    End Sub

    Private Sub Myroll()
        Die1 = Dice1.Next(1, 7)
        Die2 = Dice2.Next(1, 7)

        If Die1 = 1 And Die2 = 1 Then
            Mycount = 0
            Call Computersroll()

        End If
        If Die1 = 1 Or Die2 = 1 Then
            Call Computersroll()

        End If
        Mycount = Mycount + Die1 + Die2
        xUsersscore.Text = Mycount

        If Mycount >= 100 Then xWinner.Text = "You Win"


        If Mycount < 100 Then Prompt = "Enter 1 for user to roll again or 0 for computer to roll"

        Rollagain = Val(Answer)
        Rollagain = Val(xRollagain.Text)
        If Rollagain = 1 Then Myroll()
        If Rollagain = 0 Then Computersroll()




    End Sub
    Private Sub Computersroll()
        Die1 = Dice1.Next(1, 7)
        Die2 = Dice2.Next(1, 7)

        If Die1 = 1 And Die2 = 1 Then
            Computercount = 0
            Call Myroll()
            If Die1 = 1 Or Die2 = 1 Then
                Call Myroll()

            End If
            Computercount = Die1 + Die2
            xComputersscore.Text = Computercount

            If Computercount >= 100 Then xWinner.Text = "Computer Wins"

            If Computercount < 100 Then
                ComRoll2 = ComRoll.Next(0, 2)
                If ComRoll2 = 1 Then Myroll()
                If ComRoll2 = 0 Then Computersroll()

            End If
            
            
        End If

    End Sub
   
End Class

Last edited by passel; 04-18-2012 at 05:15 PM.
Reply With Quote
  #2  
Old 04-18-2012, 05:33 PM
passel's Avatar
passel passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,883
Default

Well the logic doesn't make a lot of sense to me, and because the two routines are setup to randomly call either themselves, or the other routine, you have a recursive situation where the routines are repeatedly calling themselves and probably never have a chance to exit the subroutine.
If you don't exit the subroutines VB doesn't have a chance to "breath" (respond to events), so it can't do things like update the text boxes so you can see what is happening.

I assume that as soon as you make a change to the xTurn textbox, the program just appears to hang and not respond to anything. That is because the code is cycling endlessly between the two routines, drilling themselves deeper and deeper into a programming hole, so it can't respond to mouse inputs, keyboard inputs, or update its display.
Eventually, if left running long enough, it should crash with an "out of stack space" error.

{edit}:By the way, I did modify the code to use a timer to step the game.
You would put a 0 or 1 in the textbox to kick it off. The change event would start the timer.
The timer would copy the value from the textbox and set the textbox to -1 (nobody's move).
If the value the timer copied was a 0 it would call the computersRoll, or if the value was 1 it would call the UsersRoll.

The code in each of the rolls was simplified to roll the dice, and if the values were 1 and 1, reset the score and set the textbox to the other players Id (0 or 1), so the next time the timer fired, it would see the value and call the appropriate player to roll.

Else, if the dice were not 1 and 1, then it would update the score and then (since I wasn't sure how you were doing the prompt thing), I just duplicated the "flip a coin" code in both players to randomly decide who would roll next (updating the textbox again so the timer would see it and call the appropriate player to roll).

It worked Ok, but I noticed that after many games, that the computer never won, and in fact its score always had a low accumlation compared to the "human" player.
It was then I noticed an error in the logic of the computer roll logic, so you might want to be on the lookout for that.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 04-18-2012 at 06:16 PM.
Reply With Quote
  #3  
Old 04-19-2012, 03:52 PM
ndegner ndegner is offline
Newcomer
 
Join Date: Apr 2012
Posts: 4
Default

Hello, Thank you for your reply. Looks like I really don't have a clue at this point in what I am doing with this program. The program does operate pretty much the way you indicated because I do run out of stack space. Not even sure how to make your corrections work. Thanks again.
Reply With Quote
  #4  
Old 04-19-2012, 04:41 PM
passel's Avatar
passel passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,883
Default

Windows programming is an "events" based environment. Everything happens because some event occurred, and notification of that event is sent to the application that it is associated with through a message interface.
Most of the time, we're not directly involved with the message handling. VB will process the message, and in turn, pass the message on to the control, and the control may raise a control event, and if we have code written in an event handler for that control's event, our code will be called.
The Graphical User Interface (GUI), is a single thread of execution. While the code we've written is executing, no other GUI related things can happen.
If we change the text property of a label or textbox, etc. then the need to "repaint" the control to reflect the change in the property will need to be done, and that will be done the next time the GUI thread can process messages, and see a "paint" message from windows for that control. The control can then update the area of the screen it is responsible for.
If your code in the event handler never finishes the one event that started the ball rolling, then no other events can happen (in the GUI thread), so no fields will update, and the display is "hung".

I don't know that I would have used the TextChanged event to kick this thing off, since every character typed, or erased will cause a TextChange event.
Most likely, it would be cleaner to have two buttons to select who rolls first, one for the human, and one for the computer.
When you click on either one, you should probably disable both (so they can't be reclicked while you're processing).
Let's assume you want the user to control the speed of the game.
It also looked like you wanted the capability of the user to be able to "pass" the dice on to the computer without rolling.
The computer, on the other hand, would either keep the roll, or pass it based on a "flip of a coin".
So, once you selected who goes first (and the buttons are disabled), you would call the appropriate Roll procedure for who was selected.
The roll procedure should just roll once, process the roll, and then note whose turn it is to roll next.
If it the computers turn, then enable the computer's button before leaving the roll sub.
If it the users turn, then enable both buttons, so the user has the choice of either rolling, or passing the roll to the computer.
That is about all there is to that.
If one of the players, wins, then display that, and if a new game is desired, reset the scores, reenable the two buttons, and you're ready to go again.

If you want the game to autoplay, I'm assuming the "auto" play would only be on the computer side. The human player would still want the opportunity to roll or pass when it is his turn.
So, in auto mode, you would turn the timer on whenever it was the computer's turn. You would have a variable indicating whose turn it is that the timer could examine.
If it is the human players turn, the timer would either do nothing, or the timer could also be stopped while it is the human's turn.
The timer would just be re-enabled when it was the computers turn.

If you wanted fully automated, where the human didn't have to interact, other than select who rolls first, then you would have the human's roll sub do the "coin flip" instead of re-enabling buttons, and the timer would call either player's roll procedure, based on whose turn it was.

Coding it that way, so that you get an event, process the event, and then leave the event handler, allows the GUI to process messages "between the events" and generate the higher level events to redraw the controls, and process timer ticks.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #5  
Old 04-19-2012, 05:52 PM
ndegner ndegner is offline
Newcomer
 
Join Date: Apr 2012
Posts: 4
Default

Hello and thanks again. This is a lot more complex than I thought. I can get the program to work in old Quickbasic but those days of its use are apparently long gone. Does this sort of program at this beginning level need to be done as a Console program and not a windows application? My son's class is an introductory programming class for those who never had programming and is the only programming class he has to take. My classes years ago in Basic, Fortran, Paschal and C apparently do not prepare me for visual basic. I will have to read further to understand the timer application. I am not even sure how to fix up the code and need to learn what the timer app is. Thanks again.
Reply With Quote
  #6  
Old 04-19-2012, 09:32 PM
passel's Avatar
passel passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,883
Default

Edit by passel: Note that I was unfamiliar with the game Pig Dice when I wrote this.
The code in this post was based on the logic that was inferred from the first post.
Being curious, I did a web search and read the wikipedia entry on Pig Dice.
The code here is a partial implementation, not the complete logic necessary for the 2-dice variation of Pig Dice.
Anyone assuming that this is an implementation of the game would be mistaken.
Just a heads up.


Well, the timer based one I made was just a quick hack based on the code you had, so I guess I could zip it up and attach it, although it is not as refined as I described above.
But it is on another computer so will have to wait.

But, on this computer I went ahead and made a quick version along the lines I mentioned, that depends on the user to press the buttons for each roll of the dice, so doesn't involve a timer.
Perhaps you can see how the logic of this code works, which is more along the lines of causing an event (press the button), process the event (roll the dice, process the roll, and exit the handler, waiting for the next event. I'll paste the code so people don't have to download the game if they just want to look at the code.
Code:
Public Class Form1
  Dim RndNumb As New Random
  Dim Die1 As Integer
  Dim Die2 As Integer
  Dim Mycount As Integer = 0
  Dim Computercount As Integer = 0
  Dim Rollagain As Integer
  Dim ComRoll2 As Integer

  Private Sub RollDice()
    Die1 = RndNumb.Next(1, 7)
    Die2 = RndNumb.Next(1, 7)
    xDie1.Text = Die1
    xDie2.Text = Die2
  End Sub

  Private Sub Myroll()
    RollDice()
    If Die1 = 1 And Die2 = 1 Then      'If I rolled double 1's then
      Mycount = 0                      '  Reset my score
      btnComputerRoll.Enabled = True   '  Only enable computers button
    Else
      Mycount += Die1 + Die2
      If Mycount >= 100 Then
        xWinner.Text = "You Win"
        pnlPlayAgain.Show()            '  Show the play Again and Quit buttons 
      Else                             'Player gets to roll again, if he want's
        EnableRollButtons()            'Enable both buttons so player can choose to roll again or pass to the computer
      End If
    End If
    xUsersscore.Text = Mycount         'Update the score readout
  End Sub

  Private Sub Computersroll()
    RollDice()

    If Die1 = 1 And Die2 = 1 Then
      Computercount = 0              'Reset the computer's score
      EnableRollButtons()            'Enable both buttons so player can choose to roll again or pass to the computer

    Else                             'Didn't roll double ones, so computer gets to choose to roll again or have the user roll
      Computercount += Die1 + Die2
      If Computercount >= 100 Then
        xWinner.Text = "Computer Wins"
        pnlPlayAgain.Show()               '  Show the play Again and Quit buttons 
      Else                                'Computer gets to roll again, if he want's
        ComRoll2 = RndNumb.Next(0, 2)     'Make a choice
        If ComRoll2 = 1 Then              'If the player has to roll
          BtnHumanRoll.Enabled = True     '  Force the player to roll (don't enable the computer button)
        Else                              'Else
          btnComputerRoll.Enabled = True  '  Only allow the computer to roll
        End If
      End If
    End If
    xComputersscore.Text = Computercount  'Update the score readout

  End Sub

  Private Sub DisableRollButtons()
    BtnHumanRoll.Enabled = False
    btnComputerRoll.Enabled = False
  End Sub

  Private Sub EnableRollButtons()
    BtnHumanRoll.Enabled = True
    btnComputerRoll.Enabled = True
  End Sub

  Private Sub BtnHumanRoll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnHumanRoll.Click
    DisableRollButtons()
    Myroll()
  End Sub

  Private Sub btnComputerRoll_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnComputerRoll.Click
    DisableRollButtons()
    Computersroll()
  End Sub

  Private Sub btnPlayAgain_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPlayAgain.Click
    pnlPlayAgain.Hide()
    Mycount = 0
    Computercount = 0
    xUsersscore.Text = 0
    xComputersscore.Text = 0
    xDie1.Text = ""
    xDie2.Text = ""
    xWinner.Text = ""
    EnableRollButtons()
  End Sub

  Private Sub btnQuit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnQuit.Click
    Me.Close()
  End Sub
End Class
Attached Files
File Type: zip PigDiceVer1.zip (16.4 KB, 27 views)
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 04-20-2012 at 09:20 AM.
Reply With Quote
  #7  
Old 04-22-2012, 07:57 PM
ndegner ndegner is offline
Newcomer
 
Join Date: Apr 2012
Posts: 4
Default

Hello passel,

Thank you for all your help. When you get into your 60s it takes awhile for things to sink in. I am going to work through this with your updated code. I have several VB books here and am slogging through them and gaining insight. Your statement about the windows enviroment being events based definetly struck a cord.
Thanks again.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
 
 
-->