Search code examples
c#textmode

How can I print somethying that isn't there?


I'm doing a text based game for a school project and I see myself stuck with a quite stupid problem. The concept is simple, there's a map, a player, some monsters and some items. For the map data structure I decided to use a 2d array of char's that have a unicode for content. On top of this, I have a camera, which has a radius. The player never moves on screen, it has a x and y, but what has motion on screen is the camera itself. This works quite fine except when I get to the corners or any outside wall. I get my camera doing this

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());

My 'cameraSize' is declared on the beginning of the class and is filled when the constructor is called

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

The class 'difficulty' is irrelevant for my problem. My problem itself is that I can't make the player positioned on the center when I get to the border walls as there is nothing to get from the array, since these are negative positions.


Solution

  • There are two approaches to this sort of problem.

    1) In your loop, check if a value if out of range and output the value by hand.

    2) Wrap your array in a custom class which ignores out of range values.
    Something like this:

    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;
            }
        }
    }
    

    My recommendation is for set to throw an exception when called on out of range values, but my example swallows the failure instead.