You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#二维数组地图收币程序报IndexOutOfRangeException错误求助

修复C#地图金币统计代码的数组越界问题

需求说明

编写C#代码统计玩家在二维数组地图中收集的金币数量,程序需按以下控制台输入格式执行:

Line 1: Size of the map
Line 2: N = Number of coins
Line 3 to 3 + N: Coin coordinates
Line 4 + N: Player's origin position
Line 5 + N: Number of moves
Line 6 + N: Moves (r for right, l for left, s for stay...)

现有代码

static void Main(string[] args)
{
    /* Get data from input file */
    var data = new List<String>();
    string line;

    while ((line = Console.ReadLine()) != null) {
        data.Add(line);
    }

    // ADD YOUR CODE HER

    // map and coins initialisation --------------------------------------------
    int mapSize = Convert.ToInt32(data[0]);
    int[,] map = new int[mapSize,mapSize];
    string tmpCoinX = "";
    string tmpCoinY = "";
    int coinX = 0;
    int coinY = 0;
    int coinAmnt = Convert.ToInt32(data[1]);
    int coinsCollected = 0;
    bool passed = false;
    for (int coinline = 2; coinline < 2+coinAmnt; coinline++)
    {
        foreach (char character in data[coinline])
        {
            if (character == ',') { passed = true; }
            else {
                if (passed == true)
                {
                    tmpCoinY += character.ToString();
                }
                else
                {
                    tmpCoinX += character.ToString();
                }
            }
        }
        passed = false;
        coinX = Convert.ToInt32(tmpCoinX);
        coinY = Convert.ToInt32(tmpCoinY);
        map[coinY, coinX] = 1;
    }

    // player position initialisation -----------------------------------------
    string Sx = "";
    string Sy = "";
    passed = false;
    foreach(char i in data[3+coinAmnt-1])
    {
        if (i == ',')
        {
            passed = true;
        }
        else
        {
            if (passed == true)
            {
                Sy = Sy + i.ToString();
            }
            else
            {
                Sx = Sx + i.ToString();
            }
        }
        
    }
    int x = Convert.ToInt32(Sx);
    int y = Convert.ToInt32(Sy);

    // imposible cases prevention --------------------------------------------
    bool imp = false;

    // reads the data list and acts accordingly
    foreach(string i in data)
    {
        if (i == "u")
        {
            y += 1;
        }
        if (i == "l")
        {
            x -= 1;
        }
        if (i == "r")
        {
            x += 1;
        }
        if (i == "d")
        {
            y -= 1;
        }
        
        if (x >= mapSize || y >= mapSize || x < 0 || y < 0)
        {
            imp = true;
            break;
        }

        if (map[y, x] == 1)
        {
            coinsCollected += 1;
            map[y, x] = 0;
        }
    }

    if (imp == true)
    {
        Console.WriteLine("out");
    }
    else
    {
        Console.Write(coinsCollected);
    }
}

测试用例

4
2
2,1
0,3
0,0
3
u
l
d

错误信息

An error occurred:

Unhandled Exception:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
  at SelectionCandidat.Program.Main (System.String[] args) [0x000f2] in <cd8ee2cfc068460888190546c241d3d1>:0 
[ERROR] FATAL UNHANDLED EXCEPTION: System.IndexOutOfRangeException: Index was outside the bounds of the array.
  at SelectionCandidat.Program.Main (System.String[] args) [0x000f2] in <cd8ee2cfc068460888190546c241d3d1>:0

修复方案

1. 修复金币坐标临时变量未重置问题

处理每一行金币坐标时,tmpCoinX和tmpCoinY未清空,导致后续坐标字符串累加,转换后数值超出地图范围触发数组越界。修改金币循环部分:

for (int coinline = 2; coinline < 2+coinAmnt; coinline++)
{
    tmpCoinX = ""; // 每次循环重置X坐标字符串
    tmpCoinY = ""; // 每次循环重置Y坐标字符串
    foreach (char character in data[coinline])
    {
        if (character == ',') { passed = true; }
        else {
            if (passed == true)
            {
                tmpCoinY += character.ToString();
            }
            else
            {
                tmpCoinX += character.ToString();
            }
        }
    }
    passed = false;
    coinX = Convert.ToInt32(tmpCoinX);
    coinY = Convert.ToInt32(tmpCoinY);
    map[coinY, coinX] = 1;
}

2. 修复移动指令遍历范围错误

原代码遍历所有输入行,将非移动指令(如地图尺寸、金币数量)当作移动处理,逻辑混乱。修改为仅遍历移动指令部分:

// 移除原foreach(data)逻辑,替换为以下代码
bool imp = false;
int moveCount = Convert.ToInt32(data[2 + coinAmnt + 1]);
int moveStartIndex = 2 + coinAmnt + 2;

for (int i = moveStartIndex; i < moveStartIndex + moveCount; i++)
{
    string move = data[i];
    if (move == "u")
    {
        y += 1;
    }
    else if (move == "l")
    {
        x -= 1;
    }
    else if (move == "r")
    {
        x += 1;
    }
    else if (move == "d")
    {
        y -= 1;
    }
    else if (move == "s")
    {
        // 停留指令,不做位置变更
    }

    // 移动后立即检查是否越界
    if (x >= mapSize || y >= mapSize || x < 0 || y < 0)
    {
        imp = true;
        break;
    }

    // 检查是否收集到金币
    if (map[y, x] == 1)
    {
        coinsCollected += 1;
        map[y, x] = 0;
    }
}

3. 新增初始位置越界检查

如果玩家初始位置本身在地图外,直接输出"out"并退出:

int x = Convert.ToInt32(Sx);
int y = Convert.ToInt32(Sy);

// 新增初始位置检查
if (x >= mapSize || y >= mapSize || x < 0 || y < 0)
{
    Console.WriteLine("out");
    return;
}

4. 优化坐标分割逻辑(可选)

手动遍历字符分割坐标容易出错,用Split方法简化:

// 处理金币坐标替换为:
string[] coinCoords = data[coinline].Split(',');
coinX = int.Parse(coinCoords[0]);
coinY = int.Parse(coinCoords[1]);

// 处理玩家初始位置替换为:
string[] playerCoords = data[2 + coinAmnt].Split(',');
int x = int.Parse(playerCoords[0]);
int y = int.Parse(playerCoords[1]);

修复后运行结果

针对提供的测试用例,玩家执行u后位置为(0,1),执行l后x变为-1,触发越界,程序输出out,符合需求。

内容的提问来源于stack exchange,提问作者notPatern

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:35:00