0

I was coding c in code blocks and wanted to move over to visual studio since it has a tendency to compile programs better, yet for some reason the ascii values that were displaying numbers fine in code blocks eem to be giving me weird results in vs. here's a snippet of what they look like:

(left) bad output, and (right) good output

Since the code is exactly the same on each platform, this leads me to believe there is some setting I overlooked int vs pertaining to ascii which is already set in code blocks. For review, here is my code:

#include <windows.h>

#define WIDTH 18
#define HEIGHT 18
#define BOMBS 50

struct xorshift_state {
    int a;
};

int xorshift(struct xorshift_state *state)
{
    int x = state->a;
    x ^= x << 13;
    x ^= x >> 17;
    x ^= x << 5;
    return state->a = x;
}

void ExpandGrid(int fullGrid[WIDTH][HEIGHT], int knownGrid[WIDTH][HEIGHT], int blankPos[2])
{
    int neighbors[8][2] = { { 0,1 },{ 1,0 },{ 1,1 },
    { 0,-1 },{ -1,0 },
    { -1,-1 },{ -1,1 },{ 1,-1 } };
    int curTile[2];

    knownGrid[blankPos[0]][blankPos[1]] = 1;
    if (fullGrid[blankPos[0]][blankPos[1]] != 0) return;

    for (int blck = 0; blck < 8; ++blck)
    {
        curTile[0] = blankPos[0] + neighbors[blck][0];
        curTile[1] = blankPos[1] + neighbors[blck][1];
        if (curTile[0] > WIDTH - 1 || curTile[1] > HEIGHT - 1 || curTile[0] < 0 || curTile[1] < 0) continue;

        if (fullGrid[curTile[0]][curTile[1]] == 0 && knownGrid[curTile[0]][curTile[1]] == 0)
        {
            knownGrid[curTile[0]][curTile[1]] = 1;
            ExpandGrid(fullGrid, knownGrid, curTile);
        }
        else if (fullGrid[curTile[0]][curTile[1]] > 0) knownGrid[curTile[0]][curTile[1]] = 1;
    }
}

int main(int argc, char *argv[])
{

    COORD characterBufferSize = { WIDTH, HEIGHT };
    COORD characterPosition = { 0, 0 };
    SMALL_RECT consoleWriteArea = { 0, 0, WIDTH - 1, HEIGHT - 1 };
    CHAR_INFO consoleBuffer[WIDTH][HEIGHT];

    HANDLE wHnd = GetStdHandle(-11);
    HANDLE rHnd = GetStdHandle(-10);

    DWORD numEventsRead = 0;
    DWORD numEvents = 0;
    INPUT_RECORD *eventBuffer = { 0 };
    int wait = 1000;

    int startGrid[WIDTH][HEIGHT] = { 0 };
    int knownGrid[WIDTH][HEIGHT] = { 0 };
    int arrowPos[2] = { 0, 0 };
    int bomb[2] = { 0 };
    struct xorshift_state seed = { argc == 2 ? (int)argv[1] : 1 };

    for (int i = 0; i < BOMBS; i++)
    {
        while (startGrid[bomb[0]][bomb[1]] < -1 || bomb[0] <= 0 || bomb[1] <= 0 || bomb[0] >= WIDTH - 1 || bomb[1] >= HEIGHT - 1)
        {
            bomb[0] = (xorshift(&seed) % WIDTH - 1) + 1;
            bomb[1] = (xorshift(&seed) % HEIGHT - 1) + 1;
        }

        startGrid[bomb[0]][bomb[1]] = -9;

        startGrid[bomb[0] + 1][bomb[1] + 1]++;
        startGrid[bomb[0] + 1][bomb[1]]++;
        startGrid[bomb[0]][bomb[1] + 1]++;
        startGrid[bomb[0] - 1][bomb[1] + 1]++;
        startGrid[bomb[0]][bomb[1] - 1]++;
        startGrid[bomb[0] + 1][bomb[1] - 1]++;
        startGrid[bomb[0] - 1][bomb[1] - 1]++;
        startGrid[bomb[0] - 1][bomb[1]]++;
    }


    while (1)
    {
        if (arrowPos[0] > WIDTH - 1) arrowPos[0] = WIDTH - 1;
        if (arrowPos[0] < 0) arrowPos[0] = 0;
        if (arrowPos[1] > HEIGHT - 1) arrowPos[1] = HEIGHT - 1;
        if (arrowPos[1] < 0) arrowPos[1] = 0;

        for (int x = 0; x < WIDTH; ++x)
        {
            for (int y = 0; y < HEIGHT; ++y)
            {

                if (knownGrid[x][y] == 1)
                {
                    if (startGrid[x][y] > 0)
                    {
                        consoleBuffer[x][y].Char.AsciiChar = '0' + startGrid[x][y];
                        consoleBuffer[x][y].Attributes = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
                    }
                    else
                    {
                        consoleBuffer[x][y].Char.AsciiChar = 'o';
                        consoleBuffer[x][y].Attributes = (startGrid[x][y] < 0 ? FOREGROUND_RED : FOREGROUND_BLUE) | FOREGROUND_INTENSITY;
                    }
                }
                else
                {
                    consoleBuffer[x][y].Char.AsciiChar = '00';
                    consoleBuffer[x][y].Attributes = 0;
                }

                if (arrowPos[0] == x && arrowPos[1] == y)
                {
                    consoleBuffer[x][y].Attributes = BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN;
                }
            }
        }

        WriteConsoleOutput(wHnd, *consoleBuffer, characterBufferSize, characterPosition, &consoleWriteArea);

        numEvents = 0;
        numEventsRead = 0;
        GetNumberOfConsoleInputEvents(rHnd, &numEvents);

        if (numEvents)
        {
            eventBuffer = malloc(sizeof(INPUT_RECORD) * numEvents);
            ReadConsoleInput(rHnd, eventBuffer, numEvents, &numEventsRead);
        }

        if (numEventsRead && wait <= 0)
        {
            wait = 1000;
            switch (eventBuffer[0].Event.KeyEvent.wVirtualKeyCode)
            {
            case 38:
                arrowPos[0]--;
                break;
            case 40:
                arrowPos[0]++;
                break;
            case 37:
                arrowPos[1]--;
                break;
            case 39:
                arrowPos[1]++;
                break;
            case 13:
                ExpandGrid(startGrid, knownGrid, arrowPos);
                break;
            }
        }

        wait--;
    }
}
TryingMyBest
  • 63
  • 10
  • Please reduce to a [mre]. Surely some hardcoded output is sufficient to demonstrate the problem. – Yunnosch Aug 24 '20 at 06:05
  • I think if you put this code in visual studio then it should produce the problem, no? – TryingMyBest Aug 24 '20 at 06:18
  • And would that help you? I assume that you want somebody to understand your code, find the problem and explain how to fix it. Your chances for that are better if you provide a MRE instead of the full code. – Yunnosch Aug 24 '20 at 06:20
  • Well thats the thing, i dont exactly know whats causing the problem, if its something extraneous in my code or inherent to the projects settings itself. I found it safest to provide the full code in case someone caught something which I did not. Something that had I shortened my code down would not have been noticed. but I can understand how minimizing the code would make it easier to understand, yes – TryingMyBest Aug 24 '20 at 06:24
  • So what happens if you reduce all of your code to the output of only the first 10 characters in your screenshot? – Yunnosch Aug 24 '20 at 06:26
  • Open and Save your file in UTF8 (through notepad for example) and then open with VS. – Majid Hajibaba Aug 24 '20 at 06:41
  • @majidhajibaba still weird outputs... I think that its more of the 'value the computer is generating' error than like an 'i typed a character in a different encoding' error, but thank you for your input either way! =). – TryingMyBest Aug 24 '20 at 07:04

1 Answers1

1

This does not do what you think it does :

bomb[0] = (xorshift(&seed) % WIDTH - 1) + 1;

From the use of this calculated value right after, you appear to expect this to return a value in the range [1,WIDTH-2].

But :

Given all those issues on that one line, I'm not surprised you see strange things happen. Not only have you not properly limited the range of the calculated value, you're also a victim of implementation defined and undefined behavior.

There might well be other issues in the code, but I'd start with these.

Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40
  • Hmm, well that's interesting, ill make note of that. But that is simply the placement of the bombs, it shouldn't affect the tile number, right? Maybe more is at play here than I understand but it just supposed to be a replacement for rand(). And since i have a while loop to make sure the values don't go out-of-bounds, the only concerning part would be shifting negatives; yet when I added an abs() function to the values the output was still scrambled... weird. – TryingMyBest Aug 24 '20 at 07:02