一个简单的游戏规则系统

2023-11-29 21:33:39 浏览数 (1)

动机

什么是规则系统

将一个用 HTML 和 JavaScript 构建的简单游戏重建为生产就绪的游戏的任务促使我重新评估其核心组件。其中,规则系统督促我寻找一种能够提升清晰度、灵活性和可维护性的方法。我将穿插代码片段和叙述,揭示游戏规则系统的创建过程。

为何结构混乱

传统的 if-then 结构感觉混乱,促使我寻找一种优雅且易于维护的替代方案。

一个解决方案

可维护的替代方案

通过使用 TypeScript 枚举定义一组消息类型,例如 'Ok'、'NoFire' 和 'NoMove',为每种类型分配数字值促进了简化的评估过程,为规则系统奠定了基础。其中,0 代表 OK,0 被转换为 false。这意味着我们可以设置一个思维映射:如果不是 OK, 0, false,则存在问题。

简化规则映射

代码语言:typescript复制
export enum ResultType {
    Ok = 0,
    NoFire,
    NoMove,
    NoFuel,
    FieldCantCreate,
    NoResources,
    NoBase,
    BaseNotInRange
}

了解以下代码:

代码语言:typescript复制
var result;
if(!false){
  result = codeWillRun()
}

可以通过逻辑操作 OR 有效地重写为:

代码语言:typescript复制
var result = false || codeWillRun()

我们可以通过采用策略,如果一切 OK,则返回 0,做出很多指定:

代码语言:typescript复制
var result = rule1() || rule2() || ... || ruleN()
if(result == 0){
    // 所有规则均满足
}

我们可以有任意多的规则,它们都会轻松地安排好位置。

创建车辆规则的示例

现在是真正的事情,车辆创建的规则

代码语言:typescript复制
export function canCreateVehicle(gameState: GameState, x: number, y: number, pl: number, vehType: number) {
    return canMapCreate(gameState, x, y) ||
        baseInRange(gameState, x, y, pl) ||
        isTooCloseToEnemy(gameState, x, y, pl) ||
        canAffordVehicle(gameState, pl, vehType);
}

'canCreateVehicle' 函数展示了使用逻辑 OR 操作符(||)链接规则的强大能力。它优雅地表达了创建车辆的条件,每个规则都封装在各自的函数中,有助于更模块化和易理解的代码库。

每个规则都遵循类似的方法,保持一致的结构,延伸到游戏的基本构建模块——基本数据类型。这种统一性不仅增强了代码的清晰度和可读性,还有助于实现模块化和可扩展的架构。无论是检查车辆创建、计算距离,还是确保结果一致性,其基本原则始终坚守在这个结构化和功能性的基础上。

确保结果一致性

代码语言:typescript复制
export function isOk(res: ResultType) {
    return res === ResultType.Ok;
}

为了保持结果一致性,'isOk' 辅助函数提供了一个提醒,即结果应为 OK。通过集中检查结果是否为 'Ok' 的逻辑,此函数减少了冗余,防止潜在的误解,有助于整体代码库的清晰度。

事后分析

使用 0 表示成功的缺点

然而,使用 0 表示成功(OK),并使用任何其他值表示错误的做法也有其缺点。最初可能会令人反直觉,挑战开发者克服根深蒂固的预期,其中 0 通常表示失败。这种非传统的方法可能看起来有点神秘,尤其是在使用逻辑 OR 操作符链接规则时。依赖非零值的真实性来表示错误可能会导致思维映射的挑战,需要开发者重新调整其理解。虽然这种方法增强了代码的组织性和可读性,但它需要对传统思维进行转变,需要一种思维导图来导航规则评估的复杂性。

支持使用零表示正面的理由

采用使用 0 表示成功,其他任何值表示错误的方法是为了获得更具信息性的规则系统。在一个二元系统中,0 代表失败,每个规则都传达了简单的通过或失败状态。然而,这种简单性是以在错误报告中丢失细节为代价的。通过为不同的错误类型指定各种非零值,这种方法允许更详细地了解规则的失败。

功能性方法的结论

通过采用功能性方法来处理游戏规则系统,代码库经历了一次复兴,平衡了简单性和复杂性。通过 TypeScript 枚举、逻辑操作符和精心制作的函数,规则系统演变成一个一致、明确和愉快的实体。这种方法特别适用于回合制游戏,不仅解决了最初实现的缺点,还为更强大和愉快的游戏制作经验铺平了道路。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞