Skip to content

Instantly share code, notes, and snippets.

@woodrowbarlow
Created October 13, 2018 17:09
Show Gist options
  • Save woodrowbarlow/44b9375443e8312c4becb771bbb3b6f6 to your computer and use it in GitHub Desktop.
Save woodrowbarlow/44b9375443e8312c4becb771bbb3b6f6 to your computer and use it in GitHub Desktop.
gcc tak.c -o tak; ./tak
#include <stdio.h>
/* each line along which a player can win */
enum axes {
HORIZ_TOP,
HORIZ_MID,
HORIZ_BOT,
VERT_LEFT,
VERT_MID,
VERT_RIGHT,
DIAG_TOP_LEFT, /* from top left to bottom right */
DIAG_BOT_LEFT, /* from bottom left to top right */
AXES_MAX
};
/* if any rank hits (plus or minus) three, the game is over */
static int ranks[AXES_MAX] = { 0 };
static char board[3][3] = {
{ ' ', ' ', ' ' },
{ ' ', ' ', ' ' },
{ ' ', ' ', ' ' },
};
static int check_game_state(void)
{
int i;
/* if any rank hits (plus or minus) three, the game is over.
* - positive indicates 'x' wins
* - negative indicates 'o' wins
*/
for (i = 0; i < AXES_MAX; i++)
{
switch (ranks[i])
{
case 3:
return 1;
case -3:
return -1;
}
}
return 0;
}
static void draw_board(void)
{
int i;
printf("\n [1] [2] [3]\n\n");
printf("[A] %c | %c | %c \n",
board[0][0], board[0][1], board[0][2]);
for (i = 1; i < 3; i++)
{
printf(" ---|---|---\n");
printf("[%c] %c | %c | %c \n", 'A' + i,
board[i][0], board[i][1], board[i][2]);
}
}
static int get_input(int *row, int *col)
{
char tmp = 0;
char r = 0;
unsigned int c = 0;
int matches = 0;
matches = scanf("%c%u", &r, &c);
while (tmp != '\n' && tmp != EOF)
{
/* scanf doesn't remove extra leftovers from the buffer */
tmp = getchar();
}
if (matches != 2 || c < 1 || c > 3)
{
return -1;
}
switch (r)
{
case 'a':
case 'b':
case 'c':
*row = r - 'a';
break;
case 'A':
case 'B':
case 'C':
*row = r - 'A';
break;
default:
return -1;
}
*col = (int) c - 1;
return 0;
}
static void make_move(int row, int col, char player)
{
int rank_factor = (player == 'x') ? 1 : -1;
/* the game ends if any rank hits (plus or minus) three.
* there is a rank for each "axis" on which you can win:
* - the three horizontal rows (top, middle, and bottom)
* - the three vertical columns (left, middle, and right)
* - the two diagonal axes (from top left, from bottom left)
*/
/* update rank for each axis this move affected */
ranks[HORIZ_TOP + row] += rank_factor;
ranks[VERT_LEFT + col] += rank_factor;
ranks[DIAG_TOP_LEFT] += ((row == 0 && col == 0) ||
(row == 1 && col == 1) ||
(row == 2 && col == 2)) ? rank_factor : 0;
ranks[DIAG_BOT_LEFT] += ((row == 2 && col == 0) ||
(row == 1 && col == 1) ||
(row == 0 && col == 2)) ? rank_factor : 0;
/* then update the board itself */
board[row][col] = player;
}
int main(void)
{
int spaces_available = 9;
char player = 'o';
while (spaces_available > 0 && check_game_state() == 0)
{
player = (player == 'x') ? 'o' : 'x';
draw_board();
int row;
int col;
while (get_input(&row, &col) != 0 || board[row][col] != ' ')
{
/* do nothing */
}
make_move(row, col, player);
spaces_available--;
}
draw_board();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment