In this set of statements:
if(robot1Count < 12) {
robot1Count++;
}
else if(robot1Count < 24) {
robot1Count++;
}
else if(robot1Count < 36) {
robot1Count++;
}
else if(robot1Count < 48) {
robot1Count++;
}
else {
robot1Count = 0;
}
Imagine this is in an infinite loop, would this loop traverse from 0 to 48, change to 0. The thing I'm wondering is if the first block is executed, would all the following blocks be ignored? Or should I change the second to else if(robot1Count < 24 && robot1Count >= 12) ? Or does that not matter?
The thing I'm wondering is if the first block is executed, would all the following blocks be ignored?
Yes, they will all be ignored. The conditions won't even be evaluated. But you know, you could have tested this yourself!
if(robot1Count < 12) {
printf("< 12");
robot1Count++;
}
else if(robot1Count < 24) {
printf(">= 12 && < 24");
robot1Count++;
}
else if(robot1Count < 36) {
printf(">= 24 && < 36");
robot1Count++;
}
else if(robot1Count < 48) {
printf(">= 36 && < 48");
robot1Count++;
}
else {
printf(">= 48");
robot1Count = 0;
}
And then you can see which messages are printed to the console and then you'd know and feel what is going on!
This:
if (cond1)
stuff1;
else if (cond2)
stuff2;
else if (cond3)
stuff3;
else
stuff4;
is identical to this:
if (cond1) {
stuff1;
}
else {
if (cond2) {
stuff2;
}
else {
if (cond3) {
stuff3;
}
else {
stuff4;
}
}
}
Yes -- the if leg and the else leg of an if statement are mututally exclusive -- if the if leg executes the else does not (and vice versa).
Of course they will be ignored, unless you switch the "else if" to "if"
if the code above is in a infinite loop
example
int robot1Count = 0;
while (1 != 2) {
if(robot1Count < 12) {
robot1Count++;
}
else if(robot1Count < 24) {
robot1Count++;
}
else if(robot1Count < 36) {
robot1Count++;
}
else if(robot1Count < 48) {
robot1Count++;
}
else {
robot1Count = 0;
}
}
in a loop this will increment to 48 and go back to 0
it will only hit robot1Count++ per single execution of the loop
Related
I am a university student and my teacher is making us to create a prey/predator simulation with OMP for. I had covid during his lectures and he didn’t upload them, so sorry I am being stupid here
Onto the question,
I have implemented Age as the absolute value for the cell as he asked but I simply cannot think of a way to make each cell have their own individual age after breeding. Here is my code:
#pragma omp parallel num_threads(4)
{
#pragma omp for schedule(dynamic, 1)
for (int i = 1; i <= Y; i++) //for loop Y
{
for (int j = 1; j <= X; j++) //for loop X
{
int Left = i - 1;
int Right = i + 1;
int Bottom = j - 1;
int Top = j + 1;
int Fish = 0;
int Shark = 0;
int FishAge = 1;
int SharkAge = -1;
int NewFishAge = 1;
//COUNTING SHARK AND FISH
//SHARK OR FISH - TOP LEFT
if (oldOcean[Left][Top] > 0)
{
Fish++;
}
else if (oldOcean[Left][Top] < 0)
{
Shark--;
}
//SHARK OR FISH - TOP
if (oldOcean[i][Top] > 0)
{
Fish++;
}
else if (oldOcean[i][Top] < 0)
{
Shark--;
}
//SHARK OR FISH - TOP RIGHT
if (oldOcean[Right][Top] > 0)
{
Fish++;
}
else if (oldOcean[Right][Top] < 0)
{
Shark--;
}
//SHARK OR FISH - LEFT
if (oldOcean[Left][j] > 0)
{
Fish++;
}
else if (oldOcean[Left][j] < 0)
{
Shark--;
}
//SHARK OR FISH - LEFT
if (oldOcean[Right][j] > 0)
{
Fish++;
}
else if (oldOcean[Right][j] < 0)
{
Shark--;
}
//SHARK OR FISH - LEFT
if (oldOcean[Left][Bottom] > 0)
{
Fish++;
}
else if (oldOcean[Left][Bottom] < 0)
{
Shark--;
}
//SHARK OR FISH - LEFT
if (oldOcean[i][Bottom] > 0)
{
Fish++;
}
else if (oldOcean[i][Bottom] < 0)
{
Shark--;
}
//SHARK OR FISH - LEFT
if (oldOcean[Right][Bottom] > 0)
{
Fish++;
}
else if (oldOcean[Right][Bottom] < 0)
{
Shark--;
}
//AGE
if (oldOcean[i][j] > 0)
{
oldOcean[i][j]++;
FishAge = oldOcean[i][j] - 2;
}
else if (oldOcean[i][j] < 0)
{
oldOcean[i][j]--;
SharkAge = oldOcean[i][j] * -1;
//std::cout << "AGE" << SharkAge;
}
//EMPTY CELLS & BREEDING
if (oldOcean[i][j] == 0)
{
//newOcean[i][j] = 0;
if (Fish >= 4 && Shark > -4 && FishAge >= 2)
{
newOcean[i][j]=1;
}
else if (Shark <= -4 && Fish < 4 && SharkAge >= 3)
{
newOcean[i][j] = -1;
}
else
{
newOcean[i][j] = 0;
}
newOcean[i][j] = oldOcean[i][j];
}
//FISH CELLS
if (oldOcean[i][j] > 0)
{
if (FishAge < 10)
{
FishAge++;
}
//std::cout <<FishAge;
if (FishAge >= 10 || Shark <= -5)
{
oldOcean[i][j] = 0; //kill fish
FishAge = 0;
}
if (Fish >= 8)
{
newOcean[i][j] = 0; //overpopulation
}
newOcean[i][j] = oldOcean[i][j];
}
//SHARK CELLS
if (oldOcean[i][j] < 0)
{
if (SharkAge <= 20 )
{
SharkAge++;
}
if ((Shark <= -6 && Fish == 0) || SharkAge >= 20)
{
oldOcean[i][j] = 0; // dies of Starvation
SharkAge = 0;
}
if (ChanceofDeath <= rand() / ((int)RAND_MAX + 32))
{
newOcean[i][j] = 0; // Random Death ???
}
newOcean[i][j] = oldOcean[i][j];
}
}
}
}
I am a very amateur coder, so any improvement feel free to tell me too please, I love to learn
my code for the age is under the "//AGE" section
Sorry again, and thanks for the help.
Even without considering age, you must check every cell in every generation. And it should be easy to maintain an age per cell during these checks:
If a dead cell has three neighbors, it gets born (cell.age = 0).
If an alive cell has two or three neighbors, it survives (cell.age++).
If an alive cell has less than two or more than three neighbors, it dies. (No cell.age any more.)
The other day, I wrote a console game of Tic-Tac-Toe in c++ for my son. He wanted me to add a computer, and I ended us using the minimax algorithm for the first time. I did some quick testing, but really just gave my laptop to my son as soon as it was printing stuff, who played with it for a couple minuets. I looked over his sholder once or twice, and noticed that it wasn't playing optimally, iv'e been trying to debug it, but I can't see where it goes wrong. I tried getting rid of alpha beta prunning, but that did not change anything.
For context, on the board the computer is -1, blank is 0, and the player is 1.
Here is the minimax function:
int minimax(int board[9], int depth, int alpha, int beta, bool isMaxizimaizingPlayer)
{
bool found = false;
for (int i = 0; i < 9; i++)
{
if (board[i] == 0)
{
found = true;
}
}
if (!found)
{
return eval(board);
}
if (depth == 0 || eval(board) != 0)
{
return eval(board);
}
if (isMaxizimaizingPlayer)
{
int maxEval = -2;
for (int spot = 0; spot < 9; spot++)
{
if (board[spot] == 0)
{
board[spot] = 1;
int e = minimax(board, depth - 1, alpha, beta, false);
if (e > maxEval)
{
maxEval = e;
}
//if (beta < alpha)
//{
// break;
//}
board[spot] = 0;
}
}
return maxEval;
}
else {
int minEval = 2;
for (int spot = 0; spot < 9; spot++)
{
if (board[spot] == 0)
{
board[spot] = -1;
int e = minimax(board, depth - 1, alpha, beta, true);
if (e < minEval)
{
minEval = e;
}
//if (beta < alpha)
//{
// break;
//}
board[spot] = 0;
}
}
return minEval;
}
}
To be compleate, here is my eval function:
int eval(int board[9])
{
/*horizontial*/
for (int i = 0; i < 3; i++)
{
if (board[i * 3] == board[i * 3 + 1] && board[i * 3 + 2] == board[i * 3] && board[i * 3] != 0)
{
return board[i * 3];
}
}
/*vertical*/
for (int i = 0; i < 3; i++)
{
if (board[i] == board[i + 3] && board[i] == board[i + 6] && board[i] != 0)
{
return board[i];
}
}
/*Both diags*/
if (board[4] != 0) {
if (board[0] == board[4] && board[0] == board[8])
{
return board[4];
}
if (board[2] == board[4] && board[4] == board[6])
{
return board[4];
}
}
return 0;
}
And here is the inital call:
int spot = 0;
int minEval = 2;
for (int i = 0; i < 9; i++)
{
if (board[i] == 0)
{
board[i] = -1;
int score = minimax(board, 3, -2, 2, false);
if (score < minEval) {
minEval = score;
spot = i;
}
board[i] = 0;
}
}
std::cout << "The computer went in spot " << spot + 1 << std::endl;
board[spot] = -1;
printBoard(board);
It looks like you only call minimax with a depth of three, so the algorithm will only look up to three moves ahead, if you want optimal play you need to set the depth to > 9, so that the agent is always looking ahead to the end of the game.
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Ok, so I have this code(declarations are global). It is basically a simple chess program and this part of the program tries to assess which fields are threatened by black pieces at a certain point in time. If a field is threatened, the c3[][] value of it goes from 0 to 1. The problem is that even after I made 100% sure the if conditions are met, the program would still refuse to set the c3[][] values to 1. And even worse, the if(c2[I][J]==9||c2[I][J]==10) partworks fine, which makes it even harder for me to identify the problem. I can provide the whole source code if necessary.
void atacalb()
{
int I,J;
for(I=1;I<=8;I++)
for(J=1;J<=8;J++)
{if(c2[I][J]==7){c3[I+1][J+1]=1,c3[I+1][J-1]=1;}
if(c2[I][J]==8){c3[I+2][J+1]=1,c3[I+2][J-1]=1,c3[I+1][J+2]=1,c3[I-1][J+2]=1,c3[I-2][J+1]=1,c3[I-2][J-1]=1,c3[I+1][J-2]=1,c3[I-1][J-2]=1;}
int z,x,ok;
for(I=1;I<=8;I++)
for(J=1;J<=8;J++)
if(c2[I][J]==9||c2[I][J]==10)
{
z=I,x=J,ok=1;
while((z<=8||x<=8)&&ok)
{z++,x++;
if(c2[z][x]==0)c3[z][x]=1;
else {c3[z][x]=1,ok=0;}
}
z=I,x=J,ok=1;
while((z<=8||x>=1)&&ok)
{i++,j--;
if(c2[z][x]==0)c3[z][x]=1;
else {c3[z][x]=1,ok=0;}
}
z=I,x=J,ok=1;
while((z>=1||x>=1)&&ok)
{z--,x--;
if(c2[z][x]==0)c3[z][x]=1;
else {c3[z][x]=1,ok=0;}
}
z=I,x=J,ok=1;
while((z>=1||x<=8)&&ok)
{z--,x++;
if(c2[z][x]==0)c3[z][x]=1;
else {c3[z][x]=1,ok=0;}
}
}
if(c2[I][J]==12||c2[I][J]==10)
{z=I,x=J,ok=1;
while(x<=8&&ok==1)
{x++;
if(c2[z][x]==0)c3[z][x]=1;
else {c3[z][x]=1,ok=0;}
}
z=I,x=J,ok=1;
while(z<=8&&ok==1)
{z++;
if(c2[z][x]==0)c3[z][x]=1;
else {c3[z][x]=1,ok=0;}
}
z=I,x=J,ok=1;
while(z>=1&&ok==1)
{z--;
if(c2[z][x]==0)c3[z][x]=1;
else {c3[z][x]=1,ok=0;}
}
z=I,x=J,ok=1;
while(x>=1&&ok==1)
{x--;
if(c2[z][x]==0)c3[z][x]=1;
else {c3[z][x]=1,ok=0;}
}
}
}
}
int main()
{//some code
atacalb();
//some more code
}
Using proper indention and bracket placement is key here! I stripped done all the code wich actually processes stuff and just left loops and if-statements in for readability. I then properly indented the code how the compiler gets to see it
int I, J;
for(I = 1; I <= 8; I++)
for(J = 1; J <= 8; J++) {
if(c2[I][J] == 7) {
}
if(c2[I][J] == 8) {
}
for(I = 1; I <= 8; I++)
for(J = 1; J <= 8; J++) /*!*/
if(c2[I][J] == 9 || c2[I][J] == 10) { ///< only this gets processed by the loop
while((z <= 8 || x <= 8) && ok){
if(c2[z][x] == 0) {
}
else {
}
}
while((z <= 8 || x >= 1) && ok) {
if(c2[z][x] == 0) {
}
else {
}
}
while((z >= 1 || x >= 1) && ok) {
if(c2[z][x] == 0) {
}
else {
}
}
while((z >= 1 || x <= 8) && ok) {
if(c2[z][x] == 0) {
}
else {
}
}
}
if(c2[I][J] == 12 || c2[I][J] == 10) { ///< not this
while(x <= 8 && ok == 1) {
if(c2[z][x] == 0) {
}
else {
}
}
while(z <= 8 && ok == 1) {
if(c2[z][x] == 0) {
}
else {
}
}
while(z >= 1 && ok == 1) {
if(c2[z][x] == 0) {
}
else {
}
}
while(x >= 1 && ok == 1) {
if(c2[z][x] == 0) {
}
else {
}
}
}
}
The problem is marked in the code above: the for loops (marked /*!*/) will not process the if-statement (if(c2[I][J] == 12 || c2[I][J] == 10)) only the first if statement after the marked loop. A way to fix this would be to either use a if-else-statement in this case or surround all your loops with curly braces as it should be done anyway. This is so that you can add and remove lines inside the brackets and can be sure that they will be processed as well. Also it makes the program flow more clear to the non-compiler-reader (i.e. the human being which tries to understand the code).
Also depending on the size of c2 which is probably an 8x8 array you should change the loop conditions. C++ uses 0-indexed arrays so an array with a size of 8 will be accessed by the indices from 0 - 7 not 1 - 8. So for example
for(I = 1; I <= 8; I++)
for(J = 1; J <= 8; J++) {
//...
should most likely be
for(I = 0; I < 8; I++) // smaller not smaller-equal
for(J = 0; J < 8; J++) {
// ...
You need to stop trying to play c++ golf if you want to debug basic problems in your code. Add white space where appropriate, including new lines.
Set a breakpoint on the line in question that sets your array location to 1, then step through the code with a watch on that variable, line by line. I can guarantee its not "refusing to set it." Its a branch in your code that you are not expecting to execute executing.
I'm trying to make a game (simple 2d platformer).
The program runs as it should, but an if statement doesn't work correctly.
I have this function:
int Collision::platformCollision(SDL_Rect *hitbox, SDL_Rect plat) {
if (checkCollision(*hitbox, plat)) {
//X
//LEFT SIDE
if (hitbox->x + hitbox->w > plat.x && hitbox->x + hitbox->w < plat.x + 5) {
hitbox->x = plat.x - hitbox->w;
return 1;
}
//RIGHT SIDE
if (hitbox->x < plat.x + plat.w && hitbox->x > plat.x + plat.w - 5) {
hitbox->x = plat.x + plat.w;
return 2;
}
//Y
//UPPER SIDE
if (hitbox->y + hitbox->h > plat.y && hitbox->y + hitbox->h < plat.y + 10) {
hitbox->y = plat.y - hitbox->h;
return 3;
}
//BOTTOM SIDE
if (hitbox->y < plat.y + plat.h && hitbox->y > plat.y + plat.h - 10) {
hitbox->y = plat.y + plat.h;
return 4;
}
}
//NOT COLLIDING
return -1;
}
So I have this function return an int whenever it collides with a certain part of the platform.
Then I have this function:
void Player::playerCheckPlatCollision(SDL_Rect rect) {
if (platformCollision(p_hitboxPTR, rect) == 3) {
setGravityF(0.0);
}
if (platformCollision(p_hitboxPTR, rect) == 4) {
p_space = false;
}
return;
}
The problem should be easy to fix.
When I debug the program it gets to return 4; in the platformCollision function, but when I do
if (platformCollision(p_hitboxPTR, rect) == 4) {
p_space = false;
}
It doesn't put p_space as false, it just ignores the == 4 and when I debugged, I saw it got to that if statement.
Can someone please help.
Thanks.
If platformCollision returns 4 on the first call, it alters state, and will not return 4 on the second call.
void Player::playerCheckPlatCollision(SDL_Rect rect) {
int bang = platformCollision(p_hitboxPTR, rect);
if (bang == 3) {
setGravityF(0.0);
} else if (bang == 4) {
p_space = false;
}
}
I'm designing and programming an elevator-like robot for a high school project. Could I possibly do anything to make this any simpler? Or better? I have attached a picture of my design that I made in AutoCAD Inventor with labels.
For those not familiar with RobotC or VEX (it is VERY similar to C and C++): the limit switches (limit1, limit2, ...) and bump switches (floor1, floor2, ...) are analog buttons and return a value of 0 if not pressed and 1 if pressed. The motor (mainMotor) rotates the gear which causes the mechanism to travel upwards on the slide. When the shaft sticking out the motor mechanism moves up and down, it presses limit switches and causes it to return a value of 1.
int callup [3];
int calldown [3];
int floorat[3];
int main ()
{
if (SensorValue[limit1] == 1)
{
floorat[0] = 1;
}
else
{
floorat[0] = 0;
}
if (SensorValue[limit2] == 1)
{
floorat[1] = 1;
}
else
{
floorat[1] = 0;
}
if (SensorValue[limit3] == 1)
{
floorat[2] = 1;
}
else
{
floorat[2] = 0;
}
if (SensorValue[floor1] == 1)
{
calldown[0] = 1;
SensorValue[LED1] = 1;
}
if (SensorValue[floor2] == 1 && floorat[2] == 1)
{
calldown[1] = 1;
SensorValue[LED2] = 1;
}
if (SensorValue[floor2] == 1 && floorat[0] == 1)
{
callup[1] = 1;
SensorValue[LED2] = 1;
}
if (SensorValue[floor3])
{
callup[2] = 1;
SensorValue[LED3] = 1;
}
motors ();
}
void motors ()
{
if (callup[2] == 1 && floorat[2] == 1)
{
int x = 1;
while (x < 3)
{
SensorValue[LED3] = 1;
wait(0.5);
SensorValue[LED3] = 0;
wait(0.5);
}
callup[2] = 0;
main ();
}
else if (callup[1] == 1 && floorat[1] == 1)
{
int x = 1;
while (x < 3)
{
SensorValue[LED2] = 1;
wait(0.5);
SensorValue[LED2] = 0;
wait(0.5);
}
callup[1] = 0;
main ();
}
else if (callup[0] == 1 && floorat[0] == 1)
{
int x = 1;
while (x < 3)
{
SensorValue[LED1] = 1;
wait(0.5);
SensorValue[LED1] = 0;
wait(0.5);
}
callup[0] = 0;
main ();
}
if (callup[2] == 1 && floorat[1] == 1 && calldown[0] == 0 || callup[2] == 1 && floorat[0] == 1 && callup[1] == 0)
{
startMotor(mainMotor, 60);
untilTouch(limit3);
stopMotor(mainMotor);
callup[2] = 0;
wait(1);
main ();
}
if (callup[1] == 1 && floorat[0] == 1)
{
startMotor(mainMotor, 60);
untilTouch(limit2);
stopMotor(mainMotor);
callup[1] = 0;
wait(1);
main();
}
if (calldown[1] == 1 && floorat[2] == 1)
{
startMotor(mainMotor, -60);
untilTouch(limit2);
stopMotor(mainMotor);
calldown[1] = 0;
wait(1);
main();
}
if (calldown[0] == 1 && floorat[2] == 1 && calldown[1] == 0 || calldown[0] == 1 && floorat[1] == 1)
{
startMotor(mainMotor, -60);
untilTouch(limit1);
stopMotor(mainMotor);
calldown[0] = 0;
wait(1);
main();
}
}
Although it shouldn't be a concern for this question, the 60 in the startMotor command is the speed of the motor, just to make it clearer.
Feel free to ask any more questions.
Let's define what are the states of an elevator at a given moment:
An elevator can go up, down, or be idle.
The elevator is at a given floor and go from one floor to the other when it trigger a switch:
Now, if we translate this into some pseudo code (which should be easily translated to RobotC) :
enum elevator_status = { idle, down, up };
int currentfloor; //1, 2, 3
switch(elevator_status)
{
case idle:
//we check if a button is pressed and possibly go up or down
if(SensorValue(floor1))
{
if(currentfloor > 1)
elevator_status = down;
}
else if(SensorValue(floor2))
{
if(currentfloor > 2)
elevator_status = down;
else if(currentfloor < 2)
elevator_status = up;
}
else if(SensorValue(floor3))
{
if(currentfloor < 3)
elevator_status = up;
}
break;
case up:
case down:
//we check if we trigger a floor switch and stop the elevator
if(SensorValue(limit1))
{
currentfloor = 1;
elevator_status = idle;
}
else if(SensorValue(limit2))
{
currentfloor = 2;
elevator_status = idle;
}
else if(SensorValue(limit3))
{
currentfloor = 3;
elevator_status = idle;
}
break;
}
//we set the speed of the motor
if(elevator_status == up)
{
set_motorstate(cw);
)
else if(elevator_status == down)
{
set_motorstate(ccw);
}
else if(elevator_status == idle)
{
set_motorstate(idle);
}
Note : in this code the elevator will only take care of new up and down floor calls when the elevator is idle. It does not store up and down call while it is moving and go there later. I do not know if it was a requirement for you.
I'm not familiar with RobotC or VEX, however I've noticed a certain amount of replicated operations that could be made into their own functions.
The following code snippets I would make into separate functions. So in the large function called motors you have the following set of operations:
int x = 1;
while (x < 3)
{
SensorValue[LED3] = 1;
wait(0.5);
SensorValue[LED3] = 0;
wait(0.5);
}
callup[2] = 0;
main ();
This is repeated with slightly different values.
Here I'd write a function like the following:
void adjust_sensors( size_t led, size_t level )
{
int x = 1;
while (x < 3)
{
SensorValue[led] = 1;
wait(0.5);
SensorValue[led] = 0;
wait(0.5);
}
callup[level] = 0;
main ();
}
You can do the same for the following code as well:
startMotor(mainMotor, 60);
untilTouch(limit3);
stopMotor(mainMotor);
callup[2] = 0;
wait(1);
main ();
Also it seems like the while loop will never end because the value of x never changes.
You also have a typo at the top when you declare:
int callown [2];
I presume you meant:
int calldown [2];
Would be good to add some comments to your code as well for clarity.
Hope this helps.
I could be way off, because I'm just a student with questions of my own but it looks like you may have made a mistake in your array sizes. For instance, when you declared:
int floorat[2];
This made the array size 2. Then you refer to 3 element locations in this array [0, 1, 2]. Also, can't you just use a regular integer, and assign it values 1, 2, or 3?
I would recommend redefining these varaibles as:
int callup;
int calldown;
int floorat;
Then you can avoid extra lines of code and simplify the if/else clauses to:
if (SensorValue[limit1] == 1)
{
floorat = 1;
}
if (SensorValue[limit2] == 1)
{
floorat = 2;
}
if (SensorValue[limit3] == 1)
{
floorat = 3;
}