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.
Related
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;
}
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;
}
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.
I am working on writing a code for the game, Mancala, and testing along the way. So far, I am getting an error that says:
Segmentation Fault (core dumped)
I'm not sure how to fix it and keep it running.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void move_clockwise(int board[], int pos, int player_1);
void move_count_clock(int board[], int pos, int player_1);
void mancala_board(int board[]);
int *current1;
int *current2;
int board[30], player_1, sum, position, direction, i, n, play, initPos, curPos, pos;
//======================================================================
int main(void)
{
int board[30];
board[0] = 4;
board[1] = 4;
board[2] = 4;
board[3] = 4;
board[4] = 4;
board[5] = 4;
board[6] = 0;
board[7] = 4;
board[8] = 4;
board[9] = 4;
board[10] = 4;
board[11] = 4;
board[12] = 4;
board[13] = 0;
printf("Welcome to Mancala\n");
printf("\n\n 5 4 3 2 1 0 \n");
printf("BLUE\n");
printf("=====[%d] [%d] [%d] [%d] [%d] [%d]-----\n", board[5], board[4], board[3], board[2], board[1], board[0]);
printf("|%d| |%d|\n", board[6], board[13]);
printf("-----[%d] [%d] [%d] [%d] [%d] [%d]=====\n", board[7], board[8], board[9], board[10], board[11], board[12]);
printf(" RED\n");
printf(" 6 7 8 9 10 11 \n\n");
sum=board[6]+board[13];
player_1=first_player();
while(sum!=48)
{
while (player_1 == 1)
{
printf("Player RED\n");
printf("Pick a position corresponding to the integer: ");
scanf("%d", position);
while (position!=6 || position!=7 || position!=8 || position!=9 || position!=10 || position!=11)
{
printf("\nInvalid input, you have to select a bowl from your side.\nPlease select another position");
scanf("%d",&position);
}
printf("Would you like to move clockwise or counter-clockwise?");
printf("\n1. Clockwise \n2. Counter-Clockwise");
scanf("%d",&direction);
while(direction!=1 && direction!=2)
{
printf("\nInvalid input, you have to select an integer corresponding to the given options.\n");
printf("\n1. Clockwise \n2. Counter-Clockwise");
scanf("%d",&direction);
}
if (direction==1)
{
position+=1;
move_clockwise(board, position, player_1);
}
if(direction==2)
{
position=+1;
move_count_clock(board, position, player_1);
}
player_1-=1;
mancala_board(board);
}
if (player_1 == 0)
{
printf("Player BLUE\n");
printf("Pick a position corresponding to the integer: ");
scanf("%d", position);
while (position!=0 || position!=1 || position!=2 || position!=3 || position!=4 || position!=5)
{
printf("\nInvalid input, you have to select a bowl from your side.\nPlease select another position");
scanf("%d",&position);
}
printf("Would you like to move clockwise or counter-clockwise?");
printf("\n1. Clockwise \n2. Counter-Clockwise");
scanf("%d",&direction);
while(direction!=1 && direction!=2)
{
printf("\nInvalid input, you have to select an integer corresponding to the given options.\n");
printf("\n1. Clockwise \n2. Counter-Clockwise");
scanf("%d",&direction);
}
if (direction==1)
{
position+=1;
move_clockwise(board, position, player_1);
}
if(direction==2)
{
position=+1;
move_count_clock(board, position, player_1);
}
player_1+=1;
mancala_board(board);
}
sum=board[6]+board[13];
}
}
//======================================================================
int first_player(void)
{
//to determine who will be player 1
play=rand()%2;
return (play);
}
//======================================================================
//Display current board
void mancala_board(int board[])
{
printf("\n\n 5 4 3 2 1 0 \n");
printf("BLUE\n");
printf("=====[%d] [%d] [%d] [%d] [%d] [%d]-----\n", board[5], board[4], board[3], board[2], board[1], board[0]);
printf("|%d| |%d|\n", board[6], board[13]);
printf("-----[%d] [%d] [%d] [%d] [%d] [%d]=====\n", board[7], board[8], board[9], board[10], board[11], board[12]);
printf(" RED\n");
printf(" 6 7 8 9 10 11 \n\n");
}
//======================================================================
//allow player to move again if late marble lands in mancala
//void move_again(int board[], int pos, int player_1)
//{
//}
//======================================================================
//captures the marbles across the current position if player's
//last marble lands on their own bowl with no marbles in
//void capture()
//{
//}
//======================================================================
void move_clockwise(int board[], int pos, int player_1)
{
initPos = pos;
n=board[pos];
pos+=1;
for (i = 0; i < n ; i++)
{
curPos +=1;
board[curPos]+=1;
if (curPos == 14)
curPos -=14;
else if (curPos >= 28)
curPos -= 28;
if (player_1 == 0)
{
current1 = &(board[curPos]);
if (current1 == &(board[6]))
{
current1 = &(board[7]);
current1 += 1;
}
}
if (player_1 == 1)
{
current2 = &(board[curPos]);
if (current2 == &(board[13]))
{
current2 = &(board[0]);
current2 += 1;
}
}
}
board[initPos] = 0;
}
//======================================================================
void move_count_clock(int board[], int pos, int player_1)
{
initPos = pos;
n=board[pos];
pos+=1;
for (i = 0; i < n ; i++)
{
curPos +=1;
board[curPos]+=1;
if (curPos == 14)
curPos -=14;
else if (curPos >= 28)
curPos -= 28;
if (player_1 == 0)
{
current1 = &(board[curPos]);
if (current1 == &(board[6]))
{
current1 = &(board[7]);
current1 += 1;
}
}
if (player_1 == 1)
{
current2 = &(board[curPos]);
if (current2 == &(board[13]))
{
current2 = &(board[0]);
current2 += 1;
}
}
}
board[initPos] = 0;
}
Maybe you want to separate the code in smaller pieces and test each piece. Or maybe this can help you: http://ericlippert.com/2014/03/05/how-to-debug-small-programs/
To put & inside scanf is correct suggestion, I think that was meant in the comment.
Anyway, this is also weird:
while (position!=6 || position!=7 || position!=8 || position!=9 || position!=10 || position!=11)
{
scanf("%d",&position);
}
what do you expect above? It will always enter that loop, and never come out, since
if position is 6 it can't be 7 hence due to OR the statement will be true.
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();