Last active
September 14, 2025 20:20
-
-
Save gcrbr/6877da53b906a904cc26401acddd2703 to your computer and use it in GitHub Desktop.
Tris
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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(¤t, 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; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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