Skip to content
Snippets Groups Projects
Commit c83dd25e authored by tanguy.cavagna's avatar tanguy.cavagna :desktop:
Browse files

Semi working prototype

parent 638a62ea
No related branches found
No related tags found
No related merge requests found
......@@ -58,7 +58,7 @@ BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 100
ColumnLimit: 140
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
......
......@@ -20,8 +20,7 @@ int main(void) {
clear();
set_gamemode(menu_choice);
getch();
launch_game();
cleanup_term();
......
#include "ui.h"
#define MENU_CHOICE_COUNT 4
#define MENU_MAX 4
#define TITLE_Y_OFFSET 5
#define MENU_CHOICE_Y_OFFSET 23
#define GAMEBOARD_Y_OFFSET 10
//==========================
// PRIVATE
//==========================
// Windows
WINDOW *ui_window = NULL;
char menu_choices[MENU_CHOICE_COUNT][10] = {"Solo", "1 Vs 1", "Computer", "Quit"};
char title[8][64] = {"$$\\ $$\\ $$$$$$\\ $$$$$$$\\ $$$$$$$\\ $$\\ $$$$$$$$\\ ",
"$$ | $\\ $$ |$$ __$$\\ $$ __$$\\ $$ __$$\\ $$ | $$ _____|",
"$$ |$$$\\ $$ |$$ / $$ |$$ | $$ |$$ | $$ |$$ | $$ | ",
"$$ $$ $$\\$$ |$$ | $$ |$$$$$$$ |$$ | $$ |$$ | $$$$$\\ ",
"$$$$ _$$$$ |$$ | $$ |$$ __$$< $$ | $$ |$$ | $$ __| ",
"$$$ / \\$$$ |$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ | ",
"$$ / \\$$ | $$$$$$ |$$ | $$ |$$$$$$$ |$$$$$$$$\\ $$$$$$$$\\ ",
"\\__/ \\__| \\______/ \\__| \\__|\\_______/ \\________|\\________|"};
/**
* @brief Print a text at the center of the given line
*
* @param foo
* @param line
*/
void printw_center(char *foo, int line) { mvaddstr(line, TERM_MID_COLS - (strlen(foo) / 2), foo); }
WINDOW *help = NULL;
/**
* @brief Set the color scheme of the programm
......@@ -34,6 +20,7 @@ void set_colors() {
init_pair(GREEN_PAIR, COLOR_GREEN, COLOR_BLACK);
init_pair(ORANGE_PAIR, COLOR_YELLOW, COLOR_BLACK);
init_pair(WHITE_PAIR, COLOR_WHITE, COLOR_BLACK);
init_pair(RED_PAIR, COLOR_RED, COLOR_BLACK);
}
/**
......@@ -41,48 +28,30 @@ void set_colors() {
*
* @return int
*/
int select_menu_choice() {
int current_choice = 0;
int selection_ctrl = 0;
do {
// Keyboard controls
switch (selection_ctrl) {
case KEY_DOWN:
current_choice += 1;
current_choice %= MENU_CHOICE_COUNT;
break;
case KEY_UP:
current_choice -= 1;
current_choice = current_choice < 0 ? MENU_CHOICE_COUNT - 1 : current_choice;
break;
}
// Print of the menu choices
for (int i = 0; i < MENU_CHOICE_COUNT; i++) {
int menu_selector_x = TERM_MID_COLS - (strlen(menu_choices[i]) / 2) - 2;
if (i == current_choice) {
attron(A_BOLD);
mvaddch(23 + i, menu_selector_x, '>'); // Menu selector ON
printw_center(menu_choices[i], 23 + i);
attroff(A_BOLD);
} else {
mvaddch(23 + i, menu_selector_x, ' '); // Menu selector OFF
printw_center(menu_choices[i], 23 + i);
}
}
} while ((selection_ctrl = getch()) != '\n');
return current_choice;
void draw_menu(int menu_item) {
char menu_choices[MENU_MAX][20] = {" Solo ", " 1 Vs 1 ", " Computer ", " Quit "};
// Print of the menu choices
for (int i = 0; i < MENU_MAX; i++) {
if (i == menu_item)
attron(A_STANDOUT);
if (i == MENU_QUIT)
attron(COLOR_PAIR(RED_PAIR));
printw_center(menu_choices[i], MENU_CHOICE_Y_OFFSET + (i * 2));
attroff(COLOR_PAIR(WHITE_PAIR));
attroff(A_STANDOUT);
}
}
//==========================
// PUBLIC
//==========================
void printw_center(char *foo, int line) { mvaddstr(line, TERM_MID_COLS - (strlen(foo) / 2), foo); }
bool init_term() {
ui_window = initscr();
cbreak();
noecho();
curs_set(0);
keypad(stdscr, true);
......@@ -103,12 +72,23 @@ bool init_term() {
void cleanup_term() {
curs_set(1);
nocbreak();
delwin(help);
delwin(ui_window);
endwin();
refresh();
}
int show_menu() {
char title[8][64] = {"$$\\ $$\\ $$$$$$\\ $$$$$$$\\ $$$$$$$\\ $$\\ $$$$$$$$\\ ",
"$$ | $\\ $$ |$$ __$$\\ $$ __$$\\ $$ __$$\\ $$ | $$ _____|",
"$$ |$$$\\ $$ |$$ / $$ |$$ | $$ |$$ | $$ |$$ | $$ | ",
"$$ $$ $$\\$$ |$$ | $$ |$$$$$$$ |$$ | $$ |$$ | $$$$$\\ ",
"$$$$ _$$$$ |$$ | $$ |$$ __$$< $$ | $$ |$$ | $$ __| ",
"$$$ / \\$$$ |$$ | $$ |$$ | $$ |$$ | $$ |$$ | $$ | ",
"$$ / \\$$ | $$$$$$ |$$ | $$ |$$$$$$$ |$$$$$$$$\\ $$$$$$$$\\ ",
"\\__/ \\__| \\______/ \\__| \\__|\\_______/ \\________|\\________|"};
// Title print
for (int i = 0; i < 8; i++)
printw_center(title[i], i + TITLE_Y_OFFSET);
......@@ -116,14 +96,97 @@ int show_menu() {
// Menu print
attron(COLOR_PAIR(GREEN_PAIR));
attron(A_BOLD);
printw_center("MENU", 20);
printw_center("====== MENU ======", MENU_CHOICE_Y_OFFSET - 3);
attroff(A_BOLD);
attron(COLOR_PAIR(WHITE_PAIR));
attron(A_DIM);
printw_center("Use arrow keys to move; Enter to chose", MENU_CHOICE_Y_OFFSET + 10);
attroff(A_DIM);
// Menu choices handler
attron(COLOR_PAIR(WHITE_PAIR));
int menu_choice = select_menu_choice();
int key = 0, menu_item = 0;
do {
switch (key) {
case KEY_DOWN:
menu_item += 1;
if (menu_item > MENU_MAX - 1)
menu_item = 0;
break;
case KEY_UP:
menu_item -= 1;
if (menu_item < 0)
menu_item = MENU_MAX - 1;
break;
}
draw_menu(menu_item);
key = getch();
} while (key != '\n');
refresh();
return menu_item;
}
void toggle_help() {
// Delete existing instance of the subwindow
if (help != NULL) {
wclear(ui_window);
delwin(help);
refresh();
help = NULL;
return;
}
// Create new instance of the subwindow
help = subwin(ui_window, 7, COLS - 2, LINES - 7, 1);
refresh();
return menu_choice;
if (help == NULL) {
cleanup_term();
exit(EXIT_FAILURE);
}
box(help, 0, 0);
mvwprintw(help, 0, 1, " Help "); // Title
// Content
// Keybindings
wattron(help, A_BOLD);
mvwprintw(help, 2, 2, "Ctrl+h");
mvwprintw(help, 3, 2, "Ctrl+t");
mvwprintw(help, 4, 2, "Ctrl+w");
wattroff(help, A_BOLD);
// Description
mvwprintw(help, 2, 10, "Show this page");
mvwprintw(help, 3, 10, "Toggle the assistance tool (only in Computer mode)");
mvwprintw(help, 4, 10, "Quit the game");
refresh();
wrefresh(help);
}
void show_gameboard(int tries_count, int word_length, char **tries, int **validations) {
for (int i = 0; i < tries_count; i++) {
// Draw current try letters
for (size_t j = 0; j < strlen(tries[i]); j++) {
if (validations[i][j] == 1)
attron(COLOR_PAIR(ORANGE_PAIR));
if (validations[i][j] == 2)
attron(COLOR_PAIR(GREEN_PAIR));
mvaddch(GAMEBOARD_Y_OFFSET + i, TERM_MID_COLS - word_length + (j * 2), tries[i][j]);
attroff(COLOR_PAIR(GREEN_PAIR));
attroff(COLOR_PAIR(ORANGE_PAIR));
}
// Draw remaning try letters placeholder
for (size_t j = 0; j < word_length - strlen(tries[i]); j++)
mvaddstr(GAMEBOARD_Y_OFFSET + i, TERM_MID_COLS + word_length - 2 - (j * 2), "_ ");
}
refresh();
}
\ No newline at end of file
......@@ -15,6 +15,7 @@
#define GREEN_PAIR 1
#define ORANGE_PAIR 2
#define WHITE_PAIR 3
#define RED_PAIR 4
// Menu choices
#define MENU_SOLO 0
......@@ -22,6 +23,23 @@
#define MENU_COMPUTER 2
#define MENU_QUIT 3
// Control key handler
#define ctrl(x) ((x)&0x1f)
// Game controls
#define KEYBIND_HELP (ctrl('h'))
#define KEYBIND_TAG (ctrl('t')) // Tool Assisted Game
#define KEYBIND_QUIT (ctrl('w'))
#define KEYBIND_GUESS '\n'
/**
* @brief Print a text at the center of the given line
*
* @param foo
* @param line
*/
void printw_center(char *foo, int line);
/**
* @brief Initialize the terminal
*
......@@ -43,4 +61,20 @@ void cleanup_term();
*/
int show_menu();
/**
* @brief Toggle the help window
*
*/
void toggle_help();
/**
* @brief Show the gameboard
*
* @param tries_count
* @param word_length
* @param tries
* @param validations
*/
void show_gameboard(int tries_count, int word_length, char **tries, int **validations);
#endif
\ No newline at end of file
......@@ -4,8 +4,139 @@
// PRIVATE
//==========================
int gamemode = -1;
bool _game_finished = false;
char **tries;
char *chosen_word;
int **validations;
int current_try_id = 0;
int current_try_letter_id = 0;
/**
* @brief Terminate a game
*/
void terminate_game() { _game_finished = true; }
/**
* @brief Add a letter to the current try
*
* @param letter
*/
void add_letter_to_try(char letter) {
tries[current_try_id][current_try_letter_id] = letter;
current_try_letter_id += 1;
}
/**
* @brief Check if the given letter is a lowercase letter only
*
* @param key
* @return true
* @return false
*/
bool validate_letter(int key) { return (key >= 97 && key <= 122); }
/**
* @brief Validate the last guess
*
*/
int *validate_last_guess(char answer[WORD_LENGHT], char try[WORD_LENGHT]) {
int a[WORD_LENGHT] = {0, 2, 0, 1, 0};
int *validation = calloc(WORD_LENGHT, sizeof(int));
for (int i = 0; i < WORD_LENGHT; i++)
validation[i] = a[i];
return validation;
}
/**
* @brief Handle controls
*
* @param key
*/
void handle_controls(int key) {
switch (key) {
case KEYBIND_HELP:
toggle_help();
break;
case KEYBIND_QUIT:
terminate_game();
break;
case KEYBIND_GUESS:
if (strlen(tries[current_try_id]) < WORD_LENGHT)
break;
int *tmp = validate_last_guess(chosen_word, tries[current_try_id]);
for (int i = 0; i < WORD_LENGHT; i++)
validations[current_try_id][i] = tmp[i];
free(tmp);
current_try_id += 1;
current_try_letter_id = 0;
break;
}
}
//==========================
// PUBLIC
//==========================
void set_gamemode(int menu_gamemode) { gamemode = menu_gamemode; }
\ No newline at end of file
void set_gamemode(int menu_gamemode) { gamemode = menu_gamemode; }
void launch_game() {
chosen_word = "SALUT";
tries = calloc(TRIES_COUNT, sizeof(char *));
validations = malloc(sizeof(int *) * TRIES_COUNT);
for (int i = 0; i < TRIES_COUNT; i++) {
validations[i] = calloc(WORD_LENGHT + 1, sizeof(int));
tries[i] = calloc(WORD_LENGHT + 1, sizeof(char)); // +1 because of \0
}
while (!game_finished()) {
// Guard clause
if (current_try_id > TRIES_COUNT - 1) {
terminate_game();
continue;
}
// Render
switch (gamemode) {
case GAMEMODE_SOLO:
printw_center("Solo", 5);
break;
case GAMEMODE_1_V_1:
printw_center("Player 1", 5);
break;
case GAMEMODE_COMPUTER:
printw_center("Computer assisted", 5);
break;
}
show_gameboard(TRIES_COUNT, WORD_LENGHT, tries, validations);
// Next letter
int key = getch();
if (validate_letter(key)) {
if (current_try_letter_id < WORD_LENGHT)
add_letter_to_try((char)key - 32); // Offset letter to only put upercase
}
handle_controls(key);
refresh();
}
for (int i = 0; i < TRIES_COUNT; i++) {
free(tries[i]);
free(validations[i]);
}
free(tries);
free(validations);
}
bool game_finished() { return _game_finished; }
\ No newline at end of file
#ifndef WORDLE_H_
#define WORDLE_H_
#include "../ui/ui.h"
#include <stdbool.h>
// Gamemodes
#define GAMEMODE_SOLO 0
#define GAMEMODE_1_V_1 1
#define GAMEMODE_COMPUTER 2
// Game setup
#define TRIES_COUNT 6
#define WORD_LENGHT 5
/**
* @brief Set the gamemode
*
......@@ -13,4 +20,18 @@
*/
void set_gamemode(int menu_gamemode);
/**
* @brief Launch the game
*
*/
void launch_game();
/**
* @brief Is the game finished
*
* @return true
* @return false
*/
bool game_finished();
#endif
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment