Othello MVC项目isLegalMove方法异常:仅检测上方合法移动
奥赛罗(Othello)isLegalMove方法问题修复
核心问题分析
- 数组引用篡改原位置:
int[] newPos = pos;未创建新数组,newPos与pos指向同一内存地址,修改newPos会直接改变原pos坐标,导致后续方向遍历使用被篡改后的位置,仅能检测第一个方向的合法移动。 - 合法移动逻辑顺序错误:奥赛罗的合法移动要求:空位置出发,某方向第一步必须是对方棋子,之后连续为对方棋子,直到遇到己方棋子。原代码第一步移动后直接跳过非对方棋子的情况,逻辑颠倒。
- 循环条件冗余且逻辑矛盾:
while循环中getSquare(newPos) == -1 && getSquare(newPos) != 0重复判断,且未正确区分玩家与对方棋子的状态,导致循环逻辑混乱。
修复后的代码
public boolean isLegalMove(int[] pos) { // 当前位置非空则直接返回非法 if (!this.board[pos[0]][pos[1]].equals("")) { return false; } // 根据你的实际逻辑替换当前玩家与对方玩家的标识 int currentPlayer = this.currentPlayer; // 假设类中维护了当前玩家的成员变量 int opponentPlayer = (currentPlayer == 1) ? 0 : 1; // 对方玩家标识 for(int[] direction : Directions.points) { // 每次遍历方向都创建独立的位置数组,避免修改原pos int[] newPos = {pos[0], pos[1]}; // 往当前方向移动一格 vector(direction, newPos); // 第一步必须是对方棋子且未出界,否则跳过该方向 if (isOffBoard(newPos) || getSquare(newPos) != opponentPlayer) { continue; } // 继续沿该方向移动,验证是否能遇到己方棋子 while (!isOffBoard(newPos)) { vector(direction, newPos); if (isOffBoard(newPos)) { break; } if (getSquare(newPos) == currentPlayer) { // 遇到己方棋子,判定当前位置为合法移动 System.out.println("Legal Move: " + pos[0] + " " + pos[1]); return true; } if (getSquare(newPos) != opponentPlayer) { // 遇到空位置或非对方棋子,该方向不合法 break; } } } return false; }
关键修复说明
- 独立位置数组:每个方向遍历前创建新的
newPos数组,确保原pos坐标不被修改,所有方向都从原始位置开始检测。 - 修正逻辑流程:先验证第一步是否为对方棋子,再循环移动直到遇到己方棋子(合法)或终止条件(不合法),完全符合奥赛罗的规则。
- 明确玩家状态:用清晰的变量区分当前玩家与对方玩家,避免逻辑混淆,需根据你的
getSquare方法返回值调整标识取值。 - 简化循环条件:移除冗余判断,让循环逻辑更直观,减少出错概率。
内容的提问来源于stack exchange,提问作者Nathaniel Crivelli
相关产品推荐
相关产品推荐

