[2015-08-05] Challenge #226 [Intermediate] Connect Four

C version. It's probably slow/verbose.

include <stdio.h>

include <stdlib.h>

include <string.h>

include <assert.h>

include <ctype.h>

define NO_WINNER 0

define P1_WIN 1

define P2_WIN 2

define MOVE_NOT_POSSIBLE 3

char** board; int board_w, board_h;

const char player1 = 'X'; const char player2 = 'O';

void alloc_board(int w, int h) { board_w = w; board_h = h; board = (char **)malloc(sizeof(char *) * h);

    for(int i = 0; i < h; i++) {
            board[i] = (char *)malloc(sizeof(char) * w);
            memset(board[i], '-', board_w);
    }

}

void print_board() { for(int i = 0; i < board_h; i++) { for(int j = 0; j < board_w; j++) putchar(board[i][j]);

            putchar('\n');
    }

}

int valid_pos(int x, int y) { return (x >= 0 && x < board_w && y >= 0 && y < board_h); }

int find_chain(int x, int y, int dx, int dy) { int chain = 0; char player = board[y][x]; if(player == '-') return 0;

    for(int i = 0; i < 4; i++, x += dx, y += dy) {
            if(!valid_pos(x, y)) return chain;

            if(board[y][x] == player)
                    chain++;
            else
                    return chain;
    }

    return chain;

}

int max3(int a, int b, int c) { int m = a; (m < b) && (m = b); (m < c) && (m = c); return m; }

int check_board() { int max_p1 = 0, max_p2 = 0;

    for(int i = 0; i < board_h; i++) {
            for(int j = 0; j < board_w; j++) {
                    if(board[i][j] == '-') continue;
                    int c1 = find_chain(j, i, 1, 0);
                    int c2 = find_chain(j, i, 0, 1);
                    int c3 = find_chain(j, i, 1, 1);

                    int max_chain = max3(c1, c2, c3);

                    if(board[i][j] == player1)
                            max_p1 = max_chain > max_p1 ? max_chain : max_p1;
                    else
                            max_p2 = max_chain > max_p2 ? max_chain : max_p2;
            }
    }

    if(max_p1 > max_p2 && max_p1 >= 4) 
            return P1_WIN;
    else if(max_p2 > max_p1 && max_p2 >= 4) 
            return P2_WIN;
    else
            return NO_WINNER;

} int make_move(char move) { if(!isalpha(move) || tolower(move) > 'g') return MOVE_NOT_POSSIBLE;

    char player = player1;
    if(islower(move))
            player = player2;
    int col = tolower(move) - 'a';

    int row = 0;
    while(row < board_h - 1 && board[(row + 1 == board_h ? row : row + 1)][col] == '-') row++;
    board[row][col] = player;
    return 0;

}

int main(int argc, char** argv) { alloc_board(7, 6);

    char moves[][2] = {
            "Cd",
            "Dd",
            "Db",
            "Cf",
            "Cc",
            "Ba",
            "Ad",
            "Ge",
            "Eg"
    };

    for(int i = 0; i < sizeof(moves) / sizeof(moves[0]); i++) {
            make_move(moves[i][0]);
            if(check_board() == P1_WIN) {
                    printf("Player 1 wins at move %d\n", i + 1);
                    break;
            }

            make_move(moves[i][1]);
            if(check_board() == P2_WIN) {
                    printf("Player 2 wins at move %d\n", i + 1);
                    break;
            }
    }

    print_board();

}

/r/dailyprogrammer Thread