making a random move in tic tac toe -in C - c

I am doing a tic tac toe game in which the user competes against the computer. When the user chooses a spot, the computer should also make a move. However, I can't seem to get that to work. Whenever the user makes a move, it instantly asks me to make another one instead of filling one of the spots with the computer symbol (O)
I did the computer part in a different function from the user's (AI() and User()) and tried calling it inside each "else if" statement of the switch, however, that only keeps the game blinking and doesn't allow me to continue.
EDIT: I also tried to, instead of making it a function, do the whole AI() process inside "else if" statements, but it only seemed to work when the user chose 1, not for the rest of the options.
EDIT #2: I changed (k = 1) to (k == 1) in the code.
To make the following code easier to read I made it 1x3 instead of 3x3:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct symbol{
int marked;
char symbol;
} SPOT;
SPOT spot1 = {0,'1'};
SPOT spot2 = {0,'2'};
SPOT spot3 = {0,'3'};
char symbol = 'X';
char compu = 'O';
void table();
int Check();
void User();
void AI();
int main(){
system("cls");
User();
AI();
Check();
return 0;
}
void table(){
printf("\n %c | %c | %c ",spot1.symbol,spot2.symbol,spot3.symbol);
}
void User(){
char choice;
do{
loop++;
do{
table();
printf("\n\nChoose a spot: ");
fflush(stdin);
scanf("%c",&choice);
} while(choice < '1' || choice > '3');
switch(choice){
case '1':
if(choice == '1'){
system("cls");
if(spot1.marked == 1){
printf("\nThat spot is taken\n");
}
else if(spot1.marked == 0){
spot1.marked = 1;
spot1.symbol = symbol;
}
}
break;
case '2':
if(choice == '2'){
system("cls");
if(spot2.marked == 1){
printf("\nThat spot is taken\n");
}
else if(spot2.marked == 0){
spot2.marked = 1;
spot2.symbol = symbol;
}
}
break;
case '3':
if(choice == '3'){
system("cls");
if(spot3.marked == 1){
printf("\nThat spot is taken\n");
}
else if(spot3.marked == 0){
spot3.marked = 1;
spot3.symbol = symbol;
}
}
break;
}while(Check() != 0 && Check() != 1);
}
void AI(){
int random,k;
srand(time(NULL));
do{
random = rand() % 4;
k = 0;
if(spot1.symbol == symbol || spot2.symbol == symbol || spot3.symbol == symbol){
k = 1;
}
}while(k == 1);
switch(random){
case '1':
if (random == 1){
spot1.symbol = compu;
spot1.marked = 1;
}
break;
case '2':
if (random == 2){
spot2.symbol = compu;
spot2.marked = 1;
}
break;
case '3':
if (random == 3){
spot3.symbol = compu;
spot3.marked = 1;
}
break;
}
}
int Check() {
if(spot1.marked == spot2.marked && spot2.marked == spot3.marked){
if(spot1.symbol == symbol){
return 1;
printf("You won!");
}
else if(spot1.symbol == compu){
return 0;
printf("You lost!");
}
}
else {
return 2;
}
}

That's because each function in your main is called one after another.
Your program is stuck in the User() call
Try changing your main to :
int main(){
system("cls");
do{
User();
AI();
}while(Check() != 0 && Check() != 1);
return 0;
}
Removing the do{...}while(Check() != 0 && Check() != 1); in the User function
and change while(k = 1); to while(k == 1);

Related

How to reset array in my tic tac toe game

I'm new to C and I'm trying to make a tic-tac-toe game for my college project and I'm struggling on how to reset my array in my game.
Every time I play again it does not reset the array. Can anyone help me with this?
Here is the code:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
char space[3][3] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'}
};
void board();
int checkWin();
int game();
void reset();
int main(){
int choice = -1;
do{
printf("\n\n\n\n\n\n\n\t\t\t ================\n");
printf("\t\t\t Tic Tac Toe\n");
printf("\t\t\t ================\n");
printf("\t\t -----------Menu-----------\n\n");
printf("\t\t 1. Play\n");
printf("\t\t 2. Exit\n");
scanf("%d", &choice);
switch(choice){
case 1: game();
break;
case 2: printf("Goodbye!!");
exit(0);
break;
default: printf(".......Wrong Key !.......Try Again!......");
break;
}
}while(choice != 0);
}
int game(){
int player = 1, i, choice;
char mark;
do
{
system("cls");
board();
player = (player % 2) ? 1 : 2;
printf("Player %d, enter a number: ", player);
scanf("%d", &choice);
mark = (player == 1) ? 'X' : 'O';
if (choice == 1)
space[0][0] = mark;
else if (choice == 2)
space[0][1] = mark;
else if (choice == 3)
space[0][2] = mark;
else if (choice == 4)
space[1][0] = mark;
else if (choice == 5)
space[1][1] = mark;
else if (choice == 6)
space[1][2] = mark;
else if (choice == 7)
space[2][0] = mark;
else if (choice == 8)
space[2][1] = mark;
else if (choice == 9)
space[2][2] = mark;
else
{
printf("Invalid move ");
player--;
getch();
}
i = checkWin();
player++;
}while (i == - 1);
board();
reset();
if (i == 1)
printf("==>\aPlayer %d win \n\n", --player);
else
printf("==>\aGame draw\n\n");
getch();
return 0;
}
int checkWin(){
if (space[0][0] == space[0][1] && space[0][1] == space[0][2])
return 1;
else if (space[1][0] == space[1][1] && space[1][1] == space[1][2])
return 1;
else if (space[2][0] == space[2][1] && space[2][1] == space[2][2])
return 1;
else if (space[0][0] == space[1][0] && space[1][0] == space[2][0])
return 1;
else if (space[0][1] == space[1][1] && space[1][1] == space[2][1])
return 1;
else if (space[0][2] == space[1][2] && space[1][2] == space[2][2])
return 1;
else if (space[0][0] == space[1][1] && space[1][1] == space[2][2])
return 1;
else if (space[0][2] == space[1][1] && space[1][1] == space[2][0])
return 1;
else if (space[0][0] != space[0][0] && space[0][1] != space[0][1] && space[0][2] != space[0][2] &&
space[1][0] != space[1][0] && space[1][1] != space[1][1] && space[1][2] != space[1][2] && space[2][0]
!= space[2][0] && space[2][1] != space[2][1] && space[2][2] != space[2][1])
return 0;
else
return - 1;
}
void reset(){
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = 0;
}
}
}
void board(){
system("cls");
printf("\n\n\tTic Tac Toe\n\n");
printf("Player 1 (X) - Player 2 (O)\n\n\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[0][0], space[0][1], space[0][2]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[1][0], space[1][1], space[1][2]);
printf("_____|_____|_____\n");
printf(" | | \n");
printf(" %c | %c | %c \n", space[2][0], space[2][1], space[2][2]);
printf(" | | \n\n");
}
I tried using for loop but it does not work; how can I solve this?
void reset(){
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = 0;
}
}
}
Your reset function is filling the entire 3x3 board matrix with zeros; these represent the nul character, not the character representing the '0' digit. Those nul characters aren't printed (and cannot be), so the board looks 'wrong' after a reset.
However, simply changing the space[i][j] = 0; line to space[i][j] = '0'; won't work! Although you will then initially see a board full of 0 digits, the way your checkWin() function works will then ensure that "Player 1" will have won the new game immediately after their first move, because there will already be rows/columns/diagonals of three identical characters.
So, to get the original ('1' thru '9') display, write your reset() function as below. (Note that the C Standard requires that the characters representing the numerical digits be in order and contiguous, so adding a value of 1 thru 9 to the '0' character will yield the appropriate digit character.)
void reset()
{
int number = 1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
space[i][j] = number++ + '0';
}
}
}
Alternatively, you can just declare and initialize a new 'board array' with the data in it, then just use memcpy to rest the space array with the contents of that:
#include <string.h> // For "memcpy"
void reset()
{
char empty[3][3] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'} };
memcpy(space, empty, sizeof(space));
}
Note, also that all the tests in the following statement are wrong:
else if (space[0][0] != space[0][0] && space[0][1] != space[0][1] && space[0][2] != space[0][2] &&
space[1][0] != space[1][0] && space[1][1] != space[1][1] && space[1][2] != space[1][2] && space[2][0]
!= space[2][0] && space[2][1] != space[2][1] && space[2][2] != space[2][1])
Each one of these is testing if an element is not equal to itself. This can never be true, so that else if block (the return 0; line) is never executed. But you don't actually need it, so you can just delete that block.

This is the code for the queuing implementation. I don't know why there is a problem with the output

The purpose of this code is to implement the queue, input I is to store a value, G is to retrieve a value, and E is to end the storage and retrieval work.
My problem is that I don't know why the output "[I]存入數值[G]取出數值[E]結束:" will output more than one after the first time.
#include <stdio.h>
#include <stdlib.h>
#define MAX 20
int main()
{
int rear = -1;
int front = -1;
int queue[MAX] = {0};
char ch;
int val;
while (rear < MAX - 1 && ch != 'E')
{
printf("[I]存入數值[G]取出數值[E]結束:");
scanf("%c", &ch);
switch (ch)
{
case 'I':
printf("請輸入數值:");
scanf("%d", &val);
rear++;
queue[rear] = val;
break;
case 'G':
if (rear > front)
{
front++;
printf("取出的值:%d\n", queue[front]);
queue[front] = 0;
}
else
{
printf("佇列已空!\n");
exit(0);
}
break;
default:
printf("\n");
break;
}
}
if (rear == MAX - 1)
printf("佇列已滿!\n");
printf("目前佇列中的資料:");
if (front >= rear)
{
printf("沒有\n");
printf("佇列已空!\n");
}
else
{
while (rear > front)
{
front++;
printf("%d ", queue[front]);
}
printf("\n");
}
return 0;
}

I have a problem with this how can I write multiple characters inside an array in c please get me a solution

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int generaterandomno(int n)
{
srand(time(NULL));
return rand() % n;
}
int greater(char char1, char char2)
{
//For Rock, Paper, Scissors - Returns 1 if c1>c2 and 0 otherwise. If c1 == c2 it will return -1
if (char1 == char2)
{
return -1;
}
else if ((char1 == 'r') && (char2 == 's'))
{
return 1;
}
else if ((char2 == 'r') && (char1 == 's'))
{
return 0;
}
else if ((char1 == 'p') && (char2 == 'r'))
{
return 1;
}
else if ((char2 == 'p') && (char1 == 'r'))
{
return 0;
}
else if ((char1 == 's') && (char2 == 'p'))
{
return 1;
}
else if ((char2 == 's') && (char1 == 'p'))
{
return 0;
}
}
int main()
{
int playerscore = 0, compscore = 0, temp;
char playerchar, compchar;
char dict[] = {'r', 'p', 's'};
printf("Welcome to The Rock, Paper, Scissors Game, I hope you will enjoy\n");
for (int i = 0; i < 3; i++)
{
// Take Player 1's input
printf("Player 1:\n");
printf("Choose 1 for Rock, 2 for Paper and 3 for Scissors\n");
scanf("%d", &temp);
getchar();
playerchar = dict[temp - 1];
printf("You chose %c\n\n", playerchar);
// Generate computer's input
printf("Computer's Turn:\n");
printf("Choose 1 for Rock, 2 for Paper and 3 for Scissors\n");
temp = generaterandomno(3) + 1;
compchar = dict[temp - 1];
printf("Computer chose %c\n\n", compchar);
// Compare the scores
if (greater(compchar, playerchar) == 1)
{
compscore += 1;
printf("Computer got it!!!\n");
}
else if (greater(compchar, playerchar) == -1)
{
compscore += 1;
playerscore += 1;
printf("It's a Draw!!!\n");
}
else
{
playerscore += 1;
printf("You got it!!!\n");
}
printf("You: %d\nComp: %d\n\n",playerscore, compscore);
}
if (playerscore > compscore)
{
printf("----------------------\n");
printf("------You Won!!!------\n");
printf("----------------------\n");
}
else if (compscore > playerscore)
{
printf("---------------------\n");
printf("---Computer Won!!!---\n");
printf("---------------------\n");
}
else
{
printf("----------------------\n");
printf("----It's a Draw!!!----\n");
printf("----------------------\n");
}
return 0;
}
char dict[] = {'r', 'p', 's'};
I have a problem with this 👆 how can I write multiple characters inside an array in c please get me a solution. I want to write rock paper and scissors replacing this please get a solution for me.....
I think what you are asking is about outputting 'rock' instead of 'r' when confirming the choice.
You could create a 2 dimensional array to hold the strings instead of a one dimensional array. For example...
char rps[][] = { "rock", "paper", "scissors" };
This would allow you to get at both the initials for example...
rps[0][0] would be 'r'
or the whole string...
rps[0] is "rock"
The important thing to note is that a string is just a char array with a null terminator.
These links will help explain a bit more.
https://www.programiz.com/c-programming/c-strings
https://www.codingame.com/playgrounds/14213/how-to-play-with-strings-in-c/array-of-c-string

Handling inputs for int, char, float

I am trying to write a program that loops asking the user to continuously input either a float, int, or char and echo it back to them until they enter 'q', then the loop ends. I do not understand how to decipher between an int, char, or float before entering the loop. I have tried if (scanf("%c", ch)) and so on for float and int and that works great, but once I added the loop in it's messing me up. I have tried several different combinations, but I have still not found my answer.
Here is one attempt to show you exactly what I am trying to do:
char ch;
int num = 0;
float fl = 0;
printf("Enter a value: ");
while(ch != 'q') {
if (scanf("%c", &ch) && !isdigit(ch)) {
printf("You entered a character %c\n", ch);
}
else if (scanf("%d", &num)) }
printf("You entered an integer %d\n", num);
}
else if (scanf("%d", &num)) {
printf("You entered a floating point number %f\n", fl);
}
printf("Enter another value: ");
}
}
This keeps doing something strange and I cannot pinpoint my problem. Thank you in advance!
You cannot accomplish that with your approach. You can scan a line and parse it accordingly:
char line[128]; /* Create a buffer to store the line */
char ch = 0;
int num;
float fl; /* Variables to store data in */
int r;
size_t n; /* For checking from `sscanf` */
/* A `do...while` loop is best for your case */
do {
printf("Enter a value: ");
if(fgets(line, sizeof(line), stdin) == NULL) /* If scanning a line failed */
{
fputs("`fgets` failed", stderr);
exit(1); /* Exits the program with a return value `1`; Requires `stdlib.h` */
}
line[strcspn(line, "\n")] = '\0'; /* Replace `\n` with `'\0'` */
r = sscanf(buffer, "%d%zn", &num, &n);
if(r == 1 && n == strlen(line)) { /* If true, entered data is an integer; `strlen` requires `string.h` */
printf("You entered an integer %d\n", num);
}
else{
r = sscanf(buffer, "%f%zn", &fl, &n);
if(r == 1 && n == strlen(line)) { /* If true, entered data is a float; `strlen` requires `string.h` */
printf("You entered a floating point number %f\n", fl);
}
else{
if(strlen(line) == 1) /* If true, entered data is a character; `strlen` requires `string.h` */
{
ch = line[0];
printf("You entered a character %c\n", ch);
}
else{ /* Entered data is something else */
printf("You entered \"%s\"\n", line);
}
}
}
}while(c != 'q');
Disclaimer: I wrote the above code using a mobile and I haven't tested it.
Update (did not test and wrote with my mobile):
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
int main(void)
{
int c = 0;
bool random = false;
bool flag = true;
bool is_float = false, is_char = false, is_number = false;
do{
c = getchar();
if(c == EOF)
break;
if(!random)
{
if(isdigit(c))
{
is_number = true;
}
else if(c == '.')
{
if(is_number)
{
if(is_float)
{
random = true;
}
else
{
is_float = true;
}
}
else if(!is_number && !is_float && !is_char)
{
is_float = true;
}
}
else if(c == '-' && !is_float && !is_number && !is_char);
else if(isalpha(c))
{
if(is_char)
random = true;
else
{
is_char = true;
if(c == 'q')
flag = false;
}
}
else
{
random = true;
}
if((is_char && is_float) || (is_char && is_number))
random = true;
if(c == '\n' && !is_char && !is_float && !is_number)
random = true;
}
if(c == '\n')
{
if(random)
/* puts("You entered a random string!"); */
puts("Invalid input!");
else if(is_float)
puts("You entered a float!");
else if(is_number)
puts("You entered a number!");
else if(is_char)
puts("You entered a character!");
else
puts("Error!");
if(!flag && !is_number && !is_float && !random)
flag = false;
else
flag = true;
is_char = is_float = is_number = random = false;
}
}while(flag);
puts("Done");
return 0;
}

why does my printf statement pop up simultaneously? and get an infinite loop?

Why is it that when I start the program, I will start by doing the first printf statement, and then i input, then it simultaneously does two printf statements.
Is this what's causing the infinite loop as well?
Starting the program
Player 1: Choose your symbol:
a
This part, they both output simultaneously
Player 2: Choose your symbol:
player1, enter placement:
And then I get an infinite loop. Is it due to the simultaneous output?
code
include <stdio.h>
int check(char player);
void move(char player);
char board[3][3] ;
int main(void)
{
int first;
char player1, player2;
printf("Player 1: Choose your symbol: \n");
player1 = getchar();
printf("Player 2: Choose your symbol: \n");
player2 = getchar();
int i=0;
int win;char turn;
while(win == 0)
{
if((i%2) == 0){
turn = player1;
move(player1);
win = check(player1);
print();}
else {
turn = player2;
move(player2);
win = check(player2);
print();}
i++;
}
if (i == 8)
printf("its a tie");
else
printf("the winner is %c", turn);
return 0;
}
/*printing the board that takes in a placement int*/
void print(void)
{
int r;
printf("\n");
for (r = 0; r < 3; r++){
printf(" %c | %c | %c \n" , board[r][0], board[r][2], board[r][3]);
if (r != 2)
printf("___________\n");
}
printf("\n");
return;
}
/*check to see if someone won*/
int check(char player)
{
int r, c;
for ( r = 0 ; r <3 ; r++)
{
if ((board[r][0] == player) && (board[r][1] == player) && (board[r][2] == player))
return 1;
}
for ( c = 0 ; c <3 ; c++)
{
if ((board[0][c] == player) && (board[1][c] == player) && (board[2][c] == player))
return 1;
}
if((board[0][0] == player) && (board[1][1] == player) && (board[2][2] == player))
return 1;
if((board[0][2] == player) && (board[1][1] == player) && (board[2][0] == player))
return 1;
return 0;
}
void move(char player)
{
int place;
printf("player1, enter placement: \n");
scanf("%d", &place);
if (place == 1)
board[0][0] = player;
else if (place == 2)
board[0][1] = player;
else if (place == 3)
board[0][2] = player;
else if (place == 4)
board[1][0] = player;
else if (place == 5)
board[1][1] = player;
else if (place == 6)
board[1][2] = player;
else if (place == 7)
board[2][0] = player;
else if (place == 8)
board[2][1] = player;
else if (place == 9)
board[2][2] = player;
}
Because first getchar() leaves a newline character in the input stream which consumed by the subsequent getchar(). One way is to use another getchar() to consume the unwanted newline chars.
printf("Player 1: Choose your symbol: \n");
player1 = getchar();
getchar(); // consume a newline
printf("Player 2: Choose your symbol: \n");
player2 = getchar();
getchar(); // consume a newline
You're probably getting the '\n' character from getchar();
You could do something like:
printf("Player 2: Choose your symbol: \n");
player2 = getchar();
while ( player2 != '\n' ) { player2 = getchar(); }
to clear standard input before reading again with the next getchar();

Resources