1. ## Assignment help

Hi,

I'm taking an intro to programming class in 1st year university, and I cannot for the life of me figure out what is wrong in my code.

We have to program the game of nim using 2 functions, a draw function which basically draws the layout using the inputted number of rocks per row, and then redraws the board when the player subtracts rocks.

The second is the play function, which takes all the inputs from the main function and converts them into the new values for the draw function. The play function returns a zero when all the rows equal zero.

In the main function there are just the input prompts and the shift between players. It loops until the play function returns zero.

Im fairly sure I have the majority of it working, but there are a few key issues that make it unplayable:

1. For some reason the draw function doubles up for the board setup and the 2nd player's turn.
2. I cannot figure out how to get my player 2 to return to player one after the loop begins again, I have tried many methods and still it does not work.
3. The inputted variables do work directly after the players turn, but on the next player's turn the board is reset to the original specifications.

This is really giving me a headache and I've spent hours and hours trying to find a solution.
I also realize there are probably dozens of things that will be bothering you REAL programmers, and I apologize profusely, however I'm more interested in just getting the damn thing to work properly before going into efficiency..

Thank's for any help!

(also sorry for the wall of text..)

Code:
```#include <stdio.h>

void draw_nim(int row_1, int row_2, int row_3) //function draws the gameboard
{
//Each of the following take the inputted row value and proceeds to output the number of O's that is inputted as well
//for Row 1

printf("Row 1: ");
for(int i = 0; i < row_1; i = i + 1)
{
printf("O");
}
printf("\n");

//Row 2

printf("Row 2: ");
for(int i = 0; i < row_2; i = i + 1)
{
printf("O");
}
printf("\n");

//Row 3

printf("Row 3: ");
for(int i = 0; i < row_3; i = i + 1)
{
printf("O");
}
printf("\n");
}

int play_nim(int rownum, int rocknum, int row_1, int row_2, int row_3) //The play function. This takes the inputted changes to the board and actually impliments them
{
if(row_1 > 0 && row_2 > 0 && row_3 > 0) //checks to make sure all the rows are are greater than zero (still have rocks present)
{
if(rownum == 1) //for row 1 it removes the rocks the player inputs
{
row_1 = row_1 - rocknum;
}

if(rownum == 2) //for row 2 it removes the rocks the player inputs
{
row_2 = row_2 - rocknum;
}

if(rownum == 3) //for row 3 it removes the rocks the player inputs
{
row_3 = row_3 - rocknum;
}

draw_nim(row_1, row_2, row_3);
}
else return 0; //if there are no rocks left on the board the function returns zero
}

int main(void)
{
int row_1, row_2, row_3; //The number of rocks in each row
int rownum, rocknum; //The inputted row number and number of rocks to be removed from said row
int player; //The variable stating which player is currently playing

//Game Setup

printf("Enter the number of rocks in each row: "); //Player imputs how many rocks rows 1, 2 and 3 each have
scanf("%d %d %d", &row_1, &row_2, &row_3);

while(row_1 <= 0 || row_2 <= 0 || row_3 <= 0) //checks to make sure that only a positive value is imputted for each row
{
printf("You must enter in values greater than zero. Try again:");
scanf("%d %d %d", &row_1, &row_2, &row_3); //lets the player input new values if the first are invalid
}

draw_nim(row_1, row_2, row_3); //draws the initial board

//Main Game

player = 1; //makes player 1 is active
if(player = 2)
player = 1;
else player = 1;

while(play_nim(rownum, rocknum, row_1, row_2, row_3) > 0) //will loop until the "play_nim" function returns a zero
{
printf("Player %d - Enter the row and number of rocks to remove: ", player); //Player one picks the row and number of rocks to remove
scanf("%d %d", &rownum, &rocknum);

//Defensive Programming and subsequent reentry of variables in case of invalid inputs

while(rownum > 3 && rownum <= 0) //Makes sure only rows 1-3 are imputted
{
printf("Invalid move. Try again: ");
scanf("%d %d", &rownum, &rocknum);
}

if(rownum == 1)
{
while(rocknum > row_1 || row_1 == 0) //ensures that player 1 cannot take more rocks than row 1 contains
{
printf("You can't take more rocks than there is left in the row! Try again: ");
scanf("%d %d", &rownum, &rocknum);
}
}

if(rownum == 2) //ensures that player 1 cannot take more rocks than in row 2
{
while(rocknum > row_2 || row_2 == 0)
{
printf("You can't take more rocks than there is left in the row! Try again: ");
scanf("%d %d", &rownum, &rocknum);
}
}

if(rownum == 3)
{
while(rocknum > row_3 || row_3 == 0) //player 1 cannot take more rocks than in row 2
{
printf("You can't take more rocks than there is left in the row! Try again: ");
scanf("%d %d", &rownum, &rocknum);
}
}

while(rocknum <= 0) //player 1 cannot take more rocks than in row 3
{
printf("You cannot take zero or negative rocks! Try again: ");
scanf("%d %d", &rownum, &rocknum);
}

play_nim(rownum, rocknum, row_1, row_2, row_3); //takes the inputted values and sticks them in the play function

player = player + 1

printf("Player %d - Enter the row and number of rocks to remove: ", player);
scanf("%d %d", &rownum, &rocknum);

//Defensive Programming (all the lines of code are the exact same as the programming for player 1)

while(rownum > 3 && rownum <= 0)
{
printf("You may only pick rows 1 to 3. Try again: ");
scanf("%d %d", &rownum, &rocknum);
}

if(rownum == 1)
{
while(rocknum > row_1)
{
printf("You can't take more rocks than there is left in the row! Try again: ");
scanf("%d %d", &rownum, &rocknum);
}
}

if(rownum == 2)
{
while(rocknum > row_2)
{
printf("You can't take more rocks than there is left in the row! Try again: ");
scanf("%d %d", &rownum, &rocknum);
}
}

if(rownum == 3)
{
while(rocknum > row_3)
{
printf("You can't take more rocks than there is left in the row! Try again: ");
scanf("%d %d", &rownum, &rocknum);
}
}

while(rocknum <= 0)
{
printf("You cannot take zero or negative rocks! Try again: ");
scanf("%d %d", &rownum, &rocknum);
}

play_nim(rownum, rocknum, row_1, row_2, row_3);
}

printf("Player %d wins!", player); //when the rows all read zero and the play function returns a zero, the game ends. This declares the winner

return 0; //the program then proceeds to die.
}```

2. Here are some warnings I got trying to compile your code.

(36): warning #2235: Not all control paths return a value. <----- Check your function for all return types not just the Else statement.
(84): warning #2030: '=' used in a conditional expression. <-------- that should be if(player==2) NOT if(player=2)
(138): error #2001: Syntax error: expected ';' but found 'printf'. <------ missing semicolon

3. I'm just a noob, but in my C Primer Plus book it says that you should have your main function before your other functions. You would also have to include function prototypes then. I know I'm not resolving your main problem, but it's a pretty quick fix that might make a better impression on your professor. At least according to C Primer Plus. Good luck!

4. @ Gratiafide it is is legal in C to declare your function definitions above main, thus leaving out the prototypes.

5. I tried fixing the mitakes that Camel-man pointed out, and now I keep getting this error that I have never seen before "error: 'for' loop initial declarations are only allowed in C99 mode" referring to line 9 I believe?
I don't see anything unusual about that for loop?

6. Code:
`for(int i = 0; i < row_1; i = i + 1)`
You are probably compiling under an earlier standard like C89, which does not support declaring variables within a for loop like that.

7. Stink I have Code Blocks what the heck. I got his program to run by initalizing i at the start of the function and erasing the ints in the three "for(int i..." parts.

8. Originally Posted by camel-man
Code:
`for(int i = 0; i < row_1; i = i + 1)`
You are probably compiling under an earlier standard like C89, which does not support declaring variables within a for loop like that.
Nope, that's fine. My compiler adds in -std=c99 thinger which makes declaring that i valid.

EDIT: realized you were talking to the other guy, not that line. Sorry!

9. Yeah, I forgot to quote gratiafide, I was referring to his comment on the error he was getting.

10. Aha. My Pelles complier apparently can handle the C99 code.

11. Originally Posted by camel-man
Here are some warnings I got trying to compile your code.

(36): warning #2235: Not all control paths return a value. <----- Check your function for all return types not just the Else statement.
(84): warning #2030: '=' used in a conditional expression. <-------- that should be if(player==2) NOT if(player=2)
(138): error #2001: Syntax error: expected ';' but found 'printf'. <------ missing semicolon
ok so I corrected the last two, but I'm not sure I understand what you mean by the first one. My function (hopefully) should be taking the inputted values, subtracting the rocks off the original number of rocks and saving it back in that variable. That variable should then be shipped over to the draw_nim function which uses them. I have it that once the number of rocks hit zero in every row that it returns zero, thus ending the main game loop. What other return types am I checking for?

12. Your if statement does not have a return value, yet your function has a return value of int. That is why you are getting that warning. Right now as you have it, you only return a 0 if the else is executed. But what do you return if the ELSE is NOT executed?

13. Just some context, I only learned about functions last week so up until then I never had to worry about return values other than the return 0 at the end of main. Basically, I have no idea how to properly use them.

When else is not executed I want it to continue accepting inputs from main and changing the draw function accordingly.. Sorry if this is nonsensical haha, I have a lot to learn

14. Code:
```player = player + 1;
//Think about that, you are incrementing player instead of switching back from player 1 to 2```
You should replace that line with the line that you had before your while loop

ex.) if(player == 1)
player = 2;
else player = 1;

Also, from lines 138 to 183 why do you have that? It is redundant, you already have the while loop, you do not need duplicate code within that while loop.

15. Well that partially takes care of the player problem! But when I play it goes:

Player 1
(player 1 does stuff)
Player 2
(player 2 does stuff)
Player 2 AGAIN
back to player 1