C#井字棋开发中if条件符合却恒返回false问题排查
C#井字棋位置校验方法始终返回false排查
问题现象
- 基于C#开发井字棋游戏过程中,
Updater类下的VerifyUserHasInputValidNumber(int userInput)方法设计目标为校验用户输入落子位置是否属于1-9的合法区间,合法输入返回true,非法输入返回false - 实际运行时经调试打印确认传入的
userInput参数值正确,但方法始终返回false,固定触发"Inputted an invalid position!"错误分支 - 已排除内存泄漏、语法格式错误类诱因
根因分析
该方法存在两处致命逻辑错误:
- 逻辑运算符误用:判断数值是否落在闭区间内,需要同时满足「大于等于左边界」「小于等于右边界」两个条件,必须使用
&&(逻辑与)运算符。原代码使用||(逻辑或)编写判断条件userInput >= 0 || userInput <= 10,该条件对所有整数恒成立——任意整数必然满足「大于等于0」或「小于等于10」两个条件中的至少一个,因此代码永远会进入if分支返回false。 - 判断逻辑与边界值双重错误:即使将运算符修正为
&&,原代码的边界值设置为0和10,会把非法值0、10判定为合法;同时if分支在条件满足时返回false,和「合法返回true」的设计目标完全相反。
修复方案
直接替换原有VerifyUserHasInputValidNumber方法即可,可删除调试用的打印语句:
public bool VerifyUserHasInputValidNumber(int userInput) { // 输入值在1-9闭区间内即为合法 return userInput >= 1 && userInput <= 9; }
问题复现原代码
// 程序入口 Game newGame = new(); newGame.RunGame(); // 类定义 internal class Game { private Player[] Players; private Updater GameUpdater; private Board GameBoard; public Game() { Players = new Player[2] { new(PlayerSymbol.X), new(PlayerSymbol.O) }; GameUpdater = new(); GameBoard = new(); } public void RunGame() { while (true) { GameBoard.DisplayBoard(); int currentPlayer = GameUpdater.SendPlayerTurnInfo(); int playerInput = Players[currentPlayer].GetUserInput(); bool playerInputtedValidNumber = GameUpdater.VerifyUserHasInputValidNumber(playerInput); if (playerInputtedValidNumber) { bool playerInputtedUnusedNumber = GameUpdater.VerifyUserHasInputUnusedSpot(GameBoard.SendBoardPiecesData(--playerInput)); if (playerInputtedUnusedNumber) { PlayerSymbol currentPlayerSymbol = Players[currentPlayer].SendPlayerSymbol(); GameBoard.UpdateBoardPiecesData(playerInput, currentPlayerSymbol); } else { Console.WriteLine("This position has already been used!"); continue; } } else { Console.WriteLine("Inputted an invalid position!"); continue; } } } } internal class Board { private string[]? BoardPieces; private string? BoardDisplay; public Board() { BoardPieces = new string[9] { " ", " ", " ", " ", " ", " ", " ", " ", " " }; BoardDisplay = $" {BoardPieces[0]} | {BoardPieces[1]} | {BoardPieces[2]} \n---+---+---\n {BoardPieces[3]} | {BoardPieces[4]} | {BoardPieces[5]} \n---+---+---\n {BoardPieces[6]} | {BoardPieces[7]} | {BoardPieces[8]} "; } public void DisplayBoard() { Console.WriteLine(BoardDisplay); } public string SendBoardPiecesData(int userInput) { return BoardPieces[userInput]; } public void UpdateBoardPiecesData(int userInput, PlayerSymbol playerSymbol) { BoardPieces[userInput] = $"{playerSymbol}"; BoardDisplay = $" {BoardPieces[0]} | {BoardPieces[1]} | {BoardPieces[2]} \n---+---+---\n {BoardPieces[3]} | {BoardPieces[4]} | {BoardPieces[5]} \n---+---+---\n {BoardPieces[6]} | {BoardPieces[7]} | {BoardPieces[8]} "; } } internal class Updater { private int PlayerIndicator; public Updater() { PlayerIndicator = 1; } public int SendPlayerTurnInfo() { if (PlayerIndicator == 1) { PlayerIndicator = 0; return PlayerIndicator; } else { PlayerIndicator = 1; return PlayerIndicator; } } // 存在bug的原校验方法 public bool VerifyUserHasInputValidNumber(int userInput) { Console.WriteLine(userInput); if (userInput >= 0 || userInput <= 10) { return false; } else { return true; } } public bool VerifyUserHasInputUnusedSpot(string userInput) { if (userInput == "X" || userInput == "O") return false; else return true; } } internal class Player { private PlayerSymbol PlayerSymbol; public Player(PlayerSymbol playerSymbol) { PlayerSymbol = playerSymbol; } public int GetUserInput() { Console.Write($"It is currently {PlayerSymbol}'s turn. Which position would you like to play at? "); string? input = Console.ReadLine(); bool isNumerical = int.TryParse(input, out int _); while (!isNumerical) { Console.Write("Invalid input, please input a number. "); input = Console.ReadLine(); isNumerical = int.TryParse(input, out int _); } return int.Parse(input); } public PlayerSymbol SendPlayerSymbol() { return PlayerSymbol; } } // 枚举定义 enum PlayerSymbol { X, O }
内容的提问来源于stack exchange,提问作者Om Khadka
相关产品推荐
相关产品推荐

