// Connect 4 #include #define NUM_ROWS 6 #define NUM_COLS 7 #define RESET "\033[0m" #define BLACK "\033[30m" /* Black */ #define RED_CLR "\033[31m" /* Red */ #define GREEN "\033[32m" /* Green */ #define YELLOW_CLR "\033[33m" /* Yellow */ #define BLUE "\033[34m" /* Blue */ #define MAGENTA "\033[35m" /* Magenta */ #define CYAN "\033[36m" /* Cyan */ #define WHITE "\033[37m" /* White */ enum cell_state { EMPTY, RED, YELLOW }; void print_gameboard(enum cell_state gameboard[NUM_ROWS][NUM_COLS]) { // clears the terminal printf("\e[1;1H\e[2J"); int i = 0; while (i < NUM_ROWS) { int j = 0; while (j < NUM_COLS) { if (gameboard[i][j] == RED) { printf(RED_CLR "%d " RESET, gameboard[i][j]); } else if (gameboard[i][j] == YELLOW) { printf(YELLOW_CLR "%d " RESET, gameboard[i][j]); } else { printf("%d ", gameboard[i][j]); } j++; } printf("\n"); i++; } } int read_player_input() { int input; printf("\nWhich column do you want to place your piece?\n"); printf("Enter the column (1-7): "); scanf("%d", &input); input--; while (input < 0 || input >= NUM_COLS) { printf("Invalid column. Enter the column (1-7): "); scanf("%d", &input); input--; } return input; } int check_horizontal(enum cell_state gameboard[NUM_ROWS][NUM_COLS], enum cell_state piece_to_check) { for (int row = 0; row < NUM_ROWS; row++) { for (int col = 0; col < NUM_COLS - 3; col++) { if (gameboard[row][col] == piece_to_check && gameboard[row][col + 1] == piece_to_check && gameboard[row][col + 2] == piece_to_check && gameboard[row][col + 3] == piece_to_check) { return 1; } } } return 0; } int check_diagonal_from_bottom_left( enum cell_state gameboard[NUM_ROWS][NUM_COLS], enum cell_state piece_to_check) { for (int row = 3; row < NUM_ROWS; row++) { for (int col = 0; col < NUM_COLS - 3; col++) { if (gameboard[row][col] == piece_to_check && gameboard[row - 1][col + 1] == piece_to_check && gameboard[row - 2][col + 2] == piece_to_check && gameboard[row - 3][col + 3] == piece_to_check) { return 1; } } } return 0; } int check_diagonal_from_top_left(enum cell_state gameboard[NUM_ROWS][NUM_COLS], enum cell_state piece_to_check) { for (int row = 0; row < NUM_ROWS - 3; row++) { for (int col = 0; col < NUM_COLS - 3; col++) { if (gameboard[row][col] == piece_to_check && gameboard[row + 1][col + 1] == piece_to_check && gameboard[row + 2][col + 2] == piece_to_check && gameboard[row + 3][col + 3] == piece_to_check) { return 1; } } } return 0; } int check_vertical(enum cell_state gameboard[NUM_ROWS][NUM_COLS], enum cell_state piece_to_check) { for (int col = 0; col < NUM_COLS; col++) { for (int row = 0; row < NUM_ROWS - 3; row++) { if (gameboard[row][col] == piece_to_check && gameboard[row + 1][col] == piece_to_check && gameboard[row + 2][col] == piece_to_check && gameboard[row + 3][col] == piece_to_check) { return 1; } } } return 0; } int check_for_win(enum cell_state gameboard[NUM_ROWS][NUM_COLS], enum cell_state piece_to_check) { return check_horizontal(gameboard, piece_to_check) || check_vertical(gameboard, piece_to_check) || check_diagonal_from_top_left(gameboard, piece_to_check) || check_diagonal_from_bottom_left(gameboard, piece_to_check); } int main(void) { enum cell_state gameboard[NUM_ROWS][NUM_COLS] = {}; int player_input; // 0 is RED, 1 is YELLOW int turn_counter = 0; while (1) { // check if piece can go into column int row_to_check = NUM_ROWS - 1; player_input = read_player_input(); while (row_to_check >= 0 && gameboard[row_to_check][player_input] != EMPTY) { row_to_check--; } if (row_to_check < 0) { // here, we have no position to printf("That's an invalid placement\n"); } else { if (turn_counter == 0) { // placing the piece gameboard[row_to_check][player_input] = RED; } else { gameboard[row_to_check][player_input] = YELLOW; } } print_gameboard(gameboard); // checking for a win... if (check_for_win(gameboard, RED)) { printf("Red win detected!\n"); } else if (check_for_win(gameboard, YELLOW)) { printf("Yellow win detected!\n"); } else { printf("Still no win\n"); } if (turn_counter == 0) { turn_counter = 1; } else { turn_counter = 0; } } return 0; }