Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- CFLAGS = -Wall -g
- src = ex19.c
- all: $(src)
- cc $(CFLAGS) -o ex19 $(src)
- ex19: object.o
- clean:
- rm -f ex19
- #ifndef _object_h
- #define _object_h
- typedef enum{
- NORTH, SOUTH, EAST, WEST
- } Direction;
- typedef struct {
- char *description;
- int (*init)(void *self);
- void (*describe)(void *self);
- void (*destroy)(void *self);
- void *(*move)(void *self, Direction direction);
- int (*attack)(void *self, int damage);
- } Object;
- int Object_init(void *self);
- void Object_destroy(void *self);
- void Object_describe(void *self);
- void *Object_move(void *self, Direction direction);
- int Object_attack(void *self, int damage);
- void *Object_new(size_t size, Object proto, char *description);
- #define NEW(T, N) Object_new(sizeof(T), T##Proto, N)
- #define _(N) proto.N
- #endif
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "object.h"
- #include <assert.h>
- void Object_destroy(void *self) {
- Object *obj = self;
- if(obj) {
- if(obj->description) free(obj->decription);
- free(obj);
- }
- }
- void Object_describe(void *self) {
- Object *obj = self;
- printf("%s.n", obj->description);
- }
- int Object_init(void *self){
- // do nothing really
- return 1;
- }
- void *Object_move(void *sefl, Direction direction){
- printf("You can't go that direction.n");
- return NULL;
- }
- int Object_attack(void *self, int damage){
- printf("You can't attack that.n");
- return 0;
- }
- void *Object_new(size_t size, Object proto, char *description){
- // setup the default functions in case they aren't set
- if(!proto.init) proto.init = Object_init;
- if(!proto.describe) proto.describe = Object_describe;
- if(!proto.destroy) proto.destroy = Object_destroy;
- if(!proto.attack) proto.attack = Object_attack;
- if(!proto.move) proto.move = Object_move;
- // this seems weird, but we can make a struct of one size,
- // then point a different pointer at it to "cast" it
- Object *el = calloc(1, size);
- *el = proto;
- // copy the description over
- el->description = strdup(description);
- // initialize it with whatever init we were given
- if(!el->init(el)){
- // looks like it didn't initialize properly
- el->destroy(el);
- return NULL;
- }
- else {
- //all done, we made an object of any type
- return el;
- }
- }
- #ifndef __ex19_h
- #define __ex19_h
- #include "object.h"
- struct Monster {
- Object proto;
- int hit_points;
- };
- typedef struct Monster Monster;
- int Monster_attack(void *self, int damage);
- int Monster_init(void *self);
- struct Room{
- Object proto;
- Monster *bad_guy;
- struct Room *north;
- struct Room *south;
- struct Room *east;
- struct Room *west;
- };
- typedef struct Room Room;
- void *Room_move(void *self, Direction direction);
- int Room_attack(void *self, int damage);
- int Room_init(void *self);
- struct Map{
- Object proto;
- Room *start;
- Room *location;
- };
- typedef struct Map Map;
- void *Map_move(void *self, Direction direction);
- int Map_attack(void *self, int damage);
- int Map_init(void *self);
- #endif
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <time.h>
- #include "ex19.h"
- int Monster_attack(void *self, int damage){
- Monster *monster = self;
- printf("You attack %s!n", monster->_(description));
- monster->hit_points -= damage;
- if(monster->hit_points > 0) {
- printf("It is still alive.n");
- return 0;
- }
- else{
- printf("It is dead!n");
- return 1;
- }
- }
- int Monster_init(void *self){
- Monster *monster = self;
- monster->hit_points = 10;
- return 1;
- }
- Object MonsterProto = {
- .init = Monster_init,
- .attack = Monster_attack
- };
- void *Room_move(void *self, Direction direction) {
- Room *room = self;
- Room *next = NULL;
- if(direction == NORTH && room->north) {
- printf("You go north, into:n");
- next = room->north;
- }
- else if(direction == SOUTH && room->south){
- printf("You go south, into:n");
- next = room->south;
- }
- else if(direction == EAST && room->east){
- printf("You go east, into:n");
- next = room->east;
- }
- else if(direction == WEST && room->west){
- printf("You go west, into:n");
- next = room->west;
- }
- else {
- printf("You can't go that direction.");
- next = NULL;
- }
- if(next){
- next->_(describe)(next);
- }
- return next;
- }
- int Room_attack(void *self, int damage){
- Room *room = self;
- Monster *monster = room->bad_guy;
- if(monster){
- monster->_(attack)(monster, damage);
- return 1;
- }
- else{
- printf("You flail in the air at nothing. Idiot.n");
- return 0;
- }
- }
- Object RoomProto = {
- .move = Room_move,
- .attack = Room_attack
- };
- void *Map_move(void *self, Direction direction){
- Map *map = self;
- Room *location = map->location;
- Room *next = NULL;
- next = location->_(move)(location, direction);
- if(next) {
- map->location = next;
- }
- return next;
- }
- int Map_attack(void *self, int damage){
- Map* map = self;
- Room *location = map->location;
- return location->_(attack)(location, damage);
- }
- int Map_init(void *self){
- Map *map = self;
- //make some rooms for a small map
- Room *hall = NEW(Room, "The great hall");
- Room *throne = NEW(Room, "The throne room");
- Room *arena = NEW(Room, "The arena, with the minotaur");
- Room *kitchen = NEW(Room, "Kitchen, you have the knife now");
- // put the bad guy in the arena
- arena->bad_guy = NEW(Monster, "The evil minotaur");
- // setup the map rooms
- hall->north = throne;
- throne->west = arena;
- throne->east = kitchen;
- throne->south = hall;
- arena->east = throne;
- kitchen->west = throne;
- //start the map and the character off in the hall
- map->start = hall;
- map->location = hall;
- return 1;
- }
- Object MapProto = {
- .init = Map_init,
- .move = Map_move,
- .attack = Map_attack
- };
- int process_input(Map *game){
- printf("n> ");
- char ch = getchar();
- getchar(); // eat enter;
- int damage = rand() % 4;
- switch(ch){
- case -1:
- printf("Giving up? You such.n");
- return 0;
- break;
- case 'n':
- game->_(move)(game, NORTH);
- break;
- case 's':
- game->_(move)(game, SOUTH);
- break;
- case 'e':
- game->_(move)(game, EAST);
- break;
- case 'w':
- game->_(move)(game, WEST);
- break;
- case 'a':
- game->_(attack)(game, damage);
- break;
- case 'l':
- printf("You can go:n");
- if(game->location->north) printf("NORTHn");
- if(game->location->south) printf("SOUTHn");
- if(game->location->east) printf("EASTn");
- if(game->location->west) printf("WESTn");
- break;
- default:
- printf("What?: %dn", ch);
- }
- return 1;
- }
- int main(int argc, char *argv[]){
- //simple way to setup the randomness
- srand(time(NULL));
- //make our map to work with
- Map *game = NEW(Map, "The hall of the Minotaur.");
- printf("You enter the ");
- game->location->_(describe)(game->location);
- while(process_input(game)) {
- }
- return 0;
- }
- 105 Room *hall = NEW(Room, "The great hall");
- 106 Room *throne = NEW(Room, "The throne room");
- 107 Room *arena = NEW(Room, "The arena, with the minotaur");
- 108 Room *kitchen = NEW(Room, "Kitchen, you have the knife now");
- 111 arena->bad_guy = NEW(Monster, "The evil minotaur");
- cc $(CFLAGS) -o ex19 $(src)
- cc -Wall -g -o ex19 ex19.c
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement