Skip to content

Instantly share code, notes, and snippets.

@gcrbr
Last active September 14, 2025 20:20
Show Gist options
  • Select an option

  • Save gcrbr/6877da53b906a904cc26401acddd2703 to your computer and use it in GitHub Desktop.

Select an option

Save gcrbr/6877da53b906a904cc26401acddd2703 to your computer and use it in GitHub Desktop.
Tris
#include "tris.h"
int main() {
printf("New game - you are X\n");
char *stati[4] = {"Running", "Draw", "X Wins", "O Wins"};
Game *game = NULL;
if(new_game(&game) > -1) {
while(1) {
int row, col = 0;
printf("Your move (row,col): ");
scanf("%d,%d", &row, &col);
if(set_and_check(game, row, col, X) < 0) {
printf("Invalid move, try again\n");
continue;
}
uint8_t status = 0;
get_status(&status, game);
if(status != STATUS_ACTIVE) {
printf("\n");
print_grid(game);
printf("\n");
printf("Game result: %s\n", stati[status - 10]);
break;
}
uint8_t o_row, o_col = 0;
get_random_free_slot(&o_row, &o_col, game);
if(set_and_check(game, o_row, o_col, O) < 0) {
printf("CPU player move error\n");
}
printf("\n");
print_grid(game);
printf("\n");
}
}
return 0;
}
#ifndef TRIS_H
#define TRIS_H
#include "tris.h"
#endif
#include <time.h>
int new_game(Game **game) {
*game = (Game*)malloc(sizeof(Game));
if(*game == NULL) return -1;
return 0;
}
void free_game(Game **game) {
if(*game != NULL) {
free(*game);
*game = NULL;
}
}
int get(uint8_t *result, Game *game, uint8_t row, uint8_t col) {
if(game == NULL || row > 2 || col > 2) return -1;
uint16_t _grid = game->grid;
uint8_t slot = 0;
for(int i = 6 - (3 * row) + (3 - col); i > 0; i--) {
slot = _grid % 3;
_grid /= 3;
}
*result = slot;
return 0;
}
int set(Game *game, uint8_t row, uint8_t col, uint8_t value) {
if(game == NULL || row > 2 || col > 2 || (value != FREE && value != X && value != O)) return -1;
uint8_t current = 0;
get(&current, game, row, col);
game->grid += (value - current) * pow(3, (6 - (3 * row) + (3 - col)) - 1);
return 0;
}
int set_and_check(Game *game, uint8_t row, uint8_t col, uint8_t value) {
uint8_t slot = 0;
get(&slot, game, row, col);
if(slot != FREE) return -1;
return set(game, row, col, value);
}
int get_random_free_slot(uint8_t *row, uint8_t *col, Game *game) {
if(game == NULL) return -1;
char free[9];
uint8_t free_size = 0;
uint16_t _grid = game->grid;
for(int i = 8; i >= 0; i--) {
uint8_t extracted = _grid % 3;
if(extracted == FREE) {
free[free_size] = i;
free_size++;
}
_grid /= 3;
}
if(free_size == 0) {
return -1;
}
static int srand_set = 0;
if(!srand_set) {
srand_set = 1;
srand(time(NULL));
}
uint8_t random_selected = free[rand() % free_size];
*row = random_selected / 3;
*col = random_selected % 3;
return 0;
}
int get_status(uint8_t *status, Game *game) {
if(game == NULL || status == NULL) return -1;
if(game->grid == 0) {
*status = STATUS_ACTIVE;
return 0;
}
uint8_t table_grid[9];
uint16_t _grid = game->grid;
uint8_t empty_found = 0;
for(int i = 8; i >= 0; --i) {
table_grid[i] = _grid % 3;
if(table_grid[i] == FREE) empty_found = 1;
_grid /= 3;
}
uint8_t players[2] = {X, O};
uint8_t status_values[2] = {STATUS_WIN_X, STATUS_WIN_O};
for(int i = 0; i < 3; ++i) {
for(int j = 0; j < 2; ++j) {
if((table_grid[3 * i] == players[j] && table_grid[(3 * i) + 1] == players[j] && table_grid[(3 * i) + 2] == players[j]) || (table_grid[i] == players[j] && table_grid[3 + i] == players[j] && table_grid[6 + i] == players[j])) {
*status = status_values[j];
return 0;
}
}
}
for(int k = 0; k < 2; ++k) {
if((table_grid[0] == players[k] && table_grid[4] == players[k] && table_grid[8] == players[k]) || (table_grid[2] == players[k] && table_grid[4] == players[k] && table_grid[6] == players[k])) {
*status = status_values[k];
return 0;
}
}
*status = empty_found ? STATUS_ACTIVE : STATUS_DRAW;
return 0;
}
int print_grid(Game *game) {
if(game == NULL) return -1;
char readable_grid[9];
char *values = "-XO";
uint16_t _grid = game->grid;
for(int i = 8; i >= 0; --i) {
uint8_t extracted = _grid % 3;
readable_grid[i] = values[extracted];
_grid /= 3;
}
for(int j = 0; j < 9; ++j) {
printf("(%c) ", readable_grid[j]);
if((j + 1) % 3 == 0) {
printf("\n");
}
}
return 0;
}
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <math.h>
#define FREE 0
#define X 1
#define O 2
#define STATUS_ACTIVE 10
#define STATUS_DRAW 11
#define STATUS_WIN_X 12
#define STATUS_WIN_O 13
typedef struct {
uint16_t grid;
} Game;
int new_game(Game **game);
void free_game(Game **game);
int get(uint8_t *result, Game *game, uint8_t row, uint8_t col);
int set(Game *game, uint8_t row, uint8_t col, uint8_t value);
int set_and_check(Game *game, uint8_t row, uint8_t col, uint8_t value);
int get_random_free_slot(uint8_t *row, uint8_t *col, Game *game);
int get_status(uint8_t *status, Game *game);
int print_grid(Game *game);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment