大灾变黑暗日子:静态分析和Roguelike游戏

本文探讨了开源Roguelike游戏《大灾变:黑暗日子》的代码质量,通过静态分析工具PVS-Studio检查,发现了若干编程错误和性能下降的问题。游戏以其独特的ASCII字符图形和丰富功能吸引玩家,但代码中存在如逻辑错误、过度检查、未覆盖的赋值运算符和潜在的无限循环等问题。作者建议开发者应经常使用静态分析工具来及时发现并修复这些问题。
摘要由CSDN通过智能技术生成

您必须已经从标题中猜到,今天的文章将关注软件源代码中的错误。但不仅如此。如果您不仅对C ++感兴趣并且在阅读其他开发人员代码中的错误,还会挖掘不寻常的视频游戏并想知道“roguelikes”是什么以及如何玩它们,那么欢迎继续阅读!

图5
在寻找不寻常的游戏时,我偶然发现了大灾变黑暗日子,由于它的图形基于黑色背景上排列的各种颜色的ASCII字符,因此在其他游戏中脱颖而出。

令人惊讶的是,这个和其他类似游戏让你感到惊讶的是它们内置了多少功能。例如,特别是在大灾变中,由于可用的数十个参数,特征和初始场景,你甚至无法创建一个没有谷歌某些指南的冲动的角色,更不用说整个游戏中发生的事件的多种变化。

由于它是一个开源代码的游戏,而且是一个用C ++编写的游戏,我们无法使用我们的静态代码分析器PVS-Studio进行检查,我正在积极参与其中。该项目的代码令人惊讶的高质量,但它仍然有一些小缺陷,其中一些我将在本文中讨论。

PVS-Studio已经检查了很多游戏。您可以在我们的文章“ 视频游戏开发中的静态分析:十大软件错误 ”中找到一些示例。

逻辑

例1:

此示例显示了经典的复制粘贴错误。

V501 “||”的左侧和右侧有相同的子表达式 operator:rng(2,7)<abs(z)|| rng(2,7)<abs(z)overmap.cpp 1503

bool overmap::generate_sub( const int z )
{
  ....
if( rng( 2, 7 ) < abs( z ) || rng( 2, 7 ) < abs( z ) )
{
  ....
  }
  ....
}

检查相同的条件两次。程序员复制了表达式但忘记修改副本。我不确定这是否是一个严重的错误,但事实是检查不能正常工作。

另一个类似错误:

V501’&&‘运算符的左侧和右侧有相同的子表达式’one_in(100000 / to_turns (dur))’。player_hardcoded_effects.cpp 547

在这里插入图片描述

例2:

V728可以简化过度检查。’(A && B)|| (!A &&!B)'表达式等同于’bool(A)== bool(B)'表达式。inventory_ui.cpp 199

bool inventory_selector_preset::sort_compare( .... ) const
{
  ....
  const bool left_fav  = g->u.inv.assigned.count( lhs.location->invlet );
  const bool right_fav = g->u.inv.assigned.count( rhs.location->invlet );
  if( ( left_fav && right_fav ) || ( !left_fav && !right_fav ) ) {
    return ....
  } 
  ....
}

这种情况在逻辑上是正确的,但它过于复杂。编写此代码的人应该对将要维护它的同事程序员表示同情。它可以用更简单的形式重写:if(left_fav == right_fav)。

另一个类似错误:

V728可以简化过度检查。’(A &&!B)|| (!A && B)'表达式等同于’bool(A)!= bool(B)'表达式。iuse_actor.cpp 2653
题外话题
我惊讶地发现今天以“roguelikes”为名的游戏只是roguelike游戏旧类型的温和代表。这一切都始于1980年的狂热游戏Rogue,它激发了许多学生和程序员用类似元素创建自己的游戏。我想很多影响力也来自桌面游戏DnD社区及其变化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值