adventure.c (22959B)
1 /* 2 * Source: https://github.com/jefftranter/6502 3 * 4 * Minor changes by Gerd Beuster (gerd@frombelow.net) in order to get 5 * it to work on Eris 2010. 6 * 7 * The Abandoned Farm House Adventure 8 * 9 * Jeff Tranter <tranter@pobox.com> 10 * 11 * Written in standard C but designed to run on the Apple Replica 1 12 * or Apple II using the CC65 6502 assembler. 13 * 14 * Copyright 2012-2015 Jeff Tranter 15 * 16 * Licensed under the Apache License, Version 2.0 (the "License"); 17 * you may not use this file except in compliance with the License. 18 * You may obtain a copy of the License at 19 * 20 * http://www.apache.org/licenses/LICENSE-2.0 21 * 22 * Unless required by applicable law or agreed to in writing, software 23 * distributed under the License is distributed on an "AS IS" BASIS, 24 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 25 * See the License for the specific language governing permissions and 26 * limitations under the License. 27 * 28 * Revision History: 29 * 30 * Version Date Comments 31 * ------- ---- -------- 32 * 0.0 13 Mar 2012 First alpha version 33 * 0.1 18 Mar 2012 First beta version 34 * 0.9 19 Mar 2012 First public release 35 * 1.0 06 Sep 2015 Lower case and other Apple II improvements. 36 * 37 */ 38 39 #include <ctype.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #ifdef __CC65__ 43 #include <conio.h> 44 #endif 45 46 /* CONSTANTS */ 47 48 /* Maximum number of items user can carry */ 49 #define MAXITEMS 5 50 51 /* Number of locations */ 52 #define NUMLOCATIONS 32 53 54 /* TYPES */ 55 56 /* To optimize for code size and speed, most numbers are 8-bit chars when compiling for CC65. */ 57 #ifdef __CC65__ 58 typedef char number; 59 #else 60 typedef int number; 61 #endif 62 63 /* Directions */ 64 typedef enum { 65 North, 66 South, 67 East, 68 West, 69 Up, 70 Down 71 } Direction_t; 72 73 /* Items */ 74 typedef enum { 75 NoItem, 76 Key, 77 Pitchfork, 78 Flashlight, 79 Lamp, 80 Oil, 81 Candybar, 82 Bottle, 83 Doll, 84 ToyCar, 85 Matches, 86 GoldCoin, 87 SilverCoin, 88 StaleMeat, 89 Book, 90 Cheese, 91 OldRadio, 92 LastItem=OldRadio 93 } Item_t; 94 95 /* Locations */ 96 typedef enum { 97 NoLocation, 98 Driveway1, 99 Driveway2, 100 Driveway3, 101 Driveway4, 102 Driveway5, 103 Garage, 104 WorkRoom, 105 Hayloft, 106 Kitchen, 107 DiningRoom, 108 BottomStairs, 109 DrawingRoom, 110 Study, 111 TopStairs, 112 BoysBedroom, 113 GirlsBedroom, 114 MasterBedroom, 115 ServantsQuarters, 116 LaundryRoom, 117 FurnaceRoom, 118 VacantRoom, 119 Cistern, 120 Tunnel, 121 Woods24, 122 Woods25, 123 Woods26, 124 WolfTree, 125 Woods28, 126 Woods29, 127 Woods30, 128 Woods31, 129 } Location_t; 130 131 /* TABLES */ 132 133 /* Names of directions */ 134 char *DescriptionOfDirection[] = { 135 "north", "south", "east", "west", "up", "down" 136 }; 137 138 /* Names of items */ 139 char *DescriptionOfItem[LastItem+1] = { 140 "", 141 "key", 142 "pitchfork", 143 "flashlight", 144 "lamp", 145 "oil", 146 "candybar", 147 "bottle", 148 "doll", 149 "toy car", 150 "matches", 151 "gold coin", 152 "silver coin", 153 "stale meat", 154 "book", 155 "cheese", 156 "old radio", 157 }; 158 159 /* Names of locations */ 160 char *DescriptionOfLocation[NUMLOCATIONS] = { 161 "", 162 "in the driveway near your car", 163 "in the driveway", 164 "in front of the garage", 165 "in front of the barn", 166 "at the door to the house", 167 "in the garage", 168 "in the workroom of the barn", 169 "in the hayloft of the barn", 170 "in the kitchen", 171 "in the dining room", 172 "at the bottom of the stairs", 173 "in the drawing room", 174 "in the study", 175 "at the top of the stairs", 176 "in a boy's bedroom", 177 "in a girl's bedroom", 178 "in the master bedroom next to\r\na bookcase", 179 "in the servant's quarters", 180 "in the basement laundry room", 181 "in the furnace room", 182 "in a vacant room next to a\r\nlocked door", 183 "in the cistern", 184 "in an underground tunnel. There are rats here", 185 "in the woods near a trapdoor", 186 "in the woods", 187 "in the woods", 188 "in the woods next to a tree", 189 "in the woods", 190 "in the woods", 191 "in the woods", 192 "in the woods", 193 }; 194 195 /* DATA */ 196 197 /* Inventory of what player is carrying */ 198 Item_t Inventory[MAXITEMS]; 199 200 /* Location of each item. Index is the item number, returns the location. 0 if item is gone */ 201 Location_t locationOfItem[LastItem+1]; 202 203 /* Map. Given a location and a direction to move, returns the location it connects to, or 0 if not a valid move. Map can change during game play. */ 204 Direction_t Move[NUMLOCATIONS][6] = { 205 /* N S E W U D */ 206 { 0, 0, 0, 0, 0, 0 }, /* 0 */ 207 { 2, 0, 0, 0, 0, 0 }, /* 1 */ 208 { 4, 1, 3, 5, 0, 0 }, /* 2 */ 209 { 0, 0, 6, 2, 0, 0 }, /* 3 */ 210 { 7, 2, 0, 0, 0, 0 }, /* 4 */ 211 { 0, 0, 2, 9, 0, 0 }, /* 5 */ 212 { 0, 0, 0, 3, 0, 0 }, /* 6 */ 213 { 0, 4, 0, 0, 8, 0 }, /* 7 */ 214 { 0, 0, 0, 0, 0, 7 }, /* 8 */ 215 { 0,10, 5, 0, 0,19 }, /* 9 */ 216 { 9, 0, 0,11, 0, 0 }, /* 10 */ 217 { 0, 0,10,12,14, 0 }, /* 11 */ 218 { 13, 0,11, 0, 0, 0 }, /* 12 */ 219 { 0,12, 0, 0, 0, 0 }, /* 13 */ 220 { 16, 0,15,17, 0,11 }, /* 14 */ 221 { 0, 0, 0,14, 0, 0 }, /* 15 */ 222 { 0,14, 0, 0, 0, 0 }, /* 16 */ 223 { 0, 0,14, 0, 0, 0 }, /* 17 */ 224 { 0, 0, 0, 0, 0,13 }, /* 18 */ 225 { 0, 0, 0,20, 9, 0 }, /* 19 */ 226 { 21, 0,19, 0, 0, 0 }, /* 20 */ 227 { 0,20, 0,22, 0, 0 }, /* 21 */ 228 { 0, 0,21, 0, 0, 0 }, /* 22 */ 229 { 24,21, 0, 0, 0, 0 }, /* 23 */ 230 { 29,23, 0,26, 0, 0 }, /* 24 */ 231 { 26, 0,24, 0, 0, 0 }, /* 25 */ 232 { 27,25,29, 0, 0, 0 }, /* 26 */ 233 { 0,26,28, 0, 0, 0 }, /* 27 */ 234 { 0,29,31,27, 0, 0 }, /* 28 */ 235 { 28,24,30,26, 0, 0 }, /* 29 */ 236 { 31, 0, 0,29, 0, 0 }, /* 30 */ 237 { 0,30, 0,29, 0, 0 }, /* 31 */ 238 }; 239 240 /* Current location */ 241 number currentLocation; 242 243 /* Number of turns played in game */ 244 int turnsPlayed; 245 246 /* True if player has lit the lamp. */ 247 number lampLit; 248 249 /* True if lamp filled with oil. */ 250 number lampFilled; 251 252 /* True if player ate food. */ 253 number ateFood; 254 255 /* True if player drank water. */ 256 number drankWater; 257 258 /* Incremented each turn you are in the tunnel. */ 259 number ratAttack; 260 261 /* Tracks state of wolf attack */ 262 number wolfState; 263 264 /* Set when game is over */ 265 number gameOver; 266 267 const char *introText = " Abandoned Farmhouse Adventure\r\n By Jeff Tranter\r\n\r\nYour three-year-old grandson has gone\r\nmissing and was last seen headed in the\r\ndirection of the abandoned family farm.\r\nIt's a dangerous place to play. You\r\nhave to find him before he gets hurt,\r\nand it will be getting dark soon...\r\n"; 268 269 const char *helpString = "Valid commands:\r\ngo east/west/north/south/up/down \r\nlook\r\nuse <object>\r\nexamine <object>\r\ntake <object>\r\ndrop <object>\r\ninventory\r\nhelp\r\nquit\r\nYou can abbreviate commands and\r\ndirections to the first letter.\r\nType just the first letter of\r\na direction to move.\r\n"; 270 271 /* Line of user input */ 272 char buffer[40]; 273 274 // gb: Not available in conio, therefore added. 275 void gets(char *s) { 276 char c; 277 while ((c = cgetc()) != '\r') { 278 cputc(c); 279 *s = c; 280 s++; 281 } 282 *s = '\0'; 283 cputs("\r\n"); 284 }; 285 286 /* Clear the screen */ 287 void clearScreen() 288 { 289 #if defined(__APPLE2__) 290 clrscr(); 291 #else 292 number i; 293 for (i = 0; i < 24; ++i) 294 cprintf("\r\n"); 295 #endif 296 } 297 298 /* Return 1 if carrying an item */ 299 number carryingItem(char *item) 300 { 301 number i; 302 303 for (i = 0; i < MAXITEMS; i++) { 304 if ((Inventory[i] != 0) && (!strcasecmp(DescriptionOfItem[Inventory[i]], item))) 305 return 1; 306 } 307 return 0; 308 } 309 310 /* Return 1 if item it at current location (not carried) */ 311 number itemIsHere(char *item) 312 { 313 number i; 314 315 /* Find number of the item. */ 316 for (i = 1; i <= LastItem; i++) { 317 if (!strcasecmp(item, DescriptionOfItem[i])) { 318 /* Found it, but is it here? */ 319 if (locationOfItem[i] == currentLocation) { 320 return 1; 321 } else { 322 return 0; 323 } 324 } 325 } 326 return 0; 327 } 328 329 /* Inventory command */ 330 void doInventory() 331 { 332 number i; 333 int found = 0; 334 335 cprintf("%s", "You are carrying:\r\n"); 336 for (i = 0; i < MAXITEMS; i++) { 337 if (Inventory[i] != 0) { 338 cprintf(" %s\r\n", DescriptionOfItem[Inventory[i]]); 339 found = 1; 340 } 341 } 342 if (!found) 343 cprintf(" nothing\r\n"); 344 } 345 346 /* Help command */ 347 void doHelp() 348 { 349 cprintf("%s", helpString); 350 } 351 352 /* Look command */ 353 void doLook() 354 { 355 number i, loc, seen; 356 357 cprintf("You are %s.\r\n", DescriptionOfLocation[currentLocation]); 358 359 seen = 0; 360 cprintf("You see:\r\n"); 361 for (i = 1; i <= LastItem; i++) { 362 if (locationOfItem[i] == currentLocation) { 363 cprintf(" %s\r\n", DescriptionOfItem[i]); 364 seen = 1; 365 } 366 } 367 if (!seen) 368 cprintf(" nothing special\r\n"); 369 370 cprintf("You can go:"); 371 372 for (i = North; i <= Down; i++) { 373 loc = Move[currentLocation][i]; 374 if (loc != 0) { 375 cprintf(" %s", DescriptionOfDirection[i]); 376 } 377 } 378 cprintf("\r\n"); 379 } 380 381 /* Quit command */ 382 void doQuit() 383 { 384 cprintf("%s", "Are you sure you want to quit (y/n)? "); 385 gets(buffer); 386 if (tolower(buffer[0]) == 'y') { 387 gameOver = 1; 388 } 389 } 390 391 /* Drop command */ 392 void doDrop() 393 { 394 number i; 395 char *sp; 396 char *item; 397 398 /* Command line should be like "D[ROP] ITEM" Item name will be after after first space. */ 399 sp = strchr(buffer, ' '); 400 if (sp == NULL) { 401 cprintf("Drop what?\r\n"); 402 return; 403 } 404 405 item = sp + 1; 406 407 /* See if we have this item */ 408 for (i = 0; i < MAXITEMS; i++) { 409 if ((Inventory[i] != 0) && (!strcasecmp(DescriptionOfItem[Inventory[i]], item))) { 410 /* We have it. Add to location. */ 411 locationOfItem[Inventory[i]] = currentLocation; 412 /* And remove from inventory */ 413 Inventory[i] = 0; 414 cprintf("Dropped %s.\r\n", item); 415 ++turnsPlayed; 416 return; 417 } 418 } 419 /* If here, don't have it. */ 420 cprintf("Not carrying %s.\r\n", item); 421 } 422 423 /* Take command */ 424 void doTake() 425 { 426 number i, j; 427 char *sp; 428 char *item; 429 430 /* Command line should be like "T[AKE] ITEM" Item name will be after after first space. */ 431 sp = strchr(buffer, ' '); 432 if (sp == NULL) { 433 cprintf("Take what?\r\n"); 434 return; 435 } 436 437 item = sp + 1; 438 439 if (carryingItem(item)) { 440 cprintf("Already carrying it.\r\n"); 441 return; 442 } 443 444 /* Find number of the item. */ 445 for (i = 1; i <= LastItem; i++) { 446 if (!strcasecmp(item, DescriptionOfItem[i])) { 447 /* Found it, but is it here? */ 448 if (locationOfItem[i] == currentLocation) { 449 /* It is here. Add to inventory. */ 450 for (j = 0; j < MAXITEMS; j++) { 451 if (Inventory[j] == 0) { 452 Inventory[j] = i; 453 /* And remove from location. */ 454 locationOfItem[i] = 0; 455 cprintf("Took %s.\r\n", item); 456 ++turnsPlayed; 457 return; 458 } 459 } 460 461 /* Reached maximum number of items to carry */ 462 cprintf("You can't carry any more. Drop something.\r\n"); 463 return; 464 } 465 } 466 } 467 468 /* If here, don't see it. */ 469 cprintf("I see no %s here.\r\n", item); 470 } 471 472 /* Go command */ 473 void doGo() 474 { 475 char *sp; 476 char dirChar; 477 Direction_t dir; 478 479 /* Command line should be like "G[O] N[ORTH]" Direction will be 480 the first letter after a space. Or just a single letter 481 direction N S E W U D or full directon NORTH etc. */ 482 483 sp = strrchr(buffer, ' '); 484 if (sp != NULL) { 485 dirChar = *(sp+1); 486 } else { 487 dirChar = buffer[0]; 488 } 489 dirChar = tolower(dirChar); 490 491 if (dirChar == 'n') { 492 dir = North; 493 } else if (dirChar == 's') { 494 dir = South; 495 } else if (dirChar == 'e') { 496 dir = East; 497 } else if (dirChar == 'w') { 498 dir = West; 499 } else if (dirChar == 'u') { 500 dir = Up; 501 } else if (dirChar == 'd') { 502 dir = Down; 503 } else { 504 cprintf("Go where?\r\n"); 505 return; 506 } 507 508 if (Move[currentLocation][dir] == 0) { 509 cprintf("You can't go %s from here.\r\n", DescriptionOfDirection[dir]); 510 return; 511 } 512 513 /* We can move */ 514 currentLocation = Move[currentLocation][dir]; 515 cprintf("You are %s.\r\n", DescriptionOfLocation[currentLocation]); 516 ++turnsPlayed; 517 } 518 519 /* Examine command */ 520 void doExamine() 521 { 522 char *sp; 523 char *item; 524 525 /* Command line should be like "E[XAMINE] ITEM" Item name will be after after first space. */ 526 sp = strchr(buffer, ' '); 527 if (sp == NULL) { 528 cprintf("Examine what?\r\n"); 529 return; 530 } 531 532 item = sp + 1; 533 ++turnsPlayed; 534 535 /* Examine bookcase - not an object */ 536 if (!strcasecmp(item, "bookcase")) { 537 cprintf("You pull back a book and the bookcase\r\nopens up to reveal a secret room.\r\n"); 538 Move[17][North] = 18; 539 return; 540 } 541 542 /* Make sure item is being carried or is in the current location */ 543 if (!carryingItem(item) && !itemIsHere(item)) { 544 cprintf("I don't see it here.\r\n"); 545 return; 546 } 547 548 /* Examine Book */ 549 if (!strcasecmp(item, "book")) { 550 cprintf("It is a very old book entitled\r\n\"Apple 1 operation manual\".\r\n"); 551 return; 552 } 553 554 /* Examine Flashlight */ 555 if (!strcasecmp(item, "flashlight")) { 556 cprintf("It doesn't have any batteries.\r\n"); 557 return; 558 } 559 560 /* Examine toy car */ 561 if (!strcasecmp(item, "toy car")) { 562 cprintf("It is a nice toy car.\r\nYour grandson Matthew would like it.\r\n"); 563 return; 564 } 565 566 /* Examine old radio */ 567 if (!strcasecmp(item, "old radio")) { 568 cprintf("It is a 1940 Zenith 8-S-563 console\r\nwith an 8A02 chassis. You'd turn it on\r\nbut the electricity is off.\r\n"); 569 return; 570 } 571 572 /* Nothing special about this item */ 573 cprintf("You see nothing special about it.\r\n"); 574 } 575 576 /* Use command */ 577 void doUse() 578 { 579 char *sp; 580 char *item; 581 582 /* Command line should be like "U[SE] ITEM" Item name will be after after first space. */ 583 sp = strchr(buffer, ' '); 584 if (sp == NULL) { 585 cprintf("Use what?\r\n"); 586 return; 587 } 588 589 item = sp + 1; 590 591 /* Make sure item is being carried or is in the current location */ 592 if (!carryingItem(item) && !itemIsHere(item)) { 593 cprintf("I don't see it here.\r\n"); 594 return; 595 } 596 597 ++turnsPlayed; 598 599 /* Use key */ 600 if (!strcasecmp(item, "key") && (currentLocation == VacantRoom)) { 601 cprintf("You insert the key in the door and it\r\nopens, revealing a tunnel.\r\n"); 602 Move[21][North] = 23; 603 return; 604 } 605 606 /* Use pitchfork */ 607 if (!strcasecmp(item, "pitchfork") && (currentLocation == WolfTree) && (wolfState == 0)) { 608 cprintf("You jab the wolf with the pitchfork.\r\nIt howls and runs away.\r\n"); 609 wolfState = 1; 610 return; 611 } 612 613 /* Use toy car */ 614 if (!strcasecmp(item, "toy car") && (currentLocation == WolfTree && wolfState == 1)) { 615 cprintf("You show Matthew the toy car and he\r\ncomes down to take it. You take Matthew\r\nin your arms and carry him home.\r\n"); 616 wolfState = 2; 617 return; 618 } 619 620 /* Use oil */ 621 if (!strcasecmp(item, "oil")) { 622 if (carryingItem("lamp")) { 623 cprintf("You fill the lamp with oil.\r\n"); 624 lampFilled = 1; 625 return; 626 } else { 627 cprintf("You don't have anything to use it with.\r\n"); 628 return; 629 } 630 } 631 632 /* Use matches */ 633 if (!strcasecmp(item, "matches")) { 634 if (carryingItem("lamp")) { 635 if (lampFilled) { 636 cprintf("You light the lamp. You can see!\r\n"); 637 lampLit = 1; 638 return; 639 } else { 640 cprintf("You can't light the lamp. It needs oil.\r\n"); 641 return; 642 } 643 } else { 644 cprintf("Nothing here to light\r\n"); 645 } 646 } 647 648 /* Use candybar */ 649 if (!strcasecmp(item, "candybar")) { 650 cprintf("That hit the spot. You no longer feel\r\nhungry.\r\n"); 651 ateFood = 1; 652 return; 653 } 654 655 /* Use bottle */ 656 if (!strcasecmp(item, "bottle")) { 657 if (currentLocation == Cistern) { 658 cprintf("You fill the bottle with water from the\r\ncistern and take a drink. You no longer\r\nfeel thirsty.\r\n"); 659 drankWater = 1; 660 return; 661 } else { 662 cprintf("The bottle is empty. If only you had\r\nsome water to fill it!\r\n"); 663 return; 664 } 665 } 666 667 /* Use stale meat */ 668 if (!strcasecmp(item, "stale meat")) { 669 cprintf("The meat looked and tasted bad. You\r\nfeel very sick and pass out.\r\n"); 670 gameOver = 1; 671 return; 672 } 673 674 /* Default */ 675 cprintf("Nothing happens\r\n"); 676 } 677 678 /* Prompt user and get a line of input */ 679 void prompt() 680 { 681 cprintf("? "); 682 gets(buffer); 683 684 /* Remove trailing newline */ 685 // gb: Already removed 686 // buffer[strlen(buffer)-1] = '\0'; 687 } 688 689 /* Do special things unrelated to command typed. */ 690 void doActions() 691 { 692 if ((turnsPlayed == 10) && !lampLit) { 693 cprintf("It will be getting dark soon. You need\r\nsome kind of light or soon you won't\r\nbe able to see.\r\n"); 694 } 695 696 if ((turnsPlayed >= 60) && (!lampLit || (!itemIsHere("lamp") && !carryingItem("lamp")))) { 697 cprintf("It is dark out and you have no light.\r\nYou stumble around for a while and\r\nthen fall, hit your head, and pass out.\r\n"); 698 gameOver = 1; 699 return; 700 } 701 702 if ((turnsPlayed == 20) && !drankWater) { 703 cprintf("You are getting very thirsty.\r\nYou need to get a drink soon.\r\n"); 704 } 705 706 if ((turnsPlayed == 30) && !ateFood) { 707 cprintf("You are getting very hungry.\r\nYou need to find something to eat.\r\n"); 708 } 709 710 if ((turnsPlayed == 50) && !drankWater) { 711 cprintf("You pass out due to thirst.\r\n"); 712 gameOver = 1; 713 return; 714 } 715 716 if ((turnsPlayed == 40) && !ateFood) { 717 cprintf("You pass out from hunger.\r\n"); 718 gameOver = 1; 719 return; 720 } 721 722 if (currentLocation == Tunnel) { 723 if (itemIsHere("cheese")) { 724 cprintf("The rats go after the cheese.\r\n"); 725 } else { 726 if (ratAttack < 3) { 727 cprintf("The rats are coming towards you!\r\n"); 728 ++ratAttack; 729 } else { 730 cprintf("The rats attack and you pass out.\r\n"); 731 gameOver = 1; 732 return; 733 } 734 } 735 } 736 737 /* wolfState values: 0 - wolf attacking 1 - wolf gone, Matthew in tree. 2 - Matthew safe, you won. Game over. */ 738 if (currentLocation == WolfTree) { 739 switch (wolfState) { 740 case 0: 741 cprintf("A wolf is circling around the tree.\r\nMatthew is up in the tree. You have to\r\nsave him! If only you had some kind of\r\nweapon!\r\n"); 742 break; 743 case 1: 744 cprintf("Matthew is afraid to come\r\ndown from the tree. If only you had\r\nsomething to coax him with.\r\n"); 745 break; 746 case 2: 747 cprintf("Congratulations! You succeeded and won\r\nthe game. I hope you had as much fun\r\nplaying the game as I did creating it.\r\n- Jeff Tranter <tranter@pobox.com>\r\n"); 748 gameOver = 1; 749 return; 750 break; 751 } 752 } 753 } 754 755 /* Set variables to values for start of game */ 756 void initialize() 757 { 758 currentLocation = Driveway1; 759 lampFilled = 0; 760 lampLit = 0; 761 ateFood = 0; 762 drankWater = 0; 763 ratAttack = 0; 764 wolfState = 0; 765 turnsPlayed = 0; 766 gameOver= 0; 767 768 /* These doors can get changed during game and may need to be reset O*/ 769 Move[17][North] = 0; 770 Move[21][North] = 0; 771 772 /* Set inventory to default */ 773 memset(Inventory, 0, sizeof(Inventory[0])*MAXITEMS); 774 Inventory[0] = Flashlight; 775 776 /* Put items in their default locations */ 777 locationOfItem[0] = 0; /* NoItem */ 778 locationOfItem[1] = Driveway1; /* Key */ 779 locationOfItem[2] = Hayloft; /* Pitchfork */ 780 locationOfItem[3] = 0; /* Flashlight */ 781 locationOfItem[4] = WorkRoom; /* Lamp */ 782 locationOfItem[5] = Garage; /* Oil */ 783 locationOfItem[6] = Kitchen; /* Candybar */ 784 locationOfItem[7] = Driveway2; /* Bottle */ 785 locationOfItem[8] = GirlsBedroom; /* Doll */ 786 locationOfItem[9] = BoysBedroom; /* ToyCar */ 787 locationOfItem[10] = ServantsQuarters; /* Matches */ 788 locationOfItem[11] = Woods25; /* GoldCoin */ 789 locationOfItem[12] = Woods29; /* SilverCoin */ 790 locationOfItem[13] = DiningRoom; /* StaleMeat */ 791 locationOfItem[14] = DrawingRoom; /* Book */ 792 locationOfItem[15] = LaundryRoom; /* Cheese */ 793 locationOfItem[16] = MasterBedroom; /* OldRadio */ 794 } 795 796 /* Main program (obviously) */ 797 int main(void) 798 { 799 while (1) { 800 initialize(); 801 clearScreen(); 802 cprintf("%s", introText); 803 804 while (!gameOver) { 805 prompt(); 806 if (buffer[0] == '\0') { 807 } else if (tolower(buffer[0]) == 'h') { 808 doHelp(); 809 } else if (tolower(buffer[0]) == 'i') { 810 doInventory(); 811 } else if ((tolower(buffer[0]) == 'g') 812 || !strcasecmp(buffer, "n") || !strcasecmp(buffer, "s") 813 || !strcasecmp(buffer, "e") || !strcasecmp(buffer, "w") 814 || !strcasecmp(buffer, "u") || !strcasecmp(buffer, "d") 815 || !strcasecmp(buffer, "north") || !strcasecmp(buffer, "south") 816 || !strcasecmp(buffer, "east") || !strcasecmp(buffer, "west") 817 || !strcasecmp(buffer, "up") || !strcasecmp(buffer, "down")) { 818 doGo(); 819 } else if (tolower(buffer[0]) == 'l') { 820 doLook(); 821 } else if (tolower(buffer[0]) == 't') { 822 doTake(); 823 } else if (tolower(buffer[0]) == 'e') { 824 doExamine(); 825 } else if (tolower(buffer[0]) == 'u') { 826 doUse(); 827 } else if (tolower(buffer[0]) == 'd') { 828 doDrop(); 829 } else if (tolower(buffer[0]) == 'q') { 830 doQuit(); 831 } else if (!strcasecmp(buffer, "xyzzy")) { 832 cprintf("Nice try, but that won't work here.\r\n"); 833 } else { 834 cprintf("I don't understand. Try 'help'.\r\n"); 835 } 836 837 /* Handle special actions. */ 838 doActions(); 839 } 840 841 cprintf("Game over after %d turns.\r\n", turnsPlayed); 842 cprintf("%s", "Do you want to play again (y/n)? "); 843 gets(buffer); 844 if (tolower(buffer[0]) == 'n') { 845 break; 846 } 847 } 848 return 0; 849 }