我有一个类似终端游戏的战舰,用户输入一个像e2这样的坐标,程序检查我的对象Box的一个实例变量,它检查hasShip是否为真,如果是真,那么它将使坐标为e2 false,并输出“Ship destroyed”
问题在于我的所有对象都被称为a1,a2,a3,a4,a5,b1,b2等。
我创建了25个Box类的实例。所有的名字都是这样的。
一旦程序输入,e4,e5等我想将该字符串转换为对象。
例如(我想做这样的事情)
target = Console.ReadLine();
target.hasShip == true;
我想将target转换为对象,然后使用target来使用Box类的方法。
因为另一种方法要求我加载if语句,这不是干净的代码,看起来不太好,如果你问我就是一种浪费。
提前致谢,
答案 0 :(得分:2)
我很慢。我没注意你正在制作类似战舰的游戏,而且我们知道"盒子"做一个矩形。我们可以将它有效地存储在一个数组中。
为什么我之前没有赶上这个事实?我想我需要正确醒来。
所以,使用数组:
var board = new Box[5, 5];
现在,为了填充它,我们可以做一个双循环:
for(var indexRow = 0; indexRow < 5; indexRow++)
{
for(var indexCol = 0; indexCol < 5; indexCol++)
{
board[indexRow, indexCol] = new Box();
}
}
注意:注意索引从0到4.总共5个值:{0,1,2,3,5}。
要从中查询,我们需要索引......
填充数组的附录
在评论中,OP表示每个Box
都有一个id,随机选择船位。
我们可以在循环中给出id:
for(var indexRow = 0; indexRow < 5; indexRow++)
{
for(var indexCol = 0; indexCol < 5; indexCol++)
{
var box = new Box();
box.vhID = (((char)(((int)'a') + indexRow))).ToString() + ((char)(((int)'1') + indexCol)).ToString();
board[indexRow, indexCol] = box;
}
}
我在这里做的是从索引构造id。基本上取'a'
的值并添加indexRow
会在'a'
为indexRow
时为0
,'b'
为1
}} 等等。同样,我们得到代表该列的数字。
注意:我们将char
转换为int
,进行添加,然后转换回char
...然后从{{1}转换回来到char
。一旦我们有了字符串,我们就可以将它们连接起来。
我认为我们不需要这个ID。但是,嘿,你可以这样做。
OP还提到他将随机挑选4个船位。足够公平:string
由于用户输入了一个字符串,我建议创建一个函数将其转换为索引对:
var random = new Random();
for (var ships = 0; ships < 4; ships++)
{
board[random.Next(0, 4), random.Next(0, 4)].hasShip = true;
}
首先验证 var input = Console.ReadLine();
if (TryGetCoordinates(input, out int irow, out int icol))
{
var target = board[irow, icol];
}
else
{
Console.WriteLine("The cell {0} does not exist.", input);
}
// ...
bool TryGetCoordinates(string cell, out int indexRow, out int indexCol)
{
// ...
}
:
null
注意:您可以随意使用 bool TryGetCoordinates(string cell, out int indexRow, out int indexCol)
{
indexRow = -1;
indexCol = -1;
if (cell == null)
{
return false;
}
// ...
}
,Trim
或ToUpper
。
我们知道必须是一个字母后跟一个数字,我们可以验证长度:
ToUpperInvariant
我们提取字符并从中提取坐标。注意到第一个是字母,另一个是数字。我们还可以验证它们是否有限。
bool TryGetCoordinates(string cell, out int indexRow, out int indexCol)
{
indexRow = -1;
indexCol = -1;
if (cell == null)
{
return false;
}
if (cell.Length != 2)
{
return false;
}
// ...
}
当然,你可以进行类似于旧答案中解释的验证循环。
注意:我在旧答案中描述的值类型问题仍然适用于数组。
我相信您不希望将 bool TryGetCoordinates(string cell, out int indexRow, out int indexCol)
{
indexRow = -1;
indexCol = -1;
if (cell == null)
{
return false;
}
if (cell.Length != 2)
{
return false;
}
indexRow = (int)cell[0] - (int)'a';
indexCol = (int)cell[1] - (int)'1';
return indexRow < 5 && indexRow >= 0 && indexCol < 5 && indexCol >= 0;
}
转换为对象(顺便说一下,string
是一个对象),您想要选择之前创建的string
对象在Box
上。而且你想在不使用if语句的情况下完成它。你需要的是一本字典。
所以,你会string
意味着它是一个字典,你可以按字符串查询并存储Dictionary<string, Box>
。
<强>补遗强>:
Box
,您可以选择其他类型。在这种情况下,string
很方便,因为它是您从string
获得的。Console.ReadLine()
,则可以创建一个存储其他内容的字典。创建和填充词典
然后,您将所有Box对象添加到Dictionary中,如下所示:
Box
其中var dict = new Dictionary<string, Box>();
// ...
dict.Add("a1", CreateBoxA1());
表示您必须创建对象的任何方式。不,您不需要为每个CreateBoxA1
创建一个方法......您可以这样做:
Box
或者其他什么。我不知道你是如何创建它们的,所以考虑一个占位符,好吗?确定。
从词典中查询和检索值
在您的词典中拥有所有dict.Add("a1", new Box());
个实例后,您可以使用Box
获得所需的实例:
string
附录:您从Console.WriteLine("Enter the name of the Box:");
var name = Console.ReadLine();
var target = dict[name];
获得的值是您使用该键添加到词典中的值。因此,如果用户输入dict[name]
,则"a1"
将是我们使用dict[name]
("a1"
)添加的值。同样,如果您需要的不是dict.Add("a1", new Box());
,您可以创建一个字典来存储不同的类型。
输入验证
您还可以使用词典来验证Box
是否对应于存在的Box,例如:
string
毋庸置疑,但是......你可以根据它做出一个循环,例如:
Console.WriteLine("Enter the name of the Box:");
var name = Console.ReadLine();
if (dict.KeyExists(name))
{
var target = dict[name];
// ...
}
else
{
Console.WriteLine("The Box {0} does not exist", name);
}
此外,不言而喻,但是......您可以添加自己的验证和卫生步骤。例如,使用ToUpper
,ToUpperInvariant
或Trim
。我想提醒一下,将Box target = null;
while(true)
{
Console.WriteLine("Enter the name of the Box:");
var name = Console.ReadLine();
if (dict.KeyExists(name))
{
target = dict[name];
break;
}
Console.WriteLine("The Box {0} does not exist", name);
}
更改为大写或小写是文化敏感的。
另请参阅:Best Practices for Using Strings in .NET。
编辑字典中的删除对象
获得从词典中检索的对象...
string
我们可以使用它,甚至可以修改它:
var target = dict[name];
如果 var target = dict[name];
if (target.hasShip) // no need for "== true" if hasShip bool
{
target.hasShip = false;
Console.WriteLine("Ship Destroyed");
}
是值类型,则必须特别注意。对于自定义类型,表示它不是Box
而是class
。值类型的问题在于它们在赋值时被复制,这意味着当您使用值类型执行struct
时,您将获得一个副本。然后,您必须在操作字典后更新字典:
var target = dict[name];
注意:正如我上面所说,这仅适用于值类型。
如果必要,您甚至可以从字典中删除 var target = dict[name];
if (target.hasShip) // no need for "== true" if hasShip bool
{
target.hasShip = false;
dict[name] = target;
Console.WriteLine("Ship Destroyed");
}
:
Box