 |
 |

04-18-2012, 03:55 PM
|
|
Newcomer
|
|
Join Date: Apr 2012
Posts: 4
|
|
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.
|

04-18-2012, 05:33 PM
|
 |
Sinecure Expert
Super Moderator * Guru *
|
|
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,714
|
|
|
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.
|

04-19-2012, 03:52 PM
|
|
Newcomer
|
|
Join Date: Apr 2012
Posts: 4
|
|
|
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.
|
|

04-19-2012, 04:41 PM
|
 |
Sinecure Expert
Super Moderator * Guru *
|
|
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,714
|
|
|
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.
|

04-19-2012, 05:52 PM
|
|
Newcomer
|
|
Join Date: Apr 2012
Posts: 4
|
|
|
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.
|
|

04-19-2012, 09:32 PM
|
 |
Sinecure Expert
Super Moderator * Guru *
|
|
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 7,714
|
|
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
|
__________________
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.
|

04-22-2012, 07:57 PM
|
|
Newcomer
|
|
Join Date: Apr 2012
Posts: 4
|
|
|
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.
|
|
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
|
|
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|
|
|
|
 |
|