/* * Simon-Says * * This games plays a series of tones/lamp combinations, which the * player has to repeat. After each successful games, the series * increases in length. ESCAPE exits. * * Copyright 1994-1995 Dave Dunfield * All rights reserved. * * Compile command: cc simon -fop */ #include #include #define LAMPS 9 /* Number of lamps to play */ #define GAME_PAUSE 1000 /* Delay between games */ #define LAMP_PAUSE 50 /* Delay between lamp/beeps */ #define TONE_LENGTH 500 /* Length of beeps (in MS) */ #define FAIL_TONE1 75 /* Fail beep #1 value */ #define FAIL_TONE2 50 /* Fail beep #2 value */ #define PASS_TONE1 1100 /* Pass beep #1 value */ #define PASS_TONE2 1200 /* Pass beep #2 value */ extern unsigned RAND_SEED; /* Seed for random number generator */ /* * Tone table to map beeps to lamps */ static unsigned lamp_beeps[] = { 200, 250, 300, 350, 400, 450, 500, 550, 600 }; /* * Play the "simon says" game */ main() { unsigned i, lamp, length, seed; /* Open a window and display the title */ wopen(0, 0, 80, 24, WSAVE|WCOPEN|NORMAL); wcursor_off(); wgotoxy(32, 0); *W_OPEN = REVERSE; wputs(" SIMON SAYS "); *W_OPEN = NORMAL; /* Draw the playing field */ wgotoxy(30, 6); xputs("7-----8-----8-----9"); wgotoxy(30, 7); xputs("| | | |"); wgotoxy(30, 8); xputs("| | | |"); wgotoxy(30, 9); xputs("| | | |"); wgotoxy(30, 10); xputs("4-----5-----5-----6"); wgotoxy(30, 11); xputs("| | | |"); wgotoxy(30, 12); xputs("| | | |"); wgotoxy(30, 13); xputs("| | | |"); wgotoxy(30, 14); xputs("4-----5-----5-----6"); wgotoxy(30, 15); xputs("| | | |"); wgotoxy(30, 16); xputs("| | | |"); wgotoxy(30, 17); xputs("| | | |"); wgotoxy(30, 18); xputs("1-----2-----2-----3"); /* Randomize the random number generator */ get_time(&i, &lamp, &seed); RAND_SEED = (i*3600) + (lamp*60) + seed; length = 1; /* First game is 1 beep */ for(;;) { seed = RAND_SEED; /* Record position in series */ retry: delay(GAME_PAUSE); wgotoxy(0, 1); wprintf("Length = %u ", length); RAND_SEED = seed; /* Save so we can reset */ for(i=0; i < length; ++i) { /* Play the series */ light_lamp(lamp = random(LAMPS)); beep(lamp_beeps[lamp], TONE_LENGTH); light_lamp(-1); delay(LAMP_PAUSE); } light_lamp(-1); wgotoxy(60, 1); wputs("Your turn."); wcleol(); RAND_SEED = seed; /* Reset position in series */ for(i=0; i < length; ++i) { if((lamp = get_key()) > LAMPS) {/* Test for exit key */ wclose(); return -1; } if(random(LAMPS) != lamp) { /* Does this one match? */ light_lamp(-1); wgotoxy(60, 1); wputs("Try again..."); wcleol(); for(i=0; i < 2; ++i) { beep(FAIL_TONE1, TONE_LENGTH/2); beep(FAIL_TONE2, TONE_LENGTH/2); } goto retry; } light_lamp(lamp); beep(lamp_beeps[lamp], TONE_LENGTH); light_lamp(-1); } wgotoxy(60, 1); wputs("You got it!"); wcleol(); for(i=0; i < 2; ++i) { /* We did it! Celebrate */ beep(PASS_TONE1, TONE_LENGTH/2); beep(PASS_TONE2, TONE_LENGTH/2); } ++length; } } /* * Light lamp from indicated lamp code (-1 = all lamps off) */ light_lamp(int lamp) { int i, x, y; for(i=0; i < LAMPS; ++i) { x = i % 3; y = i / 3; if(i == lamp) *W_OPEN = REVERSE; wgotoxy((x*6)+31, (y*4)+7); wputs(" "); wgotoxy((x*6)+31, (y*4)+8); wputs(" "); wputc(i+'1'); wputs(" "); wgotoxy((x*6)+31, (y*4)+9); wputs(" "); *W_OPEN = NORMAL; } } /* * Get a key. Return 0-LAMPS, or LAMPS+1 for exit */ get_key() { int i; for(;;) switch(i = toupper(wgetc())) { case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : return i - '1'; case 0x1B : return LAMPS+1; } } /* * Write to window with graphic character translations * Use '|' for vertical bar, '-' for horizontal bar, * Corners, sides and crosses use corresponding digits * from PC numeric keypad. */ xputs(char *ptr) { char c; for(;;) { switch(c = *ptr++) { case 0 : return; case '-' : c = 0xC4; break; case '|' : c = 0xB3; break; case '1' : c = 0xC0; break; case '2' : c = 0xC1; break; case '3' : c = 0xD9; break; case '4' : c = 0xC3; break; case '5' : c = 0xC5; break; case '6' : c = 0xB4; break; case '7' : c = 0xDA; break; case '8' : c = 0xC2; break; case '9' : c = 0xBF; } wputc(c); } }