Survival Royale 1.0.0
A very simple yet funny card game.
Loading...
Searching...
No Matches
cli.c
Go to the documentation of this file.
1// Copyright (C) 2025 Giulio Salvi, Jacopo Paradisi
2//
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program. If not, see <https://www.gnu.org/licenses/>.
15
20
21#include "cli.h"
22
23void getHelp(const char* scope) {
24 printf("game [--help [option]] | [--go] [--dont-ask-config-options] [--ignore-config-file] [--save-to-file] [--use-tui] [--verbose] [--default-player-LPs <LPs>] [--default-LPs-field <LPs>] [--allow-same-rank <false|true>] [--allow-same-suit <false|true>]\n\n");
25
26 if(strcmp(scope, "generic") == 0 || strlen(scope) == 0) {
27 printf("--help [option] (-h [option]):\n\tIf option is not given, then it shows this generic help message. Otherwise if option is given it shows an exhaustive help message for the given option.\n");
28
29 printf("--go (-g):\n\tIt starts a new game.\n");
30
31 printf("--dont-ask-config-options (-d):\n\tIt doesn't asks to the user the configuration options when the program starts.\n");
32
33 printf("--ignore-config-file (-c):\n\tIt ignores the configuration file, if it exists, so that the configuration options saved in it are not loaded.\n");
34
35 printf("--save-to-file (-S):\n\tSaves the configuration loaded to a configuration file.\n");
36
37 printf("--use-tui (-t):\n\tThe game will use the terminal user interface (TUI) when specified.\n");
38
39 printf("--verbose (-v):\n\tThe program has a verbose behaviour if this flag is specified. This option is not saved on file and it is not asked to the user.\n");
40
41 printf("--default-player-LPs <LPs> (-p <LPs>):\n\tSets with how many LPs players spawn.\n");
42
43 printf("--default-LPs-field <LPs> (-f <LPs>):\n\tSets how many LPs there are on the playing field at the beginning of the game.\n");
44
45 printf("--allow-same-rank <false|true> (-r <false|true>):\n\tSets if it is allowed for a player that its cards have the same rank.\n");
46
47 printf("--allow-same-suit <false|true> (-s <false|true>):\n\tSets if it is allowed for a player that its cards have the same suit.\n");
48 } else if(strcmp(scope, "help") == 0)
49 printf("--help [option] (-h [option]):\n\tIf option is not given, then it shows this generic help message. Otherwise if option is given it shows an exhaustive help message for the given option.\n");
50 else if(strcmp(scope, "go") == 0)
51 printf("--go (-g):\n\tIt starts a new game. The configuration is loaded from the file if it exists and unless --ignore-config-file has been specified. Otherwise it asks to the user when the program is running unless --dont-ask-config-options has been specified. If so, it uses the default configuration options.\n");
52 else if(strcmp(scope, "dont-ask-config-options") == 0)
53 printf("--dont-ask-config-options (-d):\n\tIt doesn't asks to the user the configuration options when the program starts.\n");
54 else if(strcmp(scope, "ignore-config-file") == 0)
55 printf("--ignore-config-file (-c):\n\tIt ignores the configuration file, if it exists, so that the configuration options saved in it are not loaded.\n");
56 else if(strcmp(scope, "save-to-file") == 0)
57 printf("--save-to-file (-S):\n\tSaves the configuration loaded to a configuration file.\n");
58 else if(strcmp(scope, "use-tui") == 0)
59 printf("--use-tui (-t):\n\tThe game will use the terminal user interface (TUI) when specified.\n");
60 else if(strcmp(scope, "verbose") == 0)
61 printf("--verbose (-v):\n\tThe program has a verbose behaviour if this flag is specified. This option is not saved on file and it is not asked to the user. It prints the game configuration when it is loaded and at the beginning of each phase prints the players informations.\n");
62 else if(strcmp(scope, "default-player-LPs") == 0)
63 printf("--default-player-LPs <LPs> (-p <LPs>):\n\tSets with how many LPs players spawn. If there exists the configuration file and it has not been ignored, the program considers this option instead of the file's option.\n\n\tNotice that also --default-playerLPs=<LPS> and -p=<LPs> are valid command syntaxes.\n");
64 else if(strcmp(scope, "default-LPs-field") == 0)
65 printf("--default-LPs-field <LPs> (-f <LPs>):\n\tSets how many LPs there are on the playing field at the beginning of the game. If there exists the configuration file and it has not been ignored, the program considers this option instead of the file's option.\n\n\tNotice that also --default-LPs-field=<LPs> and -f=<LPs> are valid command syntaxes.\n");
66 else if(strcmp(scope, "allow-same-rank") == 0)
67 printf("--allow-same-rank <false|true> (-r <false|true>):\n\tSets if it is allowed for a player that its cards have the same rank. If there exists the configuration file and it has not been ignored, the program considers this option instead of the file's option.\n\n\tNotice that also --allow-same-rank=<false|true> and -r=<false|true> are valid command syntaxes.\n");
68 else if(strcmp(scope, "allow-same-suit") == 0)
69 printf("--allow-same-suit <false|true> (-s <false|true>):\n\tSets if it is allowed for a player that its cards have the same suit. If there exists the configuration file and it has not been ignored, the program considers this option instead of the file's option.\n\n\tNotice that also --allow-same-suit=<false|true> and -s=<false|true> are valid command syntaxes.\n");
70}
71
72int handleCLIArguments(char** argv, const int argc) {
73 if(argc == 1 || ((strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0) && argc == 2)) {
74 getHelp("generic");
75 return ACTION_HELP;
76 } else if(argc >= 3 && (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0)) {
77 if(strcmp(argv[2], "--help") == 0 || strcmp(argv[2], "-h") == 0 || strcmp(argv[2], "help") == 0 || strcmp(argv[2], "h") == 0)
78 getHelp("help");
79 else if(strcmp(argv[2], "--go") == 0 || strcmp(argv[2], "-g") == 0 || strcmp(argv[2], "go") == 0 || strcmp(argv[2], "g") == 0)
80 getHelp("go");
81 else if(strcmp(argv[2], "--dont-ask-config-options") == 0 || strcmp(argv[2], "-d") == 0 || strcmp(argv[2], "dont-ask-config-options") == 0 || strcmp(argv[2], "d") == 0)
82 getHelp("dont-ask-config-options");
83 else if(strcmp(argv[2], "--ignore-config-file") == 0 || strcmp(argv[2], "-c") == 0 || strcmp(argv[2], "ignore-config-file") == 0 || strcmp(argv[2], "c") == 0)
84 getHelp("ignore-config-file");
85 else if(strcmp(argv[2], "--save-to-file") == 0 || strcmp(argv[2], "-S") == 0 || strcmp(argv[2], "save-to-file") == 0 || strcmp(argv[2], "S") == 0)
86 getHelp("save-to-file");
87 else if(strcmp(argv[2], "--use-tui") == 0 || strcmp(argv[2], "-t") == 0 || strcmp(argv[2], "use-tui") == 0 || strcmp(argv[2], "t") == 0)
88 getHelp("use-tui");
89 else if(strcmp(argv[2], "--verbose") == 0 || strcmp(argv[2], "-v") == 0 || strcmp(argv[2], "verbose") == 0 || strcmp(argv[2], "v") == 0)
90 getHelp("verbose");
91 else if(strcmp(argv[2], "--default-player-LPs") == 0 || strcmp(argv[2], "-p") == 0 || strcmp(argv[2], "default-player-LPs") == 0 || strcmp(argv[2], "p") == 0)
92 getHelp("default-player-LPs");
93 else if(strcmp(argv[2], "--default-LPs-field") == 0 || strcmp(argv[2], "-f") == 0 || strcmp(argv[2], "default-LPs-field") == 0 || strcmp(argv[2], "f") == 0)
94 getHelp("default-LPs-field");
95 else if(strcmp(argv[2], "--allow-same-rank") == 0 || strcmp(argv[2], "-r") == 0 || strcmp(argv[2], "allow-same-rank") == 0 || strcmp(argv[2], "r") == 0)
96 getHelp("allow-same-rank");
97 else if(strcmp(argv[2], "--allow-same-suit") == 0 || strcmp(argv[2], "-s") == 0 || strcmp(argv[2], "allow-same-suit") == 0 || strcmp(argv[2], "s") == 0)
98 getHelp("allow-same-suit");
99 else {
100 printf("Illegal CLI arguments: help option was not recognized.\n");
101 exit(EXIT_CLI_ILLEGAL);
102 }
103
104 return ACTION_HELP;
105 } else {
106 int code = ACTION_NOTHING;
107
108 for(int i = 1; i < argc; i++) {
109 if(strcmp(argv[i], "--go") == 0 || strcmp(argv[i], "-g") == 0)
110 code += ACTION_GO;
111 else if(strcmp(argv[i], "--dont-ask-config-options") == 0 || strcmp(argv[i], "-d") == 0)
113 else if(strcmp(argv[i], "--ignore-config-file") == 0 || strcmp(argv[i], "-c") == 0)
115 else if(strcmp(argv[i], "--save-to-file") == 0 || strcmp(argv[i], "-S") == 0)
116 code += ACTION_SAVE_TO_FILE;
117 else if(strcmp(argv[i], "--use-tui") == 0 || strcmp(argv[i], "-t") == 0)
118 code += ACTION_USE_TUI;
119 else if(strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0)
120 code += ACTION_BE_VERBOSE;
121 }
122
123 if(code == ACTION_NOTHING) {
124 printf("Illegal CLI argument: not recognized argument%c.\n", argc > 2 ? 's' : 0);
125 exit(EXIT_CLI_ILLEGAL);
126 } else if(code - ACTION_GO < 0) {
127 printf("Illegal CLI arguments: --go option must be passed with options --dont-ask-config-options and --ignore-config-file.\n");
128 exit(EXIT_CLI_ILLEGAL);
129 }
130
131 return code - ACTION_GO;
132 }
133}
134
137
138 for(int i = 1; i < argc; i++) {
139 if(
140 containsSubstringFrom(argv[i], "--default-player-LPs", 0) ||
141 containsSubstringFrom(argv[i], "-p", 0) ||
142 containsSubstringFrom(argv[i], "--default-LPs-field", 0) ||
143 containsSubstringFrom(argv[i], "-f", 0) ||
144 containsSubstringFrom(argv[i], "--allow-same-rank", 0) ||
145 containsSubstringFrom(argv[i], "-r", 0) ||
146 containsSubstringFrom(argv[i], "--allow-same-suit", 0) ||
147 containsSubstringFrom(argv[i], "-s", 0)
148 ) {
149 char* optionName = "";
150 char* optionValue = "";
151
152 if(containsFrom(argv[i], '=', 0)) {
153 const int equalPosition = offsetFromNext(argv[i], '=', 0);
154 optionName = substring(argv[i], 0, equalPosition);
155 optionValue = substring(argv[i], equalPosition + 1, strlen(argv[i]) - equalPosition - 1);
156 } else {
157 optionName = argv[i];
158 optionValue = argv[i + 1];
159
160 i++;
161 }
162
163 errno = 0;
164 char* endptr;
165 if(strcmp(optionName, "--default-player-LPs") == 0 || strcmp(optionName, "-p") == 0) {
166 int n = strtol(optionValue, &endptr, 10);
167
168 if(errno == ERANGE || *endptr != '\0') {
169 printf("Illegal CLI arguments: a number was expected.\n");
170 exit(EXIT_CLI_ILLEGAL);
171 }
172
173 cfg.defaultPlayersLPs = n;
174 } else if(strcmp(optionName, "--default-LPs-field") == 0 || strcmp(optionName, "-f") == 0) {
175 int n = strtol(optionValue, &endptr, 10);
176
177 if(errno == ERANGE || *endptr != '\0') {
178 printf("Illegal CLI arguments: a number was expected.\n");
179 exit(EXIT_CLI_ILLEGAL);
180 }
181
182 cfg.defaultLPsOnField = n;
183 } else if(strcmp(optionName, "--allow-same-rank") == 0 || strcmp(optionName, "-r") == 0) {
184 if(strcmp(optionValue, "true") == 0 || strcmp(optionValue, "false") == 0)
185 cfg.allowSameRank = strcmp(optionValue, "true") == 0;
186 else {
187 printf("Illegal CLI arguments: true or false were expected.\n");
188 exit(EXIT_CLI_ILLEGAL);
189 }
190 } else if(strcmp(optionName, "--allow-same-suit") == 0 || strcmp(optionName, "-s") == 0) {
191 if(strcmp(optionValue, "true") == 0 || strcmp(optionValue, "false") == 0)
192 cfg.allowSameSuit = strcmp(optionValue, "true") == 0;
193 else {
194 printf("Illegal CLI arguments: true or false were expected.\n");
195 exit(EXIT_CLI_ILLEGAL);
196 }
197 }
198 }
199 }
200
201 return cfg;
202}
GameConfiguration getConfigurationFromArguments(char **argv, const int argc)
Generates a game configuration from the given options. If some options are not specified,...
Definition cli.c:135
int handleCLIArguments(char **argv, const int argc)
It validates and intreprets the CLI options.
Definition cli.c:72
void getHelp(const char *scope)
Prints the generic help message or a detailed help message describing a particular option.
Definition cli.c:23
Definition of functions which handles CLI.
#define ACTION_BE_VERBOSE
With this action code, the program has a verbose logging behaviour.
Definition consts.h:43
#define EXIT_CLI_ILLEGAL
Exit code when the CLI options are illegal.
Definition consts.h:28
#define ACTION_SAVE_TO_FILE
With this action code, the program saves the used game configuration to file.
Definition consts.h:41
#define ACTION_GO
With this action code, the program starts a match.
Definition consts.h:47
#define ACTION_HELP
With this action code, the program has printed help messages.
Definition consts.h:49
#define ACTION_IGNORE_CONFIG_FILE
With this action code, the program ignores the configuration file when loading the game configuration...
Definition consts.h:37
#define ACTION_USE_TUI
With this action code, the program will use te terminal user interface (TUI) when specified.
Definition consts.h:45
#define ACTION_DONT_ASK_CONFIG_OPTIONS
With this action code, the program does not ask to the user the game configuration when loading the g...
Definition consts.h:39
#define ACTION_NOTHING
With this action code, the program does nothing.
Definition consts.h:35
GameConfiguration getDefaultConfiguration()
Retrieves the default game configuration.
Definition config.c:23
The game configuration structure.
bool allowSameRank
Determines if a player can have cards with the same rank. It increases randomness if set to false.
int defaultLPsOnField
The default amount of LPs on the playing field at the beginning of a match.
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.
bool containsFrom(const char *string, char character, int startPosition)
Checks if there is an occoruncy of the passed char from the passed position in the passed string.
Definition utility.c:63
int offsetFromNext(const char *string, char character, int startPosition)
Counts the offset in the string between the position and the next occoruncy of the passed char.
Definition utility.c:38
char * substring(const char *string, int startPosition, int length)
Copies a substring (heap-allocated) from the passed string. If fails when allocating memory for the s...
Definition utility.c:23
bool containsSubstringFrom(const char *string, const char *subString, int startPosition)
Checks if there is an occoruncy of the passed substring from the passed position in the passed string...
Definition utility.c:75