You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala金币收集游戏checkCoins方法JUnit测试异常求助

问题描述

我用Scala开发了一款10×10棋盘的金币收集游戏,玩家可通过上下左右移动收集金币。目前遇到的问题是:运行JUnit测试时,checkCoins()方法满足条件后,本该将saveX、saveY重置为(-1,-1),但实际未生效。我尝试过修改checkCoins()的逻辑(最初版本见下文),但问题反而更严重,且测试代码无法修改,只能调整自身实现代码及未完成方法,求可行解决方案。

当前checkCoins()实现

def checkCoins(): Unit = {
    if (math.abs(positionX - saveX) >= 3 && math.abs(positionY - saveY) >= 3) {
      val xMin = math.min(positionX, saveX)
      val xMax = math.max(positionX, saveX)
      val yMin = math.min(positionY, saveY)
      val yMax = math.max(positionY, saveY)

      for (x <- xMin to xMax; y <- yMin to yMax if board(x)(y) > 0) {
        points += board(x)(y)
        board(x)(y) = -1
      }
      saveX = -1
      saveY = -1
    }
  }

不可修改的save()方法

def save(): Unit = {
    /* This method is already implemented. You should not change it */
    saveX = positionX
    saveY = positionY
  }

最初版本的checkCoins()

val xMin = math.min(positionX, saveX)
val xMax = math.max(positionX, saveX)
val yMin = math.min(positionY, saveY)
val yMax = math.max(positionY, saveY)

if ((xMax - xMin + 1) * (yMax - yMin + 1) >= 9) {
  for (x <- xMin to xMax; y <- yMin to yMax if board(x)(y) > 0) {
    points += board(x)(y)
    board(x)(y) = -1
  }
  saveX = -1
  saveY = -1
}

解决方案

针对问题,可按以下步骤排查并修正:

1. 先确认条件是否真的被触发

在checkCoins()的条件分支内添加调试打印,验证代码块是否执行:

def checkCoins(): Unit = {
    if (math.abs(positionX - saveX) >= 3 && math.abs(positionY - saveY) >= 3) {
      println(s"条件触发:当前位置($positionX,$positionY),保存位置($saveX,$saveY)")
      // 原有逻辑代码
      saveX = -1
      saveY = -1
      println(s"重置后保存位置:($saveX,$saveY)")
    } else {
      println(s"条件未触发:当前位置($positionX,$positionY),保存位置($saveX,$saveY)")
    }
  }

如果打印显示条件未触发,说明测试用例中的位置变化不满足当前判断逻辑,需要调整条件匹配测试预期。

2. 修正条件逻辑(匹配测试预期)

如果测试预期的是玩家移动后与保存位置形成的矩形区域至少覆盖3×3范围(而非x、y方向都移动至少3格),可调整条件为判断矩形的宽高都≥3,同时增加初始状态判断避免误触发:

def checkCoins(): Unit = {
    // 先排除未执行过save()的初始状态
    if (saveX != -1 && saveY != -1) {
      val xMin = math.min(positionX, saveX)
      val xMax = math.max(positionX, saveX)
      val yMin = math.min(positionY, saveY)
      val yMax = math.max(positionY, saveY)
      
      val width = xMax - xMin + 1
      val height = yMax - yMin + 1
      // 判断是否覆盖3×3及以上区域
      if (width >= 3 && height >= 3) {
        for (x <- xMin to xMax; y <- yMin to yMax if board(x)(y) > 0) {
          points += board(x)(y)
          board(x)(y) = -1
        }
        saveX = -1
        saveY = -1
      }
    }
  }

3. 排查是否有代码覆盖重置后的saveX/saveY

检查游戏逻辑的调用顺序,确认是否在checkCoins()执行后,又调用了save()方法,导致刚重置的saveX、saveY被覆盖为当前位置。若存在此情况,需调整调用顺序:先执行checkCoins(),再执行save()。

4. 确认变量的可变状态

确保saveX、saveY是类的可变成员变量(用var声明),而非不可变的val或局部变量,否则重置操作无法影响外部测试感知的状态。示例声明:

class Game {
  var positionX: Int = 0
  var positionY: Int = 0
  var saveX: Int = -1
  var saveY: Int = -1
  // 其他变量与方法
}

内容的提问来源于stack exchange,提问作者Sevastyan Che

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 07:17:03