this is my first post in this site.
As the title says, I encountered a bug in an If - else if - else block of codes.
What the problem is that, I am pretty confident that I have covered all 9 possible outcomes that there should be.
It is quite hard to explain more, so if you guys could take a look at my .cpp file and run it ( hopefully it runs because I used c++ on a mac), you may find an easier understanding of my problem.
source code cpp file
If you browse through my action();, in the else statement, I purposely displayed that you encountered a bug so just in case there were bugs, I'd be informed.
What I am trying to do is like this:
userinput | randomAImove | outcome
A 1 statement
A 2 statement
A 3 statement
D 1 statement
D 2 statement
D 3 statement
W 1 statement
W 2 statement
W 3 statement
else 1||2||3 statement
There are corresponding statements to each conditions met.
'A', 'W', 'D' are user input. I used a toupper command to force the compiler to just check on 'A' 'W' 'D'. However, the main problem I find is that, even if the toupper works(which I confirmed), the program displays the correct statement often but still somehow manages to bug even if the user(I tried it) input from A, W, D (not-case sensitive cuz of toupper).
Please just try it and after a few tries you may encounter it also. I wrote "you encountered a bug" if you ever do encounter it.
Please help me because I can't really see any other way to find the mistake. Maybe its in my plain sight but I can't seem to notice which one is it.
Thank you!
Change the AImove function to
void AImove()
{
turn = rand () % 3 + 1;
}
(add + 1), or you may get 0 in turn and it will lead you "encounter a bug".
Related
So I'm working on a simple little text-based game in D to gain some experience working with the language. Here is a do-while loop that I'm currently struggling with:
do{
writeln("a. Advance 1 year\tc. Advance 10 years\tq. Quit");
writeln("b. Advance 5 years\td. Modify faction");
input = chomp(stdin.readln());
switch(input){
...
default:
break;
}
writeln(input[0]);
}while(input[0] != 'q');
Now the problem I'm running into is that when I hit q and enter the loop doesn't exit. It just keeps going. But then after the first time q is input, another q will terminate the loop. The writeln is in there as a sanity check, and it prints out the characters I type in exactly as typed. I feel like I'm going crazy, but it's probably just a simple type-o or something you guys will spot instantly. Nothing in the switch statement modifies 'input'.
EDIT: Okay some people have been asking to see all of the code. Here it is: http://pastebin.com/A7qM5nGW
When I said nothing in the switch modified input, it was to hide the fact I hadn't written anything in the switch yet. I've been trying to get the quit part to work right before adding the more complicated stuff. Also, here's a sample file for what I run it on: http://pastebin.com/4c2f4Z5N
Okay my friend found it. It has nothing to do with the while loop itself. I briefly forgot that args[0] is the name of the program. So it's actually running through the parent loop once with nothing, then actually quitting, and then running through the appropriate loop. It was fixed by making the parent loop like so...
foreach(filename; args[1..$]){
...
do{
...
while(input[0] != 'q');
}
as opposed to:
foreach(filename; args){
etc...
Yeah. So, I'm trying to make a code for a guessing game. In this game, there's a hard mode. In hard mode, you have 15 guesses, and have to guess between 1 and 500. But my problem is this:
I'm trying to have hard mode save & display your wins/losses, but when it outputs the contents of wins.txt it outputs something like this:
Wins: 0x7fffee26df78
Losses: 0x7fffee26e178
It's really confusing me. Here's the part of the code I have for that:
ifstream losses_var("losses.txt");
ifstream wins_var("wins.txt");
losses_var>> loss;
wins_var>> win;
wins_var.close();
losses_var.close();
Then it gets called with:
cout<<"Wins: "<< wins <<"\nLosses: "<< losses <<"\n"
If you would like to see the full source code, it's here: http://pastebin.com/gPT37uBJ
My second problem:
Hard mode won't display when you win. That's pretty much the whole problem. In my code, the loop for asking users for input uses
while (guess != randNum)
So at the end bracket I have what I want the code to display when a user wins, but it just doesn't run. It just stops. I would like it if someone could help me with this. The line that has the bug is line 97 through 105. Again, source code is here: http://pastebin.com/gPT37uBJ
You've got your variable names confused
cout<<"Wins: "<< wins <<"\nLosses: "<< losses <<"\n";
should be
cout<<"Wins: "<< win <<"\nLosses: "<< loss <<"\n";
It's important to pick good variable names. One reason is so that you don't confuse yourself about what your variables mean (if you confuse yourself think how it's going to be for someone else looking at your code).
Others have already answered the output problem (win vs. wins). The other problem is probably in your logic of while loop nesting. The outer loop (while (guess != randNum)) starts, but its body contains the entire inner loop (while (guesses_left != 0)). This means that the outer condition is not checked again until the inner loop terminates, which means you've run out of guesses. Also note that if you guess correctly, inner loop will never terminate. You probably want something like this:
while (guesses_left > 0) {
// input user's guess
if (guess < randNum) {
// process it
} else if (guess > randNum) {
// process it
} else {
// it's equal, user won
// do what's necessary for a win
return 0;
}
}
// ran out of guesses
// do what's necessary for a loss
return 0;
You are not writing your variables win and loss to cout. From your pasted code, I can see that wins and losses are ofstream objects, which means you are probably seeing addresses there. I would advise you to choose more informative variable names to avoid hard to spot mistakes like this.
I'm currently porting an application from Fortran to C and need to output some variables to compare results. I'm very new to Fortran, and although i understand the code and have now ported several thousand lines, I'm a noob at writing Fortran code myself.
This code:
write(6,'(A,I3,A,E12.8,A,E12.8,A,E12.8,A,E12.8,A,E12.8)') 'iHyd:',
& ih,'; dzdr: ',dzdr,'; tauray:', tauRay,'; zRay: ',
& zray,'; ampRay: ',realpart(aray),'+j*',
& imagpart(aray),'; qRay: ',qray,'; width :',w
Compiles fine, but when run, the program exits with:
At line 296 of file calcpr.for (unit = 6, file = 'stdout')
Fortran runtime error: Expected INTEGER for item 15 in formatted transfer, got REAL
(A,I3,A,E12.8,A,E12.8,A,E12.8,A,E12.8,A,E12.8)
^
q0: 1432.3944878270595
nArrayR: 501 nArrayZ: 201
iHyd: 1; dzdr: ************; tauray:************; zRay: ************; ampRay: NaN+j* NaN
; qRay:
Besides being really ugly, it doesn't make much sense to me, as ìh is declared as integer*8 and not as real.
So how can i solve this?
I'm counting 6 character&variable specifications in the format statement, but you're printing 8 of them.
edit:
a nicer use of the format statement would be '(A,I3,7(A,E12.8))'
Fortran "recycles" the format if there are more things to be printed than specified in the format statement. If a write statement gives results you don't understand, to diagonose the problem it may be helpful to remove the things printed one at a time until the error goes away.
It says "item 15", which I would take to be down near the end of your list, not ih at the beginning. It's clear that both "w" and "qray" are being printed as REAL; is either one of them an INTEGER? You may need to change the format specifier then.
I have a function that creates and insert some numbers in a vector.
if(Enemy2.dEnemy==true)
{
pt.y=4;
pt.x=90;
pt2.y=4;
pt2.x=125;
for(int i=0; i<6; i++)
{
Enemy2.vS1Enemy.push_back(pt);
Enemy2.vS2Enemy.push_back(pt2);
y-=70;
pt.y=y;
pt2.y=y;
}
Enemy2.dEnemy=false;
Enemy3.cEnemy=0;
}
It should insert 6 numbers in two vectors, the only problem is that it doesn't - it actually inserts more.
I don't think the snippet will run unless Enemy2.dEnemy == true, and it won't stay true for ever.
The first time the snippet runs, then Enemy2.dEnemy is set to false and it shouldn't run again.
I don't set Enemy2.dEnemy to true anywhere except when the window is created.
If I insert a break point any where in the snippet, the program will work fine - it will insert ONLY 6 numbers in the two vectors.
Any ideas what's wrong here?
ok so i did some debugging.
i found that Enemy2.dEnemy=false; is being skipped for some reason.
i tried to do this to see if it was.
if(Enemy2.dEnemy)
{
pt.y=4;
pt.x=90;
pt2.y=4;
pt2.x=125;
for(int i=0; i<6; i++)
{
Enemy2.vS1Enemy.push_back(pt);
Enemy2.vS2Enemy.push_back(pt2);
y-=70;
pt.y=y;
pt2.y=y;
}
TCHAR s[244];
Enemy2.dEnemy=false;
if(Enemy2.dEnemy)
{
MessageBox(hWnd, _T("0"), _T(""), MB_OK);
}
else
{
MessageBox(hWnd, _T("1"), _T(""), MB_OK);
}
Enemy3.cEnemy=0;
}
well the message box popped saying 1 and my code worked fine. it seems that Enemy2.dEnemy=false; doesn't have time to run ;/
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah!
ok i found where is the real problem which was causing to insert more than 6 numbers..
it was where i was asigning Enemy2.dEnemy=true;
if(Enemy2.e1)
{
Enemy2.now=time(NULL);
Enemy2.tEnemy=Enemy2.now+4;
Enemy2.e1=false;
}
if(Enemy2.tEnemy==time(NULL))
{
check=1;
Enemy2.aEnemy=0;
Enemy2.dEnemy=true;
}
the problem seems that the second if runs more than one time, which is weird!
First things first: get rid of that abominable if (Enemy2.dEnemy == true) - it should be:
if (Enemy2.dEnemy)
(I also prefer to name my booleans as a readable sentence segments like Enemy2.isABerserker or Enemy3.hasHadLeftLegCutOffThreeInchesBelowTheKnee but that's just personal preference).
Other than that, the only thing I can suggest is a threading problem. There's nothing wrong with that code per se, but there is a window in which two threads could enter the if statement and both start pushing values into your vector.
In other words, if thread 1 is doing the pushing when thread 2 encounters the if statement, thread 2 will also start pushing values, since thread 1 has yet to set dEnemy to true. And don't think you can just move the assignment to the top of the if block - that will reduce but not remove the window.
My advice is to print out the contents of the vectors in the situation where they have more than six entries and that may give a clue as to what's happened (post the output here if you wish).
Re your update that the second if below is running twice:
if(Enemy2.e1)
{
Enemy2.now=time(NULL);
Enemy2.tEnemy=Enemy2.now+4;
Enemy2.e1=false;
}
if(Enemy2.tEnemy==time(NULL))
{
check=1;
Enemy2.aEnemy=0;
Enemy2.dEnemy=true;
}
If this code is executed twice in the same second (and that's not beyond the bounds of possibility), the second if statement will run twice.
That's because time(NULL) give you the number of seconds since the epoch so, until that second is over, you may well be executing the contents of that if thousands of times (or more).
If this problem disappears when you put in a breakpoint or a diagnostic output message, that's a strong clue that the problem is undefined behavior, which is usually caused by something like dereferencing an uninitialized pointer or careless use of const_cast.
The cause of the problem probably has nothing to do with the code you're looking at. It's caused somewhere else and just happens to show up here. It's like someone being hit by a falling brick: the obvious symptom is a man lying unconscious on the sidewalk, but the real problem has nothing to do with the man or the sidewalk, it's several stories up.
If you want to find the cause of the error, remove your diagnostics until the problem reappears, then start removing everything else. Prune away all of the other code. Whenever the error stops, back up until it starts again; if you don't see the cause of the error, start pruning somewhere else. Eventually the bug will have nowhere to hide.
I'm trying to debug a method which among other things, adds items to a list which is local to the method.
However, every so often the list size gets set to zero "midstream". I would like to set the debugger to break when the list size becomes zero, but I don't know how to, and would appreciate any pointers on how to do this.
Thanks.
Why not use conditional breakpoints?
http://blogs.msdn.com/saraford/archive/2008/06/17/did-you-know-you-can-set-conditional-breakpoints-239.aspx
in C#
if(theList.Count == 0){
//do something meaningless here .e.g.
int i = 1; // << set your breakpoint here
}
in VB.NET
If theList.Count = 0 Then
'do something meaningless here .e.g.
Dim i = 1; ' << set your breakpoint here
End If
For completeness sake, here's the C++ version:
if(theList->Count == 0){
//do something meaningless here .e.g.
int i = 1; // << set your breakpoint here
}
I can give a partial answer for Visual Studio 2005. If you open the "Breakpoints" window (Alt + F9) you get a list of breakpoints. Right-click on the breakpoint you want, and choose "Condition." Then put in the condition you want.
You have already got both major options suggested:
1. Conditional breakpoints
2. Code to check for the wrong value, and with a breakpoint if so happens
The first option is the easiest and best, but on large loops it is unfortunately really slow! If you loop 100's of thousands iterations the only real option is #2. In option #1 the cpu break into the debugger on each iteration, then it evaluates the condition and if the condition for breaking is false it just continiues execution of the program. This is slow when it happens thousands of times, it is actually slow if you loop just 1000 times (depending on hardware of course)
As I suspect you really want an "global" breakpoint condition that should break the program if a certain condition is met (array size == 0), unfortunately that does not exist to my knowledge. I have made a debugging function that checks the condition, and if it is true it does something meaningless that I have a breakpoint set to (i.e. option 2), then I call that function frequently where I suspect the original fails. When the system breaks you can use the call stack to identify the faulty location.