Skip to main content
Code Review

Return to Answer

Typo in typedef
Source Link
Toby Speight
  • 87.9k
  • 14
  • 104
  • 325

#define BOARD_WIDTH 8 #define BOARD_HEGIHT 8 typedef char game_board[BOARD_HEGIHT][BOARD_WIDTH];

#define BOARD_WIDTH 8
#define BOARD_HEIGHT 8
typedef char game_board[BOARD_HEIGHT][BOARD_WIDTH];

Use system() with care. system("/usr/bin/clear") would be better, since you can't rely on users having a sane PATH. And on other platforms, is this function really supposed to do nothing? Perhaps:

#define BOARD_WIDTH 8 #define BOARD_HEGIHT 8 typedef char game_board[BOARD_HEGIHT][BOARD_WIDTH];

Use system with care. system("/usr/bin/clear") would be better, since you can't rely on users having a sane PATH. And on other platforms, is this function really supposed to do nothing?

#define BOARD_WIDTH 8
#define BOARD_HEIGHT 8
typedef char game_board[BOARD_HEIGHT][BOARD_WIDTH];

Use system() with care. system("/usr/bin/clear") would be better, since you can't rely on users having a sane PATH. And on other platforms, is this function really supposed to do nothing? Perhaps:

Source Link
Toby Speight
  • 87.9k
  • 14
  • 104
  • 325

What's <conio.h>? It's not mentioned in the C standard, and if I remove it, the code kind of compiles, so I guess it's not required.

I say "kind of" because of the warnings it generates, which shouldn't be ignored:

gcc -std=c17 -fPIC -g -Wall -Wextra -Wwrite-strings -Wno-parentheses -Wpedantic -Warray-bounds -Wstrict-prototypes -Wconversion 256860.c -o 256860
256860.c:23:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 23 | void clearScreen();
 | ^~~~
256860.c:34:1: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 34 | int promptReplay();
 | ^~~
256860.c:38:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 38 | int main()
 | ^~~~
256860.c: In function ‘main’:
256860.c:40:24: warning: ISO C forbids empty initializer braces [-Wpedantic]
 40 | char board[8][8] = {
 | ^
256860.c:49:20: warning: passing argument 1 of ‘resetBoard’ from incompatible pointer type [-Wincompatible-pointer-types]
 49 | resetBoard(board, &turn);
 | ^~~~~
 | |
 | char (*)[8]
256860.c:24:23: note: expected ‘char * (*)[8]’ but argument is of type ‘char (*)[8]’
 24 | void resetBoard(char* board[8][8], int* turn);
 | ~~~~~~^~~~~~~~~~~
256860.c:52:23: warning: passing argument 1 of ‘drawBoard’ from incompatible pointer type [-Wincompatible-pointer-types]
 52 | drawBoard(board);
 | ^~~~~
 | |
 | char (*)[8]
256860.c:25:22: note: expected ‘char * (*)[8]’ but argument is of type ‘char (*)[8]’
 25 | void drawBoard(char* board[8][8]);
 | ~~~~~~^~~~~~~~~~~
256860.c:54:24: warning: passing argument 1 of ‘addToBoard’ from incompatible pointer type [-Wincompatible-pointer-types]
 54 | addToBoard(board, &player, &turn, &posX, &posY);
 | ^~~~~
 | |
 | char (*)[8]
256860.c:26:23: note: expected ‘char * (*)[8]’ but argument is of type ‘char (*)[8]’
 26 | void addToBoard(char* board[8][8], int* player, int* turn, char* posX, char* posY);
 | ~~~~~~^~~~~~~~~~~
256860.c:55:41: warning: passing argument 1 of ‘checkWin’ from incompatible pointer type [-Wincompatible-pointer-types]
 55 | currentGameState = checkWin(board, &turn);
 | ^~~~~
 | |
 | char (*)[8]
256860.c:29:21: note: expected ‘char * (*)[8]’ but argument is of type ‘char (*)[8]’
 29 | int checkWin(char* (board)[8][8], int* turn);
 | ~~~~~~~^~~~~~~~~~~~
256860.c:59:19: warning: passing argument 1 of ‘drawBoard’ from incompatible pointer type [-Wincompatible-pointer-types]
 59 | drawBoard(board);
 | ^~~~~
 | |
 | char (*)[8]
256860.c:25:22: note: expected ‘char * (*)[8]’ but argument is of type ‘char (*)[8]’
 25 | void drawBoard(char* board[8][8]);
 | ~~~~~~^~~~~~~~~~~
256860.c: In function ‘drawBoard’:
256860.c:75:29: warning: passing argument 1 of ‘putchar’ makes integer from pointer without a cast [-Wint-conversion]
 75 | putchar(board[i][j]);
 | ~~~~~~~~^~~
 | |
 | char *
In file included from 256860.c:2:
/usr/include/stdio.h:528:25: note: expected ‘int’ but argument is of type ‘char *’
 528 | extern int putchar (int __c);
 | ~~~~^~~
256860.c: In function ‘addToBoard’:
256860.c:140:34: warning: comparison between pointer and integer
 140 | if(board[arrayRow][arrayCol] == ' ')
 | ^~
256860.c:144:39: warning: assignment to ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
 144 | board[arrayRow][arrayCol] = 'X';
 | ^
256860.c:149:39: warning: assignment to ‘char *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
 149 | board[arrayRow][arrayCol] = 'O';
 | ^
256860.c: In function ‘checkHorizontalVictory’:
256860.c:201:28: warning: comparison between pointer and integer
 201 | if(board[i][j] == ' ')
 | ^~
256860.c:205:33: warning: comparison between pointer and integer
 205 | else if(board[i][j] == 'X')
 | ^~
256860.c:209:33: warning: comparison between pointer and integer
 209 | else if(board[i][j] == 'O')
 | ^~
256860.c: In function ‘checkVerticalVictory’:
256860.c:234:28: warning: comparison between pointer and integer
 234 | if(board[i][j] == ' ')
 | ^~
256860.c:238:33: warning: comparison between pointer and integer
 238 | else if(board[i][j] == 'X')
 | ^~
256860.c:242:33: warning: comparison between pointer and integer
 242 | else if(board[i][j] == 'O')
 | ^~
256860.c: In function ‘checkDiagonalVictory’:
256860.c:263:24: warning: comparison between pointer and integer
 263 | if(board[i][i] == ' ')
 | ^~
256860.c:267:29: warning: comparison between pointer and integer
 267 | else if(board[i][i] == 'X')
 | ^~
256860.c:271:29: warning: comparison between pointer and integer
 271 | else if(board[i][i] == 'O')
 | ^~
256860.c:286:24: warning: comparison between pointer and integer
 286 | if(board[i][j] == ' ')
 | ^~
256860.c:290:29: warning: comparison between pointer and integer
 290 | else if(board[i][j] == 'X')
 | ^~
256860.c:294:29: warning: comparison between pointer and integer
 294 | else if(board[i][j] == 'O')
 | ^~
256860.c: At top level:
256860.c:306:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
 306 | checkDraw(int* turn)
 | ^~~~~~~~~
256860.c:316:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 316 | int promptReplay()
 | ^~~~~~~~~~~~
256860.c: In function ‘promptReplay’:
256860.c:320:14: warning: conversion from ‘int’ to ‘char’ may change value [-Wconversion]
 320 | choice = getchar();
 | ^~~~~~~
256860.c: In function ‘resetBoard’:
256860.c:348:25: warning: assignment to ‘char *’ from ‘char’ makes pointer from integer without a cast [-Wint-conversion]
 348 | board[i][j] = emptyboard[i][j];
 | ^
256860.c: In function ‘declareWinner’:
256860.c:355:5: warning: enumeration value ‘Playing’ not handled in switch [-Wswitch]
 355 | switch (currentGameState)
 | ^~~~~~
256860.c: At top level:
256860.c:366:6: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
 366 | void clearScreen()
 | ^~~~~~~~~~~
256860.c: In function ‘promptReplay’:
256860.c:338:1: warning: control reaches end of non-void function [-Wreturn-type]
 338 | }
 | ^

There are some serious problems there, in particular where we pass a matrix of char to functions expecting a matrix of char*.

I suggest creating a typedef for the frequently-used matrix:

#define BOARD_WIDTH 8 #define BOARD_HEGIHT 8 typedef char game_board[BOARD_HEGIHT][BOARD_WIDTH];

That makes our declarations much easier to keep consistent.

const game_board emptyboard = {
 {'-','-','-','-','-','-','-',' '},
 {'|',' ','|',' ','|',' ','|','3'},
 {'-','-','-','-','-','-','-',' '},
 {'|',' ','|',' ','|',' ','|','2'},
 {'-','-','-','-','-','-','-',' '},
 {'|',' ','|',' ','|',' ','|','1'},
 {'-','-','-','-','-','-','-',' '},
 {' ','a',' ','b',' ','c',' ',' '}
};
void clearScreen(void);
void resetBoard(game_board board, int* turn);
void drawBoard(game_board board);
void addToBoard(game_board board, int* player, int* turn, char* posX, char* posY);
void declareWinner(gameState currentGameState);
int getPlayerInput(int player, char* posX, char* posY); //Returns 1 if valid
int checkWin(game_board board, int* turn);
int checkVerticalVictory(game_board board);
int checkHorizontalVictory(game_board board);
int checkDiagonalVictory(game_board board);
int checkDraw(int* turn);
int promptReplay(void);

Normally, I'd make the board 3✕3, since the other entries in the matrix are for presentation rather than actual state.


char choice;
puts("\n\nPlay Again? (y/n): ");
choice = getchar();

Here, we not only fail to check for EOF, but we can no longer do so, as we converted the input to char. Use int, or turn to scanf():

for (;;) {
 puts("Play Again? (y/n): ");
 char choice;
 if (scanf(" %c%*[^\n]", &choice) < 1) {
 /* EOF */
 return 0;
 }
 switch (choice) {
 case 'y': case 'Y':
 return 1;
 case 'n': case 'N':
 return 0;
 }
 puts("\nWrong input.\n");
 /* loop; ask again */
}

#ifdef _WIN32
system("cls");
#elif __linux__
system("clear");
#endif

Use system with care. system("/usr/bin/clear") would be better, since you can't rely on users having a sane PATH. And on other platforms, is this function really supposed to do nothing?

#else
#error Please add support for clearing screen
lang-c

AltStyle によって変換されたページ (->オリジナル) /