How can I store an array slot to use between functions? - arrays

I'm trying to make a tic tac toe game that allows you to play against a human enemy or the computer. I'm trying to code some basic AI that will prevent you from winning by scanning the board to see if you have 2 X's or O's next to each other or in opposite corners in a column/row/diagonal and I need a way to tell the computer if and which tile it needs to print on to prevent you from winning. My code:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
void initializeBoard(); //initialize the board //
void drawBoard(); //draw it on the window //
void player_1_move(); //check if player 1 made a valid move and update the board
void player_2_move(); //check if player 2 made a valid move and update the board
//AI functions
void pickTile(); //picks a tile based on available information
void computerTurn(); //checks if the computer is going first or second
char* isThereaWinningMove(); //checks if the user is abou to win
char tempcT;
int checkWin(); //checks if either player has won at the end of every turn and if so ends the game and declares a winner //
char board[3][3]; //3x3 tic tac toe board
int main(){
int win = 0;
printf("==============");
printf("\n TIC TAC TOE \n");
printf("==============\n");
printf("The World's Number 1 Multiplayer Game! \n\n");
initializeBoard();
//let's the user pick the gamemode
int x;
printf("Press 1 to PLAY AGAINST A HUMAN or 0 to PLAY AGAINST AI: \n");
scanf("%d", &x);
while(x!=0 && x!=1){
printf("Invalid input. Press 1 to PLAY AGAINST A HUMAN or 0 to PLAY AGAINST AI: ");
scanf("%d", &x);
}
if(x==1){ //pvp
do{
drawBoard();
printf("\n\n");
player_1_move(); //player 1 (X) moves
drawBoard(); //update the board with each move
win=checkWin(); //did player 1 win?
if(win==1){
printf("\nPlayer 1 has won!");
break;
}
printf("\n\n");
player_2_move(); //player 2 (O) moves
drawBoard(); //update the board with each move
win=checkWin(); //did player 2 win?
if(win==1){
printf("\nPlayer 2 has won!");
break;
}
}while(1);
}
else{ //pvc
computerTurn();
if(tempcT == 'O'){ //if the player is going first
do{
srand( (unsigned int) time(NULL) ); //initialize random seed
drawBoard();
printf("\n\n");
player_1_move(); //user (X) moves first
drawBoard(); //update the board with each move
win=checkWin(); //did player 1 win?
if(win==1){
printf("\nPlayer has won!");
break;
}
//computer turn
printf("\n\n");
pickTile(); //picks available tile
win=checkWin();
if(win == 1){
printf("\nI win!");
break;
}
}while(1);
}
else{ //if the computer goes first
do{
//computer turn
srand( (unsigned int) time(NULL) ); //initialize random seed
printf("\n\n");
pickTile(); //picks available tile
win=checkWin();
if(win == 1){
printf("\nI win!");
break;
}
//player turn
drawBoard();
printf("\n\n");
player_1_move(); //user (X) moves first
drawBoard(); //update the board with each move
win=checkWin(); //did player 1 win?
if(win==1){
printf("\nPlayer has won!");
break;
}
}while(1);
}
}
return 0;
}
//initialize the board
void initializeBoard(){
int i, j;
for(i=0; i<=2; i++){
for(j=0; j<=2; j++){
board[i][j]= ' ';
}
}
}
//draws the board on the window
void drawBoard(){
int t;
for(t=0; t<=2; t++){
printf(" %c | %c | %c ", board[t][0], board[t][1], board[t][2]);
if(t!=2){
printf("\n---|---|---\n");
}
}
printf("\n");
}
//checks if there is a winner at the end of every turn
int checkWin(){
int i;
//checks rows
for(i=0; i<=2; i++){
if(board[i][0]==board[i][1] && board[i][0]==board[i][2] && board[i][0]!= ' '){
return 1;
}
}
//checks columns
for(i=0; i<=2; i++){
if(board[0][i]==board[1][i] && board[0][i]==board[2][i] && board[0][i]!= ' '){
return 1;
}
}
//checks diagonals from top left to bottom right
for(i=0; i<=2; i++){
if(board[0][0]==board[1][1] && board[1][1]==board[2][2] && board[0][0]!= ' '){
return 1;
}
}
//checks diagonals from bottom left to top right
for(i=0; i<=2; i++){
if(board[2][0]==board[1][1] && board[1][1]==board[0][2] && board [2][0]!= ' '){
return 1;
}
}
return 0;
}
//player 1 (X) move
void player_1_move(){
int x, y;
//player 1 picks coordinates on the board
printf("Player 1, please pick a row (1-3): ");
scanf("%d", &x);
printf("Now pick a column (1-3): ");
scanf("%d", &y);
x--, y--;
//check if it's a valid tile
while(1){
if(x<0 || x>2){
if(y<0 || y>2){
printf("Invalid tile, please enter a valid tile (same order as before, 1-3): ");
scanf("%d%d", &x, &y);
x--, y--;
}
else{
printf("Invalid row, please try again (1-3): ");
scanf("%d", &x);
x--;
}
}
else if(y<0 || y>2){
printf("Invalid column, please try again (1-3): ");
scanf("%d", &y);
y--;
}
else{
break;
}
}
//check if the tile is free
while(board[x][y]=='O' || board[x][y]=='X'){
printf("Invalid move, please enter valid coordinates (same order as before, 1-3): ");
scanf("%d%d", &x, &y);
x--, y--;
}
board[x][y]='X';
}
//player 2 (O) move
void player_2_move(){
int x, y;
//player 2 picks a tile
printf("Player 2, please pick a row (1-3): ");
scanf("%d", &x);
printf("Now pick a column (1-3): ");
scanf("%d", &y);
x--, y--;
//check if it's a valid tile
while(1){
if(x<0 || x>2){
if(y<0 || y>2){
printf("Invalid tile, please enter a valid tile (same order as before, 1-3): ");
scanf("%d%d", &x, &y);
x--, y--;
}
else{
printf("Invalid row, please try again (1-3): ");
scanf("%d", &x);
x--;
}
}
else if(y<0 || y>2){
printf("Invalid column, please try again (1-3): ");
scanf("%d", &y);
y--;
}
else{
break;
}
}
//check if the tile is free
while(board[x][y]=='O' || board[x][y]=='X'){
printf("Invalid move, please enter valid coordinates (same order as before, 1-3): ");
scanf("%d%d", &x, &y);
x--, y--;
}
board[x][y]='O';
}
//AI functions
//checks if the computer is going first or second
void computerTurn(){
int x;
printf("Press 1 if you'd like to GO FIRST and 0 if you'd like to GO SECOND: ");
scanf("%d", &x);
while(x!=0 && x!=1){
printf("Invalid input. Press 1 if you'd like to GO FIRST and 0 if you'd like to GO SECOND: ");
scanf("%d", &x);
}
if(x==1){
printf("OK, the player is going first.\n\n");
tempcT = 'O';
}
else{
printf("OK, I'm going first.\n\n");
tempcT = 'X';
}
}
//if there is a winning move available on the AI's turn
char* isThereaWinningMove(){
int i;
//checks rows
for(i=0; i<=2; i++){
if(board[i][0]==board[i][1] && board[i][1] == ' '){
return &board[i][2];
}
}
for(i=0; i<=2; i++){
if(board[i][0]==board[i][2] && board[i][1] == ' '){
return &board[i][1];
}
}
for(i=0; i<=2; i++){
if(board[i][1]==board[i][2] && board[i][0] == ' '){
return &board[i][0];
}
}
//checks columns
for(i=0; i<=2; i++){
if(board[0][i]==board[2][i] && board[1][i] == ' '){
return &board[1][i];
}
}
for(i=0; i<=2; i++){
if(board[0][i]==board[1][i] && board[2][i] == ' '){
return &board[2][i];
}
}
for(i=0; i<=2; i++){
if(board[1][i]==board[2][i] && board[0][i] == ' '){
return &board[0][i];
}
}
//checks diagonals from top left to bottom right
if(board[1][1]==board[2][2] && board[0][0] == ' '){
return &board[0][0];
}
if(board[0][0]==board[2][2] && board[1][1] == ' '){
return &board[1][1];
}
if(board[0][0]==board[1][1] && board[2][2] == ' '){
return &board[2][2];
}
//checks diagonals from bottom left to top right
if(board[1][1]==board[0][2] && board [2][0] == ' '){
return &board[2][0];
}
if(board[2][0]==board[1][1] && board [0][2] ==' '){
return &board[0][2];
}
if(board[2][0]==board[0][2] && board [1][1] == ' '){
return &board[1][1];
}
return 0;
}
//picks a tile based on available information
void pickTile(){
int rndX, rndY;
char *p = isThereaWinningMove();
//did the computer detect a winning move?
if(p != 0){
*p = tempcT;
}
//if not, pick a random available tile
else{
while(1){
rndX = rand()%3;
rndY = rand()%3;
if(board[rndX][rndY] == ' '){
board[rndX][rndY] = tempcT;
break;
}
}
}
}
Playing against a human seems to work just fine. I only have a problem with assigning tempcT's value to whatever array slot the isThereaWinningMove function will return. The code I've written now only doesn't actually run because of 2 compiler errors:
[Error] assignment of function 'char isThereaWinningMove()'
[Error] cannot convert 'int' to 'char()' in assignment

As I said through remarks to your question :
[Error] assignment of function 'char isThereaWinningMove()' [Error] cannot convert 'int' to 'char()' in assignment
isThereaWinningMove is a function, doing isThereaWinningMove = 'tempcT' you try to assign a function with an (invalid) char which as no sense.
Some other remarks :
Out of that you have several calls of isThereaWinningMove done for nothing because you loose the result.
scanf("%d", x)is invalid you wanted scanf("%d", &x)
You call srand several times with very probably the same value (program runs in the same second), so you very probably get the same value for all your rndX and rndY, you must call srand one time at the beginning of main.
In fact you want to modify the cell whose value is return by isThereaWinningMove, in C (and then C++) you can return the address of the cell rather than the cell value :
char * isThereaWinningMove(); //checks if there is a winning move available
...
char * isThereaWinningMove(){
int i;
//checks rows
for(i=0; i<=2; i++){
if(board[i][0]==board[i][1] && board[i][0]!= ' '){
return &board[i][2];
}
}
for(i=0; i<=2; i++){
if(board[i][0]==board[i][2] && board[i][0]!= ' '){
return &board[i][1];
}
}
for(i=0; i<=2; i++){
if(board[i][1]==board[i][2] && board[i][0]!= ' '){
return &board[i][0];
}
}
//checks columns
for(i=0; i<=2; i++){
if(board[0][i]==board[2][i] && board[0][i]!= ' '){
return &board[1][i];
}
}
for(i=0; i<=2; i++){
if(board[0][i]==board[1][i] && board[0][i]!= ' '){
return &board[2][i];
}
}
for(i=0; i<=2; i++){
if(board[1][i]==board[2][i] && board[0][i]!= ' '){
return &board[0][i];
}
}
//checks diagonals from top left to bottom right
if(board[1][1]==board[2][2] && board[0][0]!= ' '){
return &board[0][0];
}
if(board[0][0]==board[2][2] && board[0][0]!= ' '){
return &board[1][1];
}
if(board[0][0]==board[1][1] && board[0][0]!= ' '){
return &board[2][2];
}
//checks diagonals from bottom left to top right
if(board[1][1]==board[0][2] && board [2][0]!= ' '){
return &board[2][0];
}
if(board[2][0]==board[1][1] && board [2][0]!= ' '){
return &board[0][2];
}
if(board[2][0]==board[0][2] && board [2][0]!= ' '){
return &board[1][1];
}
return 0;
}
...
void pickTile(){
int rndX, rndY, i;
//did the computer detect a winning move?
char * p = isThereaWinningMove();
if(p != 0){
*p = tempcT;
}
//if not, pick a random available tile
else{
...
an other way is to do the assignment in isThereaWinningMove and return something else that 0 when you did
int isThereaWinningMove(); //checks if there is a winning move available
...
int isThereaWinningMove(){
int i;
//checks rows
for(i=0; i<=2; i++){
if(board[i][0]==board[i][1] && board[i][0]!= ' '){
board[i][2] = tempcT;
return 1;
}
}
for(i=0; i<=2; i++){
if(board[i][0]==board[i][2] && board[i][0]!= ' '){
board[i][1] = tempcT;
return 1;
}
}
for(i=0; i<=2; i++){
if(board[i][1]==board[i][2] && board[i][0]!= ' '){
board[i][0] = tempcT;
return 1;
}
}
//checks columns
for(i=0; i<=2; i++){
if(board[0][i]==board[2][i] && board[0][i]!= ' '){
board[1][i] = tempcT;
return 1;
}
}
for(i=0; i<=2; i++){
if(board[0][i]==board[1][i] && board[0][i]!= ' '){
board[2][i] = tempcT;
return 1;
}
}
for(i=0; i<=2; i++){
if(board[1][i]==board[2][i] && board[0][i]!= ' '){
board[0][i] = tempcT;
return 1;
}
}
//checks diagonals from top left to bottom right
if(board[1][1]==board[2][2] && board[0][0]!= ' '){
board[0][0] = tempcT;
return 1;
}
if(board[0][0]==board[2][2] && board[0][0]!= ' '){
board[1][1] = tempcT;
return 1;
}
if(board[0][0]==board[1][1] && board[0][0]!= ' '){
board[2][2] = tempcT;
return 1;
}
//checks diagonals from bottom left to top right
if(board[1][1]==board[0][2] && board [2][0]!= ' '){
board[2][0] = tempcT;
return 1;
}
if(board[2][0]==board[1][1] && board [2][0]!= ' '){
board[0][2] = tempcT;
return 1;
}
if(board[2][0]==board[0][2] && board [2][0]!= ' '){
board[1][1] = tempcT;
return 1;
}
return 0;
}
...
//picks a tile based on available information
void pickTile(){
int rndX, rndY, i;
//did the computer detect a winning move?
if (isThereaWinningMove() == 0){
//if not, pick a random available tile
while(1){
...
Whatever the way to do, also removing the useless variable i in pickTile and removing the calls of isThereaWinningMove in main some other problems appear at the execution, for instance I can have :
pi#raspberrypi:/tmp $ gcc -Wall t.cpp
pi#raspberrypi:/tmp $ ./a.out
TIC TAC TOE
The World's Number 1 Multiplayer Game!
Press 1 to PLAY AGAINST A HUMAN or 0 to PLAY AGAINST AI: 0
Press 1 if you'd like to GO FIRST and 0 if you'd like to GO SECOND: 1
OK, the player is going first. | |
---|---|---
| |
---|---|---
| |
Player 1, please pick a row (1-3): 2
Now pick a column (1-3): 2
| |
---|---|---
| X |
---|---|---
| |
| |
---|---|---
| X |
---|---|---
O | |
Player 1, please pick a row (1-3): 1
Now pick a column (1-3): 1
X | |
---|---|---
| X |
---|---|---
O | |
O | |
---|---|---
| X |
---|---|---
O | |
Player 1, please pick a row (1-3): ^C
pi#raspberrypi:/tmp $
As you can see the program got the cell 1-1 I got before it.
The reason is simple, isThereaWinningMove` can get a cell without checking it is free, so for instance
if(board[i][0]==board[i][1] && board[i][0]!= ' '){
board[i][2] = tempcT;
return 1;
}
must be
if((board[i][0]==board[i][1] && board[i][0]!= ' ') && (board[i][2] == ' ')) {
board[i][2] = tempcT;
return 1;
}
etc
Note there are also two wrong indexes, for instance using the second way for
for(i=0; i<=2; i++){
if(board[i][1]==board[i][2] && board[i][0]!= ' '){
board[i][0] = tempcT;
return 1;
}
}
you wanted (out of the missing test checking the cell is empty)
for(i=0; i<=2; i++){
if(board[i][1]==board[i][2] && board[i][1]!= ' '){
board[i][0] = tempcT;
return 1;
}
}
and for
for(i=0; i<=2; i++){
if(board[1][i]==board[2][i] && board[0][i]!= ' '){
board[0][i] = tempcT;
return 1;
}
}
you wanted (out of the missing test checking the cell is empty) :
for(i=0; i<=2; i++){
if(board[1][i]==board[2][i] && board[1][i]!= ' '){
board[0][i] = tempcT;
return 1;
}
}
Note in checkWin the loops are useless in :
//checks diagonals from top left to bottom right
for(i=0; i<=2; i++){
if(board[0][0]==board[1][1] && board[1][1]==board[2][2] && board[0][0]!= ' '){
return 1;
}
}
//checks diagonals from bottom left to top right
for(i=0; i<=2; i++){
if(board[2][0]==board[1][1] && board[1][1]==board[0][2] && board [2][0]!= ' '){
return 1;
}
}
it is enough to do
if(board[0][0]==board[1][1] && board[1][1]==board[2][2] && board[0][0]!= ' '){
return 1;
}
if(board[2][0]==board[1][1] && board[1][1]==board[0][2] && board [2][0]!= ' '){
return 1;
}

Related

Beginner C program- Segmentation fault (core dumped)

The program is compiling just fine but I keep receiving an output of:
Segmentation fault (code dumped)
The program is designed to play a simple game of tic tac toe with a human and computer that plays a random space. I'm curious as to what this message means and feel it has something to do with my pointers but I'm not sure how or where. Any help is very appreciated. Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// Initializing board
void clear_table(char board [3][3])
{
int i, j;
//Outer loop for rows
for(i=0; i<3; i++)
{
//Inner loop for columns
for(j=0; j<3; j++)
{
board[i][j] = ' ';
}
}
}
// prints the board in nice format
void display_table (char board [3][3])
{
int i, j;
printf("\n\n The board is: \n");
//Outer loop for rows
for(i=0; i<3; i++)
{
//Inner loop for columns
for(j=0; j<3; j++)
{
//Printing character
printf(" %c", board[i][j]);
}
printf(" ");
//Printing footer
printf("\n _ _ _ \n");
}
}
//Validates the move
int check_legal_option(char board[3][3], int row, int col)
{
//Checking position
if(board[row][col] == ' ')
{
//Available
return 1;
}
return 0;
}
//Function that generates a valid move for player 2
void generate_player2_move(char board[3][3], int *row, int *col)
{
//Validating move
while(1)
{
//Generating computer position
*row = rand() % 3;
*col = rand() % 3;
//Checking for empty position
if(check_legal_option(board, *row, *col) == 1)
break;
}
}
//Function that checks whether board is full or not
int check_table_full(char board[3][3])
{
int i, j;
//Outer loop for rows
for(i=0; i<3; i++)
{
//Inner loop for columns
for(j=0; j<3; j++)
{
//Board is not Full
if(board[i][j] == ' ')
return 0;
}
}
//Board Full
return 1;
}
// win returns true if the given player has won on the
// given board, else it returns false
int win (char board [3][3], char player)
{
return (board[0][0] == player && board[0][1] == player && board[0][2] == player) ||
(board[1][0] == player && board[1][1] == player && board[1][2] == player) ||
(board[2][0] == player && board[2][1] == player && board[2][2] == player) ||
(board[0][0] == player && board[1][0] == player && board[2][0] == player) ||
(board[0][1] == player && board[1][1] == player && board[2][1] == player) ||
(board[0][2] == player && board[1][2] == player && board[2][2] == player) ||
(board[0][0] == player && board[1][1] == player && board[2][2] == player) ||
(board[0][2] == player && board[1][1] == player && board[2][0] == player);
}
//Function that checks for winner
int check_three_in_a_row(char board[3][3], char player1, char player2)
{
//Checking for winning of player
if(win(board, 'X') == 1 && win(board, 'O') == 1)
{
return 2;
}
//Checking for winning of player 1
else if(win(board, 'O') == 1)
{
return 0;
}
//Checking for winning of player 2
else if(win(board, 'X') == 1)
{
return 1;
}
//Tie
else
{
return -1;
}
}
//Function that plays the game
void playGame(char board[3][3], char player1, char player2)
{
int row, col;
int winner;
//Loop till board is full
while(check_table_full(board) != 1)
{
//Player turn
while(1)
{
//Reading positions from user
printf("\n Player 1 enter your selection [row,col]: ");
scanf("%d %d", &row, &col);
//Making suitable for array indexing
row = row - 1;
col = col - 1;
//Checking for empty position
if(check_legal_option(board, row, col) == 1)
break;
else
printf("\n Invalid choice... Try again!! \n ");
}
//Storing in array
board[row][col] = player1;
//Printing board
display_table(board);
//Finding winner
winner = check_three_in_a_row(board, player1, player2);
//If either of winner is found
if(winner >= 0 && winner <= 2)
{
//Printing winner
switch(winner)
{
//Displaying winner
case 0: printf("\n Player 1 won the game... \n"); break;
case 1: printf("\n Player 2 won the game... \n"); break;
case 2: printf("\n Game Tie ... \n"); break;
}
return;
}
//Generating a move
generate_player2_move(board, &row, &col);
//Storing in array
board[row][col] = player2;
printf("\n Player 2 has entered [row,col]: %d,%d \n", row+1, col+1);
//Printing board
display_table(board);
//Finding winner
winner = check_three_in_a_row(board, player1, player2);
//If either of winner is found
if(winner >= 0 && winner <= 2)
{
//Printing winner
switch(winner)
{
//Displaying winner
case 0: printf("\n Player 1 won the game... \n"); break;
case 1: printf("\n Player 2 won the game... \n"); break;
case 2: printf("\n Game Tie ... \n"); break;
}
return;
}
}
}
//Main function
int main()
{
//Board
char board[3][3];
//Player characters
char player1Character='O', player2Character='X';
//Initializing random function
srand(time(NULL));
//Initializing board
clear_table(board);
//Printing board
display_table(board);
//Playing game
playGame(board, player1Character, player2Character);
return 0;
}
The problem is right here, at the start of the PlayGame function:
//Reading positions from user
printf("\n Player 1 enter your selection [row,col]: ");
scanf("%d %d", &row, &col);
The prompt seems to suggest that you should enter two numbers separated by a comma, like 2,2 to get the center position.
However, the format string scanf("%d %d" doesn't say anything about a comma, so the input fails and col never gets a value.

How to print the result of a function in C?

I'm currently working on a Tic Tac Toe game that will be interactive for a user. I think I have it all working, I just can't figure out how to get the displayBoard() function to print out the current state of the board so that the user knows which spaces are open and which spaces are not. How can I get the displayBoard() function to print to the screen?
My code is as follows:
#include <stdio.h>
void initializeBoard(char board[][3]);
void displayBoard(char board[][3]);
void makeMove(char board[][3], int player);
int main(void)
{
char board[3][3];
int row;
int column;
int move = 1;
int player = 1;
initializeBoard(board);
while (move > 10)
{
displayBoard(board);
makeMove(board, player);
move++;
if (move == 2 || move == 4 || move == 6 || move == 8)
{
player = 2;
}//close of if
else
{
player = 1;
}//close of else
}
}//close of main function
void initializeBoard(char board[][3])
{
int i = 0;
int j = 0;
while (i < 4)
{
while (j < 4)
{
board[i][j] = ' ';
j++;
}//close of while loop
j = 0;
i++;
}//close of while loop
}//close of initializeBoard
void displayBoard(char board[][3])
{
printf(" 1 2 3");
printf("1 [%c] [%c] [%c]", board[1][1],board[1][2],board[1][3]);
printf("2 [%c] [%c] [%c]", board[2][1],board[2][2],board[2][3]);
printf("3 [%c] [%c] [%c]", board[3][1],board[3][2],board[3][3]);
}//close of displayBoard
void makeMove(char board[][3], int player)
{
int row;
int column;
printf("Enter the row and column you'd like to fill:");
scanf("%d %d", &row, &column);
if (player == 1)
{
board[row][column] = 'X';
}//close of if
else
{
board[row][column] = 'O';
}//close of else
}//close of makeMove
you have written many things wrong, nor you have called any function to draw board in main(). Here, I have a better version of the game. You can see it and compare and make yours better. its pretty similar, its in C++ but if thats a problem, just change input and output lines. PS: i dont remember much of C
goodluck.
#include<iostream.h>
#include<conio.h>
//to print digits on board and for checks
char num[10]={'0','1','2','3','4','5','6','7','8','9'};
void gameBoard() //function to print board
{
cout<<" | | "<<endl;
cout<<" "<<num[1]<<" | "<<num[2]<<" | "<<num[3]<<" "<<endl;
cout<<"_____|_____|_____"<<endl;
cout<<" | | "<<endl;
cout<<" "<<num[4]<<" | "<<num[5]<<" | "<<num[6]<<" "<<endl;
cout<<"_____|_____|_____"<<endl;
cout<<" | | "<<endl;
cout<<" "<<num[7]<<" | "<<num[8]<<" | "<<num[9]<<" "<<endl;
cout<<" | | "<<endl;
}
int win() //function to check if a player wins or game is draw,
// returns 1 if someone won, 0 if draw and -1 is game is still going on
{
if(num[1]==num[2] && num[2]==num[3])
return 1;
else if(num[4]==num[5] && num[5]==num[6])
return 1;
else if(num[7]==num[8] && num[8]==num[9])
return 1;
else if(num[1]==num[4] && num[4]==num[7])
return 1;
else if(num[2]==num[5] && num[5]==num[8])
return 1;
else if(num[3]==num[6] && num[6]==num[9])
return 1;
else if(num[1]==num[5] && num[5]==num[9])
return 1;
else if(num[3]==num[5] && num[5]==num[7])
return 1;
else if(num[1]!='1' && num[2]!='2' && num[3]!='3' && num[4]!='4' && num[5]!='5' && num[6]!='6' && num[7]!='7' && num[8]!='8' && num[9]!='9')
return 0;
else
return -1;
}
void input() //function for player input and to assign both players signs.
{
int choice,w,player=1;
char sym;
do{
clrscr();
gameBoard();
player=(player%2)? 1:2; //to check whos turn
cout<<"\nPlayer "<<player<< " ,Enter Your Choice: ";
cin>>choice;
sym = (player == 1)? 'X' : 'O'; //assigns X to player 1 and O to player 2
if(choice==1&&num[1]=='1')
num[1]=sym;
else if(choice==2&&num[2]=='2')
num[2]=sym;
else if(choice==3&&num[3]=='3')
num[3]=sym;
else if(choice==4&&num[4]=='4')
num[4]=sym;
else if(choice==5&&num[5]=='5')
num[5]=sym;
else if(choice==6&&num[6]=='6')
num[6]=sym;
else if(choice==7&&num[7]=='7')
num[7]=sym;
else if(choice==8&&num[8]=='8')
num[8]=sym;
else if(choice==9&&num[9]=='9')
num[9]=sym;
else
{
cout<<"\n\nWrong Move, Please enter again:";
cin.ignore();
player--; //Ignores the input and let player choose again.
getch();
}
w=win();
player++;
}while(w==-1);
clrscr();
gameBoard();
if(w==1)
cout<<"\n Player "<<--player<<" wins!!";
else
cout<<"\n Game Draw";
getch();
}
int main()
{
clrscr();
input(); return 0;
}

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.

Connecting Random number in 2d array [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have generated random number into a 2d array.What I want now is to connect the same number by moving it inside the game board.The problems is it doesn't move.
I really need help!!! I am new to c programming btw. Thanks in advance.
Here's my code:
void playgame(char box[ROW][COL])
{
int x, y, choice2,num,direction=0;
char input;
do{
printf("Please select a number (1-7) : \n");
scanf("%i",&num);
if(x==0 || x==ROW-1 ||y==0 || y==COL-1)
{
printf("Invalid!\n");
}
else
{
printf("Numer %i is currently selected!\n", num);
}
}while(x==0 || x==ROW-1 ||y==0 || y==COL-1);
printf("[1]Move\n[2]Sign out\n");
printf("Enter choice: ");
scanf("%d", &choice2);
switch(choice2)
{
case 1:
{
printf("Press 'E' to go up\n");
/*codes for moving the character up.....*/
}
{
printf("Press 'D' to go right\n");
/*codes for moving the character down.....*/
}
{
printf("Press 'S' to go left\n");
/*codes for moving the character left.....*/
}
{
printf("Press 'X' to go down\n");
/*codes for moving the character up.....*/
}
{
printf("Press 'R' to remove the existing path\n");
}
fflush(stdin);
scanf("%c", &input);
break;
case 2: printf("Bye!\n");
}
for(x=0; x<9; x++)
for(y=0; y<9; y++)
{
if(input == 'E')
if(box[x][y]==num)
{
box[--x][y]==num;
}
if(input == 'D')
if(box[x][y]==num)
{
box[x][y++]==num;
}
if(input == 'S')
if(box[x][y]== num)
{
box[x][--y]== num;
}
if(input == 'X')
if(box[x][y]==num)
{
box[--x][y]==num;
}
}
}
try this:
#include <stdio.h>
#include <stdlib.h>
#define ROW 9
#define COL 9
void display(char box[ROW][COL]);
int validMove(int r, int c, char box[ROW][COL]);
void playgame(char box[ROW][COL]){
int r, c, num;
int choice, nr, nc;
char input, n;
for(;;){
printf("Please select a number (1-7) : \n");
if(1 == scanf("%i", &num) && 1<= num && num <= 7)
break;
printf("Invalid!\n");
while(getchar() != '\n');
}
printf("Numer %i is currently selected!\n", num);
n = num + '0';
for(r = 1; r < ROW-1; ++r)
for(c = 1; c < COL-1; ++c)
if(box[r][c] == n)
goto find;
find:
for(;;){
printf("[1]Move\n"
"[2]Sign out\n"
"Enter choice: ");
scanf("%d", &choice);
switch(choice){
case 1:
printf("Press 'E' to go up\n"
"Press 'D' to go right\n"
"Press 'S' to go left\n"
"Press 'X' to go down\n"
"Press 'R' to remove the existing path\n");
scanf(" %c", &input);
nr = r;
nc = c;
switch(input){
case 'E':
nr = r - 1;
break;
case 'D':
nc = c + 1;
break;
case 'S':
nc = c - 1;
break;
case 'X':
nr = r + 1;
break;
case 'R':
break;
default:
break;
}
if(validMove(nr, nc, box)){
box[nr][nc] = box[r][c];
box[r][c] = ' ';
r = nr;
c = nc;
display(box);
} else if(input != 'R'){
printf("invalid move!\n");
}
break;
case 2: printf("Bye!\n");
exit(0);
}
}
}
int validMove(int r, int c, char box[ROW][COL]){
if(r == 0 || r == ROW-1 || c == 0 || c == COL-1)
return 0;
if(box[r][c] != ' ')
return 0;
return 1;
}
void initBoard(char box[ROW][COL]){
int r, c;
for(r = 0; r < ROW; ++r){
for(c = 0; c < COL; ++c){
if(r == 0 || r == ROW-1 || c == 0 || c == COL-1)
box[r][c] = '#';
else
box[r][c] = ' ';
}
}
for(int i = 1; i <= 7; ++i){
int r = rand() % (ROW-1-1) + 1;
int c = rand() % (COL-1-1) + 1;
if(box[r][c] == ' ')
box[r][c] = i + '0';
else
--i;
}
}
void display(char box[ROW][COL]){
for(int r = 0; r < ROW; ++r){
for(int c = 0; c < COL; ++c){
putchar(box[r][c]);
}
putchar('\n');
}
}
int main(void){
char board[ROW][COL];
initBoard(board);
display(board);
playgame(board);
return 0;
}

Declaring winner in tic tac toe board

I wrote a code for a tic tac toe problem where you input the numbers into the array and the board will be printed out. There is also a function that declares the winner, but doesn't seem to be working, the function is supposed to declares the winner for any size of a tic tac toe board (right now it is 5x5).
I did a double for loop with it checking if the character is the same in the array as next to it so it moves along the rows, there's another for columns, one diagonal and the other. For some reason it isn't showing any winners, no winners always comes up. Any help is appreciated.
#include <stdio.h>
#define TRUE 1
#define FALSE 0
#define SIZE 3
#define NONE -1
#define NOUGHTS 0
#define CROSSES 1
#define EMPTY 2
void scanBoard(int board[SIZE][SIZE]);
void printBoard(int board[SIZE][SIZE]);
int getWinner(int board[SIZE][SIZE]);
int main( void ){
int board[SIZE][SIZE];
int winner;
printf("Please enter the board:\n");
scanBoard( board );
printf("Here is the board:\n");
printBoard( board );
printf("The winner is: ");
winner = getWinner(board);
if(winner == CROSSES){
printf("Crosses");
}
else if(winner == NOUGHTS){
printf("Noughts");
}
else{
printf("No one");
}
return 0;
}
void scanBoard(int board[SIZE][SIZE]){
int i;
int j;
for(i=0; i<SIZE; i++){
for(j=0; j<SIZE; j++){
scanf("%d", &board[i][j]);
}
}
}
void printBoard(int board[SIZE][SIZE]){
int i;
int j;
for(i=0; i<SIZE; i++){
for(j=0; j<SIZE; j++){
if(board[i][j] == EMPTY){
printf(". ");
}
else if(board[i][j] == CROSSES){
printf("X ");
}
else if(board[i][j] == NOUGHTS){
printf("O ");
}
}
printf("\n");
}
}
int getWinner(int board[SIZE][SIZE]){
int i;
int j;
int check;
int winner;
for(i=0; i<SIZE; i++){
for(j=0; j<SIZE-1 && check == TRUE; j++){
if(board[i][j] != board[i][j+1]){
check = FALSE;
}
}
if(check == TRUE && j == SIZE-1){
winner=board[i][0];
}
}
for(j=0; j<SIZE; j++){
for(i=0; i<SIZE-1 && check == TRUE; i++){
if(board[i][j] != board[i+1][j]){
check = FALSE;
}
}
if(check == TRUE && i == SIZE-1){
winner=board[0][j];
}
}
for(i=0; i<SIZE-1 && check == TRUE; i++){
if(board[i][i] != board[i+1][i+1]){
check = FALSE;
}
if(check == TRUE && i == SIZE-1){
winner=(board[i][i]);
}
}
for(i=SIZE; i>0 && check == TRUE; i--){
if( board[i][i] != board[i-1][i-1])
check = FALSE;
}
if(check == TRUE && i == SIZE-1){
winner=(board[i][i]);
}
return winner;
}
I did not go completely through your checking logic but here directly in getWinner, you are trigerring undefined behaviour:
for(j=0; j<SIZE-1 && check == TRUE; j++){
by reading check variable which has not been initialized (result of this is that any kind of behaviour can happen). So you may want to initialize it to default value first.
There are some implementationos of that game around, I suggest you look at some similar implementation and compare against your winner checking logic for example.
As Giorgi pointed out, you have to initialize check before you start testing its value. You also need to initialize winner to EMPTY at the start of the getWinner() function, otherwise if there is no winner, your function will return some unpredictable junk value and your main() function will probably print out the wrong result.
int getWinner(int board[SIZE][SIZE]){
int i;
int j;
int check;
int winner=EMPTY /* <<< */;
for(i=0; i<SIZE; i++){
for(j=0, check=TRUE /* <<< */; j<SIZE-1 && check == TRUE; j++){
if(board[i][j] != board[i][j+1]){
check = FALSE;
}
}
if(check == TRUE && j == SIZE-1){
winner=board[i][0];
}
}
for(j=0; j<SIZE; j++){
for(i=0, check=TRUE /* <<< */; i<SIZE-1 && check == TRUE; i++){
if(board[i][j] != board[i+1][j]){
/** etc... **/
(Note: There's also no need to continue checking once you've found a winner, so perhaps instead of winner=board[i][j]; you could just return board[i][j];. Not a big deal, though.)
You are also checking one of the diagonals twice (in two different directions). The other diagonal isn't being checked at all.

Resources