eris2010

Documentation: http://frombelow.net/projects/eris2010/
Clone: git clone https://git.frombelow.net/eris2010.git
Log | Files | Refs | README | LICENSE

wumpus.c (7372B)


      1 // Copyright Creative Computing, Morristown, New Jersey
      2 // C conversion by Payton Byrd from BASIC in "More BASIC
      3 // Computer Games" by Creative Computing.
      4 //
      5 // Adapted for CC65 by gb
      6 
      7 #include <ctype.h>
      8 #include <stdlib.h>
      9 #include <stdio.h>
     10 #include <string.h>
     11 #include <stdbool.h>
     12 #include <time.h>
     13 #include <conio.h>
     14 
     15 unsigned char arrows = 5u;
     16 
     17 unsigned char items[6];
     18 
     19 // Rooms and their connections
     20 const unsigned char rooms[20][3] =
     21 {
     22 	{ 2, 5, 8 },	// 1
     23 	{ 1, 3, 10 },	// 2
     24 	{ 2, 4, 12 },	// 3
     25 	{ 3, 5, 14 },	// 4
     26 	{ 1, 4, 6 },	// 5
     27 	{ 5, 7, 15 },	// 6
     28 	{ 6, 8, 17 },	// 7
     29 	{ 1, 7, 9 },	// 8
     30 	{ 8, 10, 18 },	// 9
     31 	{ 2, 9, 11 },	// 10
     32 	{ 10, 12, 19 },	// 11
     33 	{ 3, 11, 13 },	// 12
     34 	{ 12, 14, 20 }, // 13
     35 	{ 4, 13, 15 },	// 14
     36 	{ 6, 14, 16 },	// 15
     37 	{ 15, 17, 20 },	// 16
     38 	{ 7, 16, 18 },	// 17
     39 	{ 9, 17, 19 },	// 18
     40 	{ 11, 18, 20 },	// 19
     41 	{ 13, 16, 19 }	// 20
     42 };
     43 
     44 // Generates a random number between 1 and 20
     45 unsigned char fna()
     46 {
     47 	return (unsigned char)(rand() % 20u + 1u);
     48 }
     49 
     50 // Generates a random number between 1 and 3
     51 unsigned char fnb()
     52 {
     53 	return (unsigned char)(rand() % 3u + 1u);
     54 }
     55 
     56 // Generates a random number between 1 and 4
     57 unsigned char fnc()
     58 {
     59 	return (unsigned char)(rand() % 4u + 1u);
     60 }
     61 
     62 // Ensures all items are in different rooms.
     63 bool validateItems(void)
     64 {
     65 	unsigned char i, j;
     66 
     67 	for(i = 0; i < 6; ++i)
     68 	{
     69 		for(j = 0; j < 6; ++j)
     70 		{
     71 			if(i != j)
     72 			{
     73 				if(items[i] == items[j]) 
     74 				{
     75 					// OOPS, two items in
     76 					// same room, no good!
     77 					return false;
     78 				}
     79 			}
     80 		}
     81 	}
     82 
     83 	return true;
     84 }
     85 
     86 // Place each item in a separate room.
     87 void randomizeItems(unsigned int seed)
     88 {
     89   // Seeding of RNG changed by gb
     90   srand(seed);
     91 
     92 	do
     93 	{
     94 		items[0] = fna(); // You
     95 		items[1] = fna(); // Wumpus
     96 		items[2] = fna(); // Bat
     97 		items[3] = fna(); // Bat
     98 		items[4] = fna(); // Pit
     99 		items[5] = fna(); // Pit
    100 	}
    101 	while(!validateItems());
    102 }
    103 
    104 // Displays information about the current room.
    105 void printLocation()
    106 {	
    107 	unsigned char k;
    108 
    109 	cputs("\r\n");
    110 
    111 	for(k = 0; k < 3; ++k)
    112 	{
    113 		if(rooms[items[0]-1][k] == items[1])
    114 		{
    115 			cputs("I smell a wumpus!\r\n");
    116 		}
    117 
    118 		if(rooms[items[0]-1][k] == items[2]
    119 			|| rooms[items[0]-1][k] == items[3])
    120 		{
    121 			cputs("Bats nearby!\r\n");
    122 		}
    123 
    124 		if(rooms[items[0]-1][k] == items[4]
    125 			|| rooms[items[0]-1][k] == items[5])
    126 		{
    127 			cputs("I feel a draft!\r\n");
    128 		}
    129 	}
    130 
    131 	cprintf("You are in room %u\r\n", items[0]);
    132 	cprintf("Tunnels lead to %u, %u, %u\r\n",
    133 		rooms[items[0]-1][0],
    134 		rooms[items[0]-1][1],
    135 		rooms[items[0]-1][2]);
    136 }
    137 
    138 // User selects whether to shoot or move.
    139 unsigned char chooseOption()
    140 {
    141 	unsigned char input = '\0';
    142 
    143 	while(input != 'm' && input != 's' && input != 'q')
    144 	{
    145 		cprintf("\r\nShoot or move [M or S]: ");
    146 		input = cgetc();
    147 		tolower(input);
    148 	}
    149 
    150 	return input;
    151 }
    152 
    153 // User selects the number of rooms
    154 // to shoot the arrow through.
    155 unsigned char chooseNumberOfRooms()
    156 {
    157 	unsigned char input = 0;
    158 	unsigned char result[1] = "";
    159 
    160 	while(input < '1' || input > '5')
    161 	{
    162 		cprintf("\r\nNo. of rooms (1-5):");
    163 		input = cgetc();
    164 	}
    165 
    166 	sprintf(result, "%c", input);
    167 
    168 	return (unsigned char)atoi(result);
    169 }
    170 
    171 // User selects a room adjacent to the current
    172 // room.
    173 unsigned char chooseRoom(unsigned char currentRoom)
    174 {
    175 	char input[3];
    176 	char selectedRoom;
    177 	int result = -1;
    178 	
    179 	do
    180 	{
    181 		cprintf("\r\nChoose room [%u, %u, %u]: ",
    182 			rooms[currentRoom - 1][0],
    183 			rooms[currentRoom - 1][1],
    184 			rooms[currentRoom - 1][2]);
    185 
    186 		cscanf("%s", input);
    187 
    188 		selectedRoom = (unsigned char)atoi(input);
    189 
    190 		if(selectedRoom == rooms[currentRoom - 1][0]
    191 			|| selectedRoom == rooms[currentRoom - 1][1]
    192 			|| selectedRoom == rooms[currentRoom - 1][2])
    193 		{
    194 			result = selectedRoom;
    195 		}
    196 	} 
    197 	while(result == -1);
    198 
    199 	cputs("\r\n");
    200 
    201 	return (unsigned char)result;
    202 }
    203 
    204 // User fires an arrow
    205 char shootArrow()
    206 {
    207 	unsigned char counter, room;
    208 	unsigned char numberOfRooms;
    209 	
    210 	// Get the number of rooms for the arrow
    211 	// to travel.
    212 	numberOfRooms = chooseNumberOfRooms();
    213 		
    214 	// Start in our room.
    215 	room = items[0];
    216 
    217 	// Loop the number of rooms selected.
    218 	for(counter = 0; counter < numberOfRooms; ++counter)
    219 	{
    220 		// Move arrow to chosen room.
    221 		room = chooseRoom(room);
    222 	}
    223 
    224 	// Did we hit him?
    225 	if(room == items[1])
    226 	{
    227 		cputs("\r\nAHA!  You got the Wumpus!\r\n");
    228 		return 1;
    229 	}
    230 
    231 	// Did we hit ourself?
    232 	if(room == items[0])
    233 	{
    234 		cputs("\r\nOUCH!  The arrow got you!\r\n");
    235 		return -1;
    236 	}
    237 
    238 	// Decrement arrow count
    239 	--arrows;
    240 	cputs("\r\nMissed.\r\n");
    241 
    242 	if(arrows == 0)
    243 	{
    244 		// Uh oh.
    245 		cputs("\r\nYou are out of arrows!\r\n");
    246 		return -1;
    247 	}
    248 
    249 	return 0;
    250 }
    251 
    252 // Moves the wumpus.
    253 char moveWumpus()
    254 {
    255 	// Randomly chooses another room.
    256 	items[1] = rooms[items[1]][fnc()];
    257 	
    258 	// Are we sharing a room with the wumpus now?
    259 	if(items[1] == items[0])
    260 	{
    261 		cputs("\r\n\r\nTSK TSK TSK - Wumpus got you!");
    262 		return 1;
    263 	}
    264 
    265 	return 0;
    266 }
    267 
    268 // Move the player
    269 char movePlayer()
    270 {
    271 	unsigned char newRoom = 0;
    272 	char wumpusResult;
    273 
    274 	// Choose the room to move to.
    275 	newRoom = chooseRoom(items[0]);
    276 
    277 	// Did we actually move?
    278 	if(items[0] == newRoom)
    279 	{
    280 		cputs("Can't stay still!");
    281 		return 0;
    282 	}
    283 
    284 	// Set the items array to our new 
    285 	// room.
    286 	items[0] = newRoom;
    287 
    288 	// Did we find the wumpus?
    289 	if(items[1] == newRoom)
    290 	{
    291 		// Yup, make him move.
    292 		cputs("\r\n\r\n... OOPS!  Bumped a Wumpus!\r\n");
    293 		
    294 		wumpusResult = moveWumpus();
    295 		
    296 		return wumpusResult;
    297 	}
    298 	// Did we find a bat?
    299 	else if(items[2] == newRoom || items[3] == newRoom)
    300 	{
    301 		// Yup, it's off to Elsewhereville with the player
    302 		cputs("\r\n\r\nZAP--Super Bat Snatch!!  Elsewhereville for you!\r\n");
    303 
    304 		// Player's position is randomly selected from
    305 		// all 20 rooms.
    306 		items[0] = fna();
    307 	}
    308 	// Did we find a pit?
    309 	else if(items[4] == newRoom || items[5] == newRoom)
    310 	{
    311 		// Dum, dum, de dum...
    312 		cputs("\r\n\r\nYYYIIIIEEEE . . . Fell in pit!\r\n");
    313 		return 1;
    314 	}
    315 
    316 	return 0;
    317 }
    318 
    319 // Ye old main routine.
    320 void main(void)
    321 {
    322 	unsigned char option, shootResult;
    323 	unsigned int seed;
    324 
    325 	  // Polite header.
    326 #ifdef __CBM__
    327 	  putchar(147);
    328 #endif
    329 	  cputs("\r\nPress a key.\r\n");
    330 	  while(!kbhit()){
    331 	    ++seed;
    332 	  }
    333 	  cgetc();
    334 	  
    335 	  cputs("                WUMPUS!\r\n");
    336 	  cputs("           CREATIVE COMPUTING\r\n");
    337 	  cputs("             Morristown, NJ\r\n");
    338 	  cputs("      Converted to C by Payton Byrd\r\n");
    339 
    340 	
    341 	  // Put everything in it's place.
    342 	  randomizeItems(seed);
    343 
    344 	  // Loop until someone gets hurt.
    345 	  for(;;)
    346 	    {
    347 	      cputs("\r\n");
    348 
    349 	      // Display the location to the user.
    350 	      printLocation();
    351 
    352 	      // Get their choice of move or shoot
    353 	      option = tolower(chooseOption());
    354 	      if(option == 'q')
    355 		break;
    356 
    357 	      if(option == 's')
    358 		{
    359 		  // They chose to shoot.  Get result.
    360 		  shootResult = shootArrow();
    361 
    362 		  if(shootResult != 0)
    363 		    {
    364 		      // Something got shot
    365 		      break;
    366 		    }
    367 		}
    368 	      else
    369 		{
    370 		  // They chose to move.  Get result.
    371 		  if(movePlayer() == 1)
    372 		    {
    373 		      // Something bad happened to the player.
    374 		      break;
    375 		    }
    376 		}
    377 	    }
    378 	// That's all, folks!
    379 	  cputs("\r\nThanks for playing!\r\n");
    380 	  cgetc();
    381 }