for() loops

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
Post Reply
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5666
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

for() loops

Post by BlueCrab »

Ok, I have another question for the programming people.
I am trying to make a function that counts down from 255, and compares the value to a set variable, and then if it compares, sets another variable, and then does something based on what this last variable is. I figured that the best way to do this would be using a for loop, like so:

Code: Select all

for(i = 255; i > 0; i--)	{
		if(i == stats[0].stats.speed)
			turn = 0;
		if(i == stats[1].stats.speed)
			turn = 1;
		if(i == stats[2].stats.speed)
			turn = 2;
		if(i == stats[3].stats.speed)
			turn = 3;
		if(i == enemies[0].stats.speed)
			turn = 10;
		if(i == enemies[1].stats.speed)
			turn = 11;
		if(i == enemies[2].stats.speed)
			turn = 12;
		if(i == enemies[3].stats.speed)
			turn = 13;
		if(i == enemies[4].stats.speed)
			turn = 14;
		if(i == enemies[5].stats.speed)
			turn = 15;
		if(i == enemies[6].stats.speed)
			turn = 16;
		if(i == enemies[7].stats.speed)
			turn = 17;
		if(i == enemies[8].stats.speed)
			turn = 18;
		if(turn > -1 || turn < 4)	{
			bat_do_menu();
			break;
		}
		if(turn > 9 || turn < 19)	{
			bat_enemy_ai();
			break;
		}
// Some other code here for stuff to do while in the for loop
}
But it seems like something goes TERRIBLY wrong in the code somewhere. Because no matter what I set any of the enemies[].stats.speed to, it will always go to the part that says bat_do_menu();, and it doesn't even do that correctly. Any help would be appreciated. Thanks in advance.
User avatar
toastman
Iron Fist of Justice
Iron Fist of Justice
Posts: 4933
Joined: Sat Nov 10, 2001 3:08 am
Location: New Orleans
Has thanked: 0
Been thanked: 0
Contact:

Re: for() loops

Post by toastman »

BlueCrab wrote: if(turn > -1 || turn < 4) {
bat_do_menu();
break;
}
[/code]
But it seems like something goes TERRIBLY wrong in the code somewhere. Because no matter what I set any of the enemies[].stats.speed to, it will always go to the part that says bat_do_menu();, and it doesn't even do that correctly. Any help would be appreciated. Thanks in advance.
For that part, I think it is a simple logic error. You are running bat_do_menu if turn is greater than -1 OR less than 4, in other words every time. You want to change it to

Code: Select all

if ((turn > -1) && (turn < 4))
 //do stuff
I've had that problem bite me in the ass on multiple occasions :D
No signature.
NightHammer
Psychotic DCEmu
Psychotic DCEmu
Posts: 747
Joined: Tue Oct 08, 2002 11:37 am
Location: Back in my little hole in Russ Engineering Center
Has thanked: 0
Been thanked: 0
Contact:

Post by NightHammer »

I do believe Toastman is right. I always have that problem.

Later!
NightHammer
All your systems are belong to me
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5666
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Post by BlueCrab »

Thanks a lot, I would've never caught that! Time to make sure it works!
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5666
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Post by BlueCrab »

Ok, that solves one problem. Now on to the next, If I wanted the loop to return to its countdown after executing either the bat_do_menu() or bat_enemy_ai() functions, would it just involve taking out the break; after them, or would something else have to be changed?
Once again, thanks in advance.
EvilSporkMan
God Of All Things Sporkish
God Of All Things Sporkish
Posts: 755
Joined: Sat Feb 16, 2002 1:04 pm
Location: Somewhere over the cuckoo's nest
Has thanked: 0
Been thanked: 0

Post by EvilSporkMan »

Yeah, if you want the loop to keep looping just take out the break. Also, you really want to look up how to use a switch statement, it would save you using all those if statements. Example:

Code: Select all

for(i = 255; i > 0; i--)   {
      switch(i) {

      case stats[0].stats.speed:  turn = 0;
                                             break;
//etc

default: printf("You screwed up in that one switch statement, dude\n");
      } //ENDING BRACE OF SWITCH STATEMENT
      if(turn > -1 || turn < 4)   { 
         bat_do_menu(); 
         break; 
      } 
      if(turn > 9 || turn < 19)   { 
         bat_enemy_ai(); 
         break; 
      } 
// Some other code here for stuff to do while in the for loop 
} 
You can go anywhere you want if you look serious and carry a clipboard.
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5666
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Post by BlueCrab »

My compiler doesn't seem to like the switch.... Here's what I got spewed at me.
MSYS wrote:battle.c: In function `bat_order':
battle.c:582: case label does not reduce to an integer constant
battle.c:586: case label does not reduce to an integer constant
battle.c:590: case label does not reduce to an integer constant
battle.c:594: case label does not reduce to an integer constant
battle.c:598: case label does not reduce to an integer constant
battle.c:602: case label does not reduce to an integer constant
battle.c:606: case label does not reduce to an integer constant
battle.c:610: case label does not reduce to an integer constant
battle.c:614: case label does not reduce to an integer constant
battle.c:618: case label does not reduce to an integer constant
battle.c:622: case label does not reduce to an integer constant
battle.c:626: case label does not reduce to an integer constant
battle.c:630: case label does not reduce to an integer constant
... Oh well, back to the if statements..... :(
q_006
Mental DCEmu
Mental DCEmu
Posts: 415
Joined: Thu Oct 10, 2002 7:18 pm
Has thanked: 0
Been thanked: 0
Contact:

this didn't work??

Post by q_006 »

Code: Select all

for(i = 255; i > 0; i--)   {
   switch (i){
      case stats[0].stats.speed: turn = 0; break;
      case stats[1].stats.speed: turn = 1; break;
      case stats[2].stats.speed: turn = 2; break;
      case stats[3].stats.speed: turn = 3; break;
      case enemies[0].stats.speed: turn = 10; break;
      case enemies[1].stats.speed: turn = 11; break;
      case enemies[2].stats.speed: turn = 12; break;
      case enemies[3].stats.speed: turn = 13; break;
      case enemies[4].stats.speed: turn = 14; break;
      case enemies[5].stats.speed: turn = 15; break;
      case enemies[6].stats.speed: turn = 16; break;
      case enemies[7].stats.speed: turn = 17; break;
      case enemies[8].stats.speed: turn = 18; break;
      default: {
                    printf(" Wrong turn, try again!\n");
                    if(turn > -1 || turn < 4)   {
                      bat_do_menu();
                      break;
                    }
                    if(turn > 9 || turn < 19)   {
                      bat_enemy_ai();
                      break;
                    }
      } break;
   }//end of switch
// Some other code here for stuff to do while in the for loop
}end of for loop
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5666
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Post by BlueCrab »

I think that the compiler is complaining about the fact that I have a variable as the case. If statements will work just the same though. So I will continue to use them.
BlackAura
DC Developer
DC Developer
Posts: 9951
Joined: Sun Dec 30, 2001 9:02 am
Has thanked: 0
Been thanked: 1 time

Post by BlackAura »

The cases have to be integer constants, like 1, 15, 0xFFA5, 361622, -267 or anything like that. You can't use a variable for it becuase of the way switches are translated to machine code (as a jump table usually, and you can't use variables in a jump table).
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5666
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Post by BlueCrab »

That's what I figured the compiler messages meant, thanks for clearing it up for me.
EvilSporkMan
God Of All Things Sporkish
God Of All Things Sporkish
Posts: 755
Joined: Sat Feb 16, 2002 1:04 pm
Location: Somewhere over the cuckoo's nest
Has thanked: 0
Been thanked: 0

Post by EvilSporkMan »

My bad on the switches :|
You can go anywhere you want if you look serious and carry a clipboard.
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5666
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Post by BlueCrab »

That's ok, we all make mistakes.
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5666
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Post by BlueCrab »

I have another question involving for loops. If I have a loop like so:

Code: Select all

	for(l = 0; l <= 13; l++)	{
		if(p[l]->stats.speed == stats[0].stats.speed)	{
			turn = 0;
		}
		else if(p[l]->stats.speed == stats[1].stats.speed)	{
			turn = 1;
		}
		else if(p[l]->stats.speed == stats[2].stats.speed)	{
			turn = 2;
		}
		else if(p[l]->stats.speed == stats[3].stats.speed)	{
			turn = 3;
		}
		else if(p[l]->stats.speed == enemies[0].stats.speed)	{
			turn = 10;
		}
		else if(p[l]->stats.speed == enemies[1].stats.speed)	{
			turn = 11;
		}
		else if(p[l]->stats.speed == enemies[2].stats.speed)	{
			turn = 12;
		}
		else if(p[l]->stats.speed == enemies[3].stats.speed)	{
			turn = 13;
		}
		else if(p[l]->stats.speed == enemies[4].stats.speed)	{
			turn = 14;
		}
		else if(p[l]->stats.speed == enemies[5].stats.speed)	{
			turn = 15;
		}
		else if(p[l]->stats.speed == enemies[6].stats.speed)	{
			turn = 16;
		}
		else if(p[l]->stats.speed == enemies[7].stats.speed)	{
			turn = 17;
		}
		else if(p[l]->stats.speed == enemies[8].stats.speed)	{
			turn = 18;
		}

	// Other stuff....
}
What is the best way to make sure that once the program finds a match in the ifs that it stops looking after that? Any suggestions?
Soilwork
DCEmu Freak
DCEmu Freak
Posts: 66
Joined: Sat Jul 06, 2002 7:40 am
Location: France
Has thanked: 0
Been thanked: 0
Contact:

Post by Soilwork »

I'm not sure I understood what you want so if I got you wrong, I'm sorry.. :)
So, I think you want to leave the loop once you've found a match, right?
I see 2 ways to do that : First you can simply add a 'break' statement in each 'if' block. This will exit the loop and the program will go on right after the 'for' block.
Another way to do so would be to change the value of your 'l' counter and set it to 14, for example, in your case, so that the loop condition ain't true any more. The first solution is cleaner though :mrgreen:

Again, sorry if this isn't what you asked for.
++
Soilwork
"And then... I'm glad I found true friends..."
"Avant de mourir, je suis heureux d'avoir eu des amis..."
Image
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5666
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Post by BlueCrab »

Never mind, figured out a better way to do it. Thank you all for all of your help, and maybe after I get back from this church retreat that I have to attend, I'll have something interesting......
Post Reply