-1

I am coding the game checkers in C using the Ncurses library and I have all the pieces stored in a matrix, g.board, and when looking for possible moves I need to make sure the program doesn't try and access an element outside of the matrix, because segmentation faults. I have a solution, but it feels rather crude and I have the feeling there is a more elegant way to do this, but I can't find or think of it.

int x and int y refer the x and y location in that matrix that I want to look for possible moves around. char ck just tells me if the piece is a king a color, the normal colors can only move in one direction. g.board[y][x].possible just is bool variable in the structure that tells me if it's a possible move.

void checkPossible(int y, int x, char ck);
{
    bool left = false, right = false, top = false, bottem = false;

    // Dertimes if a tile is out of bounds 
    if (y != 0)
    {
        top = true;        
    }
    if (y != 8)
    {
        bottem = true;
    }
    if (x != 0)
    }
        left = true;
    }
    if (x != 8)
    {
        right = true;
    {

    // Sets g.board.possible to true if possible move
    if ((top == true && left == true) && (ck == 'k' || ck == 'w'))
    {
        g.board[y - 1][x - 1].possible = true; 
    }
    if ((top == true && right == true) && (ck == 'k' || ck == 'w'))
    {
        g.board[y - 1][x + 1].possible = true; 
    }
    if ((bottem == true && left == true) && (ck == 'k' || ck == 'r'))
    {
        g.board[y + 1][x - 1].possible = true; 
    }
    if ((bottem == true && right == true) && (ck == 'k' || ck == 'r'))
    {
        g.board[y + 1][x + 1].possible = true; 
    }
}

As far as I know it works, I haven't tested it much, but it feels crude. I apologize for any mistakes or less than optimal coding, I am rather new to this.

John Smith
  • 11
  • 2
  • `g.board[y - 1][x - 1].possible == true;` should use `=`, not `==`. – Barmar May 02 '19 at 06:11
  • I don't get `if (y != 0){top = true;}`. If y is NOT 0 then you are at the top? – Yunnosch May 02 '19 at 06:15
  • Because of `if (x != 0)}` and `{right = true;{` I suspect that you never successfully compiled this. Please double check that the code you show is closely enough related to what you are working on. Maybe try for a [mcve]. On the other hand, the question is more of a "please review" type than is appropriate for StackOverflow. – Yunnosch May 02 '19 at 06:17
  • @Yunnosch I think it means "If y is not 0, then the element on top of this one is inside the board". – Barmar May 02 '19 at 06:22
  • Please improve your question by [edit](https://stackoverflow.com/posts/55946497/edit)ing it to provide some [MCVE] – Basile Starynkevitch May 02 '19 at 06:25
  • 2
    Don't write things like `if (bottom == true)`. Just write `if (bottom)`. – Barmar May 02 '19 at 06:27
  • Your algorithm seems fine. There are lots of ways to improve the coding style. I suggest you post it on [codereview.se] for comments. – Barmar May 02 '19 at 06:28
  • For instance, `top = y != 0;` instead of using `if`. – Barmar May 02 '19 at 06:28
  • @BasileStarynkevitch Thanks, a way of reading it was all I needed. (no sarcasm intended) – Yunnosch May 02 '19 at 06:31
  • 1
    If you have complete working code that you want feedback on, codereview.stackexchange.com is the right place to go. You will be amazed on the amount of feedback you can get there. Do note that when you post there, the code should work. It's not for finding bugs. – klutt May 02 '19 at 06:44

2 Answers2

2

One thing looks very fishy. g.board[y - 1][x - 1].possible == true should be g.board[y - 1][x - 1].possible = true. The current code does nothing.

The code is also VERY overly complicated. Look at this:

void checkPossible(int y, int x, char ck);
{
    bool left = x != 0, 
         right = x != 8, 
         top = y !=8, 
         bottem = y!=0;

    // Sets g.board.possible to true if possible move
    if(ck == 'k' || ck == 'w') {
        g.board[y - 1][x - 1].possible = (top && left);
        g.board[y - 1][x + 1].possible = (top && right);
        g.board[y + 1][x - 1].possible = (bottem && left);
        g.board[y + 1][x + 1].possible = (bottem && right);
    }
}

In general, don't compare Boolean variables to the Boolean constants true and false or other values. Use them directly as is instead, and give them descriptive names.

Also, I would (probably, because I have not seen the rest of the code) split checking of coordinates and character. The less functionality you put in a single function, the easier it is to understand, maintain and name. Like this:

bool isValidCoordinate(int y, int x) {
    return y>=0 && y<=8 && x>=0 && x<=8;
}

bool isValidCharacter(char ck) {
    return ck == 'k' || ck == 'w';
}

I don't know if that would fit into your project, but it gives an idea of how you can do it.

klutt
  • 30,332
  • 17
  • 55
  • 95
0

Is there a better way to make sure an element outside of a matrix isn't accessed?

The only reliable way to do that in C is to check (at runtime) the indexes used to access the matrix, or to prove (before compilation) that this cannot happen. Tools like Frama-C could help you in making such a proof. However, be aware of Rice's theorem.

Accessing an element outside (the range of the array containing that element) is some undefined behavior. So if you do that, anything can happen (and that sadly includes that no observable behavior is impacted), so be scared.

On Linux, you might also use valgrind at runtime. It is very often quite helpful.

Your code could be wrong if x was negative (or above the dimension of your checker board). You'll better also check that case or prove that it cannot happen.

See also assert(3). You might want to use it (it can do runtime checks).

PS. You really should understand what undefined behavior means (even as a newbie programmer). Read What Every C Programmer Should Know about Undefined Behavior. Read also How to debug small programs. If you use some GCC compiler, invoke it as gcc -Wall -Wextra -g to get warnings and debug info. Improve your code to get no warnings, then use the gdb debugger (or else whatever debugger you have).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547