Skip to content

Instantly share code, notes, and snippets.

@rkulla
Created March 21, 2014 02:07
Show Gist options
  • Save rkulla/9678119 to your computer and use it in GitHub Desktop.
Save rkulla/9678119 to your computer and use it in GitHub Desktop.
Lottery number generator with an ncurses interface
/* curslotto.c
* Lotto number generator -by Ryan Kulla
* Compile with: gcc -o curslotto curslotto.c -lncurses
*
* Lottery number generator
*
* Usage: curslotto <num1> <num2> <num3> <num4> <num5> <num6> [slow]
*
* Examples:
*
* $ ./curslotto 1 2 3 44 50 52
*
* 2547989 tries. Your numbers were 1 2 3 44 50 52
*
* Took 2 dollars to get 1 match
* Took 7 dollars to get 2 matches
* Took 272 dollars to get 3 matches
* Took 1535 dollars to get 4 matches
* Took 255321 dollars to get 5 matches
* ...
*
* That will loop through random numbers as quickly as possible to show you how
* much money you spent to ge 1, 2, 3, 4, 5 and 6 matches. Assuming that a lotto
* ticket cost $1.00 and there's 6 numbers total with the highest number being 52.
*
* $ ./curslotto 1 2 3 44 50 52 slow
*
* That will do the same thing but slowly so you can really see what's happening.
*
* I also like to run the 'time' command on this so you can see how long the program
* took to get all 6 numbers:
*
* $ time ./curslotto 1 2 3 44 50 52
*
* To close the program early hit Ctrl+C.
*/
#include <curses.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
enum {
MAX_NUMBERS = 6,
HIGHEST_NUMBER = 52,
POSITION_TITLE_Y = 2,
POSITION_TITLE_X = 33,
POSITION_EXIT_MSG_Y = 22,
POSITION_EXIT_MSG_X = 1,
POSITION_TOP_OF_TUBE_Y = 3,
POSITION_TOP_OF_TUBE_X = 25,
DISPLAY_BOTTOM_OF_TUBE_POSITION_Y = 6,
POSITION_INSIDE_TUBE = 5,
POSITION_SCROLL_START_X = 75,
SCROLL_BACKWARD_AMOUNT = 50,
SCROLL_DECREMENT_AMOUNT = 5,
DELAY_MILLISECONDS = 100,
};
typedef struct {
int count,
matching_numbers,
matched_one,
matched_two,
matched_three,
matched_four,
matched_five,
slow_mode,
random_num,
number[MAX_NUMBERS],
my_numbers[MAX_NUMBERS];
} lotto;
lotto generate_lotto_numbers(lotto picks);
lotto check_arguments(int argc, char **argv, lotto picks);
int is_unique_pick(lotto picks);
int is_in_numbers(int *, int);
void scroll_numbers(lotto picks);
void animate(int scroll_amount, int number);
void delay(int milliseconds);
void display_title(void);
void display_lotto_tube(void);
void display_quit_message(void);
void quit_cleanly(void);
int main(int argc, char **argv) {
lotto picks = {0, 0, 0, 0, 0, 0, 0, 0};
int tries = 1;
picks = check_arguments(argc, argv, picks);
srand(time(NULL)); // Seed once for psuedo-random number generator
initscr();
curs_set(FALSE);
if (picks.slow_mode) {
display_title();
display_lotto_tube();
}
while (1) {
picks = generate_lotto_numbers(picks);
mvprintw(8, 1, "%d tries. Your numbers were %d %d %d %d %d %d.\n",
tries++,
picks.my_numbers[0], picks.my_numbers[1], picks.my_numbers[2],
picks.my_numbers[3], picks.my_numbers[4], picks.my_numbers[5]);
if (picks.slow_mode) {
scroll_numbers(picks);
} else {
delay(0);
}
if (picks.matching_numbers == 1 && !picks.matched_one) {
mvprintw(10, 1, "Took %d dollars to get 1 match", tries);
picks.matched_one = 1;
}
if (picks.matching_numbers == 2 && !picks.matched_two) {
mvprintw(11, 1, "Took %d dollars to get 2 matches", tries);
picks.matched_two = 1;
}
if (picks.matching_numbers == 3 && !picks.matched_three) {
mvprintw(12, 1, "Took %d dollars to get 3 matches", tries);
picks.matched_three = 1;
}
if (picks.matching_numbers == 4 && !picks.matched_four) {
mvprintw(13, 1, "Took %d dollars to get 4 matches", tries);
picks.matched_four = 1;
}
if (picks.matching_numbers == 5 && !picks.matched_five) {
mvprintw(14, 1, "Took %d dollars to get 5 matches", tries);
picks.matched_five = 1;
}
if (picks.matching_numbers == 6) {
mvprintw(15, 1, "Took %d dollars to get all 6 matches", tries);
break;
}
picks.count = 0;
picks.matching_numbers = 0;
}
display_quit_message();
quit_cleanly();
return 0;
}
void quit_cleanly(void) {
refresh();
endwin();
}
lotto check_arguments(int argc, char **argv, lotto picks) {
if (argc < 7) {
printf("Please enter 6 arguments, corresponding to your numbers\n");
printf("An optional 7th argument of \"slow\" will slow things down\n");
quit_cleanly();
exit(EXIT_FAILURE);
}
picks.my_numbers[0] = atoi(argv[1]);
picks.my_numbers[1] = atoi(argv[2]);
picks.my_numbers[2] = atoi(argv[3]);
picks.my_numbers[3] = atoi(argv[4]);
picks.my_numbers[4] = atoi(argv[5]);
picks.my_numbers[5] = atoi(argv[6]);
if (argc > 7 && !strcasecmp(argv[7], "slow")) {
picks.slow_mode = 1;
}
return picks;
}
void display_title(void) {
mvprintw(POSITION_TITLE_Y, POSITION_TITLE_X, "Lotto Numbers: ");
}
void display_lotto_tube(void) {
char const *tube_line = "_______________________________";
mvprintw(POSITION_TOP_OF_TUBE_Y, POSITION_TOP_OF_TUBE_X, tube_line);
mvprintw(DISPLAY_BOTTOM_OF_TUBE_POSITION_Y, POSITION_TOP_OF_TUBE_X, tube_line);
}
lotto generate_lotto_numbers(lotto picks) {
lotto *gen = &picks;
while (picks.count < MAX_NUMBERS) {
// We + 1 the result to never get 0
gen->random_num = (int)rand() % (HIGHEST_NUMBER) + 1;
if (!is_unique_pick(picks)) {
continue;
}
gen->number[picks.count++] = picks.random_num;
if (is_in_numbers(picks.my_numbers, picks.random_num)) {
gen->matching_numbers++;
}
}
return picks;
}
int is_in_numbers(int *haystack, int needle) {
unsigned short int i;
for (i = 0; i < sizeof haystack; i++) {
if (needle == haystack[i]) {
return 1;
}
}
return 0;
}
int is_unique_pick(lotto picks) {
unsigned short int i;
for (i = 0; i < picks.count; i++) {
if (picks.random_num == picks.number[i]) {
return 0;
}
}
return 1;
}
void scroll_numbers(lotto picks) {
unsigned short int i, j;
for (i = 0, j = SCROLL_BACKWARD_AMOUNT; i < MAX_NUMBERS; i++) {
animate(j, picks.number[i]);
j -= SCROLL_DECREMENT_AMOUNT;
}
}
void animate(int scroll_amount, int number) {
unsigned short int i, x;
for (i = 0, x = POSITION_SCROLL_START_X; i < scroll_amount; i++) {
mvprintw(POSITION_INSIDE_TUBE, x--, "(%d) ", number);
delay(DELAY_MILLISECONDS);
}
}
void delay(int milliseconds) {
napms(milliseconds);
refresh();
}
void display_quit_message(void) {
mvprintw(POSITION_EXIT_MSG_Y, POSITION_EXIT_MSG_X, "press any key to exit...");
getch();
addch('\n');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment