Tic tac toe program user input correction needed - c

I am building a tic tac toe game as an assignment which will put two users vs each other. I have gotten the game to run but a requirement of the game is to "ask the user to enter their move with integers in between 0 and 2, inclusive, specifying the row and column of the square to place a piece." As I have it know the user chooses a number 1-9 and enters that but based on the question i have to format it to get two numbers 1 specifying row and the other column eg 1 = 0,0 2 = 0,1 and so on. I am fairly new to programming can anyone help me implement this or point me in the right direction; also any comments or changes to the main program to improve it is welcomed.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int winner = 0, count = 0;
int data[9], index, letter, user, flag, i, k;
for (i = 0; i < 9; i++)
data[i] = ' ';
while (count < 9) {
flag = 0;
printf("\n\n");
printf("\t\t\t %c | %c | %c \n", data[0], data[1], data[2]);
printf("\t\t\t----+----+----\n");
printf("\t\t\t %c | %c | %c \n", data[3], data[4], data[5]);
printf("\t\t\t----+----+---\n");
printf("\t\t\t %c | %c | %c \n\n", data[6], data[7], data[8]);
if (count % 2 == 0) {
letter = 'X';
user = 1;
} else {
letter = 'O';
user = 2;
}
printf("User %d enter your move (1-9):", user);
scanf("%d", &index);
if (index < 1 || index > 9) {
printf("Allowed index is 1 to 9!!\n");
continue;
}
if (data[index - 1] == 'X' || data[index - 1] == 'O') {
printf("Position already occupied!!\n");
continue;
}
data[index - 1] = letter;
count++;
for (i = 0; i < 9; i++) {
if (i % 3 == 0)
flag = 0;
if (data[i] == letter)
flag++;
if (flag == 3) {
winner = 1;
goto win;
}
}
flag = 0;
for (i = 0; i < 3; i++) {
for (k = i; k <= i + 6; k = k + 3) {
if (data[k] == letter)
flag++;
}
if (flag == 3) {
winner = 1;
goto win;
}
flag = 0;
}
if ((data[0] == letter && data[4] == letter && data[8] == letter) ||
(data[2] == letter && data[4] == letter && data[6] == letter)) {
winner = 1;
goto win;
}
}
win:
printf("\n\n");
printf("\t\t\t %c | %c | %c \n", data[0], data[1], data[2]);
printf("\t\t\t----+----+----\n");
printf("\t\t\t %c | %c | %c \n", data[3], data[4], data[5]);
printf("\t\t\t----+----+---\n");
printf("\t\t\t %c | %c | %c \n\n", data[6], data[7], data[8]);
if (winner) {
printf("User %d is the winner. Congrats!!\n", user);
} else {
printf("The game is a tie\n");
}
return 0;
}

Instead of the index variable you have, you'll want an x variable and a y variable. Then, instead of scanf("%d", &index);, you could do scanf("%d,%d", &x, &y); (the player will have to enter a comma in this example.)
Then, assuming we have a variable called "board_width" which equals 3 (because I like to avoid magic numbers,) we could get the position from the user's input using data[(y * board_width) + x]

Related

variables in c changing value randomly

I'm learning C at school, and as homework I have to write the tictactoe game. No problem with the "algorithm", but I do not understand why if I change the order of the variables declaration, the program output drastically changes or even the programme stops working. For example, if I swap line 12 with line 13, the element of the array coord change values at random points of the programme. Can someone explain me why this happen?
#include <stdio.h>
#define DIM 3
#define MAX 11
int main(void) {
char c;
int state = 0; //Variable for the switch case
int nC, nR; //Variables used to count how many X or O there are in the rows and columns of the grid
int i, j;
int coord[2] = {0, 0}; //Array for the coordinates
char grid[DIM][DIM]; //Grid 3x3
char player1[MAX] = "", player2[MAX] = ""; //Name of the players
printf("Player 1, insert your name (max 10 characters): ");
gets(player1);
fflush(stdin);
printf("Player 2, insert your name (max 10 characters): ");
gets(player2);
for (i = 0; i < DIM; i++) { //Inizialize the grid with '.'
for (j = 0; j < DIM; j++) {
grid[i][j] = '.';
printf("%3c", grid[i][j]);
if (j == 0 || j == 1) printf(" |");
}
if (i == 0 || i == 1) printf("\n- - - - - - - -\n");
}
do{
switch (state) {
case 0: //State 0: Player 1 is asked for the coordinates corresponding to the position where you want to insert the X symbol
printf("\n%s your turn: ", player1);
scanf("%d %d", &coord[1], &coord[2]);
if (grid[coord[1] - 1][coord[2] - 1] == '.' && grid[coord[1] - 1][coord[2] - 1] != 'O') { //Check that the selected coordinates are free. Otherwise it prints an error message
grid[coord[1] - 1][coord[2] - 1] = 'X';
c = 'X';
state = 2;
}
else{
state = 0;
printf("Invalid coordinates!\n");
}
break;
case 1: //State 1: Player 2 is asked for the coordinates corresponding to the position where you want to insert the O symbol
printf("\n%s your turn: ", player2);
scanf("%d %d", &coord[1], &coord[2]);
if (grid[coord[1] - 1][coord[2] - 1] == '.' && grid[coord[1] - 1][coord[2] - 1] != 'X') { //Check that the selected coordinates are free. Otherwise it prints an error message
grid[coord[1] - 1][coord[2] - 1] = 'O';
c = 'O';
state = 2;
}
else{
printf("Invalid coordinates!\n");
state = 1;
}
break;
case 2: //State 2: Check if there a right combination of X or O
printf("\n");
for (i = 0; i < DIM; i++) {
for (j = 0; j < DIM; j++) {
printf("%3c", grid[i][j]);
if(j == 0 || j == 1) printf(" |");
}
if (i == 0 || i == 1) printf("\n- - - - - - - -\n");
}
nC = 0;
nR = 0;
i = coord[1] - 1;
for (j = 0; j < DIM; j++) {
if(grid[i][j] != c){
break;
}
else{
nR++;
}
}
j = coord[2] - 1;
for (i = 0; i < DIM; i++) {
if (grid[i][j] != c) {
break;
}
else{
nC++;
}
}
if (nC == 3 || nR == 3) state = 3;
else if (c == 'X') state = 1;
else state = 0;
break;
case 3:
if (c == 'X') printf("\n%s IS THE WINNER!\n", player1);
else printf("\n%s IS THE WINNER!\n", player2);
return 0;
break;
}
} while (1);
}
In C, array indices for an array with n elements run from 0 to n−1.
int coord[2] = {0, 0}; defines coord to have two elements, so their indices are 0 and 1.
Throughout the code, coord[1] and coord[2] are used. coord[2] is outside the defined array, so the behavior of the program is not defined by the C standard.

Program stops working after typing a character and I don't know how

I'm making a Hangman game for a school requirement. After running the program, it suddenly stops working after guessing a word. It's not finished yet since it's not working
here's what I'm trying to accomplish:
Hangman is a word guessing game in which the player is told how many letters are in the word. The player must discover the word by guessing letters one at a time. Each correctly guessed letter is added to the word. On each wrong guess, a body part is added to a picture of a hanged man. The player is allowed 5 mistakes, corresponding to hangman's head, body, left arm, right arm, left leg. At the 6th mistake the right leg is drawn, and the game is over. If a letter is repeated more than once, the repeating occurrences are always considered as an error, even if the first time was correct. Once the hanged man is complete, the player loses the game.
A hangman will look like this after 0 to 6 errors. There should be no whitespace at the end of lines.
+--+ +--+ +--+ +--+ +--+ +--+ +--+
| | o | o | o | o | o | o
| | | | | /| | /|\ | /|\ | /|\
|\ |\ |\ |\ |\ |\ / |\ / \
Your task is to Implement the game of Hangman. For this problem, you need to have an array holding ten different words for the player to choose from. You will be required to use rand() function under <stdlib.h> to choose between those ten words. The chosen word will then be guessed by the player.
Sample Run.
H A N G M A N
+---+
|
|
|\
===
Missed letters:
Mystery word: _ _ _
Guess a letter.
a
H A N G M A N
+---+
|
|
|\
===
Missed letters:
Mystery word: _ a _
Guess a letter.
o
H A N G M A N
+---+
| o
|
|\
===
Missed letters: o
Mystery word: _ a _
Guess a letter.
r
H A N G M A N
+---+
| o
| |
|\
===
Missed letters: o r
Mystery word: _ a _
Guess a letter.
t
H A N G M A N
+---+
| o
| |
|\
===
Missed letters: o r
Mystery word: _ a t
Guess a letter.
a
H A N G M A N
+---+
| o
| /|
|\
===
You have already guessed that letter. Choose again.
Guess a letter.
c
Yes! The secret word is "cat"! You have won!
Do you want to play again? (yes or no)
no
here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <string.h>
char word[3][10] = {"gabb", "mnl", "josh"};
char parts[6] = {" "};
char mwords[6] = {" "};
char blanks[10];
int life = 0;
int len;
char guess;
void body(int);
void generate(int);
int compare(int);
int main(){
int res;
char ans[3];
int gen;
srand(time(0));
gen = rand() % 3;
for(int i = 0; i < strlen(word[gen]); i++){
blanks[i] = '_';
}
do{
while(life < 6){
body(life);
generate(gen);
res = compare(gen);
if(res == 1){
printf("Yes! The secret word is \"%s\"! You have won!");
break;
}
}
printf("Do you want to play again? (yes or no): ");
scanf(" %s", ans);
}while(strcmp (ans, "yes") == 0);
}
this prints the body of hangman depending on the number of lives
void body(int n){
char guess;
switch(n){
case 6:
parts[5] = '\\';
case 5:
parts[4] = '/';
case 4:
parts[3] = '\\';
case 3:
parts[2] = '/';
case 2:
parts[1] = '|';
case 1:
parts[0] = 'O';
}
printf("H A N G M A N\n");
printf("\t+---+\n");
printf("\t| %c\n", parts[0]);
printf("\t| %c%c%c\n",parts[2], parts[1], parts[3]);
printf("\t|\\ %c %c\n", parts[4], parts[5]);
printf("\t===\n");
}
this generates the "guessing area"
void generate(int a){
len = strlen(word[a]);
printf("Missed words: ");
for(int i = 0; i < 6; i++){
if(mwords == '\0')
break;
else
printf("%c",mwords[i]);
}
printf("\n");
printf("Mystery word: ");
for(int i = 0;i < len; i++){
printf("%c ", blanks[i]);
}
printf("\n");
I don't know if the problem lies here
printf("Guess a letter: ");
scanf("%c", guess);
for (int i = 0; i < len; i++){
if(word[a][i] == guess)
blanks[i] = guess;
}
for(int i = 0; i < len;i++){
if(word[a][i] == guess)
break;
else
life++;
}
}
this function compares two strings
int compare(int comp){
if(strcmp (word[comp], blanks) == 0)
return 0;
else
return 1;
}
There are many errors in your code and in the logic of your program:
char ans[3]; //should be ans[4] to be able to read the word yes for example
the funtion void body(int n) in the body of switch(n) in the different case your never use break for separe each case. Solution:
switch(n){
case 6: parts[5] = '\\'; break;
case 5: parts[4] = '/'; break;
case 4: parts[3] = '\\'; break;
case 3: parts[2] = '/'; break;
case 2: parts[1] = '|'; break;
case 1: parts[0] = 'O'; break;
}
other difficult in your code logic is:
if(res == 1){
printf("Yes! The secret word is \"%s\"! You have won!\n");
break
}
When res == 1 the words are not the same, also in
printf("Yes! The secret word is \"%s\"! You have won!\n");
generate a warning message because you not add the vale for %s. The solution is:
if(res == 0){
printf("Yes! The secret word is \"%s\"! You have won!\n", word[gen]);
break;
}
But the main problem in your code logis is that your never catch the letter from the user and update the state of game. The solution may be to add a function to do this after the function generate(gen) for this functionality for example:
void readLetterUpdateLife(int gen){
bool find = false;
char letter;
scanf(" %s", &letter);
for(int i=0; i<strlen(word[gen]); ++i){
if(word[gen][i] == letter){
blanks[i] = letter;
find = true;
}
}
if(!find) mwords[life++] = letter;
}
and finaly if you want pay again the game you should be reset all variables that your using for the game, example:
printf("Do you want to play again? (yes or no): ");
scanf(" %s", ans);
if(strcmp (ans, "yes") == 0){
life = 0; //Reset the life
srand(time(0)); //Select a new seed for rand
gen = rand() % 3; //Reset the word
for(int i = 0; i < strlen(word[gen]); i++){
blanks[i] = '_'; //Clear blanks
}
strcpy(mwords," "); //Reset wrong letters
strcpy(parts," "); //Reset parts
}
based on all the changes that I propose the final program is:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <string.h>
char word[3][10] = {"gabb", "mnl", "josh"};
char parts[6] = {" "};
char mwords[6] = {" "};
char blanks[10];
int life = 0;
int len;
char guess;
void body(int);
void generate(int);
int compare(int);
void readLetterUpdateLife(int);
int main(){
int res;
char ans[4];
int gen;
srand(time(0));
gen = rand() % 3;
for(int i = 0; i < strlen(word[gen]); i++){
blanks[i] = '_';
}
do{
while(life < 6){
body(life);
generate(gen);
readLetterUpdateLife(gen);
res = compare(gen);
if(res == 0){
printf("Yes! The secret word is \"%s\"! You have won!\n", word[gen]);
break;
}
}
printf("Do you want to play again? (yes or no): ");
scanf(" %s", ans);
if(strcmp (ans, "yes") == 0){
life = 0; //Reset the life
srand(time(0)); //Select a new seed for rand
gen = rand() % 3; //Reset the word
for(int i = 0; i < strlen(word[gen]); i++){
blanks[i] = '_'; //Clear blanks
}
strcpy(mwords," "); //Reset wrong letters
strcpy(parts," "); //Reset parts
}
}while(strcmp (ans, "yes") == 0);
}
void body(int n){
char guess;
switch(n){
case 6: parts[5] = '\\'; break;
case 5: parts[4] = '/'; break;
case 4: parts[3] = '\\'; break;
case 3: parts[2] = '/'; break;
case 2: parts[1] = '|'; break;
case 1: parts[0] = 'O'; break;
}
printf("H A N G M A N\n");
printf("\t+---+\n");
printf("\t| %c\n", parts[0]);
printf("\t| %c%c%c\n",parts[2], parts[1], parts[3]);
printf("\t|\\ %c %c\n", parts[4], parts[5]);
printf("\t===\n");
}
void generate(int a){
len = strlen(word[a]);
printf("Missed words: ");
for(int i = 0; i < 6; i++){
if(mwords[i] == '\0')
break;
else
printf("%c",mwords[i]);
}
printf("\n");
printf("Mystery word: ");
for(int i = 0;i < len; i++){
printf("%c ", blanks[i]);
}
printf("\n");
}
int compare(int comp){
if(strcmp (word[comp], blanks) == 0)
return 0;
else
return 1;
}
void readLetterUpdateLife(int gen){
bool find=false;
char letter;
scanf(" %c", &letter);
for(int i=0; i<strlen(word[gen]); ++i){
if(word[gen][i] == letter){
blanks[i] = letter;
find = true;
}
}
if(!find) mwords[life++] = letter;
}

How to Fix the Logic Errors in My "Guess the Movie" Game as a C Program

I have written a Guess the Movie game in the C programming language. My logic seems to be correct but whenever I run the program, it doesn't work as expected.
Here is my code
#include <stdio.h>
#include <stdlib.h>
int main()
{
int ran = 1;
int l, j = 0, i = 0, total = 0, d = 0;
char b;
char a[20];
char s[1000];
int z;
FILE *my;
printf("Enter your name:\n ");
scanf("%s", s);
ran = rand() % 6;
if (ran == 1)
{
my = fopen("my1.txt", "r");
}
else if (ran == 2)
{
my = fopen("my.txt", "r");
}
else if (ran == 3)
{
my = fopen("my2.txt", "r");
}
else if (ran == 4)
{
my = fopen("my3.txt", "r");
}
else if (ran == 5)
{
my = fopen("my4.txt", "r");
}
for (d = 0; d < 20; d++)
fscanf(my, "%c", &a[d]);
fclose(my);
printf("GUESS THE MOVIE GAME\n");
for (j = 0; j < 7; j++)
{
if (a[j] == 'm')
{
printf("M ");
}
else
{
printf("_ ");
}
}
printf("\n");
printf("Let's begin the game\n");
for (i = 0; i < 7;)
{
if (a[i] != 'm')
{
printf("enter character number %d\n",i+1);
scanf("%c", &b);
if (b == a[i])
{
printf("its a right guess\n");
total = total + 4;
i++;
}
else if (b != a[i])
{
printf("Wrong choice\n");
if (total == 1 || total == 0)
{
total=0;
}
else
{
total = total - 2;
}
}
}
}
printf("You have guessd the movie\n");
printf("The movie name is: ");
for (i = 0; i < 7; i++)
{
printf("%c",a[i]);
}
printf("Your score is %d\n",total);
}
This is the program output that I get each time I run the above code:
Enter your name:
raj
GUESS THE MOVIE GAME
_ _ _ _ M _ _
Let's begin the game
Enter character number 1
Wrong choice
Enter character number 1
I
Wrong choice
Enter character number 1
Wrong choice
Enter character number 1
Besides the deficiencies pointed out in comments, there's this major logic error:
for (i = 0; i < 7;)
{
if (a[i] != 'm')
{
…
}
}
If the loop encounters an m, it repeats endlessly. Eliminate the if (a[i] != 'm') or add an else ++i.

Struggles with TicTacToe

I have written a program in C, that when runs, is supposed to allow the user to play a game of tic tac toe - or noughts and crosses, whether it be against the computer, or another user. I have nearly completed it, and it prints the grid out perfectly fine. However, when I go to input which row/column I want to place the symbol in, instead of inserting the symbol, it just removes a space in the grid, aligning it incorrectly. I have tried to put a loop in the main method which fills the grid in with spaces to try and prevent null values.
If anyone could suggest anything it would be much appreciated. Thanks in advance!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void user_prompt();
void clear_board(char gameBoard[3][3]);
void display_board(char gameboard[3][3]);
void user_move(char gameBoard[3][3]);
void computer_move(char gameBoard[3][3]);
int detect_win(char gameBoard[3][3]);
int gameMode;
char symbol1;
char symbol2;
char nickname1[10];
char nickname2[10] = "TicTacBot";
char gameBoard[3][3];
char playerTurn[10];
int main(void){
int i, j;
char gameBoard [3][3];
clear_board(gameBoard);
for(int i = 0; i < 3; i++) {
for(int j = 0; j < 3; j++) {
gameBoard[i][j] = ' ';
}
}
i = 0;
j = 0;
user_prompt();
display_board(gameBoard);
if(gameMode == 2){
for(i = 0; i < 9; i++){
user_move(gameBoard);
display_board(gameBoard);
if(detect_win(gameBoard) == 1){
printf("The winner is %s!!!\n", nickname1);
}
if(detect_win(gameBoard) == 2){
printf("The winner is %s!!!\n", nickname2);
}
}
}
else{
user_move(gameBoard);
display_board(gameBoard);
for(i = 0; i < 4; i++){
printf("TicTacBot's move.\n");
computer_move(gameBoard);
display_board(gameBoard);
if(detect_win(gameBoard) == 1){
printf("The winner is %s!!!\n", nickname1);
}
user_move(gameBoard);
display_board(gameBoard);
if(detect_win(gameBoard) == 1){
printf("The winner is %s!!!\n", nickname2);
}
}
}
if(detect_win(gameBoard) == 0){
("The game ended in stalemate!\n");
}
return 0;
}
/*
Prompts the user to enter a nickname, what symbol they would like to use, and whether they'd rather play against the computer or another user.
*/
void user_prompt(void){
printf("Please choose whether you would rather play against the computer (enter '1'),or another user (enter '2'): \n");
scanf("%d", &gameMode);
getchar();
while(gameMode != 1 && gameMode != 2){
printf("Please enter a valid digit: \n");
scanf("%d", &gameMode);
getchar();
}
if(gameMode == 1){
printf("Please choose whether you would rather play as 'X' (enter 'x') or as 'O' (enter 'o'): \n");
scanf(" %c", &symbol1);
getchar();
if(symbol1 == 'x') {
symbol2 == 'o';
}
else{
symbol2 == 'x';
}
}
else{
printf("Player 1, would you like to play as 'X' (enter 'x') or as 'O' (enter 'o'): \n");
scanf(" %c", &symbol1);
getchar();
while(symbol1 != 'x' && symbol1 != 'o'){
printf("Please enter a valid symbol: \n");
scanf(" %c", &symbol1);
getchar();
}
if(symbol1 == 'x'){
symbol2 == 'o';
}
else{
symbol2 == 'x';
}
}
if(gameMode == 1){
printf("Please enter a nickname: \n");
fgets(nickname1, 10, stdin);
getchar();
}
else{
printf("Please enter a nickname for player 1: \n");
fgets(nickname1, 10, stdin);
getchar();
printf("Please enter a nickname for player 2: \n");
fgets(nickname2, 10, stdin);
getchar();
}
}
/*
Resets the game board.
*/
void clear_board(char gameBoard[3][3]){
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
gameBoard[i][j] = 0;
}
}
}
/*
Displays the game board and all symbols within it.
*/
void display_board(char gameBoard[3][3]){
for(int i = 0; i < 3; i++){
for(int j = 0; j < 3; j++){
printf(" %c ", gameBoard[i][j]);
if(j == 2){
printf("\n");
}
if(j != 2){
printf("|");
}
}
if(i != 2){
printf("---+---+---\n");
}
}
}
/*
Takes input of a position on the board from the user, then places the user's symbol into that space on the game board.
*/
void user_move(char gameBoard[3][3]){
int row;
int column;
if(playerTurn == nickname1){
printf("Would you like to enter your %c in row 1, 2 or 3? \n", symbol1);
scanf("%d", &row);
getchar();
printf("Would you like to enter your %c in column 1, 2 or 3? \n", symbol1);
scanf("%d", &column);
getchar();
}
else{
printf("Would you like to enter your %c in row 1, 2 or 3? \n", symbol2);
scanf("%d", &row);
getchar();
printf("Would you like to enter your %c in column 1, 2 or 3? \n", symbol2);
scanf("%d", &column);
getchar();
}
if(row < 1 || row > 3){
printf("Please enter a valid row number: \n");
scanf("%d", &row);
getchar();
}
if(column < 1 || column > 3){
printf("Please enter a valid column number: \n");
scanf("%d", &row);
getchar();
}
if(gameBoard[row-1][column-1] != ' '){
printf("The position you entered is already taken. Try again! \n");
display_board(gameBoard);
user_move(gameBoard);
}
else if(gameBoard[row-1][column-1] != ' '){
printf("The position you entered is already taken. Try again! \n");
display_board(gameBoard);
user_move(gameBoard);
}
else{
if(playerTurn == nickname1){
gameBoard[row-1][column-1] = symbol1;
}
else{
gameBoard[row-1][column-1] = symbol2;
}
}
printf("%c", symbol2);
if(gameMode == 2){
return;
}
if(strcmp(playerTurn, nickname1)==0){
strcpy(playerTurn, nickname2);
}
else if(strcmp(playerTurn, nickname2)==0){
strcpy(playerTurn, nickname1);
}
}
/*
Automates a strategic move from the computer, aiming to win the game, or at the least prevent the user from winning
*/
void computer_move(char gameBoard[3][3]){
int row;
int column;
int endTurn = 0;
row = rand() % 3 + 0;
column = rand() % 3 + 0;
if(gameBoard[row][column] != symbol1 && gameBoard[row][column] != symbol2){
gameBoard[row][column] = symbol2;
endTurn = 1;
}
}
/*
Detects a win on the game board. Checks if there are three identical symbols in a row, or if there are no more spaces on the game board.
*/
int detect_win(char gameBoard[3][3]){
for(int row = 0; row < 3; row++){
if(gameBoard[row][0] == gameBoard[row][1] && gameBoard[row][1] == gameBoard[row][2]){
if(gameBoard[row][0] == symbol1){
return 1;
}
if(gameBoard[row][0] == symbol2){
return 2;
}
}
}
for(int column = 0; column < 3; column++){
if(gameBoard[0][column] == gameBoard[1][column] && gameBoard[1][column] == gameBoard[2][column]){
if(gameBoard[0][column] == symbol1){
return 1;
}
if(gameBoard[0][column] == symbol2){
return 2;
}
}
}
if(gameBoard[0][0] == gameBoard[1][1] && gameBoard[1][1] == gameBoard[2][2]){
if(gameBoard[1][1] == symbol1){
return 1;
}
if(gameBoard[1][1] == symbol2){
return 2;
}
}
if(gameBoard[0][2] == gameBoard [1][1] && gameBoard[1][1] == gameBoard[2][0]){
if(gameBoard[1][1] == symbol1){
return 1;
}
if(gameBoard[1][1] == symbol2){
return 2;
}
}
return 0;
}
There's a small logical error:
In line 98, 101, 117, and 121, (and perhaps other places - please check) you have used == (operator for equality check) instead of the = used for assignment.
For example,
symbol2 == 'o';
should be replaced with
symbol2 = 'o';
Hence, it just checks for equality, throws away the result, and continues; with no changes made to symbol2.

Tic-Tac-Toe Game Function To Check For Winner

I've written the following code for a tic-tac-toe game on my own:
#include <stdio.h>
#include <math.h>
void instructions();
void printboard(char board[3][3]);
int wincheck(char board[3][3]);
int main(){
char tictac[3][3] = {{'-', '-', '-'}, {'-', '-', '-'}, {'-', '-', '-'}};
int player = 0;
int win = 0;
int player_choice = 0;
int row = 0;
int col = 0;
instructions();
for(int i=0; i<9 && win==0; i++){
printboard(tictac);
player = i%2 + 1;
do{
printf("\nPlayer #%d, enter your spot choice:\n", player);
scanf("%d", &player_choice);
if(player_choice == 1){
row = 0;
col = 0;
}
else if(player_choice == 2){
row = 0;
col = 1;
}
else if(player_choice == 3){
row = 0;
col = 2;
}
else if(player_choice == 4){
row = 1;
col = 0;
}
else if(player_choice == 5){
row = 1;
col = 1;
}
else if(player_choice == 6){
row = 1;
col = 2;
}
else if(player_choice == 7){
row = 2;
col = 0;
}
else if(player_choice == 8){
row = 2;
col = 1;
}
else if(player_choice == 9){
row = 2;
col = 2;
}
else{
printf("Not a valid choice, please choose again.");
}
}while(player_choice<0 || player_choice>9 || tictac[row][col]!='-');
if(player == 1){
tictac[row][col] = 'X';
}
else if(player == 2){
tictac[row][col] = 'O';
}
if(wincheck(tictac)!=0){
win = player;
}
}
printboard(tictac);
if(!win){
printf("\n\nTHE GAME IS A DRAW!\n");
}
else{
printf("\n\nCONGRATULAIONS PLAYER #%d, YOU WON!\n", win);
}
}
void instructions(){
printf("\n\t\t\t WELCOME TO TIC TAC TOE!\n");
printf("\nGame Rules:\n");
printf("\nThe program will ask the player to enter which spot they would like to place their X or O.\nPlease use spot numbers as shown below:\n\n");
printf("\t\t\t\t 1 | 2 | 3 \n");
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t 4 | 5 | 6 \n");
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t 7 | 8 | 9 \n");
printf("\n\t------------------------LET'S BEGIN!------------------------\n\n\n");
}
void printboard(char board[3][3]){
printf("\t\t\t\t %c | %c | %c \n", board[0][0], board[0][1], board[0][2]);
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t %c | %c | %c \n", board[1][0], board[1][1], board[1][2]);
printf("\t\t\t\t---+---+---\n");
printf("\t\t\t\t %c | %c | %c \n", board[2][0], board[2][1], board[2][2]);
}
int wincheck(char board[3][3]){
if((board[0][0]==board[0][1] && board[0][0]==board[0][2]) || (board[1][0]==board[1][1] && board[1][0]==board[1][2]) || (board[2][0]==board[2][1] && board[2][0]==board[2][2])){
return 1;/*Checks to see if player has won across any of the rows.*/
}
else if((board[0][0]==board[1][0] && board[0][0]==board[2][0]) || (board[0][1]==board[1][1] && board[0][1]==board[2][1]) || (board[0][2]==board[1][2] && board[0][2]==board[2][2])){
return 1;/*Checks to see if player has won down any columns.*/
}
else if((board[0][0]==board[1][1] && board[0][0]==board[2][2]) || (board[0][2]==board[1][1] && board[0][2]==board[2][0])){
return 1;/*Checks to see if player has won in a diagonal.*/
}
else{
return 0;
}
}
I'm running into an issue when trying to play the game though. After the first player chooses a "play spot" it thinks they have won already. Because of this I believe the issue is most likely due to an error in the wincheck function but I can't quite figure out what exactly is causing the issue. I'm a beginner programmer, so I apologize if this is kind of a dumb question. I really appreciate any help you can offer!
The problem is indeed with your wincheck function. It rightly checks that the three candidate cells are equal but does not check that those cells have been populated. That means the game will be detected as won even before a move is made (since all cells are set to -, a simple equality check will pass).
It's therefore not enough to do just the equality check, you also have to ensure that at least one of those cells has been set to a real player.
You can also make your code a bit more readable with a little refactoring, something like:
// Returns the actual winner, or '-' if none. Needs x/y start cell
// and x/y deltas (direction, basically).
int checkOneWinPossibility(char board[3][3], int x, int y, int xd, int yd) {
// Check all no-winner scenarios, return winner only if they all fail.
if (board[x][y] == '-') return '-';
if (board[x][y] != board[x+xd][y+yd]) return '-';
if (board[x][y] != board[x+xd*2][y+yd*2]) return '-';
return board[x][y];
}
int checkAllWinPossibilities(char board[3][3]){
int winner;
// Horizontals.
if ((winner = checkOneWinner(board, 0, 0, 0, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 1, 0, 0, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 2, 0, 0, 1)) != '-') return winner;
// Verticals.
if ((winner = checkOneWinner(board, 0, 0, 1, 0)) != '-') return winner;
if ((winner = checkOneWinner(board, 0, 1, 1, 0)) != '-') return winner;
if ((winner = checkOneWinner(board, 0, 2, 1, 0)) != '-') return winner;
// Diagonals.
if ((winner = checkOneWinner(board, 0, 0, 1, 1)) != '-') return winner;
if ((winner = checkOneWinner(board, 2, 0, -1, 1)) != '-') return winner;
return '-';
}
That last diagonal check could be combined with the return statement just by doing:
return checkOneWinner(board, 2, 0, -1, 1);
but I prefer (being slightly OCD) to leave it as is for consistency :-)
They also both return the actual winner rather than just an indication that there is a winner. You may not need that information since it will obviously be the last player that moved, but there's no probably no substantial harm in returning the extra information.

Resources