Answered by:
Infinite Loop - having trouble exiting

Question
-
Howdy
I have about 5 to 10 subroutines and the program can use up to 5 subs at a time
for example
its a hockey simulator program so its starts with a faceoff routine and depending on what team wins the faceoff it can go to two seperate subs
so after i click a button it goes like this
Opening_faceoff()
runs code
Left_defense_Home()
runs code
if a player gets a shot i have 3 seperate shot subs (i.e. rwer, lwer, center)
LeftH_shot()
runs code
if save
Defensive_Away_Zone_faceoff()
away wins
Defensive_Away_Zone_RD
i think you get the idea, I tryed to count the plays by the following code everytime there is a faceoff
play = play + 1
and after the shot routines to stop the subroutines by this code
If play = 2 Then
Exit Sub
End If
assuming there could be any number of subroutines running not sure this would work
also i have a number of random number generations like the following that seem to get the program hung up on:
random_num = random.Next(1, 3)
not sure what to do
Nick
Thursday, August 23, 2007 4:48 PM
Answers
-
Hi Nick
Dealing with the last question first - once a function returns it has finished, you don't have to close it - it's as if a sub had reached the End Sub or an Exit Sub.
What you have suggested for ending the game would work fine but you don't have to use the FaceOffType - you could use some other criteria such as the number of plays, e.g.
and control the loop with something like:
Until whatever criteria you choose is met the loop, and the game, will continue.
Hope that helps.
Friday, August 24, 2007 11:49 PM -
This architecture is never going to work. Dave is correct you can't call a subroutine the calls another and then another which calls the calling routine. When you say you have several routines going at the same time you really don't. They are strung out on the stack like a string a of pearls and the stack only has so much room before it over flows.
So What to do? I think you need an archirtectural change where, when a subroutine sees that another needs to run that it pushes instructions on a queue and returns. The caller of that routine does not return until the queue is empty.
The queue could be an arraylist functioning as your stack actually
Private CallQueue as New Arraylist ' As a member Variable
So how could you implement such a thing?
Start with an arraylist and a structure. The structure might look like this
Public Structure SubCall
Public SubName as String
Public Arg1 as Object
Public Arg2 as Object
Public Arg3 as Object
end Structure
Let's say that Subroutine A decides that it Needs to call Sub Routine B with an argument value of 23
Subroutine A would do this:
Dim a as new SubCall
A.SubName="B"
A.Arg1 = 23
CallQueue.Add(S)
Return
Upon returning the caller does this: (I'm thinking a stack would be Better)
I'm going to break into pseudo so that i do write an operating system....
Dim B as SubCall
While (CallQueue.Count <> o) then
b = CallQueue.Pop
ProcessCall(b)
End While
return ' Game Over
ProcessCall( Call )
SelectCase Call.SubName
Case A
SubA(Call.Arg1)
Case B
SubB(Call.Arg1,Arg2)
'Etc
return
This is basically a smilar architecture to the message pump. And it insures no Snarls and Messy Hair.
Every thing is called by a central dispatcher in an orderly fashion.
Saturday, August 25, 2007 1:18 AM -
i think i got it
just changed
the last line to this
faceofftype = faceofftypes.final
Return faceofftype
thanks for the help everyone
Saturday, August 25, 2007 7:15 PM -
Yes, that will give you the expected result, but not for the right reasons.
In your Do loop you have lines like:
Select Case Text_Write()
End SelectThe problem lies here because you are not acting on the result.
Select Case Text_Write()
calls the function Text_Write and you should then have a list of Case statements defining what to do depending upon the result of the function call. However, all you want to do here is set the value of FaceOffType to the value returned by the function Text_Write. In that case there is no need for the Select Case at all. What you need is
FaceOffType = Text_Write()
Your solution sets FaceOffType in the function Text_Write. Having done that it is irrelevant what value is returned by the function. Although that works for now it will fail when you go to the next step.
A couple of suggestions which may help;
1. Consider turning Option Strict On, either by putting Option Strict On at the top of your code or by going to Tools | Options | VB Defaults and set it there. If you had done this you would have received a warning that the function Text_Write did not have a return type.
2. The function Text_Write appears to be a form of debugging aid. Have a look in Help for Debug.Write which may be of use. Actually, having just done that, it may be no help at all. To simplify it - Debug.Print will write whatever you specify to the Immediate window which you can view by pressing Ctrl-Alt-I. This can be very useful if you want to check on the progress of your app without interrupting it. Whenever you want to know the state of the application just insert a Debug.Print line and then you can examine the progress after the program has run.
Saturday, August 25, 2007 10:03 PM
All replies
-
Could you post your code to get a better picture of what you are doing with it?Thursday, August 23, 2007 7:27 PM
-
Its quite long but here it is:
the faceoff sub is longer but this gives u an idea
I also have many other subroutines
Private
Sub Away_Defensive_Faceoff()faceoff_home_win =
Falsefaceoff_away_win =
False If center1_fo_home = 9 And center1_fo_away = 8 Then If num_array(1) > 43 Thenfaceoff_home_win =
Truecenter1_home_taken = center1_home_taken + 1
center1_home_won = center1_home_won + 1
center1_away_taken = center1_away_taken + 1
ElseIf num_array(1) <= 43 Thenfaceoff_away_win =
Truecenter1_away_taken = center1_away_taken + 1
center1_away_won = center1_away_won + 1
center1_home_taken = center1_home_taken + 1
End If.......
If
faceoff_home_win = True And face_array(1) > 50 ThenRDH_Shot()
play = play + 1
ElseIf faceoff_home_win = True And face_array(1) <= 50 ThenLDH_Shot()
play = play + 1
ElseIf faceoff_away_win = True ThenDefense_Away_Zone_RD()
play = play + 1
End IfPrivate
Sub Defense_Away_Zone_RD() Dim rdSkate As Boolean = False Dim ld_pos_L As Boolean = False Dim rd_takes_shot As Boolean = False Dim ld_open As Boolean = False Dim ld_takes_shot As Boolean = False Dim rwerSkate As Boolean = False Dim rwerStick As Boolean = False Dim rwerQuick As Boolean = False Dim rwerskates As Boolean = False Dim rwer_passto_center As Boolean = False Dim rwer_pass_rd As Boolean = False Dim rwer_pass_center As Boolean = False Dim rwer_open As Boolean = False Dim rwer_takes_shot As Boolean = False Dim rwer_pass_lwer As Boolean = False Dim center_open As Boolean = False Dim center_pass_rwer As Boolean = False Dim center_takes_shot As Boolean = False Dim centerQuick As Boolean = False Dim centerSkate As Boolean = False Dim centerStick As Boolean = False Dim lwer_open As Boolean = False Dim lwer_pass_center As Boolean = False Dim lwer_pass_ld As Boolean = False Dim lwer_pass_rwer As Boolean = False Dim lwer_takes_shot As Boolean = False Dim rdpassto As New Random Dim centerpass As New Random Dim rdpass As Integer Dim ldpass As Integer Dim pass_D As Integerrdpass = rdpassto.Next(1, 6)
ldpass = Int((6 * Rnd()) + 1)
pass_D = centerpass.Next(1, 100)
rwer_open =
True ElseIf rd1_pa_away > rwer1_po_home Thenld_open =
True ElseIf rwer_open = False And ld_open = False ThenrdSkate =
True End If If rwer_open = True And rwer1_qk_away > lwer1_qk_home ThenrwerQuick =
True ElseIf rwer_open = True And rwer1_pc_away > lwer1_ck_home ThenrwerStick =
True ElseIf rwer_open = True And rwer1_sk_away > lwer1_sk_home ThenrwerSkate =
True ElseIf rwer_open = True And rwer1_pa_away > lwer1_po_home Thenrwer_pass_center =
True End Ifcenter_open =
True ElseIf rwerQuick = True Or rwerStick = True Or rwerSkate = True And rwer1_pa_away > rd1_po_home Thenlwer_open =
True ElseIf rwerQuick = True Or rwerStick = True Or rwerSkate = True And center_open = False Thenrwerskates =
True End If If rwer_pass_center = True Or center_open = True And center1_pa_away > rd1_po_home Thenlwer_open =
True ElseIf rwer_pass_center = True Or center_open = True And center1_qk_away > ld1_qk_home ThencenterQuick =
True ElseIf rwer_pass_center = True Or center_open = True And center1_sk_away > ld1_sk_home ThencenterSkate =
True ElseIf rwer_pass_center = True Or center_open = True And center1_pc_away > ld1_sk_home ThencenterStick =
True ElseIf rwer_pass_center = True Or center_open = True And center1_qk_away > rd1_qk_home ThencenterQuick =
True ElseIf rwer_pass_center = True Or center_open = True And center1_sk_away > rd1_sk_home ThencenterSkate =
True ElseIf rwer_pass_center = True Or center_open = True And center1_pc_away > rd1_sk_home ThencenterStick =
True ElseIf lwer_open = False And centerSkate = False And centerStick = False And centerQuick = False Thencenter_pass_rwer =
True End If If rwerskates = True Or center_pass_rwer = True And rwer1_pa_away > rd1_po_home Thenrwer_pass_lwer =
True ElseIf rwerskates = True Or center_pass_rwer = True And rwer1_pa_away > ld1_po_home Thenrwer_passto_center =
True ElseIf rwerskates = True Or center_pass_rwer = True And rd1_sh_away > rwer1_sh_away Thenrwer_pass_rd =
True ElseIf rwerskates = True Or center_pass_rwer = True And rwer_pass_lwer = False And rwer_passto_center = False And rwer_pass_rd = False Thenrwer_takes_shot =
TrueRwerA_Shot()
End Iflwer_pass_rwer =
True ElseIf lwer_open = True And lwer1_pa_away > rd1_po_home Thenlwer_pass_center =
True ElseIf lwer_open = True And ld1_sh_away > lwer1_sh_away Thenlwer_pass_ld =
True ElseIf lwer_open = True And lwer_pass_rwer = False And lwer_pass_center = False And lwer_pass_ld = False Thenlwer_takes_shot =
TrueLwerA_Shot()
End If If centerQuick = True Or centerSkate = True Or centerStick = True And center1_sh_away < rwer1_sh_away Thenrwer_takes_shot =
TrueRwerA_Shot()
ElseIf centerQuick = True Or centerSkate = True Or centerStick = True And center1_sh_away < lwer1_sh_away Thenlwer_takes_shot =
TrueLwerA_Shot()
ElseIf centerQuick = True Or centerSkate = True Or centerStick = True And center1_sh_away >= lwer1_sh_away Thencenter_takes_shot =
TruecenterA_Shot()
ElseIf centerQuick = True Or centerSkate = True Or centerStick = True And center1_sh_away >= rwer1_sh_away Thencenter_takes_shot =
TruecenterA_Shot()
End If If rwer_pass_lwer = True Thenlwer_takes_shot =
TrueLwerA_Shot()
End If If lwer_pass_rwer = True Thenrwer_takes_shot =
TrueRwerA_Shot()
End If If rwer_passto_center = True Or lwer_pass_center = True Thencenter_takes_shot =
TruecenterA_Shot()
End If If rwer_pass_rd = True Thenrd_takes_shot =
TrueRDA_Shot()
End If If lwer_pass_ld = True Thenld_takes_shot =
TrueLDA_Shot()
End If End SubGoes to centerA_shot Sub
and at the end it goes back to a faceoff
If
play = 2 ThenText_Write()
End IfIf rwer_goal = True Or lwer_goal = True Or center_goal = True Then
Opening_Faceoff()
ElseIf rwer_goal = False Or lwer_goal = False Or center_goal = False Then
Home_Defensive_Faceoff()
End If
creates an infinite loop and i'm not sure how to end the code or subroutine
Thursday, August 23, 2007 7:47 PM -
Its quite long but here it is:
the faceoff sub is longer but this gives u an idea
I also have many other subroutines
Private
Sub Away_Defensive_Faceoff()faceoff_home_win =
Falsefaceoff_away_win =
False If center1_fo_home = 9 And center1_fo_away = 8 Then If num_array(1) > 43 Thenfaceoff_home_win =
Truecenter1_home_taken = center1_home_taken + 1
center1_home_won = center1_home_won + 1
center1_away_taken = center1_away_taken + 1
ElseIf num_array(1) <= 43 Thenfaceoff_away_win =
Truecenter1_away_taken = center1_away_taken + 1
center1_away_won = center1_away_won + 1
center1_home_taken = center1_home_taken + 1
End If.......
If
faceoff_home_win = True And face_array(1) > 50 ThenRDH_Shot()
play = play + 1
ElseIf faceoff_home_win = True And face_array(1) <= 50 ThenLDH_Shot()
play = play + 1
ElseIf faceoff_away_win = True ThenDefense_Away_Zone_RD()
play = play + 1
End IfPrivate
Sub Defense_Away_Zone_RD() Dim rdSkate As Boolean = False Dim ld_pos_L As Boolean = False Dim rd_takes_shot As Boolean = False Dim ld_open As Boolean = False Dim ld_takes_shot As Boolean = False Dim rwerSkate As Boolean = False Dim rwerStick As Boolean = False Dim rwerQuick As Boolean = False Dim rwerskates As Boolean = False Dim rwer_passto_center As Boolean = False Dim rwer_pass_rd As Boolean = False Dim rwer_pass_center As Boolean = False Dim rwer_open As Boolean = False Dim rwer_takes_shot As Boolean = False Dim rwer_pass_lwer As Boolean = False Dim center_open As Boolean = False Dim center_pass_rwer As Boolean = False Dim center_takes_shot As Boolean = False Dim centerQuick As Boolean = False Dim centerSkate As Boolean = False Dim centerStick As Boolean = False Dim lwer_open As Boolean = False Dim lwer_pass_center As Boolean = False Dim lwer_pass_ld As Boolean = False Dim lwer_pass_rwer As Boolean = False Dim lwer_takes_shot As Boolean = False Dim rdpassto As New Random Dim centerpass As New Random Dim rdpass As Integer Dim ldpass As Integer Dim pass_D As Integerrdpass = rdpassto.Next(1, 6)
ldpass = Int((6 * Rnd()) + 1)
pass_D = centerpass.Next(1, 100)
rwer_open =
True ElseIf rd1_pa_away > rwer1_po_home Thenld_open =
True ElseIf rwer_open = False And ld_open = False ThenrdSkate =
True End If If rwer_open = True And rwer1_qk_away > lwer1_qk_home ThenrwerQuick =
True ElseIf rwer_open = True And rwer1_pc_away > lwer1_ck_home ThenrwerStick =
True ElseIf rwer_open = True And rwer1_sk_away > lwer1_sk_home ThenrwerSkate =
True ElseIf rwer_open = True And rwer1_pa_away > lwer1_po_home Thenrwer_pass_center =
True End Ifcenter_open =
True ElseIf rwerQuick = True Or rwerStick = True Or rwerSkate = True And rwer1_pa_away > rd1_po_home Thenlwer_open =
True ElseIf rwerQuick = True Or rwerStick = True Or rwerSkate = True And center_open = False Thenrwerskates =
True End If If rwer_pass_center = True Or center_open = True And center1_pa_away > rd1_po_home Thenlwer_open =
True ElseIf rwer_pass_center = True Or center_open = True And center1_qk_away > ld1_qk_home ThencenterQuick =
True ElseIf rwer_pass_center = True Or center_open = True And center1_sk_away > ld1_sk_home ThencenterSkate =
True ElseIf rwer_pass_center = True Or center_open = True And center1_pc_away > ld1_sk_home ThencenterStick =
True ElseIf rwer_pass_center = True Or center_open = True And center1_qk_away > rd1_qk_home ThencenterQuick =
True ElseIf rwer_pass_center = True Or center_open = True And center1_sk_away > rd1_sk_home ThencenterSkate =
True ElseIf rwer_pass_center = True Or center_open = True And center1_pc_away > rd1_sk_home ThencenterStick =
True ElseIf lwer_open = False And centerSkate = False And centerStick = False And centerQuick = False Thencenter_pass_rwer =
True End If If rwerskates = True Or center_pass_rwer = True And rwer1_pa_away > rd1_po_home Thenrwer_pass_lwer =
True ElseIf rwerskates = True Or center_pass_rwer = True And rwer1_pa_away > ld1_po_home Thenrwer_passto_center =
True ElseIf rwerskates = True Or center_pass_rwer = True And rd1_sh_away > rwer1_sh_away Thenrwer_pass_rd =
True ElseIf rwerskates = True Or center_pass_rwer = True And rwer_pass_lwer = False And rwer_passto_center = False And rwer_pass_rd = False Thenrwer_takes_shot =
TrueRwerA_Shot()
End Iflwer_pass_rwer =
True ElseIf lwer_open = True And lwer1_pa_away > rd1_po_home Thenlwer_pass_center =
True ElseIf lwer_open = True And ld1_sh_away > lwer1_sh_away Thenlwer_pass_ld =
True ElseIf lwer_open = True And lwer_pass_rwer = False And lwer_pass_center = False And lwer_pass_ld = False Thenlwer_takes_shot =
TrueLwerA_Shot()
End If If centerQuick = True Or centerSkate = True Or centerStick = True And center1_sh_away < rwer1_sh_away Thenrwer_takes_shot =
TrueRwerA_Shot()
ElseIf centerQuick = True Or centerSkate = True Or centerStick = True And center1_sh_away < lwer1_sh_away Thenlwer_takes_shot =
TrueLwerA_Shot()
ElseIf centerQuick = True Or centerSkate = True Or centerStick = True And center1_sh_away >= lwer1_sh_away Thencenter_takes_shot =
TruecenterA_Shot()
ElseIf centerQuick = True Or centerSkate = True Or centerStick = True And center1_sh_away >= rwer1_sh_away Thencenter_takes_shot =
TruecenterA_Shot()
End If If rwer_pass_lwer = True Thenlwer_takes_shot =
TrueLwerA_Shot()
End If If lwer_pass_rwer = True Thenrwer_takes_shot =
TrueRwerA_Shot()
End If If rwer_passto_center = True Or lwer_pass_center = True Thencenter_takes_shot =
TruecenterA_Shot()
End If If rwer_pass_rd = True Thenrd_takes_shot =
TrueRDA_Shot()
End If If lwer_pass_ld = True Thenld_takes_shot =
TrueLDA_Shot()
End If End SubGoes to centerA_shot Sub
and at the end it goes back to a faceoff
If
play = 2 ThenText_Write()
End IfIf rwer_goal = True Or lwer_goal = True Or center_goal = True Then
Opening_Faceoff()
ElseIf rwer_goal = False Or lwer_goal = False Or center_goal = False Then
Home_Defensive_Faceoff()
End If
creates an infinite loop and i'm not sure how to end the code or subroutine
Thursday, August 23, 2007 7:47 PM -
That is a lot to take in
Dave299 probably can give some good help on this one
If you don't get anything better this will help you out
What i have done recently to a project of mine that called a lot of subs in a loop was to wrap all the subs into one if then else statement and the second thing was to wrap it all into a timer tick event
Here is a link to the thread i posted a while back explaining the whole thing
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1953703&SiteID=1
It is a lot of information but if you read through it will make sense
Thursday, August 23, 2007 9:14 PM -
Uhm what does the endgame() sub look like
I actually need to somehow incorporate a timer so i can determine the time when a goal is scored so that might work for me
but the timer would have to continue through out the running of code. not sure how to do that with the example i read
any ideas
so basically the code would have to return to the beginning of code every loop not sure i understand that part
The other question i guess is why u needed 3 or 4 different tick events
and if i have up to 10 different subs where do i return to after they are used
any help would be great
Thursday, August 23, 2007 10:02 PM -
Ok, the 4 timers was just an example of using multiple timers to run multiple instances of a loop that would normally cause an overflow exception or system lockup
You don't neccessarily need 4 timers for yours
I actually only used 1 timer in my actual program
The 5th post in my thread is the main one with the code that i used
the others were just for examples
The endgame sub is just a sub that i used to show a form with the score and some other related info
And i also used it to reset variables that would be needed to run a new game
I will have to get back to you on the rest when i get back home from an appointment
Take a look at the 5th post in my thread again and read the commented notes
they should help a little
Thursday, August 23, 2007 10:38 PM -
I think we are in danger of not seeing the wood for the trees here.
visual_star - could you go through your code and just post the relevant bits showing where a sub is called from another sub and why. Do this for all the subs and then maybe we will have some chance of seeing where the problem is.
Thursday, August 23, 2007 10:49 PM -
Firstly we start the game by clicking a button
then it loads the various player attributes
then it goes to this sub
Public
Sub Opening_Faceoff()faceoff_home_win =
Falsefaceoff_away_win =
False If center1_fo_home = 9 And center1_fo_away = 8 ThenIf num_array(0) > 43 Then
faceoff_home_win =
Truecenter1_home_taken = center1_home_taken + 1
center1_home_won = center1_home_won + 1
center1_away_taken = center1_away_taken + 1
ElseIf num_array(0) <= 43 Then
faceoff_away_win =
center1_away_taken = center1_away_taken + 1
center1_away_won = center1_away_won + 1
center1_home_taken = center1_home_taken + 1
End If
decides who won the faceoff
If
faceoff_home_win = True And face_array(0) > 50 ThenLeft_Defense_home()
play = play + 1
Right_Defense_home()
play = play + 1
Left_Defense_away()
play = play + 1
ElseIf faceoff_away_win = True And face_array(0) <= 50 Then
Right_Defense_away()
play = play + 1
End If
decides which subroutine to run - These four subs run and determines which player has the puck and goes to a shooting sub routine
at the end of the shooting subroutine the following code decides which type of faceoff to go to next:
If
rwer_goal = True Or lwer_goal = True Or center_goal = True And play = 1 ThenOpening_Faceoff()
ElseIf rwer_goal = False Or lwer_goal = False Or center_goal = False And play = 1 Then
Away_Defensive_Faceoff()
Stop
End If
Private
Sub Away_Defensive_Faceoff()faceoff_home_win =
faceoff_away_win =
FalseIf center1_fo_home = 9 And center1_fo_away = 8 Then
If num_array(1) > 43 Then
faceoff_home_win =
Truecenter1_home_taken = center1_home_taken + 1
center1_home_won = center1_home_won + 1
center1_away_taken = center1_away_taken + 1
faceoff_away_win =
center1_away_taken = center1_away_taken + 1
center1_away_won = center1_away_won + 1
center1_home_taken = center1_home_taken + 1
End If
At the end of this faceoff it decides which player it goes to next
If
faceoff_away_win = True And face_array(1) > 50 ThenRDA_Shot()
play = play + 1
LDA_Shot()
play = play + 1
ElseIf faceoff_home_win = True Then
Defense_Home_Zone_RD()
play = play + 1
End If
From here it goes to a few more subroutines - but basically if a goal is scored it goes to opening faceoff, If no goal is scored it goes to another faceoff and so on
as i stated before i tried to count the number of plays but i think it gets hung up before play 2 is finished
i use the same variable names for all shooting sub routines - might be the cause of it but i'm not sure
I think its getting hung up on a few New Random generators
cause it goes to Opening_faceoff and then through Left_Defense_Home / Right_Defense_Home and goes to Away_Defensive_Faceoff() and then goes to RDH_shot and gets hung up on the following variable:
Dim
rebounds As New RandomThats where the error stops the program
Thursday, August 23, 2007 11:05 PM -
OK - That's a bit clearer.
It's late over here so I'm just off to bed but I'll have a look in the morning if no-one else deals with it before then
Thursday, August 23, 2007 11:37 PM -
visual_star,
I am going to wait and let dave see what he can tell you about this one
He seems to have a way with these things that i don't fully understand yet
Arrays and loop elimination is something he understands better than me
And at the moment i am having some brain lock on certain things (overload problem)
If you don't get it worked out then i can give you some more advice on using the timers
I don't get alerts sent to me anymore (for about a month now) so i may lose track of your post
If you need more help on my end later then you are welcome to email me at jeff@txun.net
Just send me a brief email with your thread link and i will try to help you out
Good luck
Friday, August 24, 2007 1:57 PM -
You don't mention what error you get but looking at the code I presume it is a Stack Overflow.
My problem here is that I know nothing about Hockey apart from what I have just gleaned from what you have written above. Still here goes anyway:
The problem is that you are not exiting the subs when you call the next one and the last one calls the first one and you go round in a loop until the stack overflow occurs.
One way round this is to use Functions instead of Subs and to have the decision tree as to what to do next outside of the functions.
Have a look at the following simple example which may give you the general idea. I have defined a number of enumerations which contain the possible outcomes of the various functions. The program just sits in a loop until the FaceOffType is set to None, which can be done in the Shooting function. The DoEvents in the Shooting routine is simply to allow you to stop the program with the X button.
Code SnippetPublic
Class Form1None
Opening
HomeDefensive
AwayDefensive
Home
Away
Player1
Player2
Player3
FaceOfftype = Shooting()
Case Players.Player2 Case Players.Player3 End Select Case FaceOffResults.Away End Select End Select Loop End Sub Private Function Opening_Faceoff() As FaceOffResultsApplication.DoEvents()
End
ClassFriday, August 24, 2007 4:12 PM -
Howdy
I haven't used cases much before but from what i can understand basically by using functions and cases the function returns either what faceoff to run and also later on returns what player has the puck at the end of the code and returns to the button click sub to find out what to do next.
The one thing i don't understand is the line
Do While faceofftype <> faceofftype.none
and basically how do we determine there is no faceoff later on in the code
because u can have up to 35 plays
so would u count the plays somehow in the functions and stop it at 35 plays or whatever
like
If play = 4 Then
Return FaceoffTypes.None
ElseIf lwer_goal = True and play = 1 or play = 2 or play = 3 Then
Return FaceoffTypes.Opening
ElseIf lwer_goal = False And play = 1 or play = 2 or play = 3 Then
Return FaceoffTypes.Away
End If
would something like that work?
would i have to close the functions before going somewhere else or would that happen automatically once the function returns a value?
thanks for your help
Nick
Friday, August 24, 2007 10:49 PM -
Hi Nick
Dealing with the last question first - once a function returns it has finished, you don't have to close it - it's as if a sub had reached the End Sub or an Exit Sub.
What you have suggested for ending the game would work fine but you don't have to use the FaceOffType - you could use some other criteria such as the number of plays, e.g.
and control the loop with something like:
Until whatever criteria you choose is met the loop, and the game, will continue.
Hope that helps.
Friday, August 24, 2007 11:49 PM -
This architecture is never going to work. Dave is correct you can't call a subroutine the calls another and then another which calls the calling routine. When you say you have several routines going at the same time you really don't. They are strung out on the stack like a string a of pearls and the stack only has so much room before it over flows.
So What to do? I think you need an archirtectural change where, when a subroutine sees that another needs to run that it pushes instructions on a queue and returns. The caller of that routine does not return until the queue is empty.
The queue could be an arraylist functioning as your stack actually
Private CallQueue as New Arraylist ' As a member Variable
So how could you implement such a thing?
Start with an arraylist and a structure. The structure might look like this
Public Structure SubCall
Public SubName as String
Public Arg1 as Object
Public Arg2 as Object
Public Arg3 as Object
end Structure
Let's say that Subroutine A decides that it Needs to call Sub Routine B with an argument value of 23
Subroutine A would do this:
Dim a as new SubCall
A.SubName="B"
A.Arg1 = 23
CallQueue.Add(S)
Return
Upon returning the caller does this: (I'm thinking a stack would be Better)
I'm going to break into pseudo so that i do write an operating system....
Dim B as SubCall
While (CallQueue.Count <> o) then
b = CallQueue.Pop
ProcessCall(b)
End While
return ' Game Over
ProcessCall( Call )
SelectCase Call.SubName
Case A
SubA(Call.Arg1)
Case B
SubB(Call.Arg1,Arg2)
'Etc
return
This is basically a smilar architecture to the message pump. And it insures no Snarls and Messy Hair.
Every thing is called by a central dispatcher in an orderly fashion.
Saturday, August 25, 2007 1:18 AM -
Darn,
I just realized that if A calls B and b calls A this could still have an infinte loop But I don't think it would ever have a stack over flow
Saturday, August 25, 2007 1:24 AM -
Well I changed my program around and got the following - it seems to be running ok and it doesn't cause an error but it doesn't stop at play 2 - here is the following structure and some explaination:
Enum
FaceoffTypesNone
Opening
Away_Defensive_Zone
Home_Defensive_Zone
End Enum Enum FaceoffResultsHome_LD
Home_RD
Away_LD
Away_RD
Home_defensive_RD
Away_defensive_RD
Home_Zone_Defense_Pairs
Away_Zone_Defense_Pairs
End Enum Enum PlayersLwer_away
Lwer_home
Rwer_away
Rwer_home
Center_away
Center_home
LD_away
LD_home
RD_away
RD_home
End Enum Dim FaceOfftype As FaceoffTypes = FaceoffTypes.OpeningFaceOfftype = centerH_Shot()
Case Players.Lwer_homeFaceOfftype = lwerH_Shot()
Case Players.Rwer_homeFaceOfftype = RwerH_Shot()
End Select Case FaceoffResults.Home_RDFaceOfftype = centerH_Shot()
Case Players.Lwer_homeFaceOfftype = lwerH_Shot()
Case Players.Rwer_homeFaceOfftype = RwerH_Shot()
End Select Case FaceoffResults.Away_LDFaceOfftype = centerA_Shot()
Case Players.Lwer_awayFaceOfftype = LwerA_Shot()
Case Players.Rwer_awayFaceOfftype = RwerA_Shot()
End Select Case FaceoffResults.Away_RDSelect Case Right_Defense_home()
Case Players.Center_away
FaceOfftype = centerA_Shot()
Case Players.Lwer_away
FaceOfftype = LwerA_Shot()
Case Players.Rwer_away
FaceOfftype = RwerA_Shot()
End Select
End Select
Case FaceoffTypes.Away_Defensive_Zone
Select Case Away_Defensive_Faceoff()
Case FaceoffResults.Away_defensive_RD
Select Case Defense_Away_Zone_RD()
Case Players.Center_home
FaceOfftype = centerH_Shot()
Case Players.Lwer_home
FaceOfftype = lwerH_Shot()
Case Players.Rwer_home
FaceOfftype = RwerH_Shot()
Case Players.LD_home
FaceOfftype = LDH_Shot()
Case Players.RD_home
FaceOfftype = RDH_Shot()
End Select
Select Case Defense_Pairs_Home()
Case Players.LD_home
FaceOfftype = LDH_Shot()
Case Players.RD_home
FaceOfftype = RDH_Shot()
End Select
Case FaceoffTypes.Home_Defensive_Zone
Select Case Home_Defensive_Faceoff()
Case FaceoffResults.Home_defensive_RD
Select Case Defense_Home_Zone_RD()
Case Players.Center_away
FaceOfftype = centerA_Shot()
Case Players.Lwer_away
FaceOfftype = LwerA_Shot()
Case Players.Rwer_away
FaceOfftype = RwerA_Shot()
Case Players.LD_away
FaceOfftype = LDA_Shot()
Case Players.RD_away
FaceOfftype = RDA_Shot()
End Select
Case FaceoffResults.Home_Zone_Defense_Pairs
Select Case Defense_Pairs_Away()
Case Players.LD_away
FaceOfftype = LDA_Shot()
Case Players.RD_away
FaceOfftype = RDA_Shot()
End Select
If
faceoff_home_win = True And face_array(0) > 50 Thenplay = play + 1
play = play + 1
ElseIf faceoff_away_win = True And face_array(0) > 50 Then
play = play + 1
Return FaceoffResults.Away_LD
ElseIf faceoff_away_win = True And face_array(0) <= 50 Then
play = play + 1
Return FaceoffResults.Away_RD
End If
Every faceoff has this code or simular
I'm trying to count the plays and every shooting subroutine has the following code at the end
If
rwer_goal = True Or lwer_goal = True Or center_goal = True And play = 1 ThenReturn FaceoffTypes.Opening
ElseIf rwer_goal = False Or lwer_goal = False Or center_goal = False And play = 1 Then
Return FaceoffTypes.Away_Defensive_Zone
ElseIf play = 2 Then
Return FaceoffTypes.None
End If
play is dimmed like this
Public play as integer = 0
in form 1 main module
would play be reset at any time during the code - i'm a little confused
and also why would it be running if part of the continuation of the program depends on the variable "play" has to equal 1
This structure works ok i think but it doesn't stop as per before.
thanks alot for the help everyone.
Saturday, August 25, 2007 1:46 AM -
I don't know much about functions and it is late here, so this may be a long shot but i think that the check to exit the loop is in the wrong place.
If you are using faceofftypes.none to exit the loop wouldn't you need to check if play = 2 first before any others?
something like this
If play = 2 Then
Return FaceoffTypes.None
ElseIf rwer_goal = True Or lwer_goal = True Or center_goal = True And play = 1 Then
Return FaceoffTypes.Opening
ElseIf rwer_goal = False Or lwer_goal = False Or center_goal = False And play = 1 Then
Return FaceoffTypes.Away_Defensive_Zone
End If
I may be way off here but that's what it looked like to me. But it has been a long day here so i could definetely be off on this. It does seem that yo would need to return your exit before you check the others and then enter another opening.
Hope this helps you
If not, sorry for my late night post
Saturday, August 25, 2007 3:03 AM -
I think you need to look carefully for lines like:
If rwer_goal = True Or lwer_goal = True Or center_goal = True And play = 1 Then
to make sure they are doing what you want.
Here you have four boolean values which to save me typing I will call A, B, C and D
Because of the way operator precedence works A Or B Or C And D is equivalent to A Or B Or (C And D). i.e if A or B is true or both C and D are true
What I think you want is (A Or B Or C) And D. i.e. If any of A, B or C is true AND D is true
If that is the case I would go through your app and make sure that all similar expressions are doing what you expect. Personally I always use brackets to make it clear what a formula is doing rather than rely on operator precedence.
Saturday, August 25, 2007 11:40 AM -
Renee
I thought I quite liked your idea at first but when I came to code it it was just as complicated as the method I suggested with the functions, which admittedly produce a horrendous Select Case chain.
I can't help thinking it should be possible to do this using objects and events but my first effort produced another stack overflow. Still I'll keep looking at it.
Saturday, August 25, 2007 11:43 AM -
Saturday, August 25, 2007 1:30 PM
-
thanks for all the help
I went and changed my structure to just have the opening faceoff and a function that wrote the faceoff results to a few text boxs
and it frooze on me
here is what it looks like:
Do
While faceofftype <> FaceoffTypes.finalCase FaceoffResults.Home_LD
Select Case Text_Write()
End SelectCase FaceoffResults.Home_RD
Select Case Text_Write()
End SelectCase FaceoffResults.Away_LD
Select Case Text_Write()
End Select
Case FaceoffResults.Away_RD
Select Case Text_Write()
End Select
End Select
End
Select LoopI did this just to simplify it and see if it would run only two functions the text_write sub looks like this:
Public
Function Text_Write()TextBox1.Text = center1_home_won
TextBox2.Text = center1_home_taken
TextBox4.Text = center1_away_won
TextBox5.Text = center1_away_taken
'TextBox8.Text = shots_against 'TextBox9.Text = saves 'TextBox10.Text = goals_against 'TextBox16.Text = lwershot 'TextBox17.Text = centershot 'TextBox18.Text = rwershot 'TextBox19.Text = g1_bl_home 'TextBox20.Text = g1_sk_home 'TextBox21.Text = g1_gl_home 'TextBox22.Text = g1_rb_home 'TextBox23.Text = g1_rc_home 'TextBox26.Text = ldshotReturn FaceoffTypes.final
End Function
Opening faceoff looks like this:
If
faceoff_home_win = True And face_array(0) > 50 Thenplay = play + 1
Return FaceoffResults.Home_LDElseIf faceoff_home_win = True And face_array(0) <= 50 Then
play = play + 1
Return FaceoffResults.Home_RDElseIf faceoff_away_win = True And face_array(0) > 50 Then
play = play + 1
Return FaceoffResults.Away_LDElseIf faceoff_away_win = True And face_array(0) <= 50 Then
play = play + 1
Return FaceoffResults.Away_RDNot sure if the structure needs something after Select Case Text_Write()
so i'm a little confused here.
Can u see anything i did wrong here?
Saturday, August 25, 2007 5:42 PM -
i think i got it
just changed
the last line to this
faceofftype = faceofftypes.final
Return faceofftype
thanks for the help everyone
Saturday, August 25, 2007 7:15 PM -
Yes, that will give you the expected result, but not for the right reasons.
In your Do loop you have lines like:
Select Case Text_Write()
End SelectThe problem lies here because you are not acting on the result.
Select Case Text_Write()
calls the function Text_Write and you should then have a list of Case statements defining what to do depending upon the result of the function call. However, all you want to do here is set the value of FaceOffType to the value returned by the function Text_Write. In that case there is no need for the Select Case at all. What you need is
FaceOffType = Text_Write()
Your solution sets FaceOffType in the function Text_Write. Having done that it is irrelevant what value is returned by the function. Although that works for now it will fail when you go to the next step.
A couple of suggestions which may help;
1. Consider turning Option Strict On, either by putting Option Strict On at the top of your code or by going to Tools | Options | VB Defaults and set it there. If you had done this you would have received a warning that the function Text_Write did not have a return type.
2. The function Text_Write appears to be a form of debugging aid. Have a look in Help for Debug.Write which may be of use. Actually, having just done that, it may be no help at all. To simplify it - Debug.Print will write whatever you specify to the Immediate window which you can view by pressing Ctrl-Alt-I. This can be very useful if you want to check on the progress of your app without interrupting it. Whenever you want to know the state of the application just insert a Debug.Print line and then you can examine the progress after the program has run.
Saturday, August 25, 2007 10:03 PM