Brief Explanation of the Problem - The aim of the code is to make a basic tic tac toe game using C. There are two players X and O , both can enter various numbers as choice from 1-9 for each individual chance.
The game board is similar to a 3 x 3 matrix, where -
Row 1 is for 1 to 3.
Row 2 is for 4 to 6.
Row 3 is for 7 to 9.
Any number except 1-9 will throw an error and will prompt the user to re-enter the number. Unfortunately, I'm getting the same Invalid input error for a valid input. Everything else seems to work except my loop.
Here's the code for reference -
#include<stdio.h> //Tic Tac Toe
#include<stdlib.h>
#include<conio.h>
char square[10] = {'0','1','2','3','4','5','6','7','8','9'};
int choice, player;
int checkForWin();
void displayBoard();
void mrkBoard(char mark);
int main()
{
int i;
char mark;
player = 1;
do
{
displayBoard();
player = (player % 2) ? 1:2;
printf("Player %d, enter the number: ",player);
scanf("%d",&choice);
mark = (player == 1) ? 'X' : 'O';
mrkBoard(mark);
i = checkForWin();
player++;
}while(i == -1);
return 0;
}
int checkForWin()
{
int returnValue = 0;
if (square[1] == square[2] && square[2] == square[3])
{
returnValue = 1;
}
else if (square[4] == square[5] && square[5] == square[6])
returnValue = 1;
else if (square[7] == square[8] && square[8] == square[9])
returnValue = 1;
else if (square[1] == square[5] && square[5] == square[9])
returnValue = 1;
else if (square[3] == square[5] && square[5] == square[7])
returnValue = 1;
else if (square[1] == square[4] && square[4] == square[7])
returnValue = 1;
else if (square[2] == square[5] && square[5] == square[8])
returnValue = 1;
else if (square[3] == square[6] && square[6] == square[9])
returnValue = 1;
else if(square[1] != '1' && square[2] != '2' && square[3] != '3' && square[4] != '4' &&
square[5] != '5' && square[6] != '6' && square[7] != '7' &&
square[8] != '8' && square[9] != '9')
returnValue = 0;
else
returnValue = -1;
return returnValue;
}
void displayBoard()
{
system("cls");
printf("\n\nTic Tac Toe\n\n");
printf("Player 1 (X) - Player 2 (O)\n\n\n");
printf(" | | \n");
printf(" %c | %c | %c \n", square[1], square[2],square[3]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c\n", square[4], square[5],square[6]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c\n", square[7], square[8],square[9]);
printf(" | | \n\n");
}
void mrkBoard(char mark)
{
if (choice == 1 && square[1] == '1')
square[1] = mark;
else if (choice == 2 && square[1] == '2')
square[2] = mark;
else if (choice == 3 && square[1] == '3')
square[3] = mark;
else if (choice == 4 && square[1] == '4')
square[4] = mark;
else if (choice == 5 && square[1] == '5')
square[5] = mark;
else if (choice == 6 && square[1] == '6')
square[6] = mark;
else if (choice == 7 && square[1] == '7')
square[7] = mark;
else if (choice == 8 && square[1] == '8')
square[8] = mark;
else if (choice == 9 && square[1] == '9')
square[9] = mark;
else
{
printf("Invalid ");
player--;
getch();
}
}
#include<stdio.h> //Tic Tac Toe
#include<stdlib.h>
#include<conio.h>
char square[10] = {'0','1','2','3','4','5','6','7','8','9'};
int choice, player;
int checkForWin();
void displayBoard();
void mrkBoard(char mark);
int main()
{
int i;
char mark;
player = 1;
do
{
displayBoard();
player = (player % 2) ? 1:2;
printf("Player %d, enter the number: ",player);
scanf("%d",&choice);
mark = (player == 1) ? 'X' : 'O';
mrkBoard(mark);
i = checkForWin();
player++;
}while(i == -1);
return 0;
}
int checkForWin()
{
int returnValue = 0;
if (square[1] == square[2] && square[2] == square[3])
{
returnValue = 1;
}
else if (square[4] == square[5] && square[5] == square[6])
returnValue = 1;
else if (square[7] == square[8] && square[8] == square[9])
returnValue = 1;
else if (square[1] == square[5] && square[5] == square[9])
returnValue = 1;
else if (square[3] == square[5] && square[5] == square[7])
returnValue = 1;
else if (square[1] == square[4] && square[4] == square[7])
returnValue = 1;
else if (square[2] == square[5] && square[5] == square[8])
returnValue = 1;
else if (square[3] == square[6] && square[6] == square[9])
returnValue = 1;
else if(square[1] != '1' && square[2] != '2' && square[3] != '3' && square[4] != '4' &&
square[5] != '5' && square[6] != '6' && square[7] != '7' &&
square[8] != '8' && square[9] != '9')
returnValue = 0;
else
returnValue = -1;
return returnValue;
}
void displayBoard()
{
system("cls");
printf("\n\nTic Tac Toe\n\n");
printf("Player 1 (X) - Player 2 (O)\n\n\n");
printf(" | | \n");
printf(" %c | %c | %c \n", square[1], square[2],square[3]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c\n", square[4], square[5],square[6]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c\n", square[7], square[8],square[9]);
printf(" | | \n\n");
}
void mrkBoard(char mark)
{
if (choice == 1 && square[1] == '1')
square[1] = mark;
else if (choice == 2 && square[2] == '2')
square[2] = mark;
else if (choice == 3 && square[3] == '3')
square[3] = mark;
else if (choice == 4 && square[4] == '4')
square[4] = mark;
else if (choice == 5 && square[5] == '5')
square[5] = mark;
else if (choice == 6 && square[6] == '6')
square[6] = mark;
else if (choice == 7 && square[7] == '7')
square[7] = mark;
else if (choice == 8 && square[8] == '8')
square[8] = mark;
else if (choice == 9 && square[9] == '9')
square[9] = mark;
else
{
printf("Invalid ");
player--;
getch();
}
}
Related
#include<stdio.h>
#include <conio.h>
char square[26] = {'o', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '};
char row[5] = {'1', '2', '3', '4', '5'};
char column[5] = {'1', '2', '3', '4', '5'};
int playingChoice;
int checkWin();
void board();
int main()
{
printf("\n\n");
printf("\t\t\t**** T I C T A C T O E ****\n");
printf("\n\n");
printf("Press 1 for Player Vs Player \nPress 2 for Player Vs Computer\n\n");
scanf("%d", &playingChoice);
//Human player Vs Human player Code
if(playingChoice == 1){
int player = 1, i, choiceRow, choiceColumn;
char mark;
do
{
board();
player = (player % 2) ? 1 : 2;
printf("Player %d, choose row : ", player);
scanf("%d", &choiceRow);
printf("Player %d, choose column : ", player);
scanf("%d", &choiceColumn);
mark = (player == 1) ? 'X' : 'O';
if (choiceRow == 1 && choiceColumn == 1 && square[1] == ' ')
square[1] = mark;
else if (choiceRow == 1 && choiceColumn == 2 && square[2] == ' ')
square[2] = mark;
else if (choiceRow == 1 && choiceColumn == 3 && square[3] == ' ')
square[3] = mark;
else if (choiceRow == 1 && choiceColumn == 4 && square[4] == ' ')
square[4] = mark;
else if (choiceRow == 1 && choiceColumn == 5 && square[5] == ' ')
square[5] = mark;
else if (choiceRow == 2 && choiceColumn == 1 && square[6] == ' ')
square[6] = mark;
else if (choiceRow == 2 && choiceColumn == 2 && square[7] == ' ')
square[7] = mark;
else if (choiceRow == 2 && choiceColumn == 3 && square[8] == ' ')
square[8] = mark;
else if (choiceRow == 2 && choiceColumn == 4 && square[9] == ' ')
square[9] = mark;
else if (choiceRow == 2 && choiceColumn == 5 && square[10] == ' ')
square[10] = mark;
else if (choiceRow == 3 && choiceColumn == 1 && square[11] == ' ')
square[11] = mark;
else if (choiceRow == 3 && choiceColumn == 2 && square[12] == ' ')
square[12] = mark;
else if (choiceRow == 3 && choiceColumn == 3 && square[13] == ' ')
square[13] = mark;
else if (choiceRow == 3 && choiceColumn == 4 && square[14] == ' ')
square[14] = mark;
else if (choiceRow == 3 && choiceColumn == 5 && square[15] == ' ')
square[15] = mark;
else if (choiceRow == 4 && choiceColumn == 1 && square[16] == ' ')
square[16] = mark;
else if (choiceRow == 4 && choiceColumn == 2 && square[17] == ' ')
square[17] = mark;
else if (choiceRow == 4 && choiceColumn == 3 && square[18] == ' ')
square[18] = mark;
else if (choiceRow == 4 && choiceColumn == 4 && square[19] == ' ')
square[19] = mark;
else if (choiceRow == 4 && choiceColumn == 5 && square[20] == ' ')
square[20] = mark;
else if (choiceRow == 5 && choiceColumn == 1 && square[21] == ' ')
square[21] = mark;
else if (choiceRow == 5 && choiceColumn == 2 && square[22] == ' ')
square[22] = mark;
else if (choiceRow == 5 && choiceColumn == 3 && square[23] == ' ')
square[23] = mark;
else if (choiceRow == 5 && choiceColumn == 4 && square[24] == ' ')
square[24] = mark;
else if (choiceRow == 5 && choiceColumn == 5 && square[25] == ' ')
square[25] = mark;
else
{
printf("Invalid move ");
player--;
getch();
}
i = checkWin();
player++;
}while (i == - 1);
board();
if (i == 1)
printf("==>\aPlayer %d win ", --player);
else
printf("==>\aGame draw");
getch();
return 0;
}//end if
}//end int main
void board()
{
system("cls");
printf("\n\n");
printf("\t\t\t**** T I C T A C T O E ****\n");
printf("\n\n");
printf("\n");
printf("\t\t Player 1 place [X] | ");
printf("Player 2 place [O]\n\n\n");
printf("\t\t\t 1 2 3 4 5 \n");
printf("\t\t\t --------------------------------\n");
printf("\t\t\t | | | | | | \n");
printf("\t\t\t1 | %c | %c | %c | %c | %c |\n", square[1], square[2], square[3], square[4], square[5]);
printf("\t\t\t |_____|_____|_____|_____|_____|\n");
printf("\t\t\t | | | | | | \n");
printf("\t\t\t2 | %c | %c | %c | %c | %c |\n", square[6], square[7], square[8], square[9], square[10]);
printf("\t\t\t |_____|_____|_____|_____|_____|\n");
printf("\t\t\t | | | | | | \n");
printf("\t\t\t3 | %c | %c | %c | %c | %c |\n", square[11], square[12], square[13], square[14], square[15]);
printf("\t\t\t |_____|_____|_____|_____|_____|\n");
printf("\t\t\t | | | | | | \n");
printf("\t\t\t4 | %c | %c | %c | %c | %c |\n", square[16], square[17], square[18], square[19], square[20]);
printf("\t\t\t |_____|_____|_____|_____|_____|\n");
printf("\t\t\t | | | | | | \n");
printf("\t\t\t5 | %c | %c | %c | %c | %c |\n", square[21], square[22], square[23], square[24], square[25]);
printf("\t\t\t | | | | | | \n");
printf("\t\t\t --------------------------------\n");
}
int checkWin()
{
if (square[1] == square[2] && square[2] == square[3] && square[3] == square[4] && square[4] == square[5]){
return 1;
}else if (square[6] == square[7] && square[7] == square[8] && square[8] == square[9] && square[9] == square[10]){
return 1;
}else if (square[11] == square[12] && square[12] == square[13] && square[13] == square[14] && square[14] == square[15]){
return 1;
}else if (square[16] == square[17] && square[17] == square[18] && square[18] == square[19] && square[19] == square[20]){
return 1;
}else if (square[21] == square[22] && square[22] == square[23] && square[23] == square[24] && square[24] == square[25]){
return 1;
}else if (square[1] == square[6] && square[6] == square[11] && square[11] == square[16] && square[16] == square[21]){
return 1;
}else if (square[2] == square[7] && square[7] == square[12] && square[12] == square[17] && square[17] == square[22]){
return 1;
}else if (square[3] == square[8] && square[8] == square[13] && square[13] == square[18] && square[18] == square[23]){
return 1;
}else if (square[4] == square[9] && square[9] == square[14] && square[14] == square[19] && square[19] == square[24]){
return 1;
}else if (square[5] == square[10] && square[10] == square[15] && square[15] == square[20] && square[20] == square[25]){
return 1;
}else if (square[1] == square[7] && square[7] == square[13] && square[13] == square[19] && square[19] == square[25]){
return 1;
}else if (square[5] == square[9] && square[9] == square[13] && square[13] == square[17] && square[17] == square[21]){
return 1;
}else if (square[1] != ' ' && square[2] != ' ' && square[3] != ' ' && square[4] != ' ' && square[5] != ' ' && square[6] != ' '
&& square[7] != ' ' && square[8] != ' ' && square[9] != ' ' && square[10] != ' ' && square[11] != ' ' && square[12] != ' '
&& square[13] != ' ' && square[14] != ' ' && square[15] != ' ' && square[16] != ' ' && square[17] != ' ' && square[18] != ' '
&& square[19] != ' ' && square[20] != ' ' && square[21] != ' ' && square[22] != ' ' && square[23] != ' ' && square[24] != ' '
&& square[25] != ' '){
return 0;
}else{
return - 1;
}
}
When the player enteres his desired row and column, the program automatically displays player 1 as the winner. I think the problem might be in looping but I am not sure. Kindly help me in this problem and sorry if you find my code childish since I am a beginner and this is my 2nd month into programming
Weather Vane spells out that your check of "five in a row" is incomplete in that the program is not making sure that the check is for either five X's or five O's. So taking the first test group in your code for example, instead of the current test
if (square[1] == square[2] && square[2] == square[3] && square[3] == square[4] && square[4] == square[5])
{
return 1;
}
There would be an additional test of one of the elements in the test group not being blank.
if (square[1] == square[2] && square[2] == square[3] && square[3] == square[4] && square[4] == square[5] && square[1] != ' ')
{
return 1;
}
Checking one of the elements to ensure that it is not blank in each of the test blocks would need to be repeated for each test group.
Doing that change and purposely entering choices that do not result in "five in a row" produced the final draw outcome on the terminal.
**** T I C T A C T O E ****
Player 1 place [X] | Player 2 place [O]
1 2 3 4 5
--------------------------------
| | | | | |
1 | X | O | X | O | X |
|_____|_____|_____|_____|_____|
| | | | | |
2 | O | X | O | X | O |
|_____|_____|_____|_____|_____|
| | | | | |
3 | X | O | X | O | X |
|_____|_____|_____|_____|_____|
| | | | | |
4 | O | X | O | X | O |
|_____|_____|_____|_____|_____|
| | | | | |
5 | O | X | X | X | O |
| | | | | |
--------------------------------
==>Game draw
No need to accept this answer. Just wanted to embellish the previous comment so that it was clear to you.
What I'm trying to do here is a tie toe game, but when my code enters the do - while part, it ends the process by itself. Since I could not solve this part, I did not have a chance to try whether there are other problems with the code, unfortunately, I would be glad if you could help with this issue.
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
char box_area[] = { '0','1','2','3','4','5','6','7','8','9' };
struct Player {
bool turn;
char mark;
int ID;
};
int main()
{
int return_result;
int player_number;
struct Player player1;
struct Player player2;
struct Player users[2];
users[0] = player1;
users[1] = player2;
(player1.mark = 'X') && (player2.mark = 'O');
(player1.turn = true) && (player2.turn = false);
(player1.ID = 1) && (player2.ID = 2);
do
{
box_creat();
for (int i = 0; i < 2; i++) {
if (users[i].turn == true)
{
make_move(users[i].ID);
box_creat();
users[i].turn = false;
users[i + 1].turn = true; \\ I made the logic of this section wrong
\\I will try to fix it, I realized after I sent the question
}
}
return_result = check_the_winner();
} while (return_result == 1 || return_result == -1);
return 0;
}
void box_creat(void) {
printf("| %c | %c | %c |", box_area[0], box_area[1], box_area[2]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[3], box_area[4], box_area[5]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[6], box_area[7], box_area[8]);
}
void make_move(int Player_ID)
{
int choice;
printf("Please select a area between 0-9 ");
scanf("%d", choice);
if (choice == '0' && box_area[0] == '0')
{
if (Player_ID == 1) {
box_area[0] = 'X';
}
else {
box_area[0] = 'O';
}
}
else if (choice == '1' && box_area[1] == '1')
{
if (Player_ID == 1) {
box_area[1] = 'X';
}
else {
box_area[1] = 'O';
}
}
else if (choice == '2' && box_area[2] == '2')
{
if (Player_ID == 1) {
box_area[2] = 'X';
}
else {
box_area[2] = 'O';
}
}
else if (choice == '3' && box_area[3] == '0')
{
if (Player_ID == 1) {
box_area[3] = 'X';
}
else {
box_area[3] = 'O';
}
}
else if (choice == '4' && box_area[4] == '0')
{
if (Player_ID == 1) {
box_area[4] = 'X';
}
else {
box_area[4] = 'O';
}
}
else if (choice == '5' && box_area[5] == '0')
{
if (Player_ID == 1) {
box_area[5] = 'X';
}
else {
box_area[5] = 'O';
}
}
else if (choice == '6' && box_area[6] == '0')
{
if (Player_ID == 1) {
box_area[6] = 'X';
}
else {
box_area[6] = 'O';
}
}
else if (choice == '7' && box_area[7] == '0')
{
if (Player_ID == 1) {
box_area[7] = 'X';
}
else {
box_area[7] = 'O';
}
}
else if (choice == '8' && box_area[8] == '0')
{
if (Player_ID == 1) {
box_area[8] = 'X';
}
else {
box_area[8] = 'O';
}
}
}
int check_the_winner(void)
{
if (box_area[0] && box_area[1] && box_area[2] == 'X' || 'O') {
return 1;
}
else if(box_area[3] && box_area[4] && box_area[5] == 'X' || 'O') {
return 1;
}
else if (box_area[6] && box_area[7] && box_area[8] == 'X' || 'O') {
return 1;
}
else if (box_area[2] && box_area[4] && box_area[6] == 'X' || 'O') {
return 1;
}
else if (box_area[0] && box_area[3] && box_area[6] == 'X' || 'O') {
return 1;
}
else if (box_area[2] && box_area[8] && box_area[5] == 'X' || 'O') {
return 1;
}
else if (box_area[0] && box_area[4] && box_area[8] == 'X' || 'O') {
return 1;
}
else if (box_area[1] && box_area[4] && box_area[7] == 'X' || 'O') {
return 1;
}
else {
return -1;
}
}
I tried out your program and found a few glitches that needed revision as well as adding in some additional bits of code just to neaten things up a bit. Following is your code with those revisions.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
char box_area[] = { '0','1','2','3','4','5','6','7','8','9' };
struct Player
{
bool turn;
char mark;
int ID;
};
void box_creat(void)
{
printf("| %c | %c | %c |", box_area[0], box_area[1], box_area[2]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[3], box_area[4], box_area[5]);
printf("\n\n");
printf("| %c | %c | %c |", box_area[6], box_area[7], box_area[8]);
printf("\n"); /* Added for aesthetics */
}
void make_move(int Player_ID)
{
int choice;
printf("Player %d - please select a area between 0-9 ", Player_ID);
scanf("%d", &choice); /* Corrected missing ampersand */
printf("Player: %d makes a move\n", Player_ID);
if (choice == 0 && box_area[0] == '0') /* FYI - '0' is equivalent to integer value 48 */
{
if (Player_ID == 1)
{
box_area[0] = 'X';
}
else
{
box_area[0] = 'O';
}
}
else if (choice == 1 && box_area[1] == '1')
{
if (Player_ID == 1)
{
box_area[1] = 'X';
}
else
{
box_area[1] = 'O';
}
}
else if (choice == 2 && box_area[2] == '2')
{
if (Player_ID == 1)
{
box_area[2] = 'X';
}
else
{
box_area[2] = 'O';
}
}
else if (choice == 3 && box_area[3] == '3')
{
if (Player_ID == 1)
{
box_area[3] = 'X';
}
else
{
box_area[3] = 'O';
}
}
else if (choice == 4 && box_area[4] == '4')
{
if (Player_ID == 1)
{
box_area[4] = 'X';
}
else
{
box_area[4] = 'O';
}
}
else if (choice == 5 && box_area[5] == '5')
{
if (Player_ID == 1)
{
box_area[5] = 'X';
}
else
{
box_area[5] = 'O';
}
}
else if (choice == 6 && box_area[6] == '6')
{
if (Player_ID == 1)
{
box_area[6] = 'X';
}
else
{
box_area[6] = 'O';
}
}
else if (choice == 7 && box_area[7] == '7')
{
if (Player_ID == 1)
{
box_area[7] = 'X';
}
else
{
box_area[7] = 'O';
}
}
else if (choice == 8 && box_area[8] == '8')
{
if (Player_ID == 1)
{
box_area[8] = 'X';
}
else
{
box_area[8] = 'O';
}
}
}
int check_the_winner(void)
{
if ((box_area[0] == box_area[1]) && (box_area[1] == box_area[2]) && (box_area[0] != '0')) /* Corrected the testing for proper "and" conditioning */
{
return 1;
}
else if ((box_area[3] == box_area[4]) && (box_area[4] == box_area[5]) && (box_area[3] != '3'))
{
return 1;
}
else if ((box_area[6] == box_area[7]) && (box_area[7] == box_area[8]) && (box_area[6] != '6'))
{
return 1;
}
else if ((box_area[2] == box_area[4]) && (box_area[4] == box_area[6]) && (box_area[2] != '2'))
{
return 1;
}
else if ((box_area[0] == box_area[3]) && (box_area[3] == box_area[6]) && (box_area[0] != '0'))
{
return 1;
}
else if ((box_area[2] == box_area[5]) && (box_area[5] == box_area[8]) && (box_area[2] != '2'))
{
return 1;
}
else if ((box_area[0] == box_area[4]) && (box_area[4] == box_area[8]) && (box_area[4] != '4'))
{
return 1;
}
else if ((box_area[1] == box_area[4]) && (box_area[4] == box_area[7]) && (box_area[1] != '1'))
{
return 1;
}
else
{
return -1;
}
}
int main()
{
int return_result;
//int player_number; /* Compiler said that this wasn't being used */
int swap = 1;
int i;
struct Player player1;
struct Player player2;
struct Player *users[2]; /* Used these as address pointers to player "1" and player "2" */
users[0] = &player1; /* Before making these pointers, the users array just contained copies of the player structures */
users[1] = &player2;
(player1.mark = 'X') && (player2.mark = 'O');
(player1.turn = true) && (player2.turn = false);
(player1.ID = 1) && (player2.ID = 2);
do
{
box_creat();
swap += 1;
i = swap % 2;
if (i == 1)
{
make_move(users[1]->ID);
//box_creat(); /* Being performed at the top of the loop */
users[0]->turn = false;
users[1]->turn = true;
}
else
{
make_move(users[0]->ID);
//box_creat();
users[1]->turn = false;
users[0]->turn = true;
}
return_result = check_the_winner();
if (check_the_winner() == 1) /* Added when a winner has been sensed */
{
box_creat();
if (i == 1)
{
printf("Player 2 won!\n");
}
else
{
printf("Player 1 won!\n");
}
}
}
while (return_result != 1);
return 0;
}
I added comments to most of the places I had tweaked, but here are the highlights:
I shuffled some of the functions around so that the "main" function followed all of the helper functions (the compiler was giving warnings about the original sequence of the function positions).
I corrected the "choice" tests as "choice" is an integer, so the test of "choice" needed to be compared to an integer value (e.g. zero) as opposed to character '0' (which actually has a value of 48).
The tests for three letters in a row for either player do not work in that manner. Either a test needed to be made for each box for a certain row needed to tested for an "X" or an "O", and then if that test was true the test needed to be continued for the next box in the row, and then again for the third box in the row. In lieu of that route, the test was revised to basically say "if the character in the first box in the row is the same as the character in the second box in the row, and the character in the second box in the row is the same as the character in the third box in the row, and the first box does not contain a digit character (which means is contains an "X" or an "O"), then there is a winner.
It appears that an attempt was made to mirror the contents of "Player1" and "Player2" into an array of player structures. Although initially, structure "users[0]" contained the same data as "Player1" and structure "users[1]" contained the same data as "Player2", once the data in "Player1" and "Player2" were updated, those changes did to propagate over to the "users" array. So to utilize "users" in the spirit of this program, they were defined as pointers to their respective player structures.
Those were the most significant bits. The other bits were added for a logical conclusion of the game. Note that no logic was added for a draw.
Give that a test and see if that clarifies things and follows the spirit of the project.
I have this problem and I don´t know what´s wrong. The code doesn´t have any errors or warnings but it always take the first if statement of the checkVictory function as correct.
I've tried comparing my code with another one that actually works and it looks identical to me. I´m pretty sure the mistake is in the checkVictory function because I used a variable called flag to check every if statement of the function and my returnValue (which is used as an indicator of my game status) always get triggered by the first if.
Here´s my code... (sorry for the indentation this is my first time using the website)
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void board();
void markBoard(char mark);
int checkVictory();
int player, choice, flag;
char list[10] = {'-', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
void main() {
int gameStatus;
char mark;
player = 1;
do{
board();
// change turns
player = (player % 2) ? 1 : 2;
//input
printf("Player %d, enter a number: ", player);
scanf("%i", &choice);
// set the correct character based on player turn
mark = (player == 1) ? 'X' : 'O';
markBoard(mark);
gameStatus = checkVictory();
player++;
} while (gameStatus == -1);
if (gameStatus == 1) {
printf("Player %d WIN", --player);
printf("\nflag: %i", flag);
}
else{
printf("Draw");
}
}
void board() {
system("cls");
printf("\n\n\t tic tac toe\n\n");
printf("Player 1 (X) - Player 2 (O)\n\n");
printf(" | | \n");
printf(" %c | %c | %c \n", list[1], list[2], list[3]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", list[4], list[5], list[6]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", list[7], list[8], list[9]);
printf(" | | \n");
printf("\n");
}
void markBoard(char mark) {
if (choice == 1 && list[1] == '1')
list[1] = mark;
else if (choice == 2 && list[2] == '2')
list[2] = mark;
else if (choice == 3 && list[3] == '3')
list[3] = mark;
else if (choice == 4 && list[4] == '4')
list[4] = mark;
else if (choice == 5 && list[5] == '5')
list[5] = mark;
else if (choice == 6 && list[6] == '6')
list[6] = mark;
else if (choice == 7 && list[7] == '7')
list[7] = mark;
else if (choice == 8 && list[8] == '8')
list[8] = mark;
else if (choice == 9 && list[9] == '9')
list[9] = mark;
else {
printf("Invalid move\n");
player--;
getch();
}
}
/*********************************************FUNCTION TO RETURN GAME STATUS1 FOR GAME IS OVER WITH RESULT-1 FOR GAME IS IN PROGRESSO GAME IS OVER AND NO RESULT**********************************************/
int checkVictory() {
int returnValue = 0;
if (list[1] && list[2] == list[2] && list[3]) {
returnValue = 1;
flag = 1;
}
else if (list[4] && list[5] == list[5] && list[6]) {
returnValue = 1;
flag = 2;
}
else if (list[7] && list[8] == list[8] && list[9]) {
returnValue = 1;
flag = 3;
}
else if (list[1] && list[4] == list[4] && list[7]) {
returnValue = 1;
flag = 4;
}
else if (list[2] && list[5] == list[5] && list[8]) {
returnValue = 1;
flag = 5;
}
else if (list[3] && list[6] == list[6] && list[9]) {
returnValue = 1;
flag = 6;
}
else if (list[1] && list[5] == list[5] && list[9]) {
returnValue = 1;
flag = 7;
}
else if (list[3] && list[5] == list[5] && list[7]) {
returnValue = 1;
flag = 8;
}
else if (list[1] != '1' && list[2] != '2' && list[3] != '3' &&
list[4] != '4' && list[5] != '5' && list[6] != '6' &&
list[7] != '7' && list[8] != '8' && list[9] != '9') {
returnValue = 0;
}
else
returnValue = -1;
return returnValue;
}
The problem lies with the code below.
if (list[1] && list[2] == list[2] && list[3]) {
returnValue = 1;
Your condition:
list[1] && list[2] == list[2] && list[3]
Parses as:
list[1] && (list[2] == list[2]) && list[3]
Because no element of list is 0, they all test as true. Likewise, list[2] will always be equal to itself. Consequently this condition is always true. checkVictory will always return 1. When this is called, and gameSttatus is set to 1, the do-while loop ends.
Issue: I'm trying to utilize recTest to check and return the winner of a simple Tic-Tac-Toe game.
I'm just unsure of what I need to pass in the call (line I've highlighted), and how to integrate my public square array.
I apologize if this is overly simple, I'm just having a rough time connecting the dots.
#include<stdio.h>
#include<conio.h>
char square[10] = {'o', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
// returns -1 if no v[i] satisfies p
// returns i if v[i] satisfies p (picks largest i)
// (i>=0) and (i<n)
const int numwinpos = 8;
const int winpos[8][3] = {{1,2,3},
{4,5,6},
{7,8,9},
{1,4,7},
{2,5,8},
{3,6,9},
{1,5,9},
{3,5,7}};
//Function below, and variables above<--------------------------------------
int recTest(const int v[], const int n){
if( (n>0) && (!p(v[n-1])) )
return recTest(v,n-1);
else
return n-1;
}
/*int winnerCheck() {
//not even hard-coded tho...
if (square[1] == square[2] && square[2] == square[3])
return 1;
else if (square[4] == square[5] && square[5] == square[6])
return 1;
else if (square[7] == square[8] && square[8] == square[9])
return 1; //above 3 check across
else if (square[1] == square[4] && square[4] == square[7])
return 1;
else if (square[2] == square[5] && square[5] == square[8])
return 1;
else if (square[3] == square[6] && square[6] == square[9])
return 1; //above 3 check down
else if (square[1] == square[5] && square[5] == square[9])
return 1;
else if (square[3] == square[5] && square[5] == square[7])
return 1; //above 2 check diagonal
else if (square[1] != '1' && square[2] != '2' && square[3] != '3' && square[4]
!= '4' && square[5] != '5' &&
square[6] != '6' && square[7] != '7' && square[8]
!= '8' && square[9] != '9')
return 0;
else
//exit
return -1;
}
*/
void board() {
printf("\n\n\tTic Tac Toe\n\n");
printf("Player 1 (X) - Player 2 (O)\n\n\n");
//prints the board after every input
printf(" | | \n");
printf(" %c | %c | %c \n", square[1], square[2],square[3]);
printf("____|_____|____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", square[4], square[5],square[6]);
printf("____|_____|____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", square[7], square[8],square[9]);
printf(" | | \n");
}
int main() {
/*
char board[3][3] = {
};
printf("\t|\t|\t\n");
printf("\t|\t|\t\n");
printf("________|_______|________\n");
printf("\t|\t|\t\n");
printf("\t|\t|\t\n");
printf("________|_______|________\n");
printf("\t|\t|\t\n");
printf("\t|\t|\t\n");
printf("\t|\t|\t\n");
*/
int player = 1, i, choice;
char mark;
do {
board();
player = player % 2 ? 1 : 2;
printf("Player %d, enter a number: ", player);
scanf("%d", &choice);
//mark = (player == 1) ? 'X' : 'O';
if (player == 1) {
mark = 'X';
} else {
mark = 'O';
}
if (choice == 1)
square[1] = mark;
else if (choice == 2)
square[2] = mark;
else if (choice == 3)
square[3] = mark;
else if (choice == 4)
square[4] = mark;
else if (choice == 5)
square[5] = mark;
else if (choice == 6)
square[6] = mark;
else if (choice == 7)
square[7] = mark;
else if (choice == 8)
square[8] = mark;
else if (choice == 9)
square[9] = mark;
i = recTest(square, numwinpos); //HERE <--------------------------------------
player++;
} while (i == -1);
board();//call board
if (i == 1)
printf("----->\aPlayer %d WINS!<-----", --player);//nice alert sound when printed
else
printf("----->\aC-could it be...? Game draw!<-----");//nice alert sound when printed
//getch();//waits for user input before ending
return 0;
}
A quick and dirty way to use recursion would be to do something like below... and yes this can be optimized..
int winnerCheck(int x)
{
if(x < numwinpos)
{
if((square[winpos[x][0]] == 'x') && (square[winpos[x][1]] == 'x') && (square[winpos[x][2]] == 'x') ||
(square[winpos[x][0]] == 'o') && (square[winpos[x][1]] == 'o') && (square[winpos[x][2]] == 'o'))
return 1;
else
{
return winnerCheck(++x);
}
}
return 0;
}
I tried to program a simple TicTacToe in C. The program itselfs compiles and show no errors.
So the program draws the field, reads the names and let a player put his symbol in a specific field. All this happens in a while loop, the should be run until its a draw or someone wins.
But the program just run the loop one time so there is only one turn then the program stops.
So here is my code:
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "game.h"
#define NAMELENGTH 20
int main(void) {
char names[2][NAMELENGTH];
// field positions
char field[9];
int winner = -1;
getnames(names);
printf("\n\n");
initField(field);
// set field positions to 'empty'
char actualPlayer = (char)(get_random_number()*10.0) % 2;
while (1) {
drawField(field);
turn(actualPlayer, names, field);
winner = isWinner(actualPlayer, field);
drawField(field);
if (winner >= 1) {
printwinner(winner, names);
return 0;
}
else if (winner == 0) {
printDrawGame(names);
return 0;
}
actualPlayer = (actualPlayer + 1) % 2;
}
return 0;
}
game.h Headerfile:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NAMELENGTH 20
#pragma warning(disable:4996)
extern void drawField(char *field);
extern void getnames(char nameField[][NAMELENGTH]);
extern void initField(char *field);
extern void turn(char actualPlayer, char names[][NAMELENGTH], char *field);
extern char isWinner(char actualPlayer, char *field);
extern void printwinner(char winnerNumber, char names[][NAMELENGTH]);
extern void printDrawGame(char names[][NAMELENGTH]);
extern double get_random_number();
and then my game.c where I defined my functions:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "game.h"
#define NAMELENGTH 20
#pragma warning(disable:4996)
void drawField(char *field) {
printf("________________________\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", field[0], field[1], field[2]);
printf("|_______|_______|______|\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", field[3], field[4], field[5]);
printf("|_______|_______|______|\n");
printf("| | | |\n");
printf("| %c | %c | %c |\n", field[6], field[7], field[8]);
printf("|_______|_______|______|\n");
}
void getnames(char nameField[][NAMELENGTH]) {
printf("Name of the first player: ");
scanf("%s", nameField[0]);
printf("Name of the second player: ");
scanf("%s", nameField[1]);
}
void initField(char *field) {
for (int i = 0; i <= 8; i++)
{
field[i] = i + '1';
}
}
void turn(char actualPlayer, char names[][NAMELENGTH], char *field) {
char symbol = ' ';
int p1fieldnumber;
int p2fieldnumber;
if (actualPlayer == 0)
{
do {
printf("\nIts Player %s's turn.", names[0]);
char symbol = 'X';
printf("\nNumber of the field which you want to put your symbol in: ");
scanf("%d", &p1fieldnumber);
if (field[p1fieldnumber] == 'X' || field[p1fieldnumber] == 'O')
{
printf("\nField is already occupied!");
p1fieldnumber = 10;
}
} while (p1fieldnumber < 1 || p1fieldnumber > 9);
field[p1fieldnumber-1] = 'X';
}
else {
do {
printf("\nIts Player %s's turn.", names[1]);
char symbol = 'O';
printf("\nNumber of the field which you want to put your symbol in: ");
scanf("%d", &p2fieldnumber);
if (field[p2fieldnumber] == 'X' || field[p2fieldnumber] == 'O')
{
printf("\nField is already occupied!");
p2fieldnumber = 10;
}
} while (p2fieldnumber < 1 || p2fieldnumber > 9);
field[p2fieldnumber-1] = 'O';
}
}
char isWinner(char actualPlayer, char *field) {
char pwinner = '3';
if (((field[0] == 'O') && (field[1] == 'O') && (field[2] == 'O')) ||
(field[3] == 'O') && (field[4] == 'O') && (field[5] == 'O') ||
(field[6] == 'O') && (field[7] == 'O') && (field[8] == 'O') ||
(field[0] == 'O') && (field[4] == 'O') && (field[8] == 'O') ||
(field[2] == 'O') && (field[4] == 'O') && (field[6] == 'O') ||
(field[0] == 'O') && (field[3] == 'O') && (field[6] == 'O') ||
(field[1] == 'O') && (field[4] == 'O') && (field[7] == 'O') ||
(field[2] == 'O') && (field[5] == 'O') && (field[8] == 'O'))
{
pwinner = '2';
}
else if (((field[0] == 'X') && (field[1] == 'X') && (field[2] == 'X')) ||
(field[3] == 'X') && (field[4] == 'X') && (field[5] == 'X') ||
(field[6] == 'X') && (field[7] == 'X') && (field[8] == 'X') ||
(field[0] == 'X') && (field[4] == 'X') && (field[8] == 'X') ||
(field[2] == 'X') && (field[4] == 'X') && (field[6] == 'X') ||
(field[0] == 'X') && (field[3] == 'X') && (field[6] == 'X') ||
(field[1] == 'X') && (field[4] == 'X') && (field[7] == 'X') ||
(field[2] == 'X') && (field[5] == 'X') && (field[8] == 'X'))
{
pwinner = '1';
}
else if (((field[0] == 'X') || (field[0] == 'O')) && ((field[1] == 'X') || (field[1] == 'O')) && ((field[2] == 'X') || (field[2] == 'O')) ||
((field[3] == 'X') || (field[3] == 'O')) && ((field[4] == 'X') || (field[4] == 'O')) && ((field[5] == 'X') || (field[5] == 'O')) ||
((field[6] == 'X') || (field[6] == 'O')) && ((field[7] == 'X') || (field[7] == 'O')) && ((field[8] == 'X') || (field[8] == 'O')) ||
((field[0] == 'X') || (field[0] == 'O')) && ((field[4] == 'X') || (field[4] == 'O')) && ((field[8] == 'X') || (field[8] == 'O')) ||
((field[2] == 'X') || (field[2] == 'O')) && ((field[4] == 'X') || (field[4] == 'O')) && ((field[6] == 'X') || (field[6] == 'O')) ||
((field[0] == 'X') || (field[0] == 'O')) && ((field[3] == 'X') || (field[3] == 'O')) && ((field[6] == 'X') || (field[6] == 'O')) ||
((field[1] == 'X') || (field[1] == 'O')) && ((field[4] == 'X') || (field[4] == 'O')) && ((field[7] == 'X') || (field[7] == 'O')) ||
((field[2] == 'X') || (field[2] == 'O')) && ((field[5] == 'X') || (field[5] == 'O')) && ((field[8] == 'X') || (field[8] == 'O')))
{
pwinner = '0';
}
return pwinner;
}
void printwinner(char winnerNumber, char names[][NAMELENGTH]) {
if (winnerNumber == '1') {
printf("Player %s won!", names[0]);
}
else if (winnerNumber == '2') {
printf("Player %s won!", names[1]);
}
}
void printDrawGame(char names[][NAMELENGTH]) {
printf("Draw!");
}
static int _initialized;
double get_random_number() {
if (!_initialized) {
srand(time(NULL));
_initialized = 1;
}
return (double)rand() / ((double)(RAND_MAX)+1);
}
There are multiple issues
isWinner returns characters '0', '1', '2' and '3'. Replace them with numbers 0, 1, 2, 3, because your are comparing with numbers in main.
In main instead of checking if (winner >= 1) {, which is true even if 3 is returned by isWinner, check for if (winner == 1 || winner == 2) {.
Suggest to use parentheses in isWinner around each condition separated by ||.
Parentheses as shown below for the first condition
if (((field[0] == 'O') && (field[1] == 'O') && (field[2] == 'O')) ||
((field[3] == 'O') && (field[4] == 'O') && (field[5] == 'O')) ||
((field[6] == 'O') && (field[7] == 'O') && (field[8] == 'O')) ||
((field[0] == 'O') && (field[4] == 'O') && (field[8] == 'O')) ||
((field[2] == 'O') && (field[4] == 'O') && (field[6] == 'O')) ||
((field[0] == 'O') && (field[3] == 'O') && (field[6] == 'O')) ||
((field[1] == 'O') && (field[4] == 'O') && (field[7] == 'O')) ||
((field[2] == 'O') && (field[5] == 'O') && (field[8] == 'O')))