Skip to content

Instantly share code, notes, and snippets.

@swapnilshrikhande
Forked from dylnmc/TicTacToe.c
Last active August 29, 2015 14:10
Show Gist options
  • Save swapnilshrikhande/198fa91e0920fff94dc4 to your computer and use it in GitHub Desktop.
Save swapnilshrikhande/198fa91e0920fff94dc4 to your computer and use it in GitHub Desktop.
/*
This game is for Unix only.
It is a simple yet easily navigable Tic-Tac-Toe game for the Unix terminal. To run this file, go
to your awesome Unix terminal and (after you have downloaded this text file, of course) and
navigate to this file. Then, compile and link the program with your handy compiler which will
almost definitely be installed unless you have removed it using the command 'gcc TicTacToe.c'.
This creates an executeable. To run it, you can simply type './a.out'. If you want to have a more
memorable file and/or prevent conflicts, simply change the name with the 'mv' tool
('mv a.out TicTacToe') or use the '-o' ("output file") when compiling
('gcc TicTacToe.c -o TicTacToe').
This game, although not a particularly fun game, shows how to use key strokes rather than
waiting for the Enter key. One can, therefore, press 'j', Space or any key and have it register
immediately. Hopefully it can be of use.
*/
#include <stdio.h>
#include <unistd.h> /* for STDIN_FILENO */
#include <termios.h>
void printBoard(void);
// globals
char keys[] = {0, 0, 0, 0}; // the keys entered
/* (remember: some keys produce multiple characters;
i.e. left = \x1b [ D (3 chars)
*/
int curpos = 0; // position of the cursor
int i; // helper
int p; // position for printing board in loop
char board[] = { // board
' ', ' ', ' ',
' ', ' ', ' ',
' ', ' ', ' ', };
int turn = 0; // (turn % 2 == 0) = X; (turn % 2 == 1) = O
char winner;
struct termios old, t;
int main() {
tcgetattr(STDIN_FILENO, &old);
t = old;
// format Unix terminal (reset, move to (0,0), clear to bottom, change title to "Tic-Tac-Toe", turn off cursor (prevents flickering and looks better)
printf("\x1bc\x1b[0;0H\x1b[J\x1b]0;Tic-Tac-Toe\x07\x1b[?25l");
printBoard();
char ch = 0;
while (keys[0] != 'q') {
keys[3] = keys[2];
keys[2] = keys[1];
keys[1] = keys[0];
cfmakeraw(&t);
tcsetattr(STDIN_FILENO, TCSANOW, &t);
keys[0] = getc(stdin);
tcsetattr(STDIN_FILENO, TCSANOW, &old);
// UP
if (keys[2] == 27 && keys[1] == 91 && keys[0] == 65) {
// cursor curpos on first row (move to last)
if (curpos / 3 == 0) {
curpos += 2 * 3;
} else {
curpos -= 3;
}
// DOWN
} else if (keys[2] == 27 && keys[1] == 91 && keys[0] == 66) {
// cursor curpos on last row (move to first)
if (curpos / 3 == 2) {
curpos -= 2 * 3;
} else {
curpos += 3;
}
// RIGHT
} else if (keys[2] == 27 && keys[1] == 91 && keys[0] == 67) {
// cursor curpos on right-most column (move to left-most)
if (curpos % 3 == 2) {
curpos -= 2;
} else {
curpos += 1;
}
// LEFT
} else if (keys[2] == 27 && keys[1] == 91 && keys[0] == 68) {
// cursor curpos on left-most column (move to right-most)
if (curpos % 3 == 0) {
curpos += 2;
} else {
curpos -= 1;
}
// ENTER or SPACE
} else if (keys[0] == 13 || keys[0] == 32) {
if (board[curpos] == ' ') {
if (turn % 2 == 0) {
board[curpos] = 'X';
} else {
board[curpos] = 'O';
}
turn++;
}
}
// temporary... print key pressed
//printf("\n %d %d %d %d", keys[0], keys[1], keys[2], keys[3]);
printBoard();
// check for winner
// ----------------
if (board[0] == 'X' && board[1] == 'X' && board[2] == 'X' || // row 1
board[3] == 'X' && board[4] == 'X' && board[5] == 'X' || // row 2
board[6] == 'X' && board[7] == 'X' && board[8] == 'X' || // row 3
board[0] == 'X' && board[3] == 'X' && board[6] == 'X' || // col 1
board[1] == 'X' && board[4] == 'X' && board[7] == 'X' || // col 2
board[2] == 'X' && board[5] == 'X' && board[8] == 'X' || // col 3
board[0] == 'X' && board[4] == 'X' && board[8] == 'X' || // diag top-left to bottom-right
board[2] == 'X' && board[4] == 'X' && board[6] == 'X') { // diag top-right to bottom-left
printf("\n\n\x1b[34;1mX\x1b[m wins! [enter]");
getchar();
printf("\x1b[0;0H\x1b[J");
for (i = 0; i < 9; i++) {
board[i] = ' ';
}
turn = 0;
printBoard();
}
if (board[0] == 'O' && board[1] == 'O' && board[2] == 'O' || // row 1
board[3] == 'O' && board[4] == 'O' && board[5] == 'O' || // row 2
board[6] == 'O' && board[7] == 'O' && board[8] == 'O' || // row 3
board[0] == 'O' && board[3] == 'O' && board[6] == 'O' || // col 1
board[1] == 'O' && board[4] == 'O' && board[7] == 'O' || // col 2
board[2] == 'O' && board[5] == 'O' && board[8] == 'O' || // col 3
board[0] == 'O' && board[4] == 'O' && board[8] == 'O' || // diag top-left to bottom-right
board[2] == 'O' && board[4] == 'O' && board[6] == 'O') { // diag top-right to bottom-left
printf("\n\n\x1b[33;1mO\x1b[m wins! [enter]");
getchar();
printf("\x1b[0;0H\x1b[J");
for (i = 0; i < 9; i++) {
board[i] = ' ';
}
turn = 0;
printBoard();
}
// check for tie
if (turn == 9) {
printf("\n\nIt's a tie! [Enter]");
getchar();
printf("\x1b[0;0H\x1b[J");
for (i = 0; i < 9; i++) {
board[i] = ' ';
}
turn = 0;
printBoard();
}
}
printf("\x1b[?25h");
return 0;
}
void printBoard(void) {
printf("\x1b[0;0Hpress 'q' to quit\n\n", curpos % 3 + 1, curpos / 3 + 1);
for (p = 0; p < 9; p++) {
printf("|");
if (p == curpos) {
printf("\x1b[7m"); // turn on rev. color (if cursor on this pos)
}
if (board[p] == 'X') {
printf("\x1b[34;1m");
} else if (board[p] == 'O') {
printf("\x1b[33;1m");
}
putchar(board[p]);
if (board[p] == 'X' || board[p] == 'O') {
printf("\x1b[m");
}
if (p == curpos) {
printf("\x1b[27m"); // turn off rev. color (if cursor on this pos)
}
if (p % 3 == 2) {
printf("|\n");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment