About Tic-Toc-Toe Game in C language - c

I wrote a full code for this game using do and while in C language .. but I stop in point which I don't know how I can type a code to decide if the game is drawn or not..
Thanks
This is my code
#include <stdio.h>
#include <stdlib.h>
char matrix[3][3];
char check(void);
void init_matrix(void);
void get_player1_move(void);
void get_player2_move(void);
void disp_matrix(void);
int main(void)
{
char done,choise;
printf("Welcome to the tic-tac-toe game!!!\n\n");
printf("Rule for playing the game is:\n\n");
printf("Each player must put the value of raw and column like: 1 2 to put his symbol in\nthe tic-tac-toe board.\n\n");
printf("The tic-tac-toe board looks like as follows:\n\n");
init_matrix();
disp_matrix();
printf("Are you ready to start the game? ");
scanf(" %c",&choise);
if (choise == 'y'){
do {
get_player1_move();
done = check(); /* if winner or not */
if(done!= ' ') break; /* winner!*/
disp_matrix();
get_player2_move();
disp_matrix();
done = check(); /* if winner or not */
if(done!= ' ') break; /* winner!*/
} while(done== ' ');
if(done=='X') printf("Player 1 won the game!!!!!\n");
else printf("Player 2 won the game!!!!!\n");
}
else {
printf("\n\nThank you!!!\n\n");
printf("We hope you will play the game anther time....");
}
return 0;
}
/****************************************************/
void init_matrix(void)
{
int i, j;
for(i=0; i<3; i++)
for(j=0; j<3; j++) matrix[i][j] = ' ';
}
/****************************************************/
void get_player1_move(void)
{
int x, y;
printf("Enter row and column input for player 1: ");
scanf("%d%*c%d", &x, &y);
x--; y--;
if(matrix[x][y]!= ' '){
printf("You can not choose this row and clumn!! Try again\n");
get_player1_move();
}
else matrix[x][y] = '1';
}
/****************************************************/
void get_player2_move(void)
{
int x, y;
printf("Enter row and column input for player 2: ");
scanf("%d%*c%d", &x, &y);
x--; y--;
if(matrix[x][y]!= ' '){
printf("You can not choose this row and clumn!! Try again\n");
get_player2_move();
}
else matrix[x][y] = '2';
}
/****************************************************/
void disp_matrix(void)
{
int t;
for(t=0; t<3; t++) {
printf(" : : ");
printf("\n %c : %c : %c",matrix[t][0],matrix[t][1], matrix [t][2]);
if(t!=2) printf("\n ----:----:----\n");
}
printf("\n\n");
}
/****************************************************/
char check(void)
{
int i;
for(i=0; i<3; i++) /* check rows */
if(matrix[i][0]==matrix[i][1] && matrix[i][0]==matrix[i][2])
return matrix[i][0];
for(i=0; i<3; i++) /* check columns */
if(matrix[0][i]==matrix[1][i] && matrix[0][i]==matrix[2][i])
return matrix[0][i];
/* test diagonals */
if(matrix[0][0]==matrix[1][1] && matrix[1][1]==matrix[2][2])
return matrix[0][0];
if(matrix[0][2]==matrix[1][1] && matrix[1][1]==matrix[2][0])
return matrix[0][2];
return ' ';
}

if(done=='X') should be if(done == '1') because matrix contains 1 and 2, not X and O.
To tell if the game is a draw, keep a count of the number of moves, and break out of the loop when it reaches 9. You only have to check this after player 1 moves, because player 2 always moves on even numbers.
There's no need to use do{...} while (done == ' ') because the code always breaks out of the loop when done != ' '. So just use while(1) to make an infinite loop.
int count = 0;
while (1) {
get_player1_move();
done = check(); /* if winner or not */
disp_matrix();
if(done!= ' ' || ++count == 9) break; /* winner or draw */
get_player2_move();
disp_matrix();
done = check(); /* if winner or not */
if(done!= ' ') break; /* winner!*/
++count;
}
if (done == ' ') {
printf("It's a draw!\n");
} else {
printf("Player %c won the game!!\n", done);
}

Set a boolean variable "draw" as false and if no player wins and all 9 moves are done and no free block is available set the "draw" as true. And calculate the result based on "draw" that either the game is a draw or not.

Related

I'm trying to make a program in C in which you can play hangman but as soon as it prints the option to guess the letter the program terminates

The program isn't printing after giving me the first chance to guess.
#include <stdio.h>
#include <string.h>
int main() {
char menu;
int c = 0, flag = 0, life = 8;
printf("\nWelcome to Hangman!!!");
printf("\nThis is a game of hangman.");
printf("Player 1 enters a random word and the other has to guess it.");
printf("You get 8 lives in total i.e. you can have a maximum of 8 wrong guesses.");
printf("\n");
printf("Press n for new game\n");
printf("Press q to quit\n");
printf("\n");
scanf("%c", &menu);
int i = 0, j = 0;
char w[20], ch;
if (menu == 'q') {
printf("Exiting...");
printf("Thanks for playing");
}
else if (menu == 'n') {
printf("Player 1 enters a word\n");
scanf("%s", w);
int len = strlen(w);
for (int i = 0; i < len; i++) {
toupper(w[i]);
}
printf("\e[1;1H\e[2J");
char arr[len - 1];
for (int i = 0; i < len - 1; i++) {
arr[i] = '_';
printf("%c", arr[i]);
}
printf("\n");
while (life != 0) {
for (int i = 0; i < len - 1; i++) {
if (arr[i] == '_') {
flag = 1;
break;
}
else {
flag = 0;
}
}
if (flag == 0) {
printf("You Won!!\n");
printf("You Guessed The Word: %s", w);
break;
}
else {
char ans;
printf("Enter a letter between A-Z");
scanf("%c", ans);
toupper(ans);
for (int j = 0; j < len; j++) {
if (ans == w[j]) {
arr[j] = ans;
c++;
}
}
if (c == 0) {
life--;
}
c = 0;
for (int j = 0; j < len; j++) {
printf("%c", arr[j]);
}
printf("\n Lives Remaining= %d \n", life);
}
}
if (life == 0) {
printf("\n You Lost!!! \n");
printf("The Word Was: %s", w);
}
}
else {
printf("Invalid Character");
}
}
Output:
Welcome to Hangman!!!
This is a game of hangman.Player 1 enters a random word and the other has to >guess it.You get 8 lives in total i.e. you can have a maximum of 8 wrong >guesses.
Press n for new game
Press q to quit
n
Player 1 enters a word
Hello
Enter a letter between A-Z
PS C:\Users\arora\Desktop\Programs\C>
There are quite a few problems with your program. Here are the major ones:
You want to use use space prefix in the format string for scanf(" %c", ...) to ensure previous newlines are ignored.
scanf("%c", ans); should be &ans. It causes scanf() to fail rendering the remain of the program non-interactive. Without input from the user the core game logic doesn't work.
Here are some of the other issues:
#include <ctype.h>.
(not fixed) Consider changing the menu logic so 'q' quits, and any other letter starts a game.
Game prompt contains long lines that are hard to read for the player(s).
You use a printf() per line which makes it hard to read. Use a single call and multi-line strings as input.
Try to branch your code less by making use of early return. It makes it easier to read.
Check the return value of scanf(). If it fails then whatever variable it read doesn't have a well defined value.
Ensure that scanf() read no more than 19 bytes into a 20 byte array w. It takes a little macro magic to generate the 19 so I didn't make this change but it's a good idea to #define constants for magic values like the 20.
arr is not \0 terminated (len-1). Most c programmers expect a string so it's not worth the confusion to save 1 byte.
Use a function or macro for the ANSI escape to clear the screen.
Eliminate unused variables i, j.
Reduce scope of variables (declare variables close to where you use them).
The calculation of the flag variable is cumbersome.
(not fixed) The prompt "Enter a letter between A-Z" is somewhat ambiguous. Suggest "... between A and Z".
It's generally a good idea to leave user input as you read. If you care about the repeated toupper() you can create a copy of the user input with letters in upper case, and create another variable to hold the upper case version of the player's guess. This avoid you saying things like you entered the word "BOB" when the actual input was "bob".
You attempt to use toupper() to convert each letter to upper case but don't assign the result to anything so it does not do anything constructive.
Consider some functions to document what each your code does. I added some comments for now.
(mostly not fixed) Consider using better variable names (c, w, arr, flag).
(not fixed) Should you reject a word with your magic '_' value? In general should you validate that the word is reasonable (a-z, len > 0, len < 20)?
(not fixed) Consider, in arr, just storing if a letter was correctly guess (boolean). When evaluating the state show the letter from w if it is already guessed otherwise the _.
(not fixed) If you guess a correct letter again, it's considered a good guess. Should it?
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#define clear() printf("\e[1;1H\e[2J")
int main() {
printf(
"Welcome to Hangman!!!\n"
"\n"
"This is a game of hangman.\n"
"Player 1 enters a random word and the other has to guess it.\n"
"You get 8 lives in total i.e. you can have a maximum of 8 wrong guesses.\n"
"\n"
"Press n for new game\n"
"Press q to quit\n"
);
char menu;
if(scanf(" %c",&menu) != 1) {
printf("scanf failed\n");
return 1;
}
switch(menu) {
case 'q':
printf(
"Exiting..."
"Thanks for playing\n"
);
return 0;
case 'n':
break;
default:
printf("Invalid Character");
return 1;
}
printf("Player 1 enters a word\n");
char w[20];
if(scanf("%19s", w) != 1) {
printf("scanf failed\n");
return 1;
}
clear();
char arr[20];
int len=strlen(w);
for(int i=0;i<len;i++) {
arr[i]='_';
}
arr[len] = '\0';
int life=8;
for(;;) {
printf("%d Lives Remaining\n", life);
// read a guess from player
for(int i = 0; i < len; i++) {
printf("%c", arr[i]);
}
printf(" Enter a letter between A-Z ");
char guess;
if(scanf(" %c", &guess) != 1) {
printf("scanf failed\n");
return 1;
}
// determine if any of the letters are in the secret word
int c = 0;
for(int i=0; i<len; i++) {
if(toupper(guess) == toupper(w[i])) {
arr[i]=guess;
c = 1;
}
}
if(c==0) {
life--;
}
// game over?
int flag = 0;
for(int i = 0; i<len; i++) {
if(arr[i]=='_') {
flag=1;
break;
}
}
if(flag==0) {
printf("You Won!!\n");
printf("You Guessed The Word: %s\n",w);
break;
}
if(life==0) {
printf("\n You Lost!!!\n");
printf("The Word Was: %s\n", w);
break;
}
}
}

Why I get very huge output in printf on C language?

This is my code, I want to calculate distance between robot and monster, but the output "horizontal and vertikal" is false
#include <stdio.h>
void findPos(char *dir, int a, int b)
{
int up = 0, down = 0;
int left = 0, right = 0;
int i,x,y;
for (i = 0; dir[i] != '\0' ; i++) {
//Counts each direction
if (dir[i] == 'U' || dir[i] == 'u')
up++;
else if (dir[i] == 'D' || dir[i] == 'd')
down++;
else if (dir[i] == 'L' || dir[i] == 'l')
left++;
else if (dir[i] == 'R' || dir[i] == 'r')
right++;
//In case of illegal character in the string
else
{
printf("Position Unable to Find, Enter Correct Direction.");
break;
}
}
//Final position of robot
x = right - left;
y = up - down;
printf("Final Position of the Robot: (");
printf("%d", x);
printf(",%d", y);
print(")");
printf("\nposition between robot and monster");
printf("\nhorizontal: %d", a-x);
printf("\nvertikal: %d", b-y);
}
int main()
{
char *dir;
int a,b,t;
/* Intializes random number generator */
srand((unsigned) time(&t));
/* Print 2 random numbers from 0 to 100 */
a = rand() % 100;
b = rand() % 100;
printf("\nCoordinate of monster: ");
printf("(%d,", a);
printf("%d)", b);
//Input the direction string
printf("\nEnter the Direction String: ");
scanf("%s", &dir);
//Function call to calculate position
findPos(&dir, a,b);
return 0;
}
and this is the output
Coordinate of monster: (5,47)
Enter the Direction String: UURRRRRLLL
Final Position of the Robot: (2,2)
position between robot and monster
horizontal: 19530
vertikal: 1280463440
it seems your program is exhibiting undefined behavior, you are actually lucky its not crashing, dir is never allocated . you might want to calloc it before using , also remove the & in scanf, infact move to fgets unless inclined to use scanf
printf("\nEnter the Direction String: ");
scanf("%s", dir);

Issue with Mastermind Game in C language

I've been trying for a while to make this work but I'm still stuck with some issue...I would love some help.
The thing is the code works almost the way I want, the only issue I have is when the program is telling you how many colours you guessed right, if the first colour matches it works good but if the others positions are right the program give a wrong answer (or at least not what I would like).
I'm just starting to code I know my code is really far from being perfect.
Here is my code :
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#define SIZE_STRING 4
#define SIZE_STRING_BIG 15
void randomSeed(){
srand( (unsigned)time( NULL ) );
}
int randomM(int nMin, int nMax){
return nMin + rand()%(nMax-nMin+1);
}
int main(){
randomSeed();
char szUser[SIZE_STRING_BIG];
char szP[6]={'Y','B','W','P','R','G'}, szComputer[SIZE_STRING_BIG] = {szP[randomM(0,5)], szP[randomM(0,5)], szP[randomM(0,5)], szP[randomM(0,5)], '\0'};
int counter=0;
int colour=0;
int position=0;
printf("\n\n MASTERMIND ");
printf("\n\n We'll play with this colours:");
printf("\n\n Y - Yellow B - Blue W - White");
printf("\n P - Purple R - Red G - Green");
printf("\n\n You have 8 changes to get t right. \n");
printf(" Machine choose %s", szComputer); // this line just to check everything works allright
do{
counter++;
position=0;
colour=0;
printf("\n ===================================================\n");
printf("\n Chance %d", counter);
printf("\n\n Please add your 4 colours ");
printf("\n (Please write the four capital letters without space) ");
scanf("%s",szUser);
if(strlen(szUser) != SIZE_STRING)
{
printf("\n\n Sorry you choose a wrong option.");
counter--;
} else {
if(strcmp(szUser,szComputer))
{
printf("\n Wrong choice. Try again...");
if (szUser[0] == szComputer[0])
{
position++;
}
if (szUser[1] == szComputer[1])
{
position++;
}
if (szUser[2] == szComputer[2])
{
position++;
}
if (szUser[3] == szComputer[3])
{
position++;
}
printf("\n\n You have %d in the right position", position);
if ( szUser[0] == szComputer[0] || szUser[0] == szComputer[1] || szUser[0] == szComputer[2] || szUser[0] == szComputer[3] )
{
colour++;
}
if ( szUser[1] == szComputer[1] || szUser[1] == szComputer[2] || szUser[1] == szComputer[3] )
{
colour++;
}
if ( szUser[2] == szComputer[2] || szUser[2] == szComputer[3] )
{
colour++;
}
if ( szUser[3] == szComputer[3] )
{
colour++;
}
printf("\n You have %d colours right\n", colour);
}
}
}while(strcmp(szUser,szComputer) && counter <=7);
if (strcmp(szUser,szComputer))
{
printf("\n\n Sorry, you run out of chances...");
}
if(!strcmp(szUser,szComputer))
printf("\n\n Right choice !\n");
return 0;
}
I suggest using another array to keep track of which of the computer's pegs you've already seen for the current turn of the game:
char seen[SIZE_STRING];
For each turn, reset the "seen" flags and the count of correct colour and position pegs, and the count of correct colour and wrong position pegs:
memset(seen, 0, sizeof(seen));
position = 0;
colour = 0;
Then count user pegs with the correct colour and position, marking them as seen:
for (int i = 0; i < SIZE_STRING; i++)
{
if (szUser[i] == szComputer[i])
{
seen[i] = 1;
position++;
}
}
Then count user pegs with the same colour as computer pegs that haven't been seen yet, marking the matching computer pegs as seen. These user pegs will all be at the wrong position because pegs of the correct colour at the correct position have already been accounted for above:
EDIT 1: My original version of the inner loop could count a user peg more than once if several computer pegs had the same colour as the user peg. I have added a break; statement to the inner loop to fix this so that each user peg can match at most one computer peg.
EDIT 2: The outer loop also needs to skip over any user pegs that matched in the position matching loop to avoid counting them twice.
for (int u = 0; u < SIZE_STRING; u++)
{
// Bug fix (EDIT 2). Skip user pegs already accounted for by position matching loop ...
if (szUser[u] == szComputer[u])
{
// Already accounted for this user peg.
continue;
}
for (int c = 0; c < SIZE_STRING; c++)
{
if (!seen[c] && szUser[u] == szComputer[c])
{
colour++;
seen[c] = 1;
// Bug fix (EDIT 1) due to comment by #Rup ...
break; // Skip to next user peg.
}
}
}
I've been trying with the code you posted but still doesnt work 100% properly. The code works allright almost all cases but still some cases get it wrong. I'm having trouble with the white pegs, im still having some extra white pegs in one case, for example if the code to guess is RYPG and i introduce RRRR it answer back 1 red flag and 1 white flag when it should say just 1 red flag. and if the code is RYPG and i introduce RRPP it answer back 2 red flags and 2 white flags when it should be just 2 red flags. Here is my code:
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#define SIZE_STRING 4
#define SIZE_STRING_LONG 15
void randomSeed(){
srand( (unsigned)time( NULL ) );
}
int randomM(int nMin, int nMax){
return nMin + rand()%(nMax-nMin+1);
}
int main(){
randomSeed();
char szUser[SIZE_STRING_LONG];
char szP[6]={'Y','B','W','P','R','G'}, szComputer[SIZE_STRING_LONG] = {szP[randomM(0,5)], szP[randomM(0,5)], szP[randomM(0,5)], szP[randomM(0,5)], '\0'};
int counter=0;
int colour=0;
int position=0;
char alreadyChecked[SIZE_STRING];
printf("\n\n MASTERMIND ");
printf("\n\n We'll play with this colours:");
printf("\n\n Y - Yellow B - Blue W - White");
printf("\n P - Purple R - Red G - Green");
printf("\n\n You have 8 changes to get t right. \n");
printf("\n\n White flags indicate right colour in right position");
printf("\n\n Red flags indicate right colour in wrong position");
printf("\n\n Computer choses %s", szComputer); //check if the program works allright
do{
counter++;
position=0;
colour=0;
memset(alreadyChecked, 0, sizeof(alreadyChecked));
printf("\n ===================================================\n");
printf("\n Chance %d", counter);
printf("\n\n Please enter your 4 colours choice");
printf("\n (Please write capital letters without space ");
scanf("%s",szUser);
if(strlen(szUser) != SIZE_STRING)
{
printf("\n\n Sorry you choose a wrong option.");
counter--;
} else {
if(strcmp(szUser,szComputer))
{
printf("\n Wrong choice. Try again...");
for (int u = 0; u < SIZE_STRING; u++)
{
if (szUser[u] == szComputer[u])
{
position++;
}
}
if (position > 0 && position < 2)
{
printf("\n\n You have %d red flag", position);
}
if (position > 1 )
{
printf("\n\n You have %d red flags", position);
}
for (int u = 0; u < SIZE_STRING; u++)
{
if (szUser[u] == szComputer[u])
{
continue;
}
for (int c = 0; c < SIZE_STRING; c++)
{
if (!alreadyChecked[c] && szUser[u] == szComputer[c])
{
colour++;
alreadyChecked[c] = 1;
break;
}
}
}
if (colour > 0 && colour < 2)
{
printf("\n\n You have %d white flag", colour);
}
if (colour > 1 )
{
printf("\n\n You have %d white flags", colour);
}
if (colour == 0 && position == 0)
{
printf("\n\n 0 white flags and 0 red flags");
}
}
}
}while(strcmp(szUser,szComputer) && counter <=7);
if (strcmp(szUser,szComputer))
{
printf("\n\n Sorry, you run out of chances...");
}
if(!strcmp(szUser,szComputer))
printf("\n\n Right combination !\n");
return 0;
}

Program written in C, loops indefinately or crashes after a while

this is both my first time asking a question and also one of my first times writting such a big programm. As you might guess im new at programming.
Alright the source code:
#include <stdio.h>
typedef struct{
int **a;
int size;
}_board;
typedef _board* board;
typedef struct{
int row,col;
}position;
int main () {
int i, j, turn=1, victory = 0, num=0;
_board b;
char P1symbol, P2symbol, mark, boardarray[b.size][b.size];
position p;
printf("WELCOME TO THE GAME OF TIC TAC TOE!\n");
do {
printf("\nwill player one, use X or O as his symbols? select by pressing x or o\n");
scanf(" %c", &P1symbol);
if (P1symbol == 'x' || P1symbol == 'o') {
num = 1;
}
} while ( num == 0);
if (P1symbol == 'x') {
P2symbol = "o";
}
else {
P2symbol = "x";
}
do {
printf("\n now choose the size of the game board, type a numeral and press enter");
scanf("%d", &b.size);
}while (b.size <= 0);
for (i=0; i=b.size; i++){
for (j=0; j=b.size; j++){
boardarray[i][j] = "-";
}
}
do {
do {
boardsketch(boardarray, b.size);
if (turn%2 == 1) {
printf("player 1, please choose a box to input you mark on");
mark = P1symbol;
}else{
printf("player 2, please choose a box to input you mark on");
mark = P2symbol;
}
printf("type the coordinates i,j, which correspond to the row and collumn number");
printf("make sure the numbers are valid, not taken, and between 0 and %d", b.size);
scanf("%d %d", &p.row, &p.col);
}while (p.row > b.size && p.row < 0 && p.col > b.size && p.col <0 && boardarray[p.row][p.row] != "-");
turn++;
boardarray[p.row][p.col] = mark;
} while (wincheck(boardarray, p.row, p.col, b.size) != 1);
return 0;
}
int wincheck(int row, int col, int size, char boardarray[size][size])
{
if (boardarray[row][col] = boardarray[row -1][col -1] = boardarray[row +1][col +1]) {
return 1;
}
if (boardarray[row][col] = boardarray[row -1][col] = boardarray[row +1][col]) {
return 1;
}
if (boardarray[row][col] = boardarray[row][col -1] = boardarray[row][col +1]){
return 1;
}
if (boardarray[row][col] = boardarray[row -1][col +1] = boardarray[row +1][col -1]){
return 1;
}
}
void boardsketch(int size, char boardarray[size][size]) {
int i, j;
for (i=0; i=size; i++) {
for (j=0; j=size; j++) {
if (boardarray[i][j] == '-') {
printf("| ");
} else {
printf("%c |", &boardarray[i][j]);
}
}
}
}
Now the program's purpose is to simulate a game of tic tac toe (with the addition of the user, deciding the size of the game board). My problem is that, altough compilation IS achieved the program does 2 wierd behaviors when reaching a specific line, that line being:
do {
printf("\n now choose the size of the game board, type a numeral and press enter");
scanf("%d", &b.size);
}while (b.size <= 0);
If i input a value that doesnt obey to b.size <= 0, the printf above, repeats indefinately, if i DO put a correct value, the programm doesnt resume. What am i doing wrong? again im new at programming sooooo... go easy on me :D
There are compiler errors in your code. I don't know how you got it to compile and build it the first place.
Compiler errors:
You have:
P2symbol = "o";
Type of "o" is char const*. The type of P2symbol is char. What you need is
P2symbol = `o`;
Few lines after that, you have:
P2symbol = "x";
That needs to be changed to:
P2symbol = `x`;
Few lines after that, you have:
boardarray[i][j] = "-";
It suffers from the same compiler error. You need to change it to:
boardarray[i][j] = `-`;
Your declaration and definition of boardsketch does not match with the way you are calling it. Your call is:
boardsketch(boardarray, b.size);
You have defined it as:
void boardsketch(int size, char boardarray[size][size]) {
....
}
You need to change either the call or the function definition so that they match. Also, you should declare the function before it is used. Add
void boardsketch(int size, char boardarray[size][size]);
before the start of main.
The definition and call of wincheck suffers from the same error. It also should have a declaration before it's usage.
A few lines after that call to boardarray, you have the line:
}while (p.row > b.size && p.row < 0 && p.col > b.size && p.col <0 && boardarray[p.row][p.row] != "-");
The last part of that statement suffers from the char and char const* mismatch. You need to change it to:
}while (p.row > b.size && p.row < 0 && p.col > b.size && p.col <0 && boardarray[p.row][p.row] != '-');
Run Time Errors:
You have:
_board b;
char P1symbol, P2symbol, mark, boardarray[b.size][b.size];
The problem with that is b.size is not initialized. It could be anything. Using it to declare broadarray is problem. Imagine the chaos that will ensue if the b.size were to be initialized to a negative number. For sane and predictable behavior, you should initialize b properly before using its data.
A few lines below, you are asking for size to be input by the user.
do {
printf("\n now choose the size of the game board, type a numeral and press enter");
scanf("%d", &b.size);
}while (b.size <= 0);
There is a logic error here. You are asking for the size of the board after you have already created boardarray. What you could do is gather the initial input and use them to call another function where the core of the game play happens.
/* Function that contains the core part of playing the game */
void playgame(char P1symbol, char P2symbol, int size)
{
int i, j, turn=1, victory = 0;
char mark, boardarray[size][size];
position p;
for (i=0; i=size; i++){
for (j=0; j=size; j++){
boardarray[i][j] = '-';
}
}
do {
do {
boardsketch(size, boardarray);
if (turn%2 == 1) {
printf("player 1, please choose a box to input you mark on");
mark = P1symbol;
}else{
printf("player 2, please choose a box to input you mark on");
mark = P2symbol;
}
printf("type the coordinates i,j, which correspond to the row and collumn number");
printf("make sure the numbers are valid, not taken, and between 0 and %d", size);
scanf("%d %d", &p.row, &p.col);
}while (p.row > size && p.row < 0 && p.col > size && p.col <0 && boardarray[p.row][p.row] != '-');
turn++;
boardarray[p.row][p.col] = mark;
} while (wincheck(p.row, p.col, size, boardarray) != 1);
}
Now, main can be simplified to:
int main () {
char P1symbol;
char P2symbol;
int size;
int num = 0;
printf("WELCOME TO THE GAME OF TIC TAC TOE!\n");
do {
printf("\nwill player one, use X or O as his symbols? select by pressing x or o\n");
scanf(" %c", &P1symbol);
if (P1symbol == 'x' || P1symbol == 'o') {
num = 1;
}
} while ( num == 0);
if (P1symbol == 'x') {
P2symbol = 'o';
}
else {
P2symbol = 'x';
}
do {
printf("\n now choose the size of the game board, type a numeral and press enter");
scanf("%d", &size);
}while (size <= 0);
playgame(P1symbol, P2symbol, size);
return 0;
}
Ah, the problem is your for loop after the do while. You are assigning your counters instead of evaluating the limits. Asigning them will result to true every time. Try this instead:
for (i=0; i<b.size; i++){
for (j=0; j<b.size; j++){
boardarray[i][j] = "-";
}
}
Also, do not create an array with undefine value b.size...

Encountering an infinite loop depending on compiler and declarations

In this program there is a line where I create a variable called
"crazy_integer".
If I do not create this variable, MinGW creates an infinite loop!
I do not seem to have this problem with any other compiler.
Can anyone tell me what is going on here?
To recreate: Download the latest version of CodeBlocks with MingW, create
a new console project, and try running this program.
Then, try removing the line of code where I create "crazy_integer"
and run the program again. The result should be an infinite loop.
// In this program there is a line where I create a variable called
// "crazy_integer".
//
// If I do not create this variable, CodeBlocks creates an infinite loop!
// I do not seem to have this problem with any other compiler.
//
// Can anyone tell me what is going on here?
//
// To recreate: Download the latest version of CodeBlocks with MingW, create
// a new console project, and try running this program.
//
// Then, try removing the line of code where I create "crazy_integer"
// and run the program again. The result should be an infinite loop.
#include <stdio.h>
#include <string.h>
int find_winning_move(char *, char, int);
int display_board(char *);
int is_winning_position(char *, char);
void show_win_details(int, char);
int main(void) {
int retval = 0;
char raw_data[] = "X X XO ";
char player = 'X';
printf("We are examining this board: \n");
display_board(raw_data);
find_winning_move(raw_data, player, 1);
return 0;
}
int find_winning_move(char *raw_data, char player, int depth) {
char test_position[9];
int crazy_integer=0; // Adding this line will fix an infinite loop
int i, win_result;
for (i = 0; i < 9; i++) {
if (raw_data[i] == ' ') {
strcpy(test_position, raw_data);
test_position[i] = player;
win_result = is_winning_position(test_position, player);
printf("The result of playing %c at position %d is: %d \n",
player, i, win_result);
display_board(test_position);
}
}
return 0;
}
int display_board(char *raw_data) {
char display_model[] = "[ ][ ][ ]\n[ ][ ][ ]\n[ ][ ][ ]\n";
int i, j, k; k=0;
for (i = 0; i <= 2; i++) {
for (j = 1; j <= 7; j+=3) {
display_model[ (i * 10) + j ] = raw_data[k++];
}
}
printf("%s ", display_model);
}
int is_winning_position(char *raw_data, char player) {
int i;
// Test for horizontal win
for (i = 0; i <= 6; i+=3) {
if (raw_data[i] == player
&& raw_data[i+1] == player
&& raw_data[i+2] == player)
{
return 10 + i;
}
}
// Test for vertical win
for (i = 0; i <= 2; i++) {
if (raw_data[i] == player
&& raw_data[i+3] == player
&& raw_data[i+6] == player)
{
return 20 + i;
}
}
// Test for diagonal win
if (raw_data[4] == player) {
if (raw_data[0] == player && raw_data[8] == player) {
return 31;
}
if (raw_data[2] == player && raw_data[6] == player) {
return 32;
}
}
return 0;
}
void show_win_details(int win_value, char player) {
switch (win_value) {
// Horizontal
case 10 :
printf("Horizontal win on first row for Player: %c \n",
player);
break;
case 13 :
printf("Horizontal win on second row for Player: %c \n",
player);
break;
case 16 :
printf("Horizontal win on third row for Player: %c \n",
player);
break;
// Vertical
case 20 :
printf("Vertical win on first column for Player: %c \n",
player);
break;
case 21 :
printf("Vertical win on second column for Player: %c \n",
player);
break;
case 22 :
printf("Vertical win on third column for Player: %c \n",
player);
break;
// Diagonal
case 31 :
printf("Diagonal win upper left to lower right for Player: %c \n",
player);
break;
case 32 :
printf("Diagonal win lower left to upper right for Player: %c \n",
player);
break;
default: printf("Some error occurred. \n"); break;
}
}
Your variable declaration:
char test_position[9];
Is too short for the strcpy into it (strcpy(test_position, raw_data);). The source buffer raw_data is 9 characters plus the null terminator. So it results in a buffer overflow. Adding that integer variable probably provides extra space on the stack that "fixes" the stack overflow.

Resources