-
-
Save JamesC01/479fca5e0a9074e39656faaccb038763 to your computer and use it in GitHub Desktop.
| // Tic Tac Toe in C. V1.0 by James 26/05/2019 | |
| // This is my first bigger C project. It was actually a lot easier than a I | |
| // thought it would be! It's not great, but it works perfectly decently. | |
| // I started working on it sometime around 4 in the morning, and I'm done before | |
| // 7 in the morning. So I didn't spend much time on it. | |
| // Also, I can't really claim I did the check function myself, though. The first time | |
| // I ever made tic tac toe (in C#), I ended up writing looping functions which could | |
| // check any size tic tac toe board, but I saw this current easier hard-coded solution | |
| // that just checks the cases of a 3x3 board in someone else's implementation of | |
| // the game. So I'm not sure I can take credit for it. | |
| // I think I thought about hard-coding it the first time I made tic-tac-toe, but I | |
| // thought there would be too many cases, it seems that there wasn't too many, though. | |
| // Also, I reasise I probably could've used 2d arrays, but I wanted to try it without, | |
| // since if you hadn't heard of a 2d array, you probably wouldn't be using them. | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <stdbool.h> | |
| #define SIZE 3 | |
| // Draws the board along with rows/cols, numbered. | |
| void draw_board(char board[]) | |
| { | |
| system("clear"); | |
| printf("# 1 2 3\n"); | |
| // Rows | |
| for (int i = 0, n = 0; i < SIZE; i++) | |
| { | |
| // Columns | |
| printf("%d ", i + 1); | |
| for (int j = 0; j < SIZE; j++) | |
| { | |
| printf("%c ", board[n]); | |
| n++; | |
| } | |
| printf("\n"); | |
| } | |
| } | |
| // Initializes board to '-' characters. | |
| void init_board(char board[]) | |
| { | |
| for (int i = 0; i < SIZE * SIZE; i++) | |
| { | |
| board[i] = '-'; | |
| } | |
| } | |
| // Returns true if the piece was successfully placed, | |
| // false if the position was invalid or already taken. | |
| bool place(char board[], char player) | |
| { | |
| char posinput[64]; | |
| printf("%c, pick your position (xy, rc): ", player); | |
| scanf("%s", posinput); // <-- I realise that this is potentially bad, but realistically, | |
| // the user would have to be trying to break something, and | |
| // this is just a little program I made for practice. | |
| int row = (posinput[0] - '0') - 1; | |
| int col = (posinput[1] - '0') - 1; | |
| int pos = col + row * SIZE; | |
| if (pos >= 0 && pos < SIZE * SIZE) | |
| { | |
| if (board[pos] == 'x' || board[pos] == 'o') | |
| return false; | |
| board[pos] = player; | |
| return true; | |
| } | |
| return false; | |
| } | |
| // Returns true if there are three of the same chars in a row. | |
| // b = board, p = player. Shortened for readability. | |
| bool check(char b[], char p) | |
| { | |
| // Check rows | |
| if (b[0] == p && b[1] == p && b[2] == p) | |
| return true; | |
| if (b[3] == p && b[4] == p && b[5] == p) | |
| return true; | |
| if (b[6] == p && b[7] == p && b[8] == p) | |
| return true; | |
| // Check columns | |
| if (b[0] == p && b[3] == p && b[6] == p) | |
| return true; | |
| if (b[1] == p && b[4] == p && b[7] == p) | |
| return true; | |
| if (b[2] == p && b[5] == p && b[8] == p) | |
| return true; | |
| // Check diagonals | |
| if (b[0] == p && b[4] == p && b[8] == p) | |
| return true; | |
| if (b[2] == p && b[4] == p && b[6] == p) | |
| return true; | |
| // If no one won, return false | |
| return false; | |
| } | |
| int main(void) | |
| { | |
| char board[SIZE * SIZE]; | |
| char player = 'x'; | |
| init_board(board); | |
| while (true) | |
| { | |
| draw_board(board); | |
| if (place(board, player)) | |
| { | |
| if (check(board, player)) | |
| break; | |
| if (player == 'x') | |
| player = 'o'; | |
| else | |
| player = 'x'; | |
| } | |
| } | |
| draw_board(board); | |
| printf("-----------------------------\n"); | |
| printf("Player %c wins!!!\n", player); | |
| printf("-----------------------------\n"); | |
| } |
Works fine for me, just remember to change system("clear"); to system("cls"); if you're running on windows
Works fine for me, just remember to change
system("clear");tosystem("cls");if you're running on windows
Predefined macros can be used for this, changing the code is bad solution.
If you're only trying to get it to work on Windows, checking for predefined macros seems needlessly overcomplicated compared to just changing the system call, although I seriously doubt this code will ever be used in production so the difference between the solutions is probably negligible
If you're only trying to get it to work on Windows, checking for predefined macros seems needlessly overcomplicated compared to just changing the system call, although I seriously doubt this code will ever be used in production so the difference between the solutions is probably negligible
I guess it's like 3-6 lines of code, this is not overcomplicated. Also these comments are useful for others, because this section is public. Everyone can see.
Necroposting here, but I just tried doing the same sort of thing but with a 2D array instead of without:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
char board[3][3];
char PLAYERS[] = {'x', 'o'};
void draw_board(void)
{
#ifdef _WIN32
system("cls");
#else
system("clear");
#endif
printf("# 1 2 3\n");
for (int i = 0; i < 3; i++)
{
printf("%d ", i + 1);
for (int j = 0; j < 3; j++)
{
printf("%c", board[i][j]);
if (j != 2) printf(" ");
}
printf("\n");
}
}
void init_board(void)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
board[i][j] = '-';
}
bool place(char p)
{
char pos[3] = "00";
printf("Player %c, pick your position (RowColumn):\n", p);
scanf("%s", pos);
int row = pos[0] - '0' - 1;
int col = pos[1] - '0' - 1;
if ((row >= 0 && row <= 2) && (col >= 0 && col <= 2))
{
if (board[row][col] != '-')
return false;
board[row][col] = p;
return true;
}
return false;
}
bool check(char p)
{
for (int r = 0; r < 3; r++)
if (board[r][0] == p && board[r][1] == p && board[r][2] == p)
return true;
for (int c = 0; c < 3; c++)
if (board[0][c] == p && board[1][c] == p && board[2][c] == p)
return true;
if (board[0][0] == p && board[1][1] == p && board[2][2] == p)
return true;
else if (board[0][2] == p && board[1][1] == p && board[2][0] == p)
return true;
return false;
}
bool is_board_full(void)
{
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
if (board[i][j] == '-')
return false;
return true;
}
int main(void)
{
init_board();
int player_index = 0;
while(true)
{
draw_board();
if (place(PLAYERS[player_index]))
{
if (check(PLAYERS[player_index]))
break;
else if (is_board_full())
{
draw_board();
printf("-----------------------------\nDraw!\n-----------------------------\n");
return 0;
}
player_index = 1 - player_index;
}
}
draw_board();
printf("-----------------------------\nPlayer %c wins!\n-----------------------------\n", PLAYERS[player_index]);
return 0;
}
I also tried to add a check for draw as well as making it cross-platform.
it doesnt work