动态多维数组c#
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态多维数组c#相关的知识,希望对你有一定的参考价值。
我不确定以前是否已经回答过,但这个问题确实具体。我试图在c#中编写一个dungeon生成器,我希望数组的大小是动态的,并且根据输入的大小在控制台中显示为网格。我让数组是动态的,它可以以网格形式显示每个索引,但我无法弄清楚如何使行中的索引数量动态化。这是我到目前为止所拥有的:
Random rand = new Random();
int num;
num = Convert.ToInt32(Console.ReadLine());
int x = num;
int y = num;
int i = x - 1;
int j = y - 1;
int[,] dungeon = new int[x,y];
for(int z = 0; z <= i; z++)
{
int a = 0;
for( a = 0; a <= j; a++)
{
dungeon[a,z] = rand.Next(0,2);
}
}
for (int h = 0; h <= i; h++)
{
if (h == 0)
{
Console.WriteLine("#-#-#-#-#");
}
Console.WriteLine("|" + dungeon[h,0] + "|" + dungeon[h,1] + "|" + dungeon[h,2] + "|" + dungeon[h,3] + "|");
Console.WriteLine("#-#-#-#-#");
请原谅杂乱。它尚未完成。
那么,目前网格总是一个精确的正方形。因为您对两个维度使用相同的值。您是否只想为每个维度使用单独的值?如果是这样,您需要输入中的另一个值。你可以像现在这样做。例如:
int x = Convert.ToInt32(Console.ReadLine());
int y = Convert.ToInt32(Console.ReadLine());
有几点需要注意:
- 你不需要你的
num
变量,你所做的就是立即将它分配给另一个变量,然后再也不要使用num
。首先使用您想要的变量。 - 作为学术练习,请查看
int.TryParse()
以及如何使用它的示例。目前,如果输入除整数之外的任何内容,则应用程序将崩溃。使用int.TryParse()
,您可以处理该错误情况。 - 另外,作为学术练习,请看一下使用嵌套列表而不是二维数组。像
List<List<int>>
之类的东西。在某些方面,它看起来会更加冗长(re:messy),在其他方面它会更有用。继续从那里开始,尝试将整个数据结构封装到自定义对象中(Grid
或Board
看似合理的名称)。这将允许您将任何杂乱的东西放入类中,然后游戏逻辑可以干净地与该类交互。
我希望数组的大小是动态的
因此,如果您对通用集合没有限制,我强烈建议您使用List <>。忽略更好的清理用户输入的方法,使用列表的代码可能如下所示。由于我们使用面向对象语言,因此最好创建表示我们需求的对象(单元格,网格等)。然后创建表示我们需要的那些对象(行,列,值)的属性或方法。
所以我要把你扔到最深处,但这里是我正在使用的参考资料。
Delegates, Anonymous Methods, and Lambda Expressions。 - 关于同一事物的所有不同陈述/抽象的非常好的文章。
Lambda expressions () => - Microsoft Docs。
Lambda expressions in a Query - 如何使用Linq方法和Lambda表达式查询列表。
Func(TResult) - 基本上是另一位代表.. C#现在有足够的这些吗?
Generic Classes; MyClass - 泛型的力量!
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static void Main()
{
Random rand = new Random();
int num;
num = Convert.ToInt32(Console.ReadLine());
Func<int> valueGenerator = () => { return rand.Next(0,2); };
var dungeon = new Grid<int>(num, num, valueGenerator);
foreach(var row in dungeon.Rows)
{
// First() - https://msdn.microsoft.com/en-us/library/bb291976(v=vs.110).aspx
if (row.First().Row == 0)
{
Console.WriteLine("#-#-#-#-#");
}
// ToArray() - https://msdn.microsoft.com/en-us/library/bb298736(v=vs.110).aspx
var rowValues = row.Select(r => r.Value.ToString()).ToArray();
// string.Join() - https://msdn.microsoft.com/en-us/library/57a79xd0(v=vs.110).aspx
var rowDisplay = string.Join("|", rowValues);
// $ ie Interpolated Strings - https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interpolated-strings
Console.WriteLine($"|{rowDisplay}|");
Console.WriteLine("#-#-#-#-#");
}
}
public class Grid<T>
{
private int _numberOfRows;
private int _numberOfColumns;
// List<> - https://msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.110).aspx
private List<Cell<T>> _cells;
public Grid(int numberOfRows, int numberOfColumns)
{
if (numberOfRows == 0)
throw new ArgumentOutOfRangeException("numberOfRows must be greater than zero.");
if (numberOfColumns == 0)
throw new ArgumentOutOfRangeException("numberOfColumns must be greater than zero.");
_numberOfRows = numberOfRows;
_numberOfColumns = numberOfColumns;
// Enumerable.Range - https://msdn.microsoft.com/en-us/library/system.linq.enumerable.range(v=vs.110).aspx
_cells = Enumerable.Range(0, _numberOfRows)
// Select - https://msdn.microsoft.com/en-us/library/bb548891(v=vs.110).aspx
.Select(r => Enumerable.Range(0, _numberOfColumns)
.Select(c => new Cell<T>
{
Row = r,
Col = c
})
// ToList() - https://msdn.microsoft.com/en-us/library/bb342261(v=vs.110).aspx
.ToList())
// - https://msdn.microsoft.com/en-us/library/system.linq.enumerable.selectmany(v=vs.110).aspx
.SelectMany(c => c)
.ToList();
}
public Grid(int numberOfRows, int numberOfColumns, Func<T> valueGenerator)
{
if (numberOfRows == 0)
throw new ArgumentOutOfRangeException("numberOfRows must be greater than zero.");
if (numberOfColumns == 0)
throw new ArgumentOutOfRangeException("numberOfColumns must be greater than zero.");
_numberOfRows = numberOfRows;
_numberOfColumns = numberOfColumns;
_cells = Enumerable.Range(0, _numberOfRows)
.Select(r => Enumerable.Range(0, _numberOfColumns)
.Select(c => new Cell<T>
{
Row = r,
Col = c,
Value = valueGenerator()
})
.ToList())
.SelectMany(c => c)
.ToList();
}
public IEnumerable<ICell<T>> Cells
{
get
{
return _cells;
}
}
public IEnumerable<IEnumerable<ICell<T>>> Rows
{
get
{
return _cells.GroupBy(c => c.Row)
.Select(gs => gs.OrderBy(g => g.Col).ToList())
.ToList();
}
}
public IEnumerable<IEnumerable<ICell<T>>> Columns
{
get
{
return _cells.GroupBy(c => c.Col)
.Select(gs => gs.OrderBy(g => g.Row).ToList())
.ToList();
}
}
// We expose the Interface because we don't want anyone outside grid modifying
// Row or Col
public interface ICell<T>
{
int Row { get; }
int Col { get; }
T Value { get; set; }
}
private class Cell<T> : ICell<T>
{
public T Value { get; set; }
public int Row { get; set; }
public int Col { get; set; }
}
}
}
输出(0和1是随机的......)
4
#-#-#-#-#
|0|0|0|1|
#-#-#-#-#
|1|0|0|1|
#-#-#-#-#
|0|0|1|0|
#-#-#-#-#
|0|1|1|0|
#-#-#-#-#
在所有这些之后你可能会问自己,为什么要使用泛型类Grid?好吧,我怀疑你想要存储在Cell中的唯一东西是int。也许你想存储一个代表各种事物的完整对象......
int Replaced with DungeonCell<>
以上是关于动态多维数组c#的主要内容,如果未能解决你的问题,请参考以下文章