Skip to content

Instantly share code, notes, and snippets.

@semahawk
Created November 17, 2015 13:47
Show Gist options
  • Save semahawk/212fab6592586d1b0503 to your computer and use it in GitHub Desktop.
Save semahawk/212fab6592586d1b0503 to your computer and use it in GitHub Desktop.
Fallout-like password-guessing game in C.
/* szomon :] */
/*
* Fallout-like password-guessing game.
*
* Copyright: Szymon Urbaś
* Licensed under the BSD (2-clause) license.
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#define ATTEMPTS 5
#define GODMODE 0
#define DEBUG 0
#define ARR_SIZE(a) (sizeof(a) / sizeof(*a))
int main(void)
{
char *passwords[] = {
/* works when passwords have different length
* but that's actually a dumb thing to do. */
"VIRAL",
"DARED",
"MINES",
"PARTS",
"LIKES",
"HAREM",
"THREW",
"SORTS",
"FARTS"
};
char input[256];
char *password;
unsigned count = 0;
int attempts = ATTEMPTS;
int occurrences[26] = { 0 };
int seen[26] = { 0 };
int n;
char *i, *p;
char **pp;
char *lf, *cr;
srand(time(NULL));
/* pick a random password */
password = passwords[rand() % ARR_SIZE(passwords)];
#if GODMODE
printf("GODMODE: password is %s\n\n", password);
#endif
/* print out the table with possible passwords */
for (n = 0; n < (ARR_SIZE(passwords) & ~1); n += 2){
printf(" 0x%08x %-7s", rand(), passwords[n + 0]);
printf(" 0x%08x %s\n", rand(), passwords[n + 1]);
}
/* print the 'odd' password if there's any */
if (ARR_SIZE(passwords) & 1){
printf(" 0x%08x %s\n", rand(), passwords[ARR_SIZE(passwords) - 1]);
}
printf("\n");
/* the actual guessing */
do {
/* zero-out */
count = 0;
memset(occurrences, 0, sizeof(occurrences));
memset(seen, 0, sizeof(seen));
/* print the number of attempts and the 'boxes' */
printf("%u attempt%s left! ", attempts, attempts == 1 ? "" : "s");
for (n = 0; n < attempts; n++) printf("#");
printf("\n");
/* print the prompt */
printf(" > ");
/* fetch the input */
fgets(input, 256, stdin);
/* chomp */
if ((lf = strrchr(input, '\n'))) *lf = '\0';
if ((cr = strrchr(input, '\r'))) *cr = '\0';
/* count how many times each letter in the alphabet appears in the
* password */
for (p = password; *p != '\0'; p++){
occurrences[tolower(*p) - 'a']++;
}
/* go over every character in the input.. */
for (i = input; *i != '\0'; i++){
/* ignore any non-alphabetic characters */
if (!isalpha(*i))
continue;
/* go over every character in the password and see if there's a match */
for (p = password; *p != '\0'; p++){
unsigned idx = tolower(*i) - 'a';
/* this bit is magic so I won't explain it */
if ((seen[idx] < occurrences[idx]) && (tolower(*i) == tolower(*p))){
#if DEBUG
printf("char '%c' in input is equal to char '%c' in password\n", *i, *p);
#endif
seen[idx]++;
count++;
break;
}
}
}
if (strcmp(input, password)){
printf("Incorrect! %u/%lu characters right\n", count, strlen(password));
} else {
printf("Exact match! +75XP\n");
return 0;
}
} while (--attempts);
if (!attempts){
printf("You have been temporarily locked out! Contact your's system administrator!\n");
return 1;
}
return 0;
}
/*
* vi: ft=c:ts=2:sw=2:expandtab
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment