You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
428 lines
8.3 KiB
C
428 lines
8.3 KiB
C
/*
|
|
|
|
Codebreaker, Version 1.0, Sun May 13 13:49:18 GMT 2012
|
|
|
|
Copyright (c) 2012 All Rights Reserved, Egan Ford (egan@sense.net)
|
|
|
|
THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
|
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
PARTICULAR PURPOSE.
|
|
|
|
License:
|
|
* Public Domain.
|
|
* Do what you like, remember to credit all sources when using.
|
|
|
|
*/
|
|
|
|
#include <conio.h>
|
|
|
|
#define TIME ((count*59)/959790)
|
|
#define TENTHS ((count*59)/95979)
|
|
#define DEBUG 0
|
|
#define TOP 0
|
|
#define MIDDLE 1
|
|
#define BOTTOM 2
|
|
#define NOVICE 0
|
|
#define PRO 1
|
|
#define MASTER 2
|
|
#define TIMER 600
|
|
#define srand(x) next = (x)
|
|
|
|
extern void getkey();
|
|
extern void __fastcall__ putchar(char);
|
|
extern unsigned long count;
|
|
extern unsigned char key;
|
|
|
|
void drawboard(unsigned char);
|
|
void clearscreen();
|
|
void printnum(unsigned long, unsigned char, unsigned char);
|
|
void instructions();
|
|
int rand();
|
|
//void srand(unsigned int);
|
|
|
|
const char *title = "CODEBREAKER!\r\r\"CRACKED\" BY EGAN FORD\r\r\r\r";
|
|
const char *novicepro = "WOULD YOU LIKE TO PLAY AS A\r\r[N]OVICE, [P]RO, OR [M]ASTER? ";
|
|
const char *insprompt = "DO YOU NEED INSTRUCTIONS? ";
|
|
|
|
const char *instruct1 = "\
|
|
GOAL: CRACK THE CODE. FAILURE IS NOT\r\
|
|
AN OPTION!\r\
|
|
\r\
|
|
CODE: THE CODE IS COMPOSED OF ";
|
|
|
|
const char *instruct2 = " COLORS\r\
|
|
OUT OF A SET OF ";
|
|
|
|
const char *instruct3 = ". DUPLICATES\r\
|
|
ALLOWED.\r\
|
|
\r\
|
|
RULES: YOU HAVE ";
|
|
|
|
const char *instruct4 = " ATTEMPTS. AFTER EACH\
|
|
ATTEMPT A CLUE WILL BE GIVEN.\r\
|
|
\r\
|
|
CLUES: AN * INDICATES THAT YOU HAVE A\r\
|
|
CORRECT COLOR IN THE CORRECT\r\
|
|
PLACE. A + INDICATES THAT YOU\r\
|
|
HAVE A CORRECT COLOR. YOU\r\
|
|
NEED ";
|
|
|
|
const char *instruct5 = " *'S TO WIN. THE\r\
|
|
POSITION OF THE CLUES IS NOT\r\
|
|
RELEVANT.\r\
|
|
\r\
|
|
SCORE: TIME IN SECONDS. GOOD LUCK!\r\
|
|
\r\
|
|
\r\
|
|
";
|
|
const char *instructg =
|
|
"\rA PRO GAME WITH A TWIST...\r\r\r\r YOU ONLY HAVE 60 SECONDS!\r\r\r\r";
|
|
const char *anykey = "PRESS ANY KEY TO BEGIN CRACKING ";
|
|
const char *header = "\
|
|
CODEBREAKER!\r\
|
|
\r\
|
|
";
|
|
const char *won = " YOU'VE CRACKED IT!\r";
|
|
const char *fail = " YOU'VE FAILED\r";
|
|
const char *playagain = "WOULD YOU LIKE TO PLAY AGAIN? ";
|
|
|
|
unsigned long int next = 1;
|
|
char numcolors, slots, attempts, tt;
|
|
|
|
int main(void)
|
|
{
|
|
char code[5], claimed[5], guess[5];
|
|
char colors[] = { 'R', 'G', 'B', 'Y', 'O', 'P', 'S', 'C' };
|
|
char *colorkey[] =
|
|
{ " [R]ED ", " [G]REEN ", " [B]LUE ", " [Y]ELLOW ",
|
|
" [O]RANGE ", " [P]URPLE ", " [S]ILVER ", " [C]OPPER "
|
|
};
|
|
char *gametypes[] = { "NOVICE", "PRO ", "MASTER" };
|
|
char i, j, k, right, close, gametype;
|
|
signed int timer;
|
|
unsigned int win[3], loss[3], avgtime[3], besttime[3];
|
|
|
|
for(i = 0; i < 3; ++i)
|
|
win[i] = loss[i] = avgtime[i] = besttime[i] = 0;
|
|
|
|
clearscreen();
|
|
cputs(title);
|
|
|
|
while (1) {
|
|
tt = 0;
|
|
numcolors = 8;
|
|
slots = 5;
|
|
attempts = 12;
|
|
gametype = PRO;
|
|
cputs(novicepro);
|
|
key = 0;
|
|
while (key != 'N' && key != 'P' && key != 'M')
|
|
getkey();
|
|
putchar(key);
|
|
cputs("\r\r");
|
|
if (key == 'N') {
|
|
numcolors = 6;
|
|
slots = 4;
|
|
attempts = 10;
|
|
gametype = NOVICE;
|
|
}
|
|
if (key == 'M') {
|
|
tt = 1;
|
|
gametype = MASTER;
|
|
}
|
|
instructions();
|
|
clearscreen();
|
|
|
|
timer = TIMER;
|
|
srand(count & 0xFFFF);
|
|
for (i = 0; i < slots; ++i) {
|
|
code[i] = rand() % numcolors;
|
|
}
|
|
|
|
clearscreen();
|
|
cputs(header);
|
|
if (slots == 5) {
|
|
for (i = 0; i < numcolors; ++i)
|
|
cputs(colorkey[i]);
|
|
cputs("\r");
|
|
} else {
|
|
cputs(" ");
|
|
for (i = 0; i < numcolors / 2; ++i)
|
|
cputs(colorkey[i]);
|
|
cputs("\r ");
|
|
for (i = numcolors / 2; i < numcolors; ++i)
|
|
cputs(colorkey[i]);
|
|
cputs("\r\r");
|
|
}
|
|
|
|
drawboard(TOP);
|
|
cputs(" ! ");
|
|
for (i = 0; i < slots; i++) {
|
|
#if DEBUG==1
|
|
putchar(colors[code[i]]);
|
|
#else
|
|
putchar('X');
|
|
#endif
|
|
putchar(' ');
|
|
}
|
|
cputs("! CLUE");
|
|
if (slots == 5)
|
|
cputs("S");
|
|
if (tt)
|
|
cputs(" TIME: -60.0");
|
|
cputs("\r");
|
|
drawboard(MIDDLE);
|
|
|
|
for (i = 1; i <= attempts; ++i) {
|
|
for (j = 0; j < slots; ++j)
|
|
claimed[j] = 0;
|
|
right = close = 0;
|
|
printnum(i, 2, ' ');
|
|
cputs(" ! ");
|
|
if(i == 1)
|
|
count = 0;
|
|
for (j = 0; j < slots; ++j) {
|
|
getkey();
|
|
if (tt) {
|
|
timer -= TENTHS;
|
|
count = 0;
|
|
if (timer < 0) {
|
|
timer = 0;
|
|
break;
|
|
}
|
|
}
|
|
for (k = 0; k < numcolors; ++k)
|
|
if (key == colors[k])
|
|
break;
|
|
if (k == numcolors) {
|
|
j--;
|
|
continue;
|
|
}
|
|
putchar(colors[k]);
|
|
putchar(' ');
|
|
if (k == code[j]) {
|
|
right++;
|
|
claimed[j] = 1;
|
|
}
|
|
guess[j] = k;
|
|
}
|
|
for (; j < slots; ++j) {
|
|
cputs("- ");
|
|
guess[j] = 9;
|
|
}
|
|
cputs("! ");
|
|
for (j = 0; j < slots; ++j) {
|
|
if (guess[j] == code[j])
|
|
continue;
|
|
for (k = 0; k < slots; ++k)
|
|
if (guess[j] == code[k] && !claimed[k]) {
|
|
close++;
|
|
claimed[k] = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (j = 0; j < right; ++j)
|
|
putchar('*');
|
|
for (j = 0; j < slots - right - close; ++j)
|
|
putchar(' ');
|
|
for (j = 0; j < close; ++j)
|
|
putchar('+');
|
|
|
|
if (tt) {
|
|
cputs(" TIME: -");
|
|
printnum(timer / 10, 2, '0');
|
|
putchar('.');
|
|
printnum(timer % 10, 1, '0');
|
|
putchar(0xd);
|
|
} else {
|
|
if (slots == 4)
|
|
cputs(" ");
|
|
cputs(" TIME: ");
|
|
printnum(TIME / 60, 2, '0');
|
|
putchar(':');
|
|
printnum(TIME % 60, 2, '0');
|
|
putchar(0xd);
|
|
}
|
|
|
|
if (right == slots || timer == 0)
|
|
break;
|
|
}
|
|
|
|
drawboard(MIDDLE);
|
|
cputs(" ! ");
|
|
for (i = 0; i < slots; i++) {
|
|
putchar(colors[code[i]]);
|
|
putchar(' ');
|
|
}
|
|
putchar('!');
|
|
if (slots == 4)
|
|
cputs(" ");
|
|
if (right == slots) {
|
|
cputs(won);
|
|
if(gametype == MASTER)
|
|
timer = TIMER - timer;
|
|
else
|
|
timer = TIME;
|
|
win[gametype] += 1;
|
|
if(win[gametype] == 1)
|
|
avgtime[gametype] = besttime[gametype] = timer;
|
|
else {
|
|
avgtime[gametype] = (avgtime[gametype]*(win[gametype] - 1)+timer)/win[gametype];
|
|
if(timer < besttime[gametype])
|
|
besttime[gametype] = timer;
|
|
}
|
|
}
|
|
else {
|
|
cputs(fail);
|
|
loss[gametype] += 1;
|
|
}
|
|
drawboard(BOTTOM);
|
|
putchar(0xd);
|
|
|
|
cputs(playagain);
|
|
key = 0;
|
|
while (key != 'N' && key != 'Y')
|
|
getkey();
|
|
putchar(key);
|
|
clearscreen();
|
|
if (key == 'Y')
|
|
continue;
|
|
|
|
cputs("STATS\r\r");
|
|
cputs(" -----TIMES-----");
|
|
cputs("GAME CRACKED FAILED AVERAGE BEST\r");
|
|
for(i = 0; i < 3; ++i) {
|
|
if(win[i] + loss[i] == 0)
|
|
continue;
|
|
cputs(gametypes[i]);
|
|
cputs(" ");
|
|
printnum(win[i],4,' ');
|
|
cputs(" ");
|
|
printnum(loss[i],4,' ');
|
|
cputs(" ");
|
|
if(avgtime[i] == 0) {
|
|
cputs("----- -----");
|
|
continue;
|
|
}
|
|
if(i < 2) {
|
|
printnum(avgtime[i] / 60, 2, '0');
|
|
putchar(':');
|
|
printnum(avgtime[i] % 60, 2, '0');
|
|
cputs(" ");
|
|
printnum(besttime[i] / 60, 2, '0');
|
|
putchar(':');
|
|
printnum(besttime[i] % 60, 2, '0');
|
|
}
|
|
else {
|
|
putchar(' ');
|
|
printnum(avgtime[i] / 10, 2, ' ');
|
|
putchar('.');
|
|
printnum(avgtime[i] % 10, 1, '0');
|
|
cputs(" ");
|
|
printnum(besttime[i] / 10, 2, ' ');
|
|
putchar('.');
|
|
printnum(besttime[i] % 10, 1, '0');
|
|
}
|
|
}
|
|
cputs("\r\r\r\rTO PLAY AGAIN TYPE: 280R\r\r");
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if CODESEG == 1
|
|
#pragma codeseg ("CODE1")
|
|
#endif
|
|
|
|
void drawboard(unsigned char p)
|
|
{
|
|
char i, ends[] = { '.', ':', '''};
|
|
|
|
cputs(" ");
|
|
putchar(ends[p]);
|
|
for(i=0;i<slots*2+1;++i)
|
|
putchar('-');
|
|
putchar(ends[p]);
|
|
putchar(0xd);
|
|
}
|
|
|
|
void clearscreen()
|
|
{
|
|
char i=25;
|
|
|
|
while(--i)
|
|
putchar(0xd);
|
|
}
|
|
|
|
void printnum(unsigned long n, char padding, char pad)
|
|
{
|
|
char i=8, c[8];
|
|
|
|
while(n > 0) {
|
|
c[--i]=(n%10 + 0x30);
|
|
n/=10;
|
|
}
|
|
if(padding > 0) {
|
|
while(i > 0)
|
|
c[--i]=pad;
|
|
for(i=8-padding;i<8;++i)
|
|
putchar(c[i]);
|
|
return;
|
|
}
|
|
for(;i<8;++i)
|
|
putchar(c[i]);
|
|
}
|
|
|
|
void instructions()
|
|
{
|
|
cputs(insprompt);
|
|
key = 0;
|
|
while (key != 'N' && key != 'Y')
|
|
getkey();
|
|
putchar(key);
|
|
if(key == 'N')
|
|
return;
|
|
clearscreen();
|
|
if(slots == 5)
|
|
if(tt == 0)
|
|
cputs("PRO");
|
|
else
|
|
cputs("MASTER");
|
|
else
|
|
cputs("NOVICE");
|
|
cputs(" INSTRUCTIONS\r\r");
|
|
if(tt == 0) {
|
|
cputs(instruct1);
|
|
printnum(slots,0,'0');
|
|
cputs(instruct2);
|
|
printnum(numcolors,0,'0');
|
|
cputs(instruct3);
|
|
printnum(attempts,0,'0');
|
|
cputs(instruct4);
|
|
printnum(slots,0,'0');
|
|
cputs(instruct5);
|
|
}
|
|
else
|
|
cputs(instructg);
|
|
cputs(anykey);
|
|
getkey();
|
|
}
|
|
|
|
int rand()
|
|
{
|
|
next = next * 1103515245 + 12345;
|
|
return (unsigned int)(next/65536UL) % 32768UL;
|
|
}
|
|
|
|
/*
|
|
void srand(unsigned int seed)
|
|
{
|
|
next = seed;
|
|
}
|
|
*/
|
|
|
|
|