Skip to content

Instantly share code, notes, and snippets.

@coderd00d
Created April 1, 2014 02:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save coderd00d/9906382 to your computer and use it in GitHub Desktop.
Save coderd00d/9906382 to your computer and use it in GitHub Desktop.
// main.m
#import <Foundation/Foundation.h>
#import "WumpusEngine.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
WumpusEngine *engine = [[WumpusEngine alloc] initWithMapSize: 10];
[engine runGame];
}
return 0;
}
// Room.h
#import <Foundation/Foundation.h>
typedef enum rTypes {
ROOM_EMPTY = 0,
ROOM_ENTRANCE = 1,
ROOM_GOLD = 2,
ROOM_WEAPON = 3,
ROOM_PIT = 4,
ROOM_WUMPUS = 5,
ROOM_WALL = 6
} RoomType;
@interface Room : NSObject
@property RoomType roomType;
@property int roomNumber;
@property bool playerInRoom;
- (instancetype) initAsRoomType: (RoomType) type;
- (void) display;
- (bool) isExplored;
- (void) exploreRoom;
@end
// Room.m
#import "Room.h"
@implementation Room {
bool isExplored;
}
/*************************************************************/
@synthesize roomType;
@synthesize roomNumber;
@synthesize playerInRoom;
/*************************************************************/
- (instancetype) initAsRoomType: (RoomType) type {
self = [super init];
if (self) {
roomType = type;
roomNumber = -1;
isExplored = false;
playerInRoom = false;
}
return self;
}
/*************************************************************/
-(instancetype) init {
return [self initAsRoomType: ROOM_EMPTY];
}
/*************************************************************/
-(void) display; {
if (playerInRoom) {
printf("@");
} else if (!isExplored) {
printf("?");
} else {
switch (roomType) {
case ROOM_EMPTY:
printf(".");
break;
case ROOM_ENTRANCE:
printf("^");
break;
case ROOM_GOLD:
printf("$");
break;
case ROOM_WEAPON:
printf("*");
break;
case ROOM_PIT:
printf("P");
break;
case ROOM_WUMPUS:
printf("W");
break;
case ROOM_WALL:
printf("#");
break;
default:
printf(" ");
}
}
}
/*************************************************************/
- (bool) isExplored {
return isExplored;
}
/*************************************************************/
- (void) exploreRoom {
isExplored = true;
}
/*************************************************************/
@end
// Cave.h
#import <Foundation/Foundation.h>
@class Room;
@interface Cave : NSObject
@property int playerScore;
@property bool playerHasWeapon;
- (instancetype) initAsSize: (int) n;
-(void) showHints;
-(void) showCave;
-(void) showTorchView;
-(void) showRoomDescription;
-(Room *) roomAtIndex: (int) n;
-(Room *) playerRoom;
-(bool) move: (char) dir;
-(bool) lootRoom;
-(bool) actionHandler;
@end
// Cave.m
#import "Cave.h"
#import "Room.h"
@implementation Cave {
NSMutableArray *cave;
int sizeOfCave;
int roomsPerRow;
int playerRoomIndex;
}
@synthesize playerScore;
@synthesize playerHasWeapon;
/*************************************************************/
- (instancetype) init {
return [self initAsSize: 10];
}
/*************************************************************/
- (instancetype) initAsSize: (int) n {
self = [super init];
if (self) {
Room *newRoom;
playerScore = 0;
playerHasWeapon = false;
playerRoomIndex = -1;
roomsPerRow = n+2;
sizeOfCave = roomsPerRow * roomsPerRow;
cave = [[NSMutableArray alloc] init];
// generate random cave
for (int i = 0; i < sizeOfCave; i++) {
if ( i < roomsPerRow ||
i > sizeOfCave - roomsPerRow ||
i % roomsPerRow == 0 ||
i % roomsPerRow == 11) {
newRoom = [[Room alloc] initAsRoomType: ROOM_WALL];
[newRoom exploreRoom];
} else {
newRoom = [[Room alloc] initAsRoomType: ROOM_EMPTY];
}
[newRoom setRoomNumber: i];
[cave addObject: newRoom];
}
// create a pool of room numbers to randomly pick for room assignments.
NSMutableArray *rnum = [[NSMutableArray alloc] init];
for (int i = 0; i < sizeOfCave; i++) {
if ( i < roomsPerRow ||
i > sizeOfCave - roomsPerRow ||
i % roomsPerRow == 0 ||
i % roomsPerRow == 11) {
// do nothing
} else {
NSNumber *num = [NSNumber numberWithInt: i];
[rnum addObject: num];
}
}
// wumpus rooms
int roomCount = n * n;
int limit = (int) ((float)roomCount * 0.15);
Room *modRoom;
for (int i = 0; i < limit ; i++) {
int randomIndex = arc4random() % [rnum count];
modRoom = [cave objectAtIndex: [[rnum objectAtIndex: randomIndex] intValue]];
[rnum removeObjectAtIndex: randomIndex];
[modRoom setRoomType: ROOM_WUMPUS];
}
// weapon rooms
limit = (int) ((float)roomCount * 0.15);
for (int i = 0; i < limit ; i++) {
int randomIndex = arc4random() % [rnum count];
modRoom = [cave objectAtIndex: [[rnum objectAtIndex: randomIndex] intValue]];
[rnum removeObjectAtIndex: randomIndex];
[modRoom setRoomType: ROOM_WEAPON];
}
// pit traps
limit = (int) ((float)roomCount * 0.05);
for (int i = 0; i < limit ; i++) {
int randomIndex = arc4random() % [rnum count];
modRoom = [cave objectAtIndex: [[rnum objectAtIndex: randomIndex] intValue]];
[rnum removeObjectAtIndex: randomIndex];
[modRoom setRoomType: ROOM_PIT];
}
// Gold Rooms
limit = (int) ((float)roomCount * 0.15);
for (int i = 0; i < limit ; i++) {
int randomIndex = arc4random() % [rnum count];
modRoom = [cave objectAtIndex: [[rnum objectAtIndex: randomIndex] intValue]];
[rnum removeObjectAtIndex: randomIndex];
[modRoom setRoomType: ROOM_GOLD];
}
// Entrance
limit = 1;
for (int i = 0; i < limit ; i++) {
int randomIndex = arc4random() % [rnum count];
modRoom = [cave objectAtIndex: [[rnum objectAtIndex: randomIndex] intValue]];
[modRoom setRoomType: ROOM_ENTRANCE];
playerRoomIndex = [[rnum objectAtIndex: randomIndex] intValue];
[modRoom setPlayerInRoom: true];
[modRoom exploreRoom];
[rnum removeObjectAtIndex: randomIndex];
}
}
return self;
}
/*************************************************************/
- (void) showCave {
for (Room *r in cave) {
[r display];
if ([r roomNumber] % (roomsPerRow) == 11)
printf("\n");
}
}
/*************************************************************/
- (void) showHints {
if ([[cave objectAtIndex: (playerRoomIndex - roomsPerRow)] roomType] == ROOM_WUMPUS ||
[[cave objectAtIndex: (playerRoomIndex + roomsPerRow)] roomType] == ROOM_WUMPUS ||
[[cave objectAtIndex: (playerRoomIndex - 1)] roomType] == ROOM_WUMPUS ||
[[cave objectAtIndex: (playerRoomIndex + 1)] roomType] == ROOM_WUMPUS) {
printf("A foul stench fills the air.\n");
}
if ([[cave objectAtIndex: (playerRoomIndex - roomsPerRow)] roomType] == ROOM_PIT ||
[[cave objectAtIndex: (playerRoomIndex + roomsPerRow)] roomType] == ROOM_PIT ||
[[cave objectAtIndex: (playerRoomIndex - 1)] roomType] == ROOM_PIT ||
[[cave objectAtIndex: (playerRoomIndex + 1)] roomType] == ROOM_PIT) {
printf("There is a wind of death in the air.\n");
}
printf("\n");
}
/*************************************************************/
- (void) showRoomDescription {
switch([[cave objectAtIndex: playerRoomIndex] roomType]) {
case ROOM_EMPTY:
printf("You stand in an empty room with nothing in it.\n");
break;
case ROOM_ENTRANCE:
printf("Fresh air blows in from the ENTRANCE to the cave.\n");
break;
case ROOM_GOLD:
printf("The room is filled with Gold.\n");
break;
case ROOM_WEAPON:
printf("A vorpal sword shines brightly calling you to loot it.\n");
break;
case ROOM_PIT:
printf("The ground seems to disappear and feel your fall:\n");
break;
case ROOM_WUMPUS:
printf("Before you a smelly Wumpus approaches to eat you.\n");
break;
default:
printf("You stand in the void.\n");
}
printf("\n");
}
/*************************************************************/
- (void) showTorchView {
[[cave objectAtIndex: playerRoomIndex - roomsPerRow - 1] display];
[[cave objectAtIndex: playerRoomIndex - roomsPerRow ] display];
[[cave objectAtIndex: playerRoomIndex - roomsPerRow + 1] display];
printf("\n");
[[cave objectAtIndex: playerRoomIndex - 1 ] display];
[[cave objectAtIndex: playerRoomIndex ] display];
[[cave objectAtIndex: playerRoomIndex + 1 ] display];
printf("\n");
[[cave objectAtIndex: playerRoomIndex + roomsPerRow - 1] display];
[[cave objectAtIndex: playerRoomIndex + roomsPerRow ] display];
[[cave objectAtIndex: playerRoomIndex + roomsPerRow + 1] display];
}
/*************************************************************/
-(Room *) roomAtIndex: (int) n {
return [cave objectAtIndex: n];
}
/*************************************************************/
-(Room *) playerRoom {
return [cave objectAtIndex: playerRoomIndex];
}
/*************************************************************/
-(bool) move: (char) dir {
Room *targetRoom;
Room *current = self.playerRoom;
printf("\n");
switch (dir) {
case 'N':
targetRoom = [cave objectAtIndex: playerRoomIndex - roomsPerRow ];
break;
case 'S':
targetRoom = [cave objectAtIndex: playerRoomIndex + roomsPerRow ];
break;
case 'E':
targetRoom = [cave objectAtIndex: playerRoomIndex + 1];
break;
case 'W':
targetRoom = [cave objectAtIndex: playerRoomIndex - 1];
break;
}
if ([targetRoom roomType] == ROOM_WALL) {
printf("You bump into a wall OUCH! Try a different direction!.\n\n");
return false;
}
printf("You move ");
switch (dir) {
case 'N':
printf("North\n");
break;
case 'S':
printf("South\n");
break;
case 'E':
printf("East\n");
break;
case 'W':
printf("West\n");
break;
}
printf("\n");
[current setPlayerInRoom: false];
[targetRoom setPlayerInRoom: true];
if (![targetRoom isExplored]) {
playerScore++;
}
playerRoomIndex = [targetRoom roomNumber];
[targetRoom exploreRoom];
return true;
}
/*************************************************************/
-(bool) lootRoom {
if ([[self playerRoom] roomType] == ROOM_WEAPON) {
printf("You arm yourself with a sword!\n\n");
[[self playerRoom] setRoomType: ROOM_EMPTY];
playerHasWeapon = true;
playerScore += 5;
for (Room *r in cave) {
if ([r roomType] == ROOM_WEAPON)
[r setRoomType: ROOM_GOLD];
}
return true;
} else if ([[self playerRoom] roomType] == ROOM_GOLD) {
printf("You loot some Gold!\n");
playerScore += 5;
[[self playerRoom] setRoomType: ROOM_EMPTY];
return true;
}
printf("\nThere is nothing in the room you can loot!\n\n");
return false;
}
/*************************************************************/
-(bool) actionHandler {
if ([[self playerRoom] roomType] == ROOM_WUMPUS) {
if (playerHasWeapon) {
printf("You SLAY the WUMPUS! Victory!\n\n");
[[self playerRoom] setRoomType: ROOM_EMPTY];
playerScore += 10;
return true;
} else {
printf("Uh oh! Unarmed you are no match for the hungry Wumpus.\n\n***BURP***\n\nYou make a great meal!\n");
playerScore--;
return false;
}
} else if ([[self playerRoom] roomType] == ROOM_PIT) {
playerScore--;
printf("Fall\n....Fall\n........Fall\n............Fall to your DOOM! *SPLAT*!!\n\n");
return false;
}
return true;
}
@end
// WumpusEngine.h
#import <Foundation/Foundation.h>
@interface WumpusEngine : NSObject
- (instancetype) initWithMapSize: (int) n;
- (void) runGame;
@end
// WumpusEngine.m
#import "WumpusEngine.h"
#import "Room.h"
#import "Cave.h"
@implementation WumpusEngine {
Cave *cave;
int gridSizeOfN;
}
/*************************************************************/
- (instancetype) init {
return [self initWithMapSize: 10];
}
/*************************************************************/
- (instancetype) initWithMapSize: (int) n {
self = [super init];
if (self) {
gridSizeOfN = n;
}
return self;
}
/*************************************************************/
-(void) commandHelp {
printf("\nValid Commands:\n");
printf("? -- List of commands\n");
printf("N -- Move North\n");
printf("S -- Move South\n");
printf("E -- Move East\n");
printf("W -- Move West\n");
printf("L -- Loot weapon or gold\n");
printf("R -- Run out of cave entrance\n");
printf("X -- Exit game\n\n");
}
/*************************************************************/
-(void) commandMove: (char) direction {
if ([cave move: direction]) {
[cave showRoomDescription];
}
}
/*************************************************************/
-(void) commandLoot {
[cave lootRoom];
}
/*************************************************************/
-(bool) commandRunOut {
if ([[cave playerRoom] roomType] == ROOM_ENTRANCE)
return true;
else
return false;
}
/*************************************************************/
// Main game loop
- (void) runGame {
char move;
char newline;
bool gameIsActive = true;
cave = [[Cave alloc] initAsSize: 10];
printf("Welcome to Wumpus Cave 1.0 -- May Fortune Smile Upon Thee\n\n");
while (gameIsActive) {
[cave showTorchView];
printf("\n\n");
[cave showHints];
[cave showRoomDescription];
printf("[Earned %d point(s)] [You are", [cave playerScore]);
if ([cave playerHasWeapon]) {
printf(" armed");
} else {
printf(" unarmed");
}
printf("] Enter Move (? for help)>");
scanf("%c%c", &move, &newline);
move = toupper(move);
switch (move) {
case '?' :
case 'H' :
[self commandHelp];
break;
case 'N' :
case 'S' :
case 'E' :
case 'W' :
[self commandMove:move];
if([cave actionHandler]) {
// do nothing
} else {
[self endOfGame];
gameIsActive = false;
}
break;
case 'L' :
[self commandLoot];
break;
case 'R' :
if ([self commandRunOut]) {
printf("\nYou run out of the cave and head to town!\n");
[self endOfGame];
gameIsActive = false;
} else {
printf("\nYou can only run out of the cave at the entrance!\n\n");
}
break;
case 'X' :
gameIsActive = false;
break;
default:
printf("\nCommand not recognized. Try again.\n\n");
}
}
};
/*************************************************************/
- (void) endOfGame {
printf("\n***GAME OVER*** You Scored %d point(s)!!\n\n", [cave playerScore]);
}
/*************************************************************/
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment