vier_gewinnt git · main
git clone https://git.christianimmanuel.de/games/vier_gewinnt.gitwget https://git.christianimmanuel.de/games/vier_gewinnt/archive/vier_gewinnt.tar.gzmain.c raw
#include <stdlib.h>
#include <stdio.h>
// #include <sys/ioctl.h> // window size
// #include <unistd.h> // window size
#include "keypress.c"
#include <termios.h>
#define ROWS_MAX 12
#define COLS_MAX 12
// disable user input
void disable_input_buffering() {
struct termios t;
tcgetattr(STDIN_FILENO, &t);
t.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &t);
}
// enable user input
void enable_input_buffering() {
struct termios t;
tcgetattr(STDIN_FILENO, &t);
t.c_lflag |= (ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &t);
}
#ifdef _WIN32
#define WINDOWS
#include <windows.h>
#else
#include <time.h>
void sleep_seconds(double seconds) {
clock_t start_time = clock();
double elapsed_time;
do {
elapsed_time = ((double)(clock() - start_time)) / CLOCKS_PER_SEC;
} while (elapsed_time < seconds);
}
#endif
void draw_game(char game_area[COLS_MAX][ROWS_MAX]) {
system("clear");
printf("\n\n");
printf("\n┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐\n");
for (int i = 0; i < COLS_MAX; i++) {
printf("│");
for (int k = 0; k < ROWS_MAX; k++)
printf(" %c │", game_area[i][k]);
if (i != ROWS_MAX-1)
printf("\n├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤\n");
else printf("\n└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘\n");
}
}
void draw_area_pos(char player, int x, int y) {
if (player == 'x')
printf("\033[38;5;28m");
else if (player == 'o')
printf("\033[38;5;124m");
printf("\033[%d;%dH%c\033[0m", y, x, player);
}
void draw_in_pos(int pos, char player) {
printf("\033[%d;%dH ", 3, 0);
printf("\033[%d;%dH", 3, pos*3+pos-2);
if (player == 'x')
printf("\033[48;5;28m");
else
printf("\033[48;5;124m");
printf(" %c \033[0m", player);
printf("\033[%d;%dH", 3, pos*3+pos-1);
}
void draw_drop(char area[COLS_MAX][ROWS_MAX], char player, int pos) {
disable_input_buffering();
double sleep = 0.1;
int i;
for (i = 0; i < ROWS_MAX; i++){
if (area[pos-1][i] != '.')
break;
draw_area_pos(player, 3*pos+pos-1, 5+2*i);
fflush(stdout);
#ifdef WINDOWS
Sleep((int)sleep * 100);
#else
sleep_seconds(sleep/10);
#endif
draw_area_pos('.', 3*pos+pos-1, 5+2*i);
}
enable_input_buffering();
}
int set_drop(char area[COLS_MAX][ROWS_MAX], char player, int pos) {
int i;
for (i = 0; i < ROWS_MAX && area[pos-1][i] == '.'; i++);
if (i > 0)
area[pos-1][i-1] = player;
return i-1;
}
char check_winner(char area[COLS_MAX][ROWS_MAX], int x, int y) {
char c = area[x][y];
for (int i = -3; i < 1; i++) {
char m[] = {0,0,0,0};
for (int k = 0; k < 4; k++) {
if (x+i+k > -1 && x+i+k < ROWS_MAX && area[x+i+k][y] == c) m[0]++;
if (y+i+k > -1 && y+i+k < COLS_MAX && area[x][y+i+k] == c) m[1]++;
if (x+i+k > -1 && x+i+k < ROWS_MAX &&
y+i+k > -1 && y+i+k < COLS_MAX &&
area[x+i+k][y+i+k] == c) m[2]++;
if (x+i+k > -1 && x+i+k < ROWS_MAX &&
y-i-k > -1 && y-i-k < COLS_MAX &&
area[x+i+k][y-i-k] == c) m[3]++;
}
for (int j = 0; j < 4; j++) {
if (m[j] == 4) return c;
}
}
return '.';
}
void draw_winner(char winner) {
printf("\033[48;5;231m");
(winner == 'x') ?
printf("\033[38;5;28m") :
printf("\033[38;5;124m");
printf("\033[%d;%dH!!! Winner: %c !!!\033[0m", ROWS_MAX*3/2, COLS_MAX*3/2, winner);
}
int main() {
char game_area[COLS_MAX][ROWS_MAX];
for (int i = 0; i < COLS_MAX; i++)
for (int k = 0; k < ROWS_MAX; k++)
game_area[i][k] = '.';
draw_game(game_area);
char key = '0';
int in_pos = 1;
char player = 'x';
while (1) {
key = '0';
while (key != 10) {
draw_in_pos(in_pos, player);
key = get_keypress();
switch (key) {
case 'a':
in_pos = in_pos == 1 ? COLS_MAX : in_pos-1;
break;
case 'd':
in_pos = in_pos == COLS_MAX ? 1 : in_pos+1;
break;
}
}
int drop_y = set_drop(game_area, player, in_pos);
if (drop_y > -1) {
// animate drop
draw_drop(game_area, player, in_pos);
// draw final position
draw_area_pos(player, 3*in_pos+in_pos-1, 5+2*(drop_y));
// switch player
char winner = check_winner(game_area, in_pos-1, drop_y);
if (winner != '.')
draw_winner(winner);
player = player == 'x' ? 'o' : 'x';
}
}
}