从Console.ReadKey().KeyChar中减去1

  • 本文关键字:KeyChar Console ReadKey c#
  • 更新时间 :
  • 英文 :


作为一个提高我编码技能的个人项目,我正在创建一个小型cmd行文本游戏。该程序通过以下行接收用户输入:char Answer=char。ToUpper(Console.ReadKey((.KeyChar(

在这个程序的大多数情况下,它运行得很好,用户点击一个按钮,它就会自动获取用户键入的内容(这个答案主要用于列出的选项(,然而,我有一个错误,用户可以键入列表中没有显示的数字。下面是一个如何发生这种情况的例子。

PrintMessage.print(ViewEnter(character, input), 4);
for (int i = 0; i < x.buildings[character.CurBuild].Rooms.Length; i++)
{
PrintMessage.print("t" + (i + 1) + " - Room " + (i + 1));
}
try
{
PrintMessage.printSame("Choice: ", 4);
answer = Console.ReadKey(true);
Console.Clear();
if (int.TryParse(answer.KeyChar.ToString(), out num))
{
character.CurRoom = num - 1;
PrintMessage.print("You enter the " + 
x.buildings[character.CurBuild].rooms[character.CurRoom].areaDescription);
}
}
catch
{
PrintMessage.printError("Please enter a valid selection.");
}

for循环显示用户要键入的有效选项列表。i+1用于列表中用户友好的数值(因此第一个选项不是0,而是显示为1(。然而,我一直在试图弄清楚如何从上面显示的列表的用户输入中减去一个数值。我的直觉反应是重新编码我的用户输入方法,这将消除这个错误和其他类似的错误(我目前有(。

当玩家进入建筑物或进入房间时,这个bug会影响两个区域。两者都使用相同风格的代码,只是根据当前位置使用不同的变量

有没有一种半简单或优雅的方法可以从Console.ReadKey((中减去1?如果事态发展到紧要关头,我不介意重新记录我的用户输入,我只是希望有一条出路。

如果您想将用户输入限制为仅有效的数字,那么您只需在if条件中检查该数字,方法是检查该数字是否大于零且小于或等于数组的长度(这是您将其作为选项提供的数字范围(。然后可以从中减去1作为索引:

if (int.TryParse(answer.KeyChar.ToString(), out num) && 
num > 0 && num <= x.buildings[character.CurBuild].Rooms.Length)
{
character.CurRoom = num - 1;
PrintMessage.print("You enter the " + 
x.buildings[character.CurBuild].rooms[character.CurRoom].areaDescription);
}

附带说明一下,trycatch没有捕获任何内容,因为int.TryParse没有抛出异常。相反,我们可以做的是将条件放入dowhile循环中,该循环不断要求输入,直到返回有效响应:

// This do/while loop will continue until the user enters a valid number
do
{
PrintMessage.print(ViewEnter(character, input), 4);
for (int i = 0; i < x.buildings[character.CurBuild].Rooms.Length; i++)
{
PrintMessage.print("t" + (i + 1) + " - Room " + (i + 1));
}
PrintMessage.printSame("Choice: ", 4);
answer = Console.ReadKey(true);
Console.Clear();
} while (!int.TryParse(answer.KeyChar.ToString(), out num) || 
num < 1 || num > x.buildings[character.CurBuild].Rooms.Length);
// When we exit the loop, we know that `num` is valid. Now we subtract `1` and continue
character.CurRoom = num - 1;
PrintMessage.print("You enter the " + 
x.buildings[character.CurBuild].rooms[character.CurRoom].areaDescription);

try / catch在这里对您没有帮助(请参阅我上面的评论(。虽然Rufus已经给了你一个答案,但你还需要修改你的阅读循环,这样你就可以在无效时不断要求输入。。我会把它分成一个这样的方法:

private int ReadRoom(int maxRoom,int minRoom=1) {
for(var i=minRoom;i<=maxRoom;i++) {
PrintMessage.print("t" + i + " - Room " + i);
}
while (true) {
PrintMessage.printSame("Choice: ", 4);
answer = Console.ReadKey(true);
Console.Clear();
if (!int.TryParse(answer.KeyChar.ToString(),out num)) {
//You may want to combine this with the next block (or 
//change the message to list all valid inputs)
PrintMessage.printError("Expecting a number");
} else if (num<minRoom || num>maxRoom) {
PrintMessage.printError("Please choose a valid room ("+minRoom+"-"+maxRoom+")");
} else {
//The room is in the right range, so return it to the calling function
return num-1;
}
}
}
public void YourFunc() {
//...
PrintMessage.print(ViewEnter(character, input), 4);
character.CurRoom = ReadRoom(1,x.buildings[character.CurBuild].Rooms.Length);
PrintMessage.print("You enter the " + 
x.buildings[character.CurBuild].rooms[character.CurRoom].areaDescription);
//...
}

其中,YourFunc只是示例代码所在位置的示例名称。注意,ReadRoom将永远要求输入,直到输入minRoommaxRoom之间的有效数字(您可能还想在此处读取控制字符。也许esc退出程序,所以此处也应该允许它?

我要感谢大家的帮助。在尝试了你们每个人发布的内容后,我意识到它的当前版本已经远远超出了我对这个项目的最初范围(自我功能蔓延(,我试图在没有确保它的基础正常工作的情况下做太多太快的事情。为此(以及为什么我要发布我自己问题的答案(,我已经将当前版本转移到了一个新的分支(标记为Defunct(,并将重新开始,同时努力打下更坚实的基础。

正如我在上面的问题中所说,这个项目对我来说纯粹是个人的,目的是更好地掌握代码并学习如何做新事情(其中一个是过程领域生成器(,我早在2015年就开始了这个项目(断断续续,几年来一直在做其他事情(。

再次感谢大家的帮助。

最新更新