Closed. This question needs details or clarity. It is not currently accepting answers. Learn more。
想改进这个问题吗?添加细节并通过editing this post澄清问题。
三年前关闭。
我有以下文件:
例19.c:
游戏力学c:
例19.h
对象c
对象h
我试图使ex19.c使用gamemechanics.c中的函数和结构。但是每当我尝试编译时,都会得到以下错误:
我的问题是,我如何开始弄清楚真正发生了什么,因为在这一点上,我只是做一个混合和匹配,只是看看是什么使它工作,但这并不能帮助我理解为什么会发生错误(因为它总是失败)。所以,首先为什么我会得到一个错误的MapProto未声明,即使我在gamemechanics.c中声明了?。我试过创建游戏机制。但后来我对依赖项的工作方式感到困惑。这是ex19从学c的艰辛之路。我可以尝试创建一个gamemechanics.h来创建函数原型,但是我很困惑如何在系统中实现它。任何建议都会有帮助的。关于如何使这个问题更容易理解的建议也会有帮助。
想改进这个问题吗?添加细节并通过editing this post澄清问题。
三年前关闭。
我有以下文件:
例19.c:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "object.h"
#include "ex19.h"
//#include "gamemechanics.h"
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;
}
游戏力学c:
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "ex19.h"
#include "object.h"
//#include "gamemechanics.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 if(direction == SOUTHWEST && room->southwest) {
printf("You go southwest, into:\n");
next = room->southwest;
} else if(direction == NORTHEAST && room->northeast) {
printf("You go northeast, into: \n");
next = room->northeast;
} else if(direction == NORTHWEST && room->northwest) {
printf("You go northwest, into: \n");
next = room->northwest;
} else if(direction == SOUTHEAST && room->southeast) {
printf("You go southeast, into: \n");
next = room->southeast;
} 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");
Room *bathroom = NEW(Room, "The bathroom, place where people shit");
Room *playroom = NEW(Room, "A child's playroom");
Room *dungeon = NEW(Room, "The dungeon with the witch");
Room *jail = NEW(Room, "The jail with crooked criminals");
// put the bad guy in the arena
arena->bad_guy = NEW(Monster, "The evil minotaur");
//ashwini is adding a new monster
dungeon->bad_guy = NEW(Monster,"Witch");
dungeon->bad_guy->hit_points = 20;
// setup the map rooms
hall->north = throne;
throne->west = arena;
throne->east = kitchen;
throne->south = hall;
arena->east = throne;
kitchen->west = throne;
//ashwini's addition to the map
throne->northeast = dungeon;
kitchen->north = dungeon;
dungeon->southwest = throne;
dungeon->south = kitchen;
dungeon->east = jail;
throne->northwest = jail;
arena->north = jail;
jail->southeast = throne;
jail->south = arena;
jail->east = dungeon;
throne->southeast = playroom;
kitchen->south = playroom;
playroom->north = kitchen;
playroom->west = hall;
playroom->northwest = throne;
throne->southwest = bathroom;
arena->south = bathroom;
bathroom->northeast = throne;
bathroom->north = arena;
bathroom->east = hall;
// 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 suck.\n");
return 0;
break;
case 'n':
game->_(move)(game, NORTH);
break;
case 'N':
game->_(move)(game,NORTHEAST);
break;
case 's':
game->_(move)(game, SOUTH);
break;
case 'S':
game->_(move)(game,SOUTHWEST);
break;
case 'e':
game->_(move)(game, EAST);
break;
case 'E':
game->_(move)(game,SOUTHEAST);
break;
case 'w':
game->_(move)(game, WEST);
break;
case 'W':
game->_(move)(game,NORTHWEST);
break;
case 'a':
game->_(attack)(game, damage);
break;
case 'l':
printf("You can go:\n");
if(game->location->north) printf("NORTH(n)\n");
if(game->location->south) printf("SOUTH(s)\n");
if(game->location->east) printf("EAST(e)\n");
if(game->location->west) printf("WEST(w)\n");
if(game->location->northeast) printf("NORTHEAST(N)\n");
if(game->location->northwest) printf("NORTHWEST(W)\n");
if(game->location->southeast) printf("SOUTHEAST(E)\n");
if(game->location->southwest) printf("SOUTHWEST(S)\n");
break;
default:
printf("What?: %d\n", ch);
}
return 1;
}
例19.h
#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;
struct Room *southwest;
struct Room *southeast;
struct Room *northeast;
struct Room *northwest;
};
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
对象c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "object.h"
#include <assert.h>
void Object_destroy(void *self)
{
Object *obj = self;
assert(obj != NULL);
if(obj) {
if(obj->description) free(obj->description);
free(obj);
}
}
void Object_describe(void *self)
{
Object *obj = self;
assert(obj!=NULL);
printf("%s.\n", obj->description);
}
int Object_init(void *self)
{
// do nothing really
return 1;
}
void *Object_move(void *self, 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)
{
assert(description != NULL);
// 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);
assert(el!=NULL);
*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;
}
}
对象h
#ifndef _object_h //this is if note defined
#define _object_h //checks if there is alread an object_h
//above is usefule if we are including it multiple times, it doesn't reinclude,
//just does it once and keeps refereing back
typedef enum {
NORTH, SOUTH, EAST, WEST, SOUTHWEST, NORTHWEST, SOUTHEAST,NORTHEAST
} 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
我试图使ex19.c使用gamemechanics.c中的函数和结构。但是每当我尝试编译时,都会得到以下错误:
:~/c_learning/ex19_folder$ gcc -c ex19.c gamemechanics.c object.c
In file included from ex19.c:6:0:
ex19.c: In function ‘main’:
ex19.c:17:21: error: ‘MapProto’ undeclared (first use in this function)
Map *game = NEW(Map, "The Hall of the Minotaur.");
^
object.h:26:41: note: in definition of macro ‘NEW’
#define NEW(T, N) Object_new(sizeof(T), T##Proto, N)
^
ex19.c:17:21: note: each undeclared identifier is reported only once for each function it appears in
Map *game = NEW(Map, "The Hall of the Minotaur.");
^
object.h:26:41: note: in definition of macro ‘NEW’
#define NEW(T, N) Object_new(sizeof(T), T##Proto, N)
^
我的问题是,我如何开始弄清楚真正发生了什么,因为在这一点上,我只是做一个混合和匹配,只是看看是什么使它工作,但这并不能帮助我理解为什么会发生错误(因为它总是失败)。所以,首先为什么我会得到一个错误的MapProto未声明,即使我在gamemechanics.c中声明了?。我试过创建游戏机制。但后来我对依赖项的工作方式感到困惑。这是ex19从学c的艰辛之路。我可以尝试创建一个gamemechanics.h来创建函数原型,但是我很困惑如何在系统中实现它。任何建议都会有帮助的。关于如何使这个问题更容易理解的建议也会有帮助。
最佳答案
当编译器解析ex19.c时,它只知道
标准标题
对象h
例19.h
例19.c
因为这些是ex19.c引用的唯一文件。即使您在命令行中指定了gamemechanics.c,编译器在编译ex19.c时也不会查看该文件。
如果希望编译器在编译ex19.c时了解MapProto
,则需要创建gamemechanics.h并将该文件包含在ex19.c中
你在游戏机制中需要的声明
extern Object MapProto;
关于c - ex19通过困难的方式学习c。错误:未声明“MapProto”(此功能首次使用),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34501049/
10-10 17:12