RCRPG/C: Difference between revisions
Content added Content deleted
m (→Code: last minute bug fix) |
Underscore (talk | contribs) (Various small improvements; now compiles without warnings under "gcc -std=c99 -pedantic-errors -Wall".) |
||
Line 44: | Line 44: | ||
#include <time.h> |
#include <time.h> |
||
#include <string.h> |
#include <string.h> |
||
#include <curses.h> |
#include <curses.h> |
||
#define MAX(a,b) ( (a)>(b) ? (a) : (b) ) |
#define MAX(a,b) ( (a)>(b) ? (a) : (b) ) |
||
/* position */ |
/* position */ |
||
struct position { |
struct position { |
||
unsigned ns, ew, ud; |
|||
}; |
}; |
||
typedef struct position position_t; |
typedef struct position position_t; |
||
/* objects */ |
/* objects */ |
||
enum objects { |
enum objects { |
||
Line 60: | Line 60: | ||
}; |
}; |
||
typedef enum objects object_t; |
typedef enum objects object_t; |
||
/* rooms */ |
/* rooms */ |
||
#define DESCR_LEN 256 |
#define DESCR_LEN 256 |
||
Line 67: | Line 67: | ||
#define UD_LIMIT 4 |
#define UD_LIMIT 4 |
||
#define MAX_OBJS_PER_ROOM 20 |
#define MAX_OBJS_PER_ROOM 20 |
||
enum dir { |
enum dir { |
||
NORTH=0, SOUTH, |
NORTH=0, SOUTH, |
||
Line 74: | Line 74: | ||
}; |
}; |
||
enum dir invdir[DIR_NUM] = { SOUTH, NORTH, WEST, EAST, DOWN, UP }; |
enum dir invdir[DIR_NUM] = { SOUTH, NORTH, WEST, EAST, DOWN, UP }; |
||
position_t incdir[DIR_NUM] = { |
position_t incdir[DIR_NUM] = { |
||
{ 1, 0, 0 }, |
{ 1, 0, 0 }, |
||
Line 81: | Line 81: | ||
{ 0, 0, 1 }, { 0, 0, -1 } |
{ 0, 0, 1 }, { 0, 0, -1 } |
||
}; |
}; |
||
char *str_dirs = "nsewud"; |
char *str_dirs = "nsewud"; |
||
struct room { |
struct room { |
||
struct room *dirs[DIR_NUM]; |
struct room *dirs[DIR_NUM]; |
||
Line 89: | Line 89: | ||
int lo; /* last object */ |
int lo; /* last object */ |
||
int description; |
int description; |
||
bool visited; |
|||
}; |
}; |
||
typedef struct room room_t; |
typedef struct room room_t; |
||
/* descriptions */ |
/* descriptions */ |
||
char *descriptions[] = { |
char *descriptions[] = { |
||
Line 106: | Line 106: | ||
"room which breathes pain" |
"room which breathes pain" |
||
}; |
}; |
||
char *objs[] = { |
char *objs[] = { |
||
"nothing", "sledge", "ladder", "gold", "equipped sledge" |
"nothing", "sledge", "ladder", "gold", "equipped sledge" |
||
}; |
}; |
||
char *dirnames[] = { |
char *dirnames[] = { |
||
"north", "south", "east", "west", "up", "down" |
"north", "south", "east", "west", "up", "down" |
||
}; |
}; |
||
/* room stores and more (private) */ |
/* room stores and more (private) */ |
||
room_t *rooms[NS_LIMIT*EW_LIMIT*UD_LIMIT]; |
room_t *rooms[NS_LIMIT*EW_LIMIT*UD_LIMIT]; |
||
unsigned room_i = 0; |
|||
int py = 0; |
int py = 0; |
||
/* what you carry */ |
/* what you carry */ |
||
#define MAX_CARRYABLE 25 |
#define MAX_CARRYABLE 25 |
||
object_t carrylist[MAX_CARRYABLE]; |
object_t carrylist[MAX_CARRYABLE]; |
||
unsigned carried_number = 0; |
|||
/* where are you */ |
/* where are you */ |
||
position_t my_pos = { NS_LIMIT>>1, EW_LIMIT>>1, UD_LIMIT>>1 }; |
position_t my_pos = { NS_LIMIT>>1, EW_LIMIT>>1, UD_LIMIT>>1 }; |
||
position_t goal_pos; |
position_t goal_pos; |
||
room_t *currentroom = NULL; |
room_t *currentroom = NULL; |
||
/* ladders pos.s (global) */ |
/* ladders pos.s (global) */ |
||
position_t ladders[UD_LIMIT]; |
position_t ladders[UD_LIMIT]; |
||
/* random */ |
/* random */ |
||
int rangerandom(int from , int to) |
int rangerandom(int from , int to) |
||
Line 144: | Line 144: | ||
return from + (int) ((to-from+1)*(rand() / (RAND_MAX+1.0))); |
return from + (int) ((to-from+1)*(rand() / (RAND_MAX+1.0))); |
||
} |
} |
||
/* add_object */ |
/* add_object */ |
||
void add_object(object_t *ol, int *n, object_t o) |
void add_object(object_t *ol, int *n, object_t o) |
||
Line 153: | Line 153: | ||
} |
} |
||
} |
} |
||
/* check goal */ |
/* check goal */ |
||
bool in_pos(position_t *p) |
|||
{ |
{ |
||
if ( (my_pos.ns == p->ns) && |
if ( (my_pos.ns == p->ns) && |
||
Line 162: | Line 162: | ||
return false; |
return false; |
||
} |
} |
||
/* ROOM */ |
/* ROOM */ |
||
room_t *create_room(enum objects ob1, ...) |
room_t *create_room(enum objects ob1, ...) |
||
Line 169: | Line 169: | ||
enum objects o; |
enum objects o; |
||
int i, l; |
int i, l; |
||
if ( room_i >= (NS_LIMIT*EW_LIMIT*UD_LIMIT) ) return NULL; |
if ( room_i >= (NS_LIMIT*EW_LIMIT*UD_LIMIT) ) return NULL; |
||
rooms[room_i] = malloc(sizeof(room_t)); |
rooms[room_i] = malloc(sizeof(room_t)); |
||
for(i=0; i < DIR_NUM; i++) rooms[room_i]->dirs[i] = NULL; |
for(i=0; i < DIR_NUM; i++) rooms[room_i]->dirs[i] = NULL; |
||
rooms[room_i]->lo = 0; |
rooms[room_i]->lo = 0; |
||
if ( ob1 != NOTHING ) |
if ( ob1 != NOTHING ) |
||
add_object(rooms[room_i]->ol, &rooms[room_i]->lo, ob1); |
add_object(rooms[room_i]->ol, &rooms[room_i]->lo, ob1); |
||
va_start(ap, ob1); |
va_start(ap, ob1); |
||
while( (o = va_arg(ap, enum objects)) != NOTHING ) { |
while( (o = va_arg(ap, enum objects)) != NOTHING ) { |
||
Line 183: | Line 183: | ||
} |
} |
||
va_end(ap); |
va_end(ap); |
||
rooms[room_i]->visited = false; |
rooms[room_i]->visited = false; |
||
rooms[room_i]->description = rangerandom(0, sizeof(descriptions)/sizeof(void *) - 1); |
rooms[room_i]->description = rangerandom(0, sizeof(descriptions)/sizeof(void *) - 1); |
||
/* put some random object - sledge or gold */ |
/* put some random object - sledge or gold */ |
||
for(i=0; i < 4; i++) { |
for(i=0; i < 4; i++) { |
||
Line 198: | Line 198: | ||
} |
} |
||
} |
} |
||
room_i++; |
room_i++; |
||
return rooms[room_i-1]; |
return rooms[room_i-1]; |
||
} |
} |
||
void free_rooms() |
void free_rooms() |
||
{ |
{ |
||
Line 209: | Line 209: | ||
for(i=0; i < room_i; i++) free(rooms[i]); |
for(i=0; i < room_i; i++) free(rooms[i]); |
||
} |
} |
||
/* show description */ |
/* show description */ |
||
void print_cmd(int y, int x, char *str) |
void print_cmd(int y, int x, char *str) |
||
{ |
{ |
||
int i, l; |
int i, l; |
||
l = strlen(str); |
l = strlen(str); |
||
move(y, x); |
move(y, x); |
||
Line 230: | Line 230: | ||
} |
} |
||
} |
} |
||
void show_description() |
void show_description() |
||
{ |
{ |
||
int i, pe; |
int i, pe; |
||
char buf[100]; |
char buf[100]; |
||
py = 0; |
py = 0; |
||
clear(); |
clear(); |
||
Line 248: | Line 248: | ||
sprintf(buf, " (%d,%d,%d)", my_pos.ns, my_pos.ew, my_pos.ud); |
sprintf(buf, " (%d,%d,%d)", my_pos.ns, my_pos.ew, my_pos.ud); |
||
addstr(buf); |
addstr(buf); |
||
move(3, 0); |
move(3, 0); |
||
addstr("You can see:"); |
addstr("You can see:"); |
||
Line 305: | Line 305: | ||
move(++py, 0); addstr("> "); |
move(++py, 0); addstr("> "); |
||
} |
} |
||
void help() |
void help() |
||
{ |
{ |
||
Line 336: | Line 336: | ||
} |
} |
||
} |
} |
||
/* cmd_get */ |
/* cmd_get */ |
||
bool cmd_get() |
|||
{ |
{ |
||
if ( carried_number == MAX_CARRYABLE ) { |
if ( carried_number == MAX_CARRYABLE ) { |
||
Line 352: | Line 352: | ||
return true; |
return true; |
||
} |
} |
||
/* cmd_equip */ |
/* cmd_equip */ |
||
bool cmd_equip() |
|||
{ |
{ |
||
if ( carried_number == 0 ) { |
if ( carried_number == 0 ) { |
||
Line 374: | Line 374: | ||
return true; |
return true; |
||
} |
} |
||
bool cmd_drop(void); |
|||
bool cmd_hit() |
|||
{ |
{ |
||
int d, c; |
int d, c; |
||
bool nok = true; |
|||
if ( carried_number == 0 ) { |
if ( carried_number == 0 ) { |
||
clrtoeol(); |
clrtoeol(); |
||
Line 407: | Line 407: | ||
case 'u': |
case 'u': |
||
case 'd': |
case 'd': |
||
d = |
d = strchr(str_dirs, c) - str_dirs; |
||
if ( ((my_pos.ns + incdir[d].ns) >= NS_LIMIT) || |
if ( ((my_pos.ns + incdir[d].ns) >= NS_LIMIT) || |
||
((my_pos.ew + incdir[d].ew) >= EW_LIMIT) || |
((my_pos.ew + incdir[d].ew) >= EW_LIMIT) || |
||
Line 437: | Line 437: | ||
return true; |
return true; |
||
} |
} |
||
/* cmd_drop */ |
/* cmd_drop */ |
||
bool cmd_drop() |
|||
{ |
{ |
||
if ( carried_number == 0 ) { |
if ( carried_number == 0 ) { |
||
Line 453: | Line 453: | ||
return true; |
return true; |
||
} |
} |
||
/* main loop */ |
/* main loop */ |
||
bool do_action() |
|||
{ |
{ |
||
int c, d; |
int c, d; |
||
while(1) |
while(1) |
||
{ |
{ |
||
Line 507: | Line 507: | ||
case 'u': |
case 'u': |
||
case 'd': |
case 'd': |
||
d = |
d = strchr(str_dirs, c) - str_dirs; |
||
if ( currentroom->dirs[d] == NULL ) { |
if ( currentroom->dirs[d] == NULL ) { |
||
clrtoeol(); |
clrtoeol(); |
||
Line 543: | Line 543: | ||
return false; |
return false; |
||
} |
} |
||
int main() |
int main() |
||
{ |
{ |
||
int i; |
int i; |
||
bool quit = false; |
|||
initscr(); cbreak; noecho(); |
initscr(); cbreak(); noecho(); |
||
srand(time(NULL)); |
srand(time(NULL)); |
||
/* init ladders in at least one room of each "floor" */ |
/* init ladders in at least one room of each "floor" */ |
||
for(i=0; i < UD_LIMIT; i++) { |
for(i=0; i < UD_LIMIT; i++) { |
||
Line 559: | Line 559: | ||
ladders[i].ud = i; |
ladders[i].ud = i; |
||
} |
} |
||
/* goal pos */ |
/* goal pos */ |
||
goal_pos.ns = rangerandom(0, NS_LIMIT-1); |
goal_pos.ns = rangerandom(0, NS_LIMIT-1); |
||
goal_pos.ew = rangerandom(0, EW_LIMIT-1); |
goal_pos.ew = rangerandom(0, EW_LIMIT-1); |
||
goal_pos.ud = rangerandom(0, UD_LIMIT-1); |
goal_pos.ud = rangerandom(0, UD_LIMIT-1); |
||
/* init room */ |
/* init room */ |
||
currentroom = create_room(SLEDGE, GOLD, NOTHING); |
currentroom = create_room(SLEDGE, GOLD, NOTHING); |
||
/* main loop */ |
/* main loop */ |
||
while( (! in_pos(&goal_pos)) && !quit ) |
while( (! in_pos(&goal_pos)) && !quit ) |
||
Line 589: | Line 589: | ||
getch(); |
getch(); |
||
} |
} |
||
free_rooms(); |
free_rooms(); |
||
nocbreak(); echo(); endwin(); |
nocbreak(); echo(); endwin(); |