Search code examples
crecursioncygwin

Connect-N in C; recursive counting problems?


I'm trying to write a version of Connect-4 where you can specify the board size, how many tiles you need to connect to win, and I'm having problems with counting the tiles in specific directions.

I know there are 8 directions on the board, and I know in certain places you can only call for certain directions, and as such I wrote the following function to check for counts in directions, recursively.

int DirectionCheck(Board *board, int connect, int prow, int pcol, int drow, int dcol, int player, int count){
    int **spaces = board->spaces;
    int rowindex = (board->rows) - 1;
    int colindex = (board->columns) - 1;

    if((drow == -1) & (dcol == 1)){
        if((spaces[pcol][prow] == player) && (prow > 0) && (pcol < colindex)){
            prow = prow - 1;
            pcol = pcol + 1;
            ++count;
            return DirectionCheck(board, connect, prow, pcol, -1, 1, player, count);
        }else{
            return count;
        }
    }else if((drow == 1) & (dcol == -1)){
        if((spaces[pcol][prow] == player) && (pcol>0) && (prow < rowindex)){
            prow = prow + 1;
            pcol = pcol - 1;
            ++count;

            return DirectionCheck(board, connect, prow, pcol, 1, -1, player, count);
        }else{
            return count;
        }
    }else if((drow == 1) & (dcol == 1)){
        if((spaces[pcol][prow] == player) && (prow < rowindex) && (pcol < colindex)){
            prow = prow + 1;
            pcol = pcol + 1;
            ++count;

            return DirectionCheck(board, connect, prow, pcol, 1, 1, player, count);
        }else{
            return count;
        }
    }else if((drow == -1) && (dcol == -1)){
        if((spaces[pcol][prow] == player) && (pcol > 0) && (prow > 0)){
            prow = prow - 1;
            pcol = pcol - 1;
            ++count;

            return DirectionCheck(board, connect, prow, pcol, -1, -1, player, count);
        }else{
            return count;
        }
    }else if((drow == 1) && (dcol == 0)){
        if((spaces[pcol][prow] == player) && (prow < rowindex)){
            prow = prow + 1;
            ++count;

            return DirectionCheck(board, connect, prow, pcol, 1, 0, player, count);
        }else{
            return count;
        }
    }else if((drow == -1) && (dcol == 0)){
        if((spaces[pcol][prow] == player) && (prow > 0)){
            prow = prow - 1;
            ++count;

            return DirectionCheck(board, connect, prow, pcol, -1, 0, player, count);
        }else{
            return count;
        }
    }else if((drow == 0) && (dcol == 1)){
        if((spaces[pcol][prow] == player) && (pcol < colindex))    {
            pcol = pcol + 1;
            ++count;

            return DirectionCheck(board, connect, prow, pcol, 0, 1, player, count);
        }else{
            return count;
        }
    }else if((drow == 0) && (dcol == -1)){
        if((spaces[pcol][prow] == player) && (pcol > 0)){
            pcol = pcol - 1;
            ++count;

            return DirectionCheck(board, connect, prow, pcol, 0, -1, player, count);
        }else{
            return count;
        }
    }else{
        printf("This should never appear!");

        return 0;
    }
}

You pass in a board ( a structure I made that contains a height, width, and a matrix), a position in a row, a position in a column, the direction you want to move in the row, the direction you want to move in the column, the current player, and the count (which is 0 in most cases).

When I run this on a board with one piece in it, it returns a 0, but does not print the "this should never appear!" condition I set. It should return a 1. I'm not sure what I'm doing incorrectly. Any help would be great.

Also, I know all of my other functions are working correctly as I've tested them individually.

I'm calling the function as follows: int count = 0; int count2 = DirectionCheck(board, 4, prow, pcol, -1, 1, player, count);

My goal is to have this check to see if there's a piece up and to the right of the current piece, which is dynamically allocated based on what the player inputs into the function. If there are no pieces to the top and right of the current piece, it should print out a 0. Otherwise, it should increment the count, and then repeat the function.


Solution

  • I felt like your function was way too complicated. The thing you were asking about that was wrong was that the check for the current position being occupied needed to be at the top. But there were various other things wrong with it:

    1. What is connect? It is unused.
    2. A few places you used & instead of && although it happened to work.
    3. A lot of repetition of code.
    4. Recursion when not needed.

    I took the liberty of rewriting your function like this:

    // Note, this function should never be called with drow == 0 and dcol == 0.
    int DirectionCheck(const Board *board, int prow, int pcol,
            int drow, int dcol, int player)
    {
        int count = 0;
    
        while (prow >= 0 && pcol >= 0 &&
                prow < board->rows && pcol < board->columns) {
            if (board->spaces[pcol][prow] == player)
                count++;
            else
                break;
            prow += drow;
            pcol += dcol;
        }
        return count;
    }