【问题标题】:How can I print somethying that isn't there?如何打印不存在的东西?
【发布时间】:2016-10-01 04:59:18
【问题描述】:

我正在为一个学校项目制作一个基于文本的游戏,但我发现自己遇到了一个非常愚蠢的问题。 这个概念很简单,有一张地图、一个玩家、一些怪物和一些物品。 对于地图数据结构,我决定使用具有 unicode 内容的 char 的 2d 数组。 最重要的是,我有一个相机,它有一个半径。玩家永远不会在屏幕上移动,它有一个 x 和 y,但屏幕上的运动是相机本身。这工作得很好,除非我到达角落或任何外墙。 我让我的相机这样做

int size = cameraSize/2;
int top = player.GetY() - size, bottom = player.GetY() + size;
char[,] camera = new char[cameraSize, cameraSize];
Console.SetCursorPosition(0,0);

for (int i = top; i < bottom; i++)
{
    for (int j = top; j < bottom; j++)
    {
        camera[i, j] = map.ReMapPosition(i, j);
        Console.Write(camera[i,j]);
    }
    Console.Write("\n");
}

Console.SetCursorPosition(cameraSize,cameraSize);
Console.Write(player.GetPlayerChar());

我的 'cameraSize' 在类的开头声明,并在调用构造函数时填充

private int cameraSize;
cameraSize = difficulty.GetCameraSize();

“难度”类与我的问题无关。 我的问题本身是,当我到达边界墙时,我无法让玩家定位在中心,因为从阵列中没有任何东西可以得到,因为这些是负位置。

【问题讨论】:

  • 假设在负坐标处存在 一个值,您可以读取该值而不会出现越界异常。您希望该值是多少?
  • 一个简单的空白区域就可以了,我只需要能够让玩家保持居中,但也能够走到角落并靠近墙壁。
  • 好的。下一个问题。为什么你有一个camera 数组?你写入它,你读出它,为什么你需要一个数组?为什么不只是一个简单的char 变量?
  • 说实话,这是我尝试解决问题两个多小时的结果......
  • 好的,然后停下来,退后一步,重新思考问题,而不是随意尝试。当坐标有效时,您需要一种行为 - 获取该地图坐标处的值 - 如果坐标无效,则需要另一种行为 - 获取空格。 这是一个方法的规范,所以写那个方法。或者,更确切地说是两种方法。一个应该叫做IsValid,它应该接受一个坐标和一个地图,并返回一个布尔值。另一个应该叫GetMapValue,它应该带一个坐标、一张地图,然后叫IsValid。你知道这将如何运作吗?

标签: c# text mode


【解决方案1】:

解决这类问题有两种方法。

1) 在您的循环中,检查一个值是否超出范围并手动输出该值。

2) 将您的数组包装在一个忽略超出范围值的自定义类中。
像这样的:

class MyWrapper
{
    private readonly char[,] data;
    public MyWrapper(char[,] data)
    {
        this.data=data;
    }
    private bool InRange(int x, int y)
    {
        return x >= 0 && y >= 0 && x < data.GetLength(0) && y < data.GetLength(1);
    }
    public char this[int x, int y]
    {
        get
        { 
            return InRange(x,y) ? data[x,y] : ' ';
        }
        set
        {
            if(InRange(x,y)) data[x,y] = value;
        }
    }
}

我的建议是 set 在调用超出范围的值时抛出异常,但我的示例反而吞下了失败。

【讨论】:

  • 我喜欢这个答案,但我该如何做这个包装?
  • 运行MyWrapper foo = new MyWrapper(camera);后,将camera[1,2]的所有实例替换为foo[1,2]。
  • 所以我试过了,它编译得很好,但它没有显示任何输出
  • 我在dotnetfiddle.net/7L8dVi 分享了一个使用这个包装器的独立示例。我使用~ 代替空格来使输出更清晰。
  • 顺便说一句,请注意我的小提琴渲染 [x,y] 有点谎言(应该是 [y,x]),或者循环应该倒置。只要您对此保持一致,犯此错误通常是可以的,但它往往会使以后调试有点头疼。
【解决方案2】:

C# 不能“检索不存在的值”,但您确实有几个选择

  • 检查您是否试图获得负仓位,或者仓位太大,并返回一个空格

    或

  • 在所有边上将数组的大小增加cameraSize/2,这将有效地将宽度和高度增加cameraSize,然后使其到达玩家只能在坐标(cameraSize/2,cameraSize/2)中移动的位置和(mapWidth-cameraSize/2,mapHeight-cameraSize/2)。 (&lt;-- 坐标可能为 (y,x),因为二维数组的工作方式以及代码的编写方式)。这样一来,相机周围总是有一个填充物,所以不应该有负面指标

【讨论】:

  • 我确实考虑过您的第二个解决方案,但在我尝试实施后,我只是认为这将是一种不干净的解决方案。
  • 是的......我把它放在那里作为最后的手段。这将是一个很大的痛苦,并导致非常丑陋的代码
  • 没错!尽管如此,还是感谢您的提示
猜你喜欢
  • 2016-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 2016-12-11
  • 2018-12-03
  • 1970-01-01
相关资源
最近更新 更多