Errors in Tic-Tac-Toe Game - c

I've been trying to code a tic-tac-toe game in C except I've gotten some errors I don't understand. I know this still needs some work but right now I just want to run the program before I add to it. Can someone help me? Here's my code:
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
int board[3][3] = {
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}
};
int main (void)
{
int const user1 = 1;
int const user2 = 2;
char move[10];
while (! all_locations_filled()) {
printf("User-1, please enter your move:");
scanf("%s", move[10]);
if(valid_location(move[10]))
mark_location(user1, move[10]);
display_board(board[3][3]);
else if(won_the_game(user1)
printf("Congratulations User-1, You Won the Game!");
break;
else
printf("Invalid Move");
printf("User-2, please enter your move:");
scanf("%s", move[10]);
if(valid_location(move[10]))
mark_location(user2, move[10]);
display_board();
else if(won_the_game(user2)
printf("Congratulations User-2, You Won the Game!");
break;
else
printf("Invalid Move");
return 0;
}
bool valid_location(char str[10]) {
int strcmp(x, y);
if (strcmp(str[10], "upperLeft") == 0 || strcmp(str[10], "up") == 0 || strcmp(str[10], "upperRight") == 0 || strcmp(str[10], "left") == 0 || strcmp(str[10], "center") == 0 || strcmp(str[10], "right") == 0 || strcmp(str[10], "lowerLeft") == 0 || strcmp(str[10], "down") == 0 || strcmp(str[10], "lowerRight") == 0)
return true;
}
void mark_location(int userU, char str[10]) {
int strcmp(x, y);
if (strcmp(str[10], "upperLeft") == 0)
board[0][0] = userU;
else if (strcmp(str[10], "up") == 0)
board[0][1] = userU;
else if (strcmp(str[10], "upperRight") == 0)
board[0][2] = userU;
else if (strcmp(str[10], "left") == 0)
board[1][0] = userU;
else if (strcmp(str[10], "center") == 0)
board[1][1] = userU;
else if (strcmp(str[10], "right") == 0)
board[1][2] = userU;
else if (strcmp(str[10], "lowerLeft") == 0)
board[2][0] = userU;
else if (strcmp(str[10], "down") == 0)
board[2][1] = userU;
else if (strcmp(str[10], "lowerRight") == 0)
board [2][2] = userU;
}
char display_board(int array[][]) {
int i, j;
for (i=0; i<3; ++i)
for (j=0; j<3; ++j)
if (array[i][j] == 0)
print("-");
else if (array[i][j] == 1)
print("x");
else if (array[i][j] == 2)
print("o");
}
void all_locations_filled() {
int i, j;
for (i=0; i<3; ++i)
for (j=0; j<3; ++j)
if board[i][j] == 0
return false;
return true;
}
bool won_the_game(userU) {
int i, j;
if (board[0][j] == userU)
return true;
else if (board[1][j] == userU)
return true;
else if (board[2][j] == userU)
return true;
else if (board[i][0] == userU)
return true;
else if (board[i][1] == userU)
return true;
else if (board[i][2] == userU)
return true;
else
return false;
}
Here are the errors the compiler gives me:
tictactoe.c: In function ‘main’:
tictactoe.c:19: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’
tictactoe.c:24: error: expected expression before ‘else’
tictactoe.c:115: error: expected declaration or statement at end of input
tictactoe.c:115: error: expected declaration or statement at end of input

if(valid_location(move[10]))
mark_location(user1, move[10]);
display_board(board[3][3]);
you have to use "{" and "}" because you have 2 lines.

Use move instead of move[10] in your scanf statement, and when you're passing it to functions. move refers to the array, move[10] just means the 10th position in that array.
Put braces {} around the code in your if / else blocks if they're more than a single line of code (or preferably always, but that's a style issue.)

I found some errors...
scanf("%s", move[10]);
What do you want to do here? If you want to read a string, use
scanf("%s", move );
If you want to read only one character in the 10th position of the array, use
scanf("%c", &move[9] );
Note that your array was declared as move[10], so it's positions go from move[0] to move[9]. Position move[10] is not valid.
Here:
if(valid_location(move[10]))
mark_location(user1, move[10]);
display_board(board[3][3]);
else if(won_the_game(user1)
printf("Congratulations User-1, You Won the Game!");
break;
else
printf("Invalid Move");
You probably meant:
if(valid_location(move[10]))
{
mark_location(user1, move[10]);
display_board(board[3][3]);
}
else if(won_the_game(user1)
{
printf("Congratulations User-1, You Won the Game!");
break;
}
else
printf("Invalid Move");
And here:
void all_locations_filled() {
int i, j;
for (i=0; i<3; ++i)
for (j=0; j<3; ++j)
if board[i][j] == 0
return false;
return true;
}
You forgot the () in the "if". It should be:
if (board[i][j] == 0)
Also, your functions must be declared before you call them. So, declare de functions before main.
You don't have to implement it there, just declare. For example:
void all_locations_filled();
int main (void)
{
...
}
In the last function:
bool won_the_game(userU)
you have to define the type of "userU".
You also forgot to close the brace "}" in the end of the main's while.

You are trying to scan an integer but the scanf argument expects an string (char array). Try %d instead of %s. Thats the Formatstring for Decimal numbers.

If you want to put more then one instruction after an if, you should close it in {}.
Otherwise, the compiler think that only the first is in-condition, and the rest should be done anyway.

scanf("%s", move); not scanf("%s", move[10]);
if(valid_location(move)) not if(valid_location(move[10]))
mark_location(user1, move); not mark_location(user1, move[10]);
if (strcmp(str, "upperLeft") == 0) not if (strcmp(str[10], "upperLeft") == 0)
etc. etc.
You don't do arrays in C by putting square brackets after each and every use of an array. You use the square bracket in basically two situations, you are declaring the array in which case the brackets contain the size of the array, you are accessing an element of the array in which case the brackets contain the index.
You probably won't want to hear this but there's plenty else wrong with your code. You probably need to read a book, and start a bit simpler.

After you've dealt with your compiler errors you might want to look at the function won_the_game which is reading uninitialised variables i and j and will probably give you "access violation" errors as i and j are likely to be out of bounds.
In addition your logic is wrong since obviously you don't win by just occupying one position.

Related

the first while loop works but it doesnt proceed to the next while loop right below it

void main() {
int y = 0;
char password[30], username[40], total_items[10000], input_item,
ip11[] = "-IPhone 11\n", ipX[] = "-IPhone X\n";
char ap[] = "-AirPods\n", chrg[] = "-Charger\n";
char scrpro[] = "-Screen Protector\n", reset_str[] = " ";
int i = 0, total_amount = 0, auth = 4;
while (auth > 10)
;
{
printf("Enter Username:");
scanf("%s", &username);
fflush(stdin);
printf("Enter password:");
scanf("%s", &password);
fflush(stdin);
if ((strcmp(username, "admin") == 0) &&
(strcmp(password, "admin123") == 0)) {
auth += 7;
} else {
printf("Invalid password or username\n");
printf("%d tries left\n", auth);
auth -= 1;
}
}
while (y > 5) {
printf("Welcome,These are the items that we sell:\n");
printf("-----------------------------------------------\n");
printf("a. IPhone X - $1200 \nb. IPhone 11 - $1500\n");
printf(
"c. AirPods - $300 \nd. Charger - $15 \ne. Screen Protector - "
"$20\n");
printf("\n");
printf("To buy, key in the alphabet beside the item.\n");
printf("Please input 1 item at a time\n");
while (i < 10) {
printf("Enter item wanted(input 'z' to finish cart):");
scanf(" %c", &input_item);
if ((input_item == 'a') || (input_item == 'A')) {
total_amount += 1200;
strcat(total_items, ipX);
} else if ((input_item == 'b') || (input_item == 'B')) {
total_amount = total_amount + 1500;
strcat(total_items, ip11);
} else if ((input_item == 'c') || (input_item == 'C')) {
total_amount = total_amount + 300;
strcat(total_items, ap);
} else if ((input_item == 'd') || (input_item == 'D')) {
total_amount = total_amount + 15;
strcat(total_items, chrg);
} else if ((input_item == 'e') || (input_item == 'E')) {
total_amount = total_amount + 20;
strcat(total_items, scrpro);
} else if ((input_item == 'z') || (input_item == 'Z'))
i += 10;
else
printf("Invalid item, please input again\n");
}
printf("Your total is: $%d\n", total_amount);
printf("Your items are:\n%s\n", total_items);
printf("Please collect your receipt and head over to the counter\n");
printf("Thank you for coming to OneTop!\n");
printf("\n");
strcpy(total_items, reset_str);
}
}
I expected the code to proceed to the second while loop but the code instead just crashes.
Incorrect format specifier:
scanf("%s", &username);
username is a constant pointer to the first element of the array. There's no need to use the & operator with it.
Stray semicolon:
The statement:
while (auth > 10)
;
is equivalent to saying:
"While auth is greater than 10, do nothing."
It's dead code.
The block of code after the while loop will always execute, irregardless of the value of auth.
Even if you were to remove the semi-colon, the program would never enter the loop, as:
auth == 4
And the condition:
if (auth > 10)
is false.
Similarly, the second loop would never be entered, as:
y == 0
And the condition:
if (y > 5)
is false.
Flushing stdin:
fflush(stdin);
is undefined behaviour.
Once the abstract state machine reaches undefined behaviour, no further assumption about the continuation of the execution of the program can be made.
Aside:
Implementation-defined definition of main:
From C11:
The function called at program startup is named main. The
implementation declares no prototype for this function. It shall be
defined with a return type of int and with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent;10) or in some other implementation-defined manner.
Did you check your variables? Your first while loop while(auth > 10);, but auth = 4. Maybe you meant while(auth < 10);. Same for while (y > 5),, because y = 0

why is my if statement going to "else" even though it should stop at "else if"?

I'm trying to make a chomp game in c as a school assignment, but have been stuck at a silly IF - statement...
Basically, every time it runs (the CheckMove function), if I make a turn that isn't correct, it goes straight down to the else statement instead of returning the correct int... why??
I have removed lots of the code that isn't part of the problem. hope it is okay.. din't know if it is more appreciated to post the whole program instead...
Please help!
while(1)
{
PrintBoard();
player = (player == 2) ? 1 : 2;
while(1)
{
GetMove(player, move);
if (CheckMove(move) == 0) // if everything is fine, break the loop and change player
{
UpdateBoard(move);
break;
}
else if (CheckMove(move) == 1) //this never gets triggered
{
printf("\nAlready taken. Please try again! (row col): ");
continue;
}
else if (CheckMove(move) == 2) //this never gets triggered
{
printf("\nYou lost!\n");
return 0;
}
else if (CheckMove(move) == 3) //This ALWAYS gets triggered
{
printf("\nIllegal move. Try again! (row col): ");
continue;
}
}
}
}
void Initialize()... // initializes the board
void PrintBoard()... // prints the board
void GetMove(int player, int move[2])
{
printf("\nPlayer %d: your move! (row col): ", player);
for (int i = 0; i < 2; i++) scanf(" %d", &move[i]);
}
int CheckMove(int move[2])
{
int check = 99;
if ((move[0] >= 1 && move[0] < 5) && (move[1] >= 1 && move[1] <= 10))
{
move[0] -= 1;
move[1] -= 1;
// more checks
if (board[move[0]][move[1]] == 'Z')
{
check = 1;
}
else if(board[move[0]][move[1]] == 'X')
{
check = 2;
}
else
{
check = 0;
}
}
else { check = 3; } //as soon as I hit check 1 or 2, I end up here...
return check;
}

Receiving exit code -1073741819 when program is ran

I'm making a tic-tac-toe program in C. My code is listed below.
#include <stdio.h>
#include <conio.h>
char evaluateWinConditions(char board[3][3]);
int main(void)
{
puts("---");
puts("---");
puts("---");
char board[3][3] = {{"-"}}; // board
char key = 0; // stores key presses
// stores position of mouse pointer
int row = 1;
int column = 1;
// stores player turn
int player = 1;
printf("\033[%d;%dH", row, column);
while (evaluateWinConditions(board) == 0) {
key = _getch();
switch (key) {
case 'a':
column -= 1;
break;
case 'w':
row -= 1;
break;
case 'd':
column += 1;
break;
case 's':
row += 1;
break;
case ' ':
if (player == 1) {
printf("%c", 'X');
board[row][column] = 'X';
player = 2;
}
else {
printf("%c", 'O');
board[row][column] == 'O';
player = 1;
}
break;
}
printf("\033[%d;%dH", row, column);
}
printf("\033[5;1H");
if (evaluateWinConditions(board == 1)) printf("Player 1 wins.");
else printf("Player 2 wins.");
}
char evaluateWinConditions(char board[3][3])
{
if (board[0][0] == board[0][1] == board[0][2] ||
board[1][0] == board[1][1] == board[1][2] ||
board[2][0] == board[2][1] == board[2][2] ||
board[0][0] == board[1][1] == board[2][2] ||
board[0][2] == board[1][1] == board[2][0]) {
if (board[0][0] == "X") return 1;
else return 2;
}
else {
return 0;
}
}
When I compile the program, there's no errors. However, I receive a run time error with code -1073741819 when I run the program. I'm using Windows 10 64-bit and Visual Studio 2019. This error appears after about one second when I run the program. When I debug the program in Visual Studio, I receive an error on line 74 "Exception thrown: read access violation; board was nullptr"
The probable cause of the exception is a consequence of the nonsensical comparison board == 1 in the function call evaluateWinConditions(board == 1). The board == 1 comparison is a constraint violation (use of equality operator between pointer and integer that isn't a null pointer constant) that is probably evaluating to the int value 0, and that int value 0 (which is not a null pointer constant here) is probably being converted in an implementation-defined way to a null pointer (which is another constraint violation due to lack of an explicit cast) of type char (*)[3] to become the value of the board parameter in the evaluateWinConditions function. The evaluateWinConditions function is dereferencing that null pointer, resulting in an access violation exception.
There are plenty of other errors in the original code.

Function recursively runs forever if value above 3 is input

As a mandatory preface, I am new to C, and am likely simply missing something extremely obvious. I appreciate any and all time and effort taken to look over my silly problem.
I have a recursive function whose purpose is to print out a large "x" made of smaller x characters, where width is the length of each side of the x. For example, a width of "3" would have the following output:
Shape:
X X
X
X X
Returning.
Where "Returning." prints just before returning to main.
The following function does just this for a width of 1 and 3, but fails to do so with 5, 7, 9, etc.
void Recurse(int left, int right, int flag, int num){
int i;
if(((left && right) == num/2) && (flag == 0)){
for(i=0;i<num;i++){
if (i == (num/2) ){
printf("X");
}
else
printf(" ");
}
printf("\n");
flag = 1;
Recurse(left-1, right+1, flag, num);
}
else if(flag == 0){
for(i=0;i<num;i++){
if((i == left) || (i == right)){
printf("X");
}
else
printf(" ");
}
printf("\n");
Recurse(left+1, right-1, flag, num);
}
else if(flag == 1){
for(i=0;i<num;i++){
if((i == left) || (i == right)){
printf("X");
}
else
printf(" ");
}
printf("\n");
if (((left == 0) && (right == num-1)) && (flag == 1))
printf("\nReturning.\n");
return;
Recurse(left-1, right+1, flag, num);
}
}
The only thing I have in my main function is an initialization of width with some odd int, and a call to the function. I would like to get the code actually... printing correctly prior to cleaning up the logic a bit. Thank you for any help provided.
In
if(((left && right) == num/2) && (flag == 0)){
left && right is a boolean value, probably you wanted
if ((left == num/2) && (right == num/2) && (flag == 0)){

Comparison with multiple == (Fruit machine task)

I'm struggling with my "IF" comparison between 3 variables.
The program is supposed to comapare wheels 1, 2 and 3, and reward the player with £5 if all 3 are the same, and £2 if 2 of the 3 are the same.
However sometimes it doesn't work ( gives me £5 even though none are the same)
Please could someone take a look and tell me how to fix it?
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
const char *symbol[4] = {" bell ", " orange ", " cherry ", "horseshoe"};
int main ()
{
srand(time(NULL));
int playagain =1;
int wheel_1,wheel_2,wheel_3;
int i;
int money=10;
int j = (rand()%30)+10;
int start=1;
int k;
printf("you have £%d. Press any key to gamble £1\n", money);
getchar();
while(playagain == 1)
{
for (i=0; i<j; i++)
{
printf("\033[2J\033[0;0f");
printf("\033[%d;%df", 0, 0);
wheel_1 = (rand()%4);
wheel_2 = (rand()%4);
wheel_3 = (rand()%4);
printf("%s ", symbol[wheel_1]);
printf("%s ", symbol[wheel_2]);
printf("%s \n", symbol[wheel_3]);
for (k=0; k<10000000; k++)
{
}
}
printf("%d, %d, %d\n", wheel_1, wheel_2, wheel_3);
if (wheel_1 == wheel_2 == wheel_3)
{
printf("Congrats! You win £5\n");
money = (money+5)-1;
}
else if (wheel_1 == wheel_2 ||
wheel_1 == wheel_3 ||
wheel_2 == wheel_3 )
{
printf("Congrats! You win £2\n");
money = (money+2)-1;
}
else
{
printf("Unlucky, you have lost your £1\n");
money--;
}
printf ("You now have £%d\n", money);
char *replay;
printf ("would you like to play again?");
scanf ("%s", &replay);
if (strcmp(&replay, "yes") == 0)
{
playagain = 1;
}
else
{
playagain = 0;
}
}
}
The way you are using if to compare wheels is wrong
if (wheel_1 == wheel_2 == wheel_3)// Wrong
You should be using
if ((wheel_1 == wheel_2 ) && (wheel_2 == wheel_3))
Almost everything in C returns a value. The expression wheel_2 == wheel_3 also returns a value. The value returned by this expression compares equal to zero if the condition is false else it is non zero(will be 1).
When you do wheel_2 == wheel_3 and suppose the expression is true then it will return 1. This is again compared with wheel_1 like wheel_1 == 1.
As above, it looks like you need:
if((wheel_1 == wheel_2) && (wheel_2 == wheel_3))
Let us know if it works like this :-).
Yes, in here you would have to keep the comparison values differently,
beacuse that x=y=z would return a value and that would be true even though they are not.
Hence you keep them as in associate property if(x==y) && if(y==z) so you naturally get x=z.

Resources