Stuck and need help
BlitzMax Forums/BlitzMax Beginners Area/Stuck and need help
| ||
I'm working on a simple game and am stuck. Hopefully someone here and help me out. For now, all the game does is fill 1 of 4 squares in the middle of the screen. After hitting the space bar to begin, the player hits the Up arrow and fills the corresponding square at the top of the screen. Then the program fills a different square in the center and the user moves it to the top. The process repeats until all 4 upper squares are filled. After the 4 upper squares are filled, the middle squares are supposed to be empty, but the previously filled square doesn't clear and I don't know why. I have debugging code to show which of the center (C1, C2..) and upper squares (U1, U2...) are filled. Why does the last center square not clear? Disclaimer: I am a novice programmer and I know I don't follow the best programming practices. Thanks for looking. Bill Graphics 800,600 Global i=0:Int Global C1=0:Int Global C2=0:Int Global C3=0:Int Global C4=0:Int Global U1=0:Int Global U2=0:Int Global U3=0:Int Global U4=0:Int Global CU1=0:Int Global CU2=0:Int Global CU3=0:Int Global CU4=0:Int Global Arrow:String="" Global PickedNumber=0:Int Global StartGame=0:Int Global PlayerMove=0:Int 'this is changed to 1 once the player hits an arrow key. It is changed back to 0 once the squares are moved. Global CenterInPlay=0:Int 'if box in center is filled, don't call PickCenterSquare SeedRnd MilliSecs () Function PickCenterSquare() Local TestNum=0:Int While TestNum=0 PickedNumber=Rand(1,4) Select PickedNumber Case 1 If U1=0 Then C1=1 TestNum=1 End If Case 2 If U2=0 Then C2=1 TestNum=1 End If Case 3 If U3=0 Then C3=1 TestNum=1 End If Case 4 If U4=0 Then C4=1 TestNum=1 End If End Select Wend Return End Function Function HitArrow() If Arrow = "U" Then If C1 = 1 Then If U1 = 0 Then U1 = 1 CenterInPlay=0 C1 = 0 End If End If If C2 = 1 Then If U2 = 0 Then U2 = 1 CenterInPlay = 0 C2 = 0 End If End If If C3 = 1 Then If U3 = 0 Then U3 = 1 CenterInPlay=0 C3 = 0 End If End If If C4 = 1 Then If U4 = 0 Then U4 = 1 CenterInPlay=0 C4 = 0 End If End If End If End Function Repeat Cls While StartGame=0 If KeyHit(KEY_SPACE) Then StartGame=1 End If Wend 'draw center box SetLineWidth(4) SetColor(0,200,100) DrawLine 349,249,451,249 DrawLine 349,349,451,349 DrawLine 349,249,349,349 DrawLine 451,349,451,249 'draw upper box DrawLine 349,49,451,49 DrawLine 349,149,451,149 DrawLine 349,49,349,149 DrawLine 451,49,451,149 If CenterInPlay=0 Then 'clears center squares SetColor(0,0,0) DrawRect(401,250,50,50) DrawRect(401,300,50,50) DrawRect(350,300,50,50) DrawRect(350,250,50,50) PickCenterSquare CenterInPlay=1 End If Print "Picked number is: " + PickedNumber Print "C1 is: " + C1 + " C2 is: " + C2 + " C3 is: " + C3 + " C4 is: " + C4 Print "U1 is: " + U1 + " U2 is: " + U2 + " U3 is: " + U3 + " U4 is: " + U4 If C1=1 Then SetColor(255,0,0) DrawRect(400,251,50,50) End If If C2=1 Then SetColor(255,0,0) DrawRect(400,299,50,50) End If If C3=1 Then SetColor(255,0,0) DrawRect(350,299,50,50) End If If C4=1 Then SetColor(255,0,0) DrawRect(350,251,50,50) End If If KeyDown(KEY_UP) Then If CenterInPlay = 1 Then Arrow="U" HitArrow Arrow ="" End If Delay(100) End If If U1 = 1 Then SetColor(255,0,0) DrawRect 399,52,50,50 End If If U2 = 1 Then SetColor(255,0,0) DrawRect 399,98,50,50 End If If U3 = 1 Then SetColor(255,0,0) DrawRect 352,98,50,50 End If If U4 = 1 Then SetColor(255,0,0) DrawRect 352,52,50,50 End If Flip Until MouseHit(1) |
| ||
It would be easier to read your source if you put your code within code tags. Use [ code ] [ /code ] without the spaces. [ codebox ] [/codebox ] can be used for longer code The reason your middle square is not clearing is because when you fill the forth square, u1,u2,u3 and u4 all = 1, which causes an endless loop in the PickCenterSquare function. This is why the program locks up when all 4 squares are filled. Do a test to make sure that there is a free square available. Function PickCenterSquare() If u1 And u2 And u3 And u4 Then Return 'test for free square Local TestNum=0:Int etc... Also, you might want to spend a bit of time learning about arrays in BlitzMAX. |
| ||
Your while loop is run forever in certain cases (I print a text there). EDIT: Tom was faster ... but even if the source of your problem was narrowed down: also check how things could get shortened (I shortened your "if"-parts as an if 1 --if 2 ----do could be written as if 1 and 2 --do bye Ron bye Ron |
| ||
Thank you for the replies. I took your advice and now the program no longer gets stuck in an endless loop. I have a long way to go on this game and will certainly ask more questions. Bill |
| ||
I did a simple maze game example a while back which is in my worklog. I posted the full source code in the thread so that may help you out a bit with tracking what's in what square on a grid. |
| ||
Bill, your code is straightforward and clear, it's very brute-force and linear but that's not necessarily a bad thing. If you indent it like Derron did with each block getting indented between an if and an endif like soif such and such indent this bit and this bit endif it will improve the readability hugely. For you right now "best programming practices" are what keeps it simple and understandable for yourself. And that remains true to a surprising extent-- a lot of times things that are elegant are not easy to understand and a lot of times they are surprisingly slow and it's brute force linear logic that wins the day. If I have the choice between doing something clever or doing something a bit more brute force but simple to understand, I choose the latter every time especially when learning a new language. You can always go in later and make it more efficient. As some bearded philosopher once said, "Premature optimization is the root of much evil." Also you don't need the "then" statements but by all means keep them there if it makes the code easier for you to understand. |
| ||
I've been working on my 'Moving Boxes' program over the last few weeks and have made a lot of progress. I have most of the game's functionality completed, but now it locks up after several moves. My code is quite long and inefficient, so I won't post it right now. Instead, does anyone have suggestions about debugging? I used the DebugStop command in a couple of locations, but I can't find what exactly is causing the lock up. Is there a way to trace the running code line by line? Thanks again for all of the previous comments and suggestions. Bill |
| ||
Is there a way to trace the running code line by line? Not without dropping lots of DebugLog everywhere. ... which leads me to the thought that it might be nice to have a "profile/trace" option in bcc - to do just that. (although the amount of trace you can generate in a very short time in BlitzMax may give you other headaches). |
| ||
Is there a way to trace the running code line by line? Using the step button in MaxIDE toolbar ? -Henri |
| ||
[edit] Is there a way to trace the running code line by line? Instead, does anyone have suggestions about debugging? [/edit] This may help ... http://www.blitzbasic.com/Community/posts.php?topic=95478 |
| ||
Is there a way to trace the running code line by line? ... Using the step button in MaxIDE toolbar ? This may help ... The code is not "running" when you are stepping through it. It is paused, waiting for you to do something. If you have lots of functions, stick a DebugLog "function name" in each of them. That might give you a head start where to go next. |
| ||
@Brucey, You're right, I totally agree. I've edited my post as I made a mistake with the 'quote' that I was replying to. |
| ||
A "stuck" always means it ended in a dead loop. Means: check your loops debuglog("before loop3") bla debuglog("after loop3") you will surely see a "before loop3" somewhere, but no "after loop3". bye Ron |
| ||
Personally I never use software debuggers. I manually put breakpoints that print variables that are in question. Break up your program into functions as much as you can and then test each individual function exhaustively and that way you know that each function is bulletproof so when you begin to write the main body of the program, it is like building with Legos that are already heavily tested as opposed to Legos that are in uncertain states of reliability. It also helps you compartmentalize confusion. There is only so much you can hold in your head at one time. If something is confusing, but you get to a point where you can understand it momentarily, if you then write a function that is a simple interface hiding complex workings, you have canned your momentary understanding in a way that will be usable later when you no longer understand that piece of the puzzle. You can then even chop those functions out and use them later in other programs. When you have a program built up this way, bugs become a matter of "function foo not working and I don't know why" instead of "whole program not working and I don't understand why." Later you can get into what's called test-driven development. There, you figure out what functions you need, then figure out an exhaustive test to make sure that a function works before actually coding that function. What happens if I feed it negative values or huge values? For this given input, I should get that specific output, is that happening? When you have a bunch of these tests written, and you set them up to run every time you start the program, you will see immediately if the tests (called a "test harness") print PASS or FAIL for any given function. This, if you change something and it breaks some other part of the program, you will know right away rather than fifteen minutes later when your gnat brain no longer remembers what it was doing. And I'm not just talking to you-- a huge part if not all of debugging has to do with the recognition that we have tiny gnat brains, and accepting that, and then using the computer to automate as much of the testing process as possible. Breaking things up also allows you to work on some other part of the program when you start getting brainfried. Debugging and programming in general are exceedingly taxing mentally and I am convinced that there is some chemical or brain nutrient that gets depleted. Just some general thoughts. It is probably a good idea to use the software debugger, I should learn. I didn't even know about debuglog until just now but I can imagine what it does. |
| ||
Thanks for the comments. I printed the status of most of the variables and saw something was getting incremented when it shouldn't. This means it hits 4 when it should be 3, and locks up. At least that's what I think was the cause. I moved this code to a different location and now I can play forever. |
| ||
http://en.wikipedia.org/wiki/Off-by-one_error |
| ||
Personally I never use software debuggers. I manually put breakpoints that print variables that are in question. o_OWhy on earth would you do that, when the debugger tells you the contents of every variable anyway?? (aside from the fact that a breakpoint doesn't print anything. It's a point where code execution stops and the debugger kicks in). |
| ||
Sometimes I find it helps to check if a number is > the max allowed rather than a specific "if x = 4" or similar. Of course this would mean you would still have something incrementing that shouldn't be, and might not notice it, so it's six of one and half a dozen of the other. |
| ||
That is why someone invented the "else" or "default" select x case 1 ... case 2 ... default ... endselect if x=1... elseif x=2 ... else ... bye Ron |
| ||
I laughed when I saw there was a Wikipedia entry for the type of error I had. Now I feel like a real programmer. I was able to fix a couple of bugs and now my game runs correctly. It's still far from complete, but as of right now, it's bug free. Thanks for the help. Bill |