X-Git-Url: https://jxself.org/git/?p=wumpus.git;a=blobdiff_plain;f=superhack.c;fp=superhack.c;h=6c2b29e46f1c755dd24e18f3e6dd8b81f00539a3;hp=8ddd148cfec9e9095ad0b9ad88974a0db3b51c12;hb=cb769b76c094d53c1423af9d4f6d1eb84fbfb0e5;hpb=c7c254cd65138c2371678823b08df68c97dc9bd7 diff --git a/superhack.c b/superhack.c index 8ddd148..6c2b29e 100644 --- a/superhack.c +++ b/superhack.c @@ -12,447 +12,410 @@ * SPDX-License-Identifier: BSD-2-Clause */ -#include #include +#include #include #include -#include -#include #include +#include +#include static int path[5]; static int j, k, scratchloc, pies; -static char inp[BUFSIZ]; /* common input buffer */ +static char inp[BUFSIZ]; /* common input buffer */ #define NUMBERS "0123456789" -#define YOU 0 -#define RMS 1 -#define STARLET1 2 -#define STARLET2 3 -#define DROID1 4 -#define DROID2 5 -#define LUSER1 6 -#define LUSER2 7 -#define LOCS 8 +#define YOU 0 +#define RMS 1 +#define STARLET1 2 +#define STARLET2 3 +#define DROID1 4 +#define DROID2 5 +#define LUSER1 6 +#define LUSER2 7 +#define LOCS 8 static int loc[LOCS]; -#define NOT 0 -#define WIN 1 -#define LOSE -1 +#define NOT 0 +#define WIN 1 +#define LOSE -1 static int finished; -#define IGNORE(r) do{if(r);}while(0) - -static int cave[20][3] = -{ - {1,4,7}, - {0,2,9}, - {1,3,11}, - {2,4,13}, - {0,3,5}, - {4,6,14}, - {5,7,16}, - {0,6,8}, - {7,9,17}, - {1,8,10}, - {9,11,18}, - {2,10,12}, - {11,13,19}, - {3,12,14}, - {5,13,15}, - {14,16,19}, - {6,15,17}, - {8,16,18}, - {10,17,19}, - {12,15,18}, +#define IGNORE(r) \ + do { \ + if (r) \ + ; \ + } while (0) + +static int cave[20][3] = { + {1, 4, 7}, {0, 2, 9}, {1, 3, 11}, {2, 4, 13}, {0, 3, 5}, + {4, 6, 14}, {5, 7, 16}, {0, 6, 8}, {7, 9, 17}, {1, 8, 10}, + {9, 11, 18}, {2, 10, 12}, {11, 13, 19}, {3, 12, 14}, {5, 13, 15}, + {14, 16, 19}, {6, 15, 17}, {8, 16, 18}, {10, 17, 19}, {12, 15, 18}, }; -#define FNA() (rand() % 20) +#define FNA() (rand() % 20) -#define FNB() (rand() % 3) +#define FNB() (rand() % 3) -#define FNC() (rand() % 4) +#define FNC() (rand() % 4) int getlet(prompt) char *prompt; { - (void) printf("%s? ", prompt); - if (fgets(inp, sizeof(inp), stdin)) { - return(tolower(inp[0])); - } - else { - fputs("\n",stdout); - exit(1); - } + (void)printf("%s? ", prompt); + if (fgets(inp, sizeof(inp), stdin)) { + return (tolower(inp[0])); + } else { + fputs("\n", stdout); + exit(1); + } } -#define PM(x) puts(x); - -void print_instructions() -{ - PM("Welcome to `Hunt the Superhack'\n") - -PM(" The superhack lives on the 9th floor of 45 Technology Square in"); -PM("Cambridge, Massachusetts. Your mission is to throw a pie in his face.\n"); - - PM(" First, you'll have to find him. A botched experiment by an MIT"); - PM("physics group has regularized the floor's topology, so that each"); - PM("room has exits to three other rooms. (Look at a dodecahedron to"); - PM("see how this works --- if you don't know what a dodecahedron is,"); - PM("ask someone.)\n"); - - PM("You:"); - PM(" Each turn you may move to an adjacent room or throw a pie. If"); - PM("you run out of pies, you lose. Each pie can pass through up to"); - PM("five rooms (connected by a continuous path from where you are). You"); - PM("aim by telling the computer which rooms you want to throw through."); - PM("If the path is incorrect (presumes a nonexistent connection) the "); - PM("pie moves at random."); - - PM(" If a pie hits the superhack, you win. If it hits you, you lose!\n"); - - (void) fputs("", stdout); - IGNORE(fgets(inp, sizeof(inp), stdin)); - (void) putchar('\n'); - - PM("Hazards:"); - PM(" Starlets --- two rooms contain lonely, beautiful women. If you"); - PM("enter these, you will become fascinated and forget your mission as"); - PM("you engage in futile efforts to pick one up. You weenie."); - PM(" Droids --- two rooms are guarded by experimental AI security "); - PM("droids. If you enter either, the droid will grab you and hustle"); - PM("you off to somewhere else, at random."); - PM(" Lusers --- two rooms contain hungry lusers. If you blunder into"); - PM("either, they will eat one of your pies."); - PM(" Superhack --- the superhack is not bothered by hazards (the"); - PM("lusers are in awe of him, he's programmed the droids to ignore him,"); - PM("and he has no sex life). Usually he is hacking. Two things can"); - PM("interrupt him; you throwing a pie or you entering his room.\n"); - PM(" On an interrupt, the superhack moves (3/4 chance) or stays where"); - PM("he is (1/4 chance). After that, if he is where you are, he flames"); - PM("you and you lose!\n"); - - (void) fputs("", stdout); - (void) fgets(inp, sizeof(inp), stdin); - (void) putchar('\n'); - - PM("Warnings:"); - PM(" When you are one room away from the superhack or a hazard,"); - PM("the computer says:"); - PM(" superhack: \"I smell a superhack!\""); - PM(" security droid: \"Droids nearby!\""); - PM(" starlet: \"I smell perfume!\""); - PM(" luser: \"Lusers nearby!\""); - - PM("If you take too long finding the superhack, hazards may move. You"); - PM("will get a warning when this happens.\n"); - - PM("Commands:"); - PM(" Available commands are:\n"); - PM(" ? --- print long instructions."); - PM(" m --- move to room with given number."); - PM(" t --- throw through given rooms."); +#define PM(x) puts(x); + +void print_instructions() { + PM("Welcome to `Hunt the Superhack'\n") + + PM(" The superhack lives on the 9th floor of 45 Technology Square " + "in"); + PM("Cambridge, Massachusetts. Your mission is to throw a pie in his " + "face.\n"); + + PM(" First, you'll have to find him. A botched experiment by an " + "MIT"); + PM("physics group has regularized the floor's topology, so that each"); + PM("room has exits to three other rooms. (Look at a dodecahedron to"); + PM("see how this works --- if you don't know what a dodecahedron is,"); + PM("ask someone.)\n"); + + PM("You:"); + PM(" Each turn you may move to an adjacent room or throw a pie. If"); + PM("you run out of pies, you lose. Each pie can pass through up to"); + PM("five rooms (connected by a continuous path from where you are). " + "You"); + PM("aim by telling the computer which rooms you want to throw " + "through."); + PM("If the path is incorrect (presumes a nonexistent connection) the "); + PM("pie moves at random."); + + PM(" If a pie hits the superhack, you win. If it hits you, you " + "lose!\n"); + + (void)fputs("", stdout); + IGNORE(fgets(inp, sizeof(inp), stdin)); + (void)putchar('\n'); + + PM("Hazards:"); + PM(" Starlets --- two rooms contain lonely, beautiful women. If " + "you"); + PM("enter these, you will become fascinated and forget your mission " + "as"); + PM("you engage in futile efforts to pick one up. You weenie."); + PM(" Droids --- two rooms are guarded by experimental AI security "); + PM("droids. If you enter either, the droid will grab you and hustle"); + PM("you off to somewhere else, at random."); + PM(" Lusers --- two rooms contain hungry lusers. If you blunder " + "into"); + PM("either, they will eat one of your pies."); + PM(" Superhack --- the superhack is not bothered by hazards (the"); + PM("lusers are in awe of him, he's programmed the droids to ignore " + "him,"); + PM("and he has no sex life). Usually he is hacking. Two things can"); + PM("interrupt him; you throwing a pie or you entering his room.\n"); + PM(" On an interrupt, the superhack moves (3/4 chance) or stays " + "where"); + PM("he is (1/4 chance). After that, if he is where you are, he " + "flames"); + PM("you and you lose!\n"); + + (void)fputs("", stdout); + (void)fgets(inp, sizeof(inp), stdin); + (void)putchar('\n'); + + PM("Warnings:"); + PM(" When you are one room away from the superhack or a hazard,"); + PM("the computer says:"); + PM(" superhack: \"I smell a superhack!\""); + PM(" security droid: \"Droids nearby!\""); + PM(" starlet: \"I smell perfume!\""); + PM(" luser: \"Lusers nearby!\""); + + PM("If you take too long finding the superhack, hazards may move. " + "You"); + PM("will get a warning when this happens.\n"); + + PM("Commands:"); + PM(" Available commands are:\n"); + PM(" ? --- print long instructions."); + PM(" m --- move to room with given number."); + PM(" t --- throw through given rooms."); #ifdef DEBUG - PM(" d --- dump hazard locations."); + PM(" d --- dump hazard locations."); #endif /* DEBUG */ - PM("\nThe list of room numbers after t must be space-separated. Anything"); - PM("other than one of these commands displays a short help message."); + PM("\nThe list of room numbers after t must be space-separated. " + "Anything"); + PM("other than one of these commands displays a short help message."); } -void move_hazard(where) -int where; +void move_hazard(where) int where; { - int newloc; + int newloc; - retry: - newloc = FNA(); - for (j = 0; j < LOCS; j++) { - if (loc[j] == newloc) { - goto retry; - } - } +retry: + newloc = FNA(); + for (j = 0; j < LOCS; j++) { + if (loc[j] == newloc) { + goto retry; + } + } - loc[where] = newloc; + loc[where] = newloc; } -void check_hazards() -{ - /* basic status report */ - (void) printf("You are in room %d. Exits lead to %d, %d, %d. You have %d pies left.\n", - loc[YOU]+1, - cave[loc[YOU]][0]+1, - cave[loc[YOU]][1]+1, - cave[loc[YOU]][2]+1, - pies); - - /* maybe it's migration time */ - if (FNA() == 0) - switch(2 + FNB()) - { - case STARLET1: - case STARLET2: - PM("Swish, swish, swish --- starlets are moving!"); - move_hazard(STARLET1); - move_hazard(STARLET2); - break; - - case DROID1: - case DROID2: - PM("Clank, clank, clank --- droids are moving!"); - move_hazard(DROID1); - move_hazard(DROID2); - break; - - case LUSER1: - case LUSER2: - PM("Grumble, grumble, grumble --- lusers are moving!"); - move_hazard(LUSER1); - move_hazard(LUSER2); - break; - } - - /* display hazard warnings */ - for (k = 0; k < 3; k++) - { - int room = cave[loc[YOU]][k]; +void check_hazards() { + /* basic status report */ + (void)printf("You are in room %d. Exits lead to %d, %d, %d. You have " + "%d pies left.\n", + loc[YOU] + 1, cave[loc[YOU]][0] + 1, cave[loc[YOU]][1] + 1, + cave[loc[YOU]][2] + 1, pies); + + /* maybe it's migration time */ + if (FNA() == 0) + switch (2 + FNB()) { + case STARLET1: + case STARLET2: + PM("Swish, swish, swish --- starlets are moving!"); + move_hazard(STARLET1); + move_hazard(STARLET2); + break; + + case DROID1: + case DROID2: + PM("Clank, clank, clank --- droids are moving!"); + move_hazard(DROID1); + move_hazard(DROID2); + break; + + case LUSER1: + case LUSER2: + PM("Grumble, grumble, grumble --- lusers are moving!"); + move_hazard(LUSER1); + move_hazard(LUSER2); + break; + } - if (room == loc[RMS]) { - (void) puts("I smell a superhack!"); - } - else if (room == loc[STARLET1] || room == loc[STARLET2]) { - (void) puts("I smell perfume!"); - } - else if (room == loc[DROID1] || room == loc[DROID2]) { - (void) puts("Droids nearby!"); - } - else if (room == loc[LUSER1] || room == loc[LUSER2]) { - (void) puts("Lusers nearby!"); + /* display hazard warnings */ + for (k = 0; k < 3; k++) { + int room = cave[loc[YOU]][k]; + + if (room == loc[RMS]) { + (void)puts("I smell a superhack!"); + } else if (room == loc[STARLET1] || room == loc[STARLET2]) { + (void)puts("I smell perfume!"); + } else if (room == loc[DROID1] || room == loc[DROID2]) { + (void)puts("Droids nearby!"); + } else if (room == loc[LUSER1] || room == loc[LUSER2]) { + (void)puts("Lusers nearby!"); + } } - } } -void throw() -{ - extern void check_shot(), move_superhack(); - int j9; +void throw() { + extern void check_shot(), move_superhack(); + int j9; - j9 = sscanf(inp + strcspn(inp, NUMBERS), "%d %d %d %d %d", - &path[0], &path[1], &path[2], &path[3], &path[4]); + j9 = sscanf(inp + strcspn(inp, NUMBERS), "%d %d %d %d %d", &path[0], + &path[1], &path[2], &path[3], &path[4]); - if (j9 < 1) - { - PM("Sorry, I didn't see any room numbers after your throw command."); - return; - } - - for (k = 0; k < j9; k++) { - if (k >= 2 && path[k] == path[k - 2]) - { - (void) puts("Pies can't fly that crookedly --- try again."); - return; + if (j9 < 1) { + PM("Sorry, I didn't see any room numbers after your throw " + "command."); + return; } - } - - scratchloc = loc[YOU]; - - for (k = 0; k < j9; k++) - { - int k1; - for (k1 = 0; k1 < 3; k1++) - { - if (cave[scratchloc][k1] == path[k]) - { - scratchloc = path[k]; - check_shot(); - if (finished != NOT) { - return; + for (k = 0; k < j9; k++) { + if (k >= 2 && path[k] == path[k - 2]) { + (void)puts( + "Pies can't fly that crookedly --- try again."); + return; } - } - } - scratchloc = cave[scratchloc][FNB()]; + scratchloc = loc[YOU]; - check_shot(); + for (k = 0; k < j9; k++) { + int k1; + + for (k1 = 0; k1 < 3; k1++) { + if (cave[scratchloc][k1] == path[k]) { + scratchloc = path[k]; + check_shot(); + if (finished != NOT) { + return; + } + } + } - } + scratchloc = cave[scratchloc][FNB()]; - if (finished == NOT) - { - (void) puts("You missed."); + check_shot(); + } - scratchloc = loc[YOU]; + if (finished == NOT) { + (void)puts("You missed."); - move_superhack(); + scratchloc = loc[YOU]; - if (--pies <= 0) { - finished = LOSE; - } - } + move_superhack(); + if (--pies <= 0) { + finished = LOSE; + } + } } -void check_shot() -{ - if (scratchloc == loc[RMS]) - { - (void) puts("Splat! You got the superhack! You win."); - finished = WIN; - } - - else if (scratchloc == loc[YOU]) - { - (void) puts("Ugh! The pie hit you! You lose."); - finished = LOSE; - } -} +void check_shot() { + if (scratchloc == loc[RMS]) { + (void)puts("Splat! You got the superhack! You win."); + finished = WIN; + } -void move_superhack() -{ - k = FNC(); + else if (scratchloc == loc[YOU]) { + (void)puts("Ugh! The pie hit you! You lose."); + finished = LOSE; + } +} - if (k < 3) { - loc[RMS] = cave[loc[RMS]][k]; - } +void move_superhack() { + k = FNC(); - if (loc[RMS] != loc[YOU]) { - return; - } + if (k < 3) { + loc[RMS] = cave[loc[RMS]][k]; + } - (void) puts("The superhack flames you to a crisp. You lose!"); + if (loc[RMS] != loc[YOU]) { + return; + } - finished = LOSE; + (void)puts("The superhack flames you to a crisp. You lose!"); + finished = LOSE; } -void move() -{ - if (sscanf(inp + strcspn(inp, NUMBERS), "%d", &scratchloc) < 1) - { - PM("Sorry, I didn't see a room number after your `m' command."); - return; - } +void move() { + if (sscanf(inp + strcspn(inp, NUMBERS), "%d", &scratchloc) < 1) { + PM("Sorry, I didn't see a room number after your `m' command."); + return; + } - scratchloc--; + scratchloc--; - for (k = 0; k < 3; k++) { - if (cave[loc[YOU]][k] == scratchloc) { - goto goodmove; - } - } + for (k = 0; k < 3; k++) { + if (cave[loc[YOU]][k] == scratchloc) { + goto goodmove; + } + } - PM("You can't get there from here!"); - return; + PM("You can't get there from here!"); + return; goodmove: - loc[YOU] = scratchloc; - - if (scratchloc == loc[RMS]) - { - PM("Yow! You interrupted the superhack."); - move_superhack(); - } - else if (scratchloc == loc[STARLET1] || scratchloc == loc[STARLET2]) - { - PM("You begin to babble at an unimpressed starlet. You lose!"); - finished = LOSE; - } - else if (scratchloc == loc[DROID1] || scratchloc == loc[DROID2]) - { - PM("Zap --- security droid snatch. Elsewheresville for you!"); - scratchloc = loc[YOU] = FNA(); - goto goodmove; - } - else if (scratchloc == loc[LUSER1] || scratchloc == loc[LUSER2]) - { - PM("Munch --- lusers ate one of your pies!"); - pies--; - } + loc[YOU] = scratchloc; + + if (scratchloc == loc[RMS]) { + PM("Yow! You interrupted the superhack."); + move_superhack(); + } else if (scratchloc == loc[STARLET1] || scratchloc == loc[STARLET2]) { + PM("You begin to babble at an unimpressed starlet. You lose!"); + finished = LOSE; + } else if (scratchloc == loc[DROID1] || scratchloc == loc[DROID2]) { + PM("Zap --- security droid snatch. Elsewheresville for you!"); + scratchloc = loc[YOU] = FNA(); + goto goodmove; + } else if (scratchloc == loc[LUSER1] || scratchloc == loc[LUSER2]) { + PM("Munch --- lusers ate one of your pies!"); + pies--; + } } -int main(int argc, char *argv[]) -{ - if (argc >= 2 && strcmp(argv[1], "-s") == 0) { - srand(atoi(argv[2])); - } - else { - srand((int)time((long *) 0)); - } - - for (;;) - { - badlocs: - for (j = 0; j < LOCS; j++) { - loc[j] = FNA(); +int main(int argc, char *argv[]) { + if (argc >= 2 && strcmp(argv[1], "-s") == 0) { + srand(atoi(argv[2])); + } else { + srand((int)time((long *)0)); } - for (j = 0; j < LOCS; j++) { - for (k = 0; k < LOCS; k++) { - if (j == k) { - continue; - } - else if (loc[j] == loc[k]) { - goto badlocs; - } - } - } + for (;;) { + badlocs: + for (j = 0; j < LOCS; j++) { + loc[j] = FNA(); + } - (void) puts("Hunt the Superhack"); + for (j = 0; j < LOCS; j++) { + for (k = 0; k < LOCS; k++) { + if (j == k) { + continue; + } else if (loc[j] == loc[k]) { + goto badlocs; + } + } + } - pies = 5; - scratchloc = loc[YOU]; - finished = NOT; + (void)puts("Hunt the Superhack"); - while (finished == NOT) - { - int c; + pies = 5; + scratchloc = loc[YOU]; + finished = NOT; - check_hazards(); + while (finished == NOT) { + int c; - c = getlet("Throw, move or help [t,m,?]"); + check_hazards(); - if (c == 't') { - throw(); - } - else if (c == 'm') { - move(); - } - else if (c == '?') { - print_instructions(); - } + c = getlet("Throw, move or help [t,m,?]"); + + if (c == 't') { + throw(); + } else if (c == 'm') { + move(); + } else if (c == '?') { + print_instructions(); + } #ifdef DEBUG - else if (c == 'd') - { - (void) printf("RMS is at %d, starlets at %d/%d, droids %d/%d, lusers %d/%d\n", - loc[RMS] + 1, - loc[STARLET1] + 1, loc[STARLET2] + 1, - loc[DROID1] + 1, loc[DROID2] + 1, - loc[LUSER1] + 1, loc[LUSER2] + 1); - } + else if (c == 'd') { + (void)printf("RMS is at %d, starlets at %d/%d, " + "droids %d/%d, lusers %d/%d\n", + loc[RMS] + 1, loc[STARLET1] + 1, + loc[STARLET2] + 1, loc[DROID1] + 1, + loc[DROID2] + 1, loc[LUSER1] + 1, + loc[LUSER2] + 1); + } #endif /* DEBUG */ - else - { - PM("Available commands are:\n"); - PM(" ? --- print long instructions."); - PM(" m --- move to room with given number."); - PM(" t --- throw through given rooms."); + else { + PM("Available commands are:\n"); + PM(" ? --- print long " + "instructions."); + PM(" m --- move to room with given " + "number."); + PM(" t --- throw through given " + "rooms."); #ifdef DEBUG - PM(" d --- dump hazard locations."); + PM(" d --- dump hazard locations."); #endif /* DEBUG */ - PM("The list of room numbers after t must be space-separated"); - } + PM("The list of room numbers after t must be " + "space-separated"); + } - (void) putchar('\n'); - } + (void)putchar('\n'); + } - if (getlet("Play again") != 'y') - { - PM("Happy hacking!"); - break; + if (getlet("Play again") != 'y') { + PM("Happy hacking!"); + break; + } } - } - return 0; + return 0; } /* superhack.c ends here */