chore: add 3.4.6.2
chore: add 3.4.6.3
chore: add 3.4.6.4
chore: add 3.4.6.5
chore: add 3.4.6.6
chore: add 3.4.6.7
chore: add 3.4.6.8
chore: add 3.4.6.9
chore: add 3.4.6.10
docs: add 3.6.5.1
This commit is contained in:
FallenYing
2023-07-27 23:15:47 +08:00
parent b9449a0d88
commit b043fd1d05
14 changed files with 535 additions and 89 deletions

View File

@@ -1,13 +1,14 @@
# 8.移动方向
<em>传统的文本冒险使用</em><em>指南针方向</em><em>进行导航。</em>
<em>传统的文本冒险使用</em><em>[指南针方向](https://en.wikipedia.org/wiki/Cardinal_direction)</em><em>进行导航。</em>
例如,我们在第 6 章中绘制的地图上,玩家可能想<strong>向东</strong>移动,从田野移动到洞穴。我们可以通过给连接<strong>Cave</strong>的通道标上“east”来实现这一点。但是我们首先需要解决两个问题。
1. 我们可能仍然想把这段通道称为“entrance”和“east”。但现在一个对象只能有一个标签。
2. 在更大的地图上具有更多的位置和道路标签“east”将被定义多次。到目前为止标签在我们的游戏中是全球独一无二的没有重复项。
思考题:你能否想出解决办法?
::: warning 🤔 思考题:你能否想出解决办法?
:::
这些问题同样适用于其他对象,而不仅仅是通道。
@@ -17,11 +18,11 @@
这立即将我们带到了解析器的第三个问题:
1. 一个标签只能是一个单词;“ sliver coin”这是俩单词他不接受啊
1. 一个标签只能是一个单词;“sliver coin”这是俩单词他不接受啊
所有三个问题都将在本章中解决,从问题#1 开始。它通过为每个对象提供一个标签列表来解决,而不仅仅是一个标签。
# object.h
## object.h
```c
typedef struct object {
@@ -47,7 +48,7 @@ extern OBJECT objs[];
#define endOfObjs (objs + 10)
```
# object.c
## object.c
```c
#include <stdio.h>
@@ -63,7 +64,7 @@ static const char *tags6[] = {"east", "entrance", NULL};
static const char *tags7[] = {"west", "exit", NULL};
static const char *tags8[] = {"west", "north", "south", "forest", NULL};
static const char *tags9[] = {"east", "north", "south", "rock", NULL};
//我们不固定标签长度在结束的时候用NULL来标记
//我们不固定标签长度,在结束的时候用 NULL 来标记
OBJECT objs[] = {
{"an open field" , tags0, NULL , NULL },
{"a little cave" , tags1, NULL , NULL },
@@ -75,22 +76,22 @@ OBJECT objs[] = {
{"an exit to the west" , tags7, cave , field },
{"dense forest all around" , tags8, field, NULL },
{"solid rock all around" , tags9, cave , NULL }
//我们用NULL来阻绝进入一个你不知道的地方
//我们用 NULL 来阻绝进入一个你不知道的地方
};
```
当然,要让这个改动生效,我们还需要调整<em>noun.c</em>中的<em>objectHasTag</em>函数。
<em>同时,我们将让函数 getVisible</em>和<em>getPossession</em> 告知玩家他必须更具体的选择你到底是银币还是金币 ,而不是随机选择任何一个对象。
<em>同时,我们将让函数 getVisible</em>和<em>getPossession</em> 告知玩家他必须更具体的选择你到底是银币还是金币,而不是随机选择任何一个对象。
# noun.h
## noun.h
```c
extern OBJECT *getVisible(const char *intention, const char *noun);
extern OBJECT *getPossession(OBJECT *from, const char *verb, const char *noun);
```
# <strong>noun.c</strong>
## <strong>noun.c</strong>
```c
#include <stdbool.h>
@@ -107,7 +108,7 @@ static bool objectHasTag(OBJECT *obj, const char *noun)
for (tag = obj->tags; *tag != NULL; tag++)
{
if (strcmp(*tag, noun) == 0) return true;
}//扫描对象的tag列表
}//扫描对象的 tag 列表
}
return false;
}
@@ -187,9 +188,9 @@ OBJECT *getPossession(OBJECT *from, const char *verb, const char *noun)
}
```
问题 #3 可以通过从函数<em>parseAndExecute</em>中删除一个 [空格](http://en.wikipedia.org/wiki/Space_(punctuation))字符来解决(下面的第 10 行)。这个解决方案远非完美('silver' 和 'coin' 之间的双空格是咩的),但直到我们在第 13 章中让自己成为一个更好的解析器之前。
问题 #3 可以通过从函数<em>parseAndExecute</em>中删除一个 [空格](http://en.wikipedia.org/wiki/Space_(punctuation))字符来解决(下面的第 10 行)。这个解决方案远非完美('silver' 和 'coin' 之间的双空格是咩的),但直到我们在第 13 章中让自己成为一个更好的解析器之前。
# parsexec.c
## parsexec.c
```c
#include <stdbool.h>
@@ -249,4 +250,5 @@ bool parseAndExecute(char *input)
现在对象数组 ( <em>object.c</em> ) 开始在多个维度上增长(特别是在引入多个标签的情况下),我们需要一种使其更易于维护的方法。
猜猜看该怎么办?
::: warning 🤔 猜猜看该怎么办?
:::