27int main(
int argc,
char** argv) {
83 printf(
"The terminal's host is not supported. Please, use Windows Terminal App.\n");
90 SetConsoleOutputCP(CP_UTF8);
95 int maxRows = 0, maxColumns = 0;
103 HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
104 if (hSnapshot == INVALID_HANDLE_VALUE)
107 DWORD processId = GetCurrentProcessId();
108 while (processId != 0) {
110 pe32.dwSize =
sizeof(PROCESSENTRY32);
113 if (Process32First(hSnapshot, &pe32)) {
115 if (pe32.th32ProcessID == processId) {
116 if(strcmp(pe32.szExeFile,
"WindowsTerminal.exe") == 0)
119 processId = pe32.th32ParentProcessID;
123 }
while (Process32Next(hSnapshot, &pe32));
127 CloseHandle(hSnapshot);
131 if (processId == 0) {
132 CloseHandle(hSnapshot);
137 CloseHandle(hSnapshot);
145 return rand()%(max - min + 1) + min;
159 printgr(
"#b#Can the players have the cards with the same rank? (y,Y,n,N) #r#");
161 int _ = scanf(
"%c", &opt);
162 }
while(opt !=
'y' && opt !=
'Y' && opt !=
'n' && opt !=
'N');
172 printgr(
"#b#Can the players have the cards with the same suit? (y, Y, n, N) #r#");
174 int _ = scanf(
"%c", &opt);
175 }
while(opt !=
'y' && opt !=
'Y' && opt !=
'n' && opt !=
'N');
179 if(n < 0 && n != -1) {
184 printgr(
"#b#How many LPs on the field should there be by default? #r#");
186 const int a = scanf(
"%d", &n);
194 if(n <= 0 && n != -1) {
199 printgr(
"#b#How many LPs should the players have by default? #r#");
201 const int a = scanf(
"%d", &n);
213 int playersCounter = 2;
216 if(playersCounter < 2 || playersCounter > 20) {
223 printgr(
"#b#Please, insert the players number: #r#");
224 int _ = scanf(
"%d", &playersCounter);
225 }
while(playersCounter < 2 || playersCounter > 20);
227 return playersCounter;
240 Card* deck = malloc(
sizeof(
Card)*40);
244 for(
int i = 0; i < 40; i++)
286 for(
int i = 0; i < playersCounter; i++)
298 for(
int i = 0; i < 40; i++) {
355 for(
int i = 39; i > 0; i--) {
367 int maxRows = 0, maxColumns = 0, totalPages = 0, bestStartColumn = 0;
380 printfgr(
"The current phase starts from #b#player %d#r#.", game->
players[starterPlayerPosition]->
id);
387 navigatePages(pages, totalPages, maxRows, maxColumns, bestStartColumn, position, game);
402 printgr(
"#b#The card has not been revealed#r#.\n");
404 printfgr(
"#b#Player %d#r#, your #b#faced down card#r# has been #b##%d#already revealed#r#!\n",
id,
FgBrightRed);
432 printfgr(
"#b#Player %d's faced down card#r# has been #b##%d#already revealed#r#! #b#No effect by the last card has been applied#r#.", player->
id,
FgBrightRed);
446 printfgr(
"By the effect of the #b#player %d's faced %s card#r# now on the #b#playing field#r# there are #b##%d#%d LPs#r#.", player->
id, facedUpCard ?
"up" :
"down",
FgGreen, game->
lifePointsOnTheField);
461 for(
int i = 0; i < 137; i++)
497 printfgr(
"By the effect of the #b#player %d's faced %s card#r# now on the #b#playing field#r# there are #b##%d#0 LPs#r#.", player->
id, facedUpCard ?
"up" :
"down",
FgBrightYellow);
507 printfgr(
"#b#No effect by the player %d's faced %s card has been applied#r#.", player->
id, facedUpCard ?
"up" :
"down");
523 printgr(
"Do you want to #b#reveal#r# your #b#faced down#r# card and #b#apply its effect#r#?? (y,Y,n,N) ");
524 int _ = scanf(
"%c", &ans);
525 }
while(ans !=
'Y' && ans !=
'N' && ans !=
'y' && ans !=
'n');
529 return ans ==
'Y' || ans ==
'y';
579 players[p++] = game->
players[i];
601 for(
int i = 0; i < 40; i++)
613 for(
int i = 0; i < playersCounter; i++)
614 if(players[i]->lifePoints > 0)
623 printgr(
"you drop #b#1 LP#r# to the #b#playing field#r#.");
627 printgr(
"you force the #b#next player#r# to reveal #b#his faced down card#r# and #b#apply its effect#r#.");
629 printgr(
"you give #b#1 LP#r# to the #b#previous player#r#.");
631 printgr(
"you give #b#1 LP#r# to the #b#second following player#r#.");
633 printgr(
"you claim #b#all#r# the #b#LPs#r# on the playing field.");
640 printfgr(
"Player %d #b#faced %s#r# card is a #b#", playerId, facedUp ?
"up" :
"down");
642 printgr(
"#r#, the effect is: ");
656 printgr(
" #b#faced down#r# card is a #b#");
657 printCard(card, logsConfiguration,
false);
659 printgr(
"#r#. The effect is: ");
Implemented following https://en.wikipedia.org/wiki/ANSI_escape_code.
void Pause(bool clear)
Waits for the user to press a key without waiting for 'Enter' to be pressed.
void printgr(const char *text)
Prints a text with the graphic rendition specified with custom graphic rendition format specifiers.
void eraseInDisplay(int n)
Clears part of the screen.
void cursorHorizontalAbsolute(int n)
Moves the cursor to column n.
void cursorPosition(int n, int m)
Moves the cursor at n-th row and at the m-th column.
void screenSize(int *width, int *height)
It returns the width and the height of the screen. On unix-like platforms, in case of errors,...
void clearScreen()
Clears the entire terminal's window's content.
void scrollUp(int n)
Scrolls the whole page up by n rows.
void printfgr(char *text,...)
Prints text as printgr but handles standard C format specifiers %, d, i, u, x, X, f,...
Declaration of constant values for ANSI module.
#define FgBrightYellow
ANSI standard bright yellow foreground color.
#define FgBrightCyan
ANSI standard bright cyan foreground color.
#define FgBrightRed
ANSI standard bright red foreground color.
#define FgGreen
ANSI standard green foreground color.
#define FgBrightGreen
ANSI standard bright green foreground color.
GameConfiguration getConfigurationFromArguments(char **argv, const int argc)
Generates a game configuration from the given options. If some options are not specified,...
int handleCLIArguments(char **argv, const int argc)
It validates and intreprets the CLI options.
GameConfiguration getGameConfiguration(const int code, const GameConfiguration cliGameConfiguration)
Gets the game configuration based on the action code. If action code is ACTION_HELP,...
#define EXIT_WINDOWS_TERMINAL_HOST_NOT_SUPPORTED
Exit code when the terminal's host process, on Windows, is not supported.
#define EXIT_TERMINAL_TOO_SMALL
Exit code when the terminal is too small for the TUI.
#define EXIT_ALLOC_FAILURE
Exit code when dynamic memory allocation fails.
Definition of logger functions.
void printPlayers(Game game, bool newLine)
Prints user-friendly the players' infos.
void printPageData(PageData pages[], LogsConfiguration logsConfiguration, int totalPages, bool newLine)
Prints user-friendly the pages' infos.
void printGameConfiguration(GameConfiguration gameConfiguration, LogsConfiguration logsConfiguration, bool newLine)
Prints user-friendly game configuration settings.
void printCard(Card card, LogsConfiguration logsConfiguration, bool newLine)
Prints user-friendly the card rank and suit.
LogsConfiguration prepareLogs()
Generates the logger configuration for the current session. Tries to generate the log file.
void giveCards(Game *game, Card *deck)
Assigns new cards to the player. It is not guaranteed that the old cards might be reassigned to the s...
Card * prepareCardDeck()
Generates a deck with cards ordered randomly. It is guaranteed that no duplicated cards occurs in the...
bool cardAreEqual(Card card1, Card card2)
Checks if two cards are equal.
bool isGameEnded(Game *game)
Determines whether the game is ended.
void shuffleDeck(Card *deck)
Shuffles the deck using Fisher - Yates algorithm.
Card * buildDeck()
Generates a deck.
void printCardEffect(Card card, bool newLine)
Prints user-friendly the card's effect.
bool handleGamePhase(Game *game)
Handles the current game phase.
int main(int argc, char **argv)
Player * buildPlayer()
Generates a player.
bool cardsWereGiven(Player **players, int playersCounter, Player player)
Checks if the cards of a given player have been already given to other players.
void freeGame(Game *game)
Frees a game structure.
Card buildCard()
Generates a card.
bool revealFacedDownCard(Card card)
Asks to the player if he wants to reveal the faced down card.
Game prepareGame(int playersCounter, Card *deck, GameConfiguration gameConfiguration, LogsConfiguration logsConfiguration)
Generates a game structure with the given players number and with the given data gave by the game con...
void freePlayer(Player *player)
Frees a player.
bool checkTerminalSize()
Checks if the terminal size is suitable for the TUI (Terminal User Interface).
void setupTerminal()
On Windows, configures that the terminal such that it supports UTF-8 encoded chars.
void revealCard(Card card, int playerId, bool facedUp, bool newLine)
Prints user-friendly the card revealed from a player.
Game buildGame(int playersCounter)
Generates a game with the given number of players.
int randomInt(const int min, const int max)
Generates a random number in the range (inclusive).
void announceWinner(Player player)
Announces the winner.
bool applyEffect(Game *game, int playerPosition, bool facedUpCard)
Applies the effect of the player at the given index in the players vector.
bool checkTerminalHost()
On Windows, it checks if the terminal's host process is supported.
void freePlayers(Player **players, int playersCounter)
Free all the players in the vector.
void checkTerminal()
Checks if the terminal size is suitable for the TUI (Terminal User Interface); if the terminal it is ...
int askPlayerNumber()
Asks the number of players to the user.
void removeDeadPlayers(Game *game)
Removes the dead players from the players vector.
void withdrawCards(Game *game)
Generates via the function buildCard new cards that are given to the players.
void tellFacedDownCard(Card card, int playerId)
Prints user-friendly the faced down card revealed of the player.
GameConfiguration askConfigurationOptionsViaTerminal()
Asks to the user via terminal the game configuration.
bool deckHasCard(Card *deck, Card card)
Checks if a card is present in a deck.
void announceDeadPlayers(Game *game)
Announces the dead players.
int countDeadPlayers(Game *game)
Counts how many dead players there are in the players vector.
void freeDeck(Card *deck)
Frees the cards deck.
Player * preparePlayer(int id, Card *deck, GameConfiguration configuration)
Generates a player structure with the given player id and with the given data gave by the game config...
Declaration of game-related constants, definition of game-related structures and functions.
bool cardAreEqual(Card card1, Card card2)
Checks if two cards are equal.
#define Seven
Integer const to represent rank seven.
Player * buildPlayer()
Generates a player.
#define Jack
Integer const to represent rank jack.
#define Ace
Integer const to represent rank ace.
#define Clubs
Integer const to represent suit clubs.
#define Hearts
Integer const to represent suit hearts.
#define Six
Integer const to represent rank six.
#define Queen
Integer const to represent rank queen.
#define King
Integer const to represent rank king.
#define Two
Integer const to represent rank two.
Defines a structure for the cards.
unsigned int rank
The rank of the card.
unsigned int suit
The suit of the card.
The game configuration structure.
bool allowSameRank
Determines if a player can have cards with the same rank. It increases randomness if set to false.
bool useTui
Determines if the gama has to use the terminal user interface (TUI).
int defaultLPsOnField
The default amount of LPs on the playing field at the beginning of a match.
bool beVerbose
Determines if the program has to have a verbose logging behaviour.
int defaultPlayersLPs
The default amount of LPs that every player have at the beginning of a match.
bool allowSameSuit
Determines if a player can have cards with the same suit It increases randomness if set to false.
Defines a structure for the game.
unsigned int lifePointsOnTheField
The amount of LPs currently on the playing field.
GameConfiguration gameConfiguration
The configuration for the game.
unsigned int playersCounter
The amount of players currently alive.
Player ** players
The currently alive players vector.
LogsConfiguration logsConfiguration
The configuration for the logs, if the game has to be verbose.
The configuration for the logger.
Struct to represent the layout and data of a page containing player information.
Defines a structure for the player's info.
Card facedDownCard
The faced down card.
bool revealedFacedDownCard
Flag for recording if the faced down card has been revealed; it can be toggled even if the faced down...
unsigned int lifePoints
The current player LPs.
unsigned int id
The player ID.
Card facedUpCard
The faced up card.
Terminal User Interface (TUI) implementation for card game display.
void drawPageFrame(int maxRows, int maxColumns)
Draws the frame for a page, including borders and separators.
PageData * getPageData(int maxRows, int maxColumns, Player **players, int totalPlayers, int *totalPages, int *bestStartColumn)
Computes the page layout for players and allocates memory for the page data.
void freePageData(PageData *pages, int totalPages)
Frees the memory allocated for page data.
bool isTerminalSizeValid(int maxRows, int maxColumns)
Checks if the terminal size meets the minimum requirements.
#define LOG_SECTION_HEIGHT
Integer const to represent the height of the logs section.
void navigatePages(PageData *pagesData, int totalPages, int maxRows, int maxColumns, int bestStartColumn, int playerIndex, Game *game)
Navigates between pages and handles player actions during their turn.