Advertisement
Guest User

Untitled

a guest
Dec 22nd, 2014
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.53 KB | None | 0 0
  1. CFLAGS = -Wall -g
  2. src = ex19.c
  3.  
  4. all: $(src)
  5. cc $(CFLAGS) -o ex19 $(src)
  6.  
  7. ex19: object.o
  8.  
  9. clean:
  10. rm -f ex19
  11.  
  12. #ifndef _object_h
  13. #define _object_h
  14.  
  15. typedef enum{
  16. NORTH, SOUTH, EAST, WEST
  17. } Direction;
  18.  
  19. typedef struct {
  20. char *description;
  21. int (*init)(void *self);
  22. void (*describe)(void *self);
  23. void (*destroy)(void *self);
  24. void *(*move)(void *self, Direction direction);
  25. int (*attack)(void *self, int damage);
  26. } Object;
  27.  
  28. int Object_init(void *self);
  29. void Object_destroy(void *self);
  30. void Object_describe(void *self);
  31. void *Object_move(void *self, Direction direction);
  32. int Object_attack(void *self, int damage);
  33. void *Object_new(size_t size, Object proto, char *description);
  34.  
  35. #define NEW(T, N) Object_new(sizeof(T), T##Proto, N)
  36. #define _(N) proto.N
  37.  
  38. #endif
  39.  
  40. #include <stdio.h>
  41. #include <string.h>
  42. #include <stdlib.h>
  43. #include "object.h"
  44. #include <assert.h>
  45.  
  46. void Object_destroy(void *self) {
  47. Object *obj = self;
  48.  
  49. if(obj) {
  50. if(obj->description) free(obj->decription);
  51. free(obj);
  52. }
  53. }
  54.  
  55. void Object_describe(void *self) {
  56. Object *obj = self;
  57. printf("%s.n", obj->description);
  58. }
  59.  
  60. int Object_init(void *self){
  61. // do nothing really
  62. return 1;
  63. }
  64.  
  65. void *Object_move(void *sefl, Direction direction){
  66. printf("You can't go that direction.n");
  67. return NULL;
  68. }
  69.  
  70. int Object_attack(void *self, int damage){
  71. printf("You can't attack that.n");
  72. return 0;
  73. }
  74.  
  75. void *Object_new(size_t size, Object proto, char *description){
  76. // setup the default functions in case they aren't set
  77. if(!proto.init) proto.init = Object_init;
  78. if(!proto.describe) proto.describe = Object_describe;
  79. if(!proto.destroy) proto.destroy = Object_destroy;
  80. if(!proto.attack) proto.attack = Object_attack;
  81. if(!proto.move) proto.move = Object_move;
  82.  
  83. // this seems weird, but we can make a struct of one size,
  84. // then point a different pointer at it to "cast" it
  85. Object *el = calloc(1, size);
  86. *el = proto;
  87.  
  88. // copy the description over
  89. el->description = strdup(description);
  90.  
  91. // initialize it with whatever init we were given
  92. if(!el->init(el)){
  93. // looks like it didn't initialize properly
  94. el->destroy(el);
  95. return NULL;
  96. }
  97. else {
  98. //all done, we made an object of any type
  99. return el;
  100. }
  101. }
  102.  
  103. #ifndef __ex19_h
  104. #define __ex19_h
  105.  
  106. #include "object.h"
  107.  
  108. struct Monster {
  109. Object proto;
  110. int hit_points;
  111. };
  112.  
  113. typedef struct Monster Monster;
  114.  
  115. int Monster_attack(void *self, int damage);
  116. int Monster_init(void *self);
  117.  
  118. struct Room{
  119. Object proto;
  120.  
  121. Monster *bad_guy;
  122.  
  123. struct Room *north;
  124. struct Room *south;
  125. struct Room *east;
  126. struct Room *west;
  127. };
  128.  
  129. typedef struct Room Room;
  130.  
  131. void *Room_move(void *self, Direction direction);
  132. int Room_attack(void *self, int damage);
  133. int Room_init(void *self);
  134.  
  135. struct Map{
  136. Object proto;
  137. Room *start;
  138. Room *location;
  139. };
  140.  
  141. typedef struct Map Map;
  142.  
  143. void *Map_move(void *self, Direction direction);
  144. int Map_attack(void *self, int damage);
  145. int Map_init(void *self);
  146.  
  147. #endif
  148.  
  149. #include <stdio.h>
  150. #include <stdlib.h>
  151. #include <string.h>
  152. #include <errno.h>
  153. #include <time.h>
  154. #include "ex19.h"
  155.  
  156. int Monster_attack(void *self, int damage){
  157. Monster *monster = self;
  158. printf("You attack %s!n", monster->_(description));
  159. monster->hit_points -= damage;
  160. if(monster->hit_points > 0) {
  161. printf("It is still alive.n");
  162. return 0;
  163. }
  164. else{
  165. printf("It is dead!n");
  166. return 1;
  167. }
  168. }
  169.  
  170. int Monster_init(void *self){
  171. Monster *monster = self;
  172. monster->hit_points = 10;
  173. return 1;
  174. }
  175.  
  176. Object MonsterProto = {
  177. .init = Monster_init,
  178. .attack = Monster_attack
  179. };
  180.  
  181. void *Room_move(void *self, Direction direction) {
  182. Room *room = self;
  183. Room *next = NULL;
  184.  
  185. if(direction == NORTH && room->north) {
  186. printf("You go north, into:n");
  187. next = room->north;
  188. }
  189. else if(direction == SOUTH && room->south){
  190. printf("You go south, into:n");
  191. next = room->south;
  192. }
  193. else if(direction == EAST && room->east){
  194. printf("You go east, into:n");
  195. next = room->east;
  196. }
  197. else if(direction == WEST && room->west){
  198. printf("You go west, into:n");
  199. next = room->west;
  200. }
  201. else {
  202. printf("You can't go that direction.");
  203. next = NULL;
  204. }
  205.  
  206. if(next){
  207. next->_(describe)(next);
  208. }
  209. return next;
  210. }
  211.  
  212. int Room_attack(void *self, int damage){
  213. Room *room = self;
  214. Monster *monster = room->bad_guy;
  215.  
  216. if(monster){
  217. monster->_(attack)(monster, damage);
  218. return 1;
  219. }
  220. else{
  221. printf("You flail in the air at nothing. Idiot.n");
  222. return 0;
  223. }
  224. }
  225.  
  226. Object RoomProto = {
  227. .move = Room_move,
  228. .attack = Room_attack
  229. };
  230.  
  231. void *Map_move(void *self, Direction direction){
  232. Map *map = self;
  233. Room *location = map->location;
  234. Room *next = NULL;
  235.  
  236. next = location->_(move)(location, direction);
  237. if(next) {
  238. map->location = next;
  239. }
  240. return next;
  241. }
  242.  
  243. int Map_attack(void *self, int damage){
  244. Map* map = self;
  245. Room *location = map->location;
  246. return location->_(attack)(location, damage);
  247. }
  248.  
  249. int Map_init(void *self){
  250. Map *map = self;
  251.  
  252. //make some rooms for a small map
  253. Room *hall = NEW(Room, "The great hall");
  254. Room *throne = NEW(Room, "The throne room");
  255. Room *arena = NEW(Room, "The arena, with the minotaur");
  256. Room *kitchen = NEW(Room, "Kitchen, you have the knife now");
  257.  
  258. // put the bad guy in the arena
  259. arena->bad_guy = NEW(Monster, "The evil minotaur");
  260.  
  261. // setup the map rooms
  262. hall->north = throne;
  263.  
  264. throne->west = arena;
  265. throne->east = kitchen;
  266. throne->south = hall;
  267.  
  268. arena->east = throne;
  269. kitchen->west = throne;
  270.  
  271. //start the map and the character off in the hall
  272. map->start = hall;
  273. map->location = hall;
  274.  
  275. return 1;
  276. }
  277.  
  278. Object MapProto = {
  279. .init = Map_init,
  280. .move = Map_move,
  281. .attack = Map_attack
  282. };
  283.  
  284. int process_input(Map *game){
  285. printf("n> ");
  286. char ch = getchar();
  287. getchar(); // eat enter;
  288.  
  289. int damage = rand() % 4;
  290. switch(ch){
  291. case -1:
  292. printf("Giving up? You such.n");
  293. return 0;
  294. break;
  295. case 'n':
  296. game->_(move)(game, NORTH);
  297. break;
  298. case 's':
  299. game->_(move)(game, SOUTH);
  300. break;
  301. case 'e':
  302. game->_(move)(game, EAST);
  303. break;
  304. case 'w':
  305. game->_(move)(game, WEST);
  306. break;
  307. case 'a':
  308. game->_(attack)(game, damage);
  309. break;
  310. case 'l':
  311. printf("You can go:n");
  312. if(game->location->north) printf("NORTHn");
  313. if(game->location->south) printf("SOUTHn");
  314. if(game->location->east) printf("EASTn");
  315. if(game->location->west) printf("WESTn");
  316. break;
  317. default:
  318. printf("What?: %dn", ch);
  319. }
  320. return 1;
  321. }
  322.  
  323. int main(int argc, char *argv[]){
  324. //simple way to setup the randomness
  325. srand(time(NULL));
  326.  
  327. //make our map to work with
  328. Map *game = NEW(Map, "The hall of the Minotaur.");
  329. printf("You enter the ");
  330. game->location->_(describe)(game->location);
  331. while(process_input(game)) {
  332. }
  333. return 0;
  334. }
  335.  
  336. 105 Room *hall = NEW(Room, "The great hall");
  337. 106 Room *throne = NEW(Room, "The throne room");
  338. 107 Room *arena = NEW(Room, "The arena, with the minotaur");
  339. 108 Room *kitchen = NEW(Room, "Kitchen, you have the knife now");
  340.  
  341. 111 arena->bad_guy = NEW(Monster, "The evil minotaur");
  342.  
  343. cc $(CFLAGS) -o ex19 $(src)
  344.  
  345. cc -Wall -g -o ex19 ex19.c
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement