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

Java开发终端国际象棋出现java.lang.OutOfMemoryError如何解决

问题根因

你的java.lang.OutOfMemoryError和JVM内存分配大小无关,完全是循环逻辑错误触发死循环,短时间内生成海量无效Location对象占满堆内存导致的,具体错误点如下:

  • 斜向(象)移动的右上、左上两段for循环终止条件完全错误:循环变量i逐次递减,你写的终止判断是i < this.getBoard().getRows(),不管i减到0、-1000还是更小的负数,都永远满足“小于棋盘行数”的条件,循环根本不会停止。
  • 车的左移段for循环终止条件写反:循环变量i从col-1开始逐次递减,终止判断却写的是i < this.getBoard().getColumns(),同样是i永远满足判断条件的死循环。
  • 所有滑动遍历逻辑都没有在碰到棋子后终止循环:国际象棋象、车、后这类滑动棋子,沿固定方向移动时碰到第一个棋子就无法继续前进,你现在碰到棋子后只是把位置加入吃子列表,没有break跳出循环,哪怕坐标越界循环还会持续运行。
  • 斜向循环的终止条件只判断了行坐标边界,完全没校验列坐标possibleCol是否在棋盘列范围内,哪怕列已经越界,只要行还满足条件循环就不会停。
修复方案

修复核心规则:沿每个方向遍历时,for循环的终止条件必须同时校验行、列坐标是否在棋盘边界内;一旦遍历到任意棋子,不管是己方还是对方,处理完位置后立刻break终止当前方向的遍历,不允许穿子移动。

修复后的斜向(象)移动逻辑

// 右下方向:行递增,列递增
int possibleCol = col + 1;
for (int i = row + 1; i < this.getBoard().getRows() && possibleCol < this.getBoard().getColumns(); i++, possibleCol++){
    Piece pieceAt = this.getBoard().getPieceAt(i, possibleCol);
    Location location = new Location(i, possibleCol);
    if (pieceAt == null){
        possibleMoves.add(location);
    } else {
        possibleKills.add(location);
        break;
    }
}

// 右上方向:行递减,列递增
possibleCol = col + 1;
for (int i = row - 1; i >= 0 && possibleCol < this.getBoard().getColumns(); i--, possibleCol++){
    Piece pieceAt = this.getBoard().getPieceAt(i, possibleCol);
    Location location = new Location(i, possibleCol);
    if (pieceAt == null){
        possibleMoves.add(location);
    } else {
        possibleKills.add(location);
        break;
    }
}

// 左下方向:行递增,列递减
possibleCol = col - 1;
for (int i = row + 1; i < this.getBoard().getRows() && possibleCol >= 0; i++, possibleCol--){
    Piece pieceAt = this.getBoard().getPieceAt(i, possibleCol);
    Location location = new Location(i, possibleCol);
    if (pieceAt == null){
        possibleMoves.add(location);
    } else {
        possibleKills.add(location);
        break;
    }
}

// 左上方向:行递减,列递减
possibleCol = col - 1;
for (int i = row - 1; i >= 0 && possibleCol >= 0; i--, possibleCol--){
    Piece pieceAt = this.getBoard().getPieceAt(i, possibleCol);
    Location location = new Location(i, possibleCol);
    if (pieceAt == null){
        possibleMoves.add(location);
    } else {
        possibleKills.add(location);
        break;
    }
}

修复后的车直线移动逻辑

重点修正左移方向的循环终止条件,所有方向碰到棋子后立刻break:

// 下移方向:行递增,列固定
int possibleRow = row + 1;
for (int i = possibleRow; i < this.getBoard().getRows(); i++){
    Piece pieceAt = this.getBoard().getPieceAt(i, col);
    Location location = new Location(i, col);
    if (pieceAt == null){
        possibleMoves.add(location);
    } else {
        possibleKills.add(location);
        break;
    }
}

// 上移方向:行递减,列固定
possibleRow = row - 1;
for (int i = possibleRow; i >= 0; i--){
    Piece pieceAt = this.getBoard().getPieceAt(i, col);
    Location location = new Location(i, col);
    if (pieceAt == null){
        possibleMoves.add(location);
    } else {
        possibleKills.add(location);
        break;
    }
}

// 右移方向:列递增,行固定
int possibleCol = col + 1;
for (int i = possibleCol; i < this.getBoard().getColumns(); i++){
    Piece pieceAt = this.getBoard().getPieceAt(row, i);
    Location location = new Location(row, i);
    if (pieceAt == null){
        possibleMoves.add(location);
    } else {
        possibleKills.add(location);
        break;
    }
}

// 左移方向:列递减,行固定
possibleCol = col - 1;
for (int i = possibleCol; i >= 0; i--){
    Piece pieceAt = this.getBoard().getPieceAt(row, i);
    Location location = new Location(row, i);
    if (pieceAt == null){
        possibleMoves.add(location);
    } else {
        possibleKills.add(location);
        break;
    }
}
额外优化建议
  • 后的合法移动直接复用象+车的移动逻辑即可,不需要重复编写8个方向的遍历循环。
  • 补充阵营判断:当前possibleKills会把己方棋子也加入可吃子列表,需要新增判断,只有敌方棋子所在位置才能加入吃子列表;碰到己方棋子直接break,不要加入任何可移动列表。
  • 可以把8个移动方向的行、列偏移量提前存在二维数组里,比如int[][] dirs = {{1,1}, {1,-1}, {-1,1}, {-1,-1}, {1,0}, {-1,0}, {0,1}, {0,-1}},遍历方向数组统一处理滑动逻辑,避免重复写8段高度相似的for循环,减少写错条件的概率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 01:21:34