Files
pkmn/pkmn.c
gauvain-thomas 8bbcfd967a Random pkmn
2024-02-18 15:24:39 +01:00

198 lines
5.1 KiB
C

#define SHINEY_PROB 8192
#include <stdlib.h>
#include <argp.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <regex.h>
const char *argp_program_version =
"pkmn 1.0";
const char *argp_program_bug_address =
"<gauvain.thomas@gmail.com>";
/* Program documentation. */
static char doc[] =
"Argp example #3 -- a program with options and arguments using argp";
/* A description of the arguments we accept. */
static char args_doc[] = "pokemon_name";
/* The options we understand. */
static struct argp_option options[] = {
{"random", 'r', 0, 0, "Use a random pokemon"},
{"shiney", 's', 0, 0, "Use a shiney pokemon"},
{"verbose", 'v', 0, 0, "Produce verbose output" },
{ 0 }
};
/* Used by main to communicate with parse_opt. */
struct arguments
{
char *args[1]; /* arg*/
int silent, verbose;
int random, shiney; /* random and shiney flags */
};
/* Parse a single option. */
static error_t
parse_opt (int key, char *arg, struct argp_state *state)
{
/* Get the input argument from argp_parse, which we
know is a pointer to our arguments structure. */
struct arguments *arguments = state->input;
switch (key)
{
case 'v':
arguments->verbose = 1;
break;
case 'r':
arguments->random = 1;
break;
case 's':
arguments->shiney = 1;
break;
case ARGP_KEY_ARG:
if (state->arg_num >= 1)
/* Too many arguments. */
argp_usage (state);
arguments->args[state->arg_num] = arg;
break;
case ARGP_KEY_END:
if (state->arg_num < 0)
/* Not enough arguments. */
argp_usage (state);
break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
/* Our argp parser. */
static struct argp argp = { options, parse_opt, args_doc, doc };
int pkmn_name_from_file(char *pokemon_file, char *pokemon_name) {
int BUFFER_SIZE = 512;
// A file is of the form "[S_][0-9][0-9][0-9]_pokemon.cow"
// We want to write the pokemon name in pokemon_name
// Using regex: s/^[S_]*[0-9]*_//g
// char *pokemon_file = "843_silicobra.cow";
char regex_pattern[] = "^[0-9]+_(([a-zA-Z]|-)+)\\.cow$"; // Regex pattern to match the Pokémon name
regex_t regex;
regmatch_t matches[100];
char match_buffer[BUFFER_SIZE];
int ret;
// Compile the regular expression
ret = regcomp(&regex, regex_pattern, REG_EXTENDED);
if (ret != 0) {
fprintf(stderr, "Failed to compile regex\n");
return 1;
}
// Execute the regular expression
ret = regexec(&regex, pokemon_file, 100, matches, 0);
if (ret == 0) {
// Extract the matched substring
int start = matches[1].rm_so;
int end = matches[1].rm_eo;
int match_length = end - start;
if (match_length < BUFFER_SIZE - 1) {
strncpy(match_buffer, pokemon_file + start, match_length);
match_buffer[match_length] = '\0';
strcpy(pokemon_name, match_buffer);
} else {
fprintf(stderr, "Match too long for buffer\n");
}
} else if (ret == REG_NOMATCH) {
fprintf(stderr, "No match found\n");
} else {
fprintf(stderr, "Regex match failed\n");
}
// Free the regex memory
regfree(&regex);
return 0;
}
int main (int argc, char **argv) {
struct arguments arguments;
char pkmn_path[] = "~/pokemons/";
/* Default values. */
arguments.verbose = 0;
arguments.random = 0;
arguments.shiney = 0;
// A pokemon has a 1/SHINEY_PROB chance of being shiney
srand(time(NULL));
arguments.shiney = (rand() % SHINEY_PROB) == 0;
/* Parse our arguments; every option seen by parse_opt will
be reflected in arguments. */
argp_parse (&argp, argc, argv, 0, 0, &arguments);
if (arguments.verbose) {
printf("ARG1 = %s\n", arguments.args[0]);
printf("VERBOSE = %s\n", arguments.verbose ? "yes" : "no");
printf("RANDOM = %s\n", arguments.random ? "yes" : "no");
printf("SHINEY = %s\n", arguments.shiney ? "yes" : "no");
}
char pokemon_file[512];
if (arguments.random) {
system("ls ~/pokemons/yes | shuf -n 1 > /tmp/pkmn");
FILE *f = fopen("/tmp/pkmn", "r");
fscanf(f, "%s", pokemon_file);
fclose(f);
if (arguments.verbose) {
printf("Random pokemon: %s\n", pokemon_file);
}
} else {
// TODO
exit(EXIT_FAILURE);
sprintf(pokemon_file, "%s%s", pkmn_path, arguments.args[0]);
}
if (arguments.shiney) {
// Append "S_" at the beginning of the file
char tmp[512];
sprintf(tmp, "S_%s", pokemon_file);
sprintf(pokemon_file, "%s", tmp);
if (arguments.verbose) {
printf("Shiney pokemon: %s\n", pokemon_file);
}
}
// Extract the pokemon name from the file
char pokemon_name[512];
pkmn_name_from_file(pokemon_file, pokemon_name);
if (arguments.verbose) {
printf("Pokemon file: %s\n", pokemon_file);
printf("Pokemon name: %s\n", pokemon_name);
}
// Execute the command echo "$pokemon_name!" | cowsay -f "$cow_file" -W 70
char command[1024];
if (arguments.shiney) {
sprintf(command, "echo \"Shiny %s!\" | cowsay -f %s%s -W 70", pokemon_name, pkmn_path, pokemon_file);
} else {
sprintf(command, "echo \"%s!\" | cowsay -f %syes/%s -W 70", pokemon_name, pkmn_path, pokemon_file);
}
system(command);
exit(EXIT_SUCCESS);
}