Created
April 1, 2014 02:05
-
-
Save coderd00d/9906382 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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