首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >文字冒险游戏-文字输入处理

文字冒险游戏-文字输入处理
EN

Code Review用户
提问于 2018-01-17 05:46:13
回答 1查看 781关注 0票数 4

作为一个有趣的项目,我和我的妻子,我决定制作一个小的文字冒险游戏- la Zork。我决定使用自己的引擎,而不是使用可用的引擎。它不会那么难,因为没有图形。

我提交给评审的代码是一个代表游戏中一个房间的类。processInput方法接受播放机键入的单词并确定适当的响应。

我关注嵌套条件的大量使用,我想知道是否有一种设计模式,或者可能有一种不同的数据结构,可以使代码更简洁。

代码语言:javascript
复制
import { Room, Output } from "../room";
import { GameState } from "../game-controller";

export class CenterRoom extends Room {
    roomName = 'centerRoom';

    roomState = {
        openedBox: false,
        keyTaken: false,
        northDoorUnlocked: false
    }

    processInput(terms: string[], gameState: GameState): Output {
        let output: Output = {
            text: '',
            moveTo: '',
            inventory: {
                add: [],
                remove: []
            }
        }

        // LOOK
        if (terms.includes('look')) {
            if (terms.includes('around')) {
                if (this.roomState.northDoorUnlocked) {
                    output.text = 'You are standing in an empty square room. Each of the four walls has a door.\n' +
                        'You can see a small box on the floor in the middle of the room.\n' +
                        'The door on the North wall is opened and leads to another room steeped in darkness.';
                    return output;
                }
                output.text = 'You are standing in an empty square room. Each of the four walls has a door.\n' +
                    'You can see a small box on the floor in the middle of the room.';
                return output;
            }
            if (terms.includes('box')) {
                if (this.roomState.openedBox && !this.roomState.keyTaken)
                    output.text = 'It is a plain wooden box with a lid. Inside, you see a small metal key.';
                else
                    output.text = 'It is a plain wooden box with a lid.'
                return output;
            }
            output.text = `Sorry, you can't look at that.`;
            return output;
        }

        // OPEN
        if (terms.includes('open')) {
            if (terms.includes('box')) {
                this.roomState.openedBox = true;
                output.text = 'You open the box. Inside, you see a small metal key.'
                return output;
            }
            output.text = `Sorry, you can't open that.`;
            return output;
        }

        // TAKE
        if (terms.includes('take')) {
            if (terms.includes('key') && this.roomState.openedBox) {
                if (this.roomState.keyTaken)
                    output.text = `You have already taken the key`;
                else {
                    this.roomState.keyTaken = true;
                    output.text = 'You take the key.';
                    output.inventory.add = ['a small metal key']
                }
                return output;
            }
            output.text = `Sorry, you can't take that.`
            return output;
        }

        // UNLOCK
        if (terms.includes('unlock')) {
            if (terms.includes('door') && this.roomState.keyTaken) {
                if (terms.includes('north')) {
                    if (this.roomState.northDoorUnlocked)
                        output.text = 'You have already unlocked the North door';
                    else
                        output.text = 'You unlock and open the north door.\n' +
                            'The room on the other side is steeped in darkness.'
                    this.roomState.northDoorUnlocked = true;
                    return output;
                }
                output.text = `Please identify the door you wish to unlock?`
                return output;
            } else {
                output.text = `Sorry, you can't unlock that.`
                return output;
            }
        }

        // WALK
        if (terms.includes('walk')) {
            if (terms.includes('north') && this.roomState.northDoorUnlocked) {
                output.moveTo = 'northRoom';
                return output;
            }
        }

        return super.processInput(terms, gameState);
    }
}
EN

回答 1

Code Review用户

回答已采纳

发布于 2018-01-18 21:47:28

灵活,但不是可伸缩的

必须为每个房间编写这样的输入处理程序,您可以做任何您想做的事情,但它似乎没有很好的可伸缩性:

  • 有些文本被重复了好几次。如果您需要修复拼写错误,或者想要调整一些描述,该怎么办?很容易在一个地方修复它而忘记另一个地方。
  • 同样,动词可能会在多个房间重复,这增加了在不同房间使用不同动词的可能性,这会使游戏更难(也更令人沮丧)控制。
  • 如果您想支持别名(如inspect boxgo north ),怎么办?
  • 很难确保所有可能的(有意义的)交互都得到考虑。look at north dooropen north door呢?

对于更复杂的房间来说,这些问题可能会变得更严重。

替代:一种数据驱动的方法

正如乔纳森已经提到的,数据驱动的方法,如果设计得当,应该更容易管理,并带来更健壮和一致的体验。例如,您的房间(大致)可以用下列数据来描述:

代码语言:javascript
复制
new Room(
    name = 'center room',
    description = 'empty square room. Each of the four walls has a door.'
    items = [
        new Item(
            name = 'box',
            description = 'plain wooden box with a lid',
            canBePickedUp = false,
            isContainer = true,
            isClosed = true,
            items = [
                new Item(
                    name = 'metal key',
                    description = 'small metal key',
                    unlocks = 'north door'),
            ]),
    ],
    exits = [
        new Exit(
            name = 'north door',
            description = 'the door leads to another room steeped in darkness'
            isLocked = true,
            destination = 'dark room'),
    ]);

这样,所有常见的动词都可以由一个函数来处理。毕竟,大多数动词都有几个常见的步骤:

  • 名称查找:当前的房间是否包含有此名称的项或退出?
    • 如果没有,则显示失败消息。
    • 如果是多个,让玩家从一个匹配的东西列表中选择。

  • 一些特定于动词的检查:
    • take只对项目有效,只有那些可选择的项才有效.
    • look显示事物的描述,可能显示它们的状态(打开/关闭),以及它们包含什么(容器项)或它们导致什么(如果适用的话)(退出)。
    • 只有当播放机持有可以解锁指定出口的项时,unlock才能工作。
    • 诸若此类。

一个好处是,一旦你把一个项目添加到一个房间里,所有可能的交互都会“正常工作”--它可以被查看、获取、打开等等,而不需要任何额外的代码。这甚至适用于由播放器丢弃的项目,而不管它们最初来自何处。现在,添加其他可以与项目交互并导航世界的生物也相对容易。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/185280

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档