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.
Related
I am creating a tic tac toe program. I have different functions for testing different possible outcomes. When I test my diagonal possibility, it works correctly. However, when I try to test rows or columns it always returns 0. I think it's because my return statement and break statements are in the wrong place ,but I can't find the right place.
int testCol (int board[3][3]){//test cols for win
int b = 0;
int c = 0;
for (b = 0; b < 3; b++){
if (board[0][b] == 1 && board[1][b] == 1 && board[2][b] == 1){//test player 1
return 1;
cout << "I work" << endl;
break;
}
else if(board[0][b] == 2 && board[1][b] == 2 && board[2][b] == 2){//test player 2
return 2;
break;
}
else{//if none are true return no win
return 0;
}
}
}
Two things; you need to move the return 0 outside of the loop. Otherwise, you'll never get around to testing all of the possibilities. Second, your output statement is after a return, so it's unreachable.
You dont need a break statement after return. Last return in your function seems to be a false status from function, so you can keep it out of the loop. Your output statement from first if branch should come before your return.
int testCol (int board[3][3]){//test cols for win
int b = 0;
int c = 0;
for (b = 0; b < 3; b++){
if (board[0][b] == 1 && board[1][b] == 1 && board[2][b] == 1){//test player 1
cout << "I work" << endl;
return 1;
}
else if(board[0][b] == 2 && board[1][b] == 2 && board[2][b] == 2){//test player 2
return 2;
}
}
return 0;
}
You return early when you found a full column. If there is no winner, you return 0 after you tested all columns.
Here the fixed version.
int testCol (int board[3][3]){//test cols for win
for (int b = 0; b < 3; b++){
if (board[0][b] == 1 && board[1][b] == 1 && board[2][b] == 1){//test player 1
return 1;
}
else if(board[0][b] == 2 && board[1][b] == 2 && board[2][b] == 2){//test player 2
return 2;
}
}
return 0;
}
Beginner at c++ here.
for (int z = 0; z < arraysize; z++) {
if (generated[z][0] == generated[z][1] && generated[z][1] == generated[z][2]) {
wins++;
}
if (generated[0][z] == generated[1][z] && generated[1][z] == generated[2][z]) {
wins++;
}
As you can see it checks for the horizontal lines. I would like to check wether or not there are 3 in a row diagonally. If there is, the wins variable should add one. Any ideas?
You can do this by using z as the index for both extents instead of just one.
for (int z = 0; z < arraysize; z++)
{
if (generated[z][z] == generated[0][0])
{
//... handle it
}
if (generated[arraysize - z - 1][z] == generated[arraysize - 1][0])
{
//... handle it
}
}
Unfortunately this will only get you so far. The current logic in your code is not going to work as you expect. The problem is that it keeps a cumulative count of matches across all lines both horizontally and vertically. If you have several partial matches you could end up with a an incorrect win value. You can avoid this problem by adding a couple of additional loops to check the contents of each the vertical and horizontal lines as you perform your scan. This will require a couple of additional flags to be added as well to keep track of whether there is a win in either direction. The following example should provide you with a much more flexible set of checks that are flexible and can be used for any size array.
bool hwin = false;
bool vwin = false;
int d1wins = 0;
int d2wins = 0;
for (int z = 0; z < arraysize; z++)
{
int hwins = 0;
int vwins = 0;
// Check horizontal line
for (int i = 0; i < arraysize; ++i)
{
if (generated[i][z] == generated[0][z])
{
hwins++;
}
}
hwin = hwin || hwins == arraysize;
// Check vertical line
for (int i = 0; i < arraysize; ++i)
{
if (generated[z][i] == generated[z][0])
{
vwins++;
}
}
vwin = vwin || vwins == arraysize;
// Check diagonal
if (generated[z][z] == generated[0][0])
{
d1wins++;
}
// Check diagonal
if (generated[arraysize - z - 1][z] == generated[arraysize - 1][0])
{
d2wins++;
}
}
bool dwin = d1wins == arraysize || d2wins == arraysize;
From two if condition, you used, I think you are trying something like 3*3 Tic-tac-toe.
So, if your arraysize is 3, you can't use following checking in your loop:
if (generated[z][z] == generated[z+1][z+1] && generated[z+1][z+1] == generated[z+2][z+2])
{
wins++;
}
z+2 and z+1 will cross the array limit.
So you can check it outside of your loop:
generated[0][0] == generated[1][1] && generated[1][1] == generated[2][2]
generated[0][2] == generated[1][1] && generated[1][1] == generated[2][0]
I am trying to make this go through the array in a spiral order. When it finds 2, it should replace it with 0 and the next number in the spiral order should become 2. So, if my array is
000
200
000
is should become
000
020
000
The variable ok tells me if I found that number 2 and simply modifies the next number to 2. Note that it doesn't loop through it. When It reaches the center of the array, it stops and doesn't go backwards or starts over.
Any ideas why it doesn't work? It simply doesn't modify my array at all.
#include<iostream>
using namespace std;
#define ROWS 3
#define COLS 3
int main()
{
int arr[ROWS][COLS] = {{2,0,0},
{0,0,0},
{0,0,0}};
// Four direction counters of current movement
// Horizontal right, vertical bottom, horizontal left and vertical top respectively
int hr, vb, hl, vt, ok=0;
// levl indicates current depth of our imaginary rectangle into array. Starting value is zero
// since we are looping on the boundaries and ending value is the inner most rectangle
int levl;
for (levl=0; levl < COLS - levl; levl++)
{
for(hr=levl; hr < COLS-levl; hr++) // go right
{
if (ok==1)
{
arr[levl][hr] == 2;
ok = 2;
}
if ( (arr[levl][hr] == 2) && (ok == 0) )
{
arr[levl][hr] == 0;
ok = 1;
}
}
for(vb=levl+1; vb < COLS-levl; vb++) // go down
{
if (ok == 1)
{
arr[vb][hr-1] == 2;
ok = 2;
}
if ( (arr[vb][hr-1] == 2) && (ok == 0) )
{
arr[vb][hr-1] == 0;
ok = 1;
}
}
for(hl=vb-1; hl-1 >= levl; hl--) // go left
{
if ( ok == 1)
{
arr[vb-1][hl-1] == 2;
ok = 2;
}
if ( (arr[vb-1][hl-1] == 2) && (ok == 0) )
{
arr[vb-1][hl-1] == 0;
ok = 1;
}
}
for(vt=vb-1; vt-1 > levl; vt--) // go up
{
if (ok == 1)
{
arr[vt-1][hl] == 2;
ok = 2;
}
if ( (arr[vt-1][hl] == 2) && (ok==0) )
{
arr[vt-1][hl] == 0;
ok = 1;
}
}
}
cout << endl;
for(int t = 0;t < 3;t++)
{
for(int u = 0;u < 3;u++)
cout<<arr[t][u]<<" ";
cout<<endl;
}
int a;
cin>>a;
return 0;
}
The reason that your array is not being modified is because you are using "==" instead of "=". So
if ((arr[levl][hr] == 2)&&(ok==0))
{
arr[levl][hr] == 0;
ok=1;
}
should be
if ((arr[levl][hr] == 2)&&(ok==0))
{
arr[levl][hr] = 0;
ok=1;
}
== Is a comparison operator and = assigns the value. Check your code very carefully and make it more readable for you could be able to find easy mistakes like that :).
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;
}
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