summaryrefslogtreecommitdiff
path: root/src/main.c
blob: 01a440df3cc5aff3b4d3e1101e8fb7286bd2dd05 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

#include "consts.h"
#include "protos.h"

SOLUTION is_board_solved(BOARD board) {
    char cases[8] = {EMPTY};
    char i;

    // rows and cols
    for (i = 0; i < 3; i++) {
        cases[i] = board[i][0] * board[i][1] * board[i][2];
        cases[i + 3] = board[0][i] * board[1][i] * board[2][i];
    }

    // diagonals
    cases[6] = board[0][0] * board[1][1] * board[2][2];
    cases[7] = board[0][2] * board[1][1] * board[2][0];

    // check cases for winner
    for (i = 0; i < 8; i++) {
        if (cases[i] == 1) {
            // X won
            return X_WON;
        } else if (cases[i] == 8) {
            // O won
            return O_WON;
        }
    }

    // check cases for remaining moves
    for (i = 0; i < 9; i++) {
        if (cases[i] == EMPTY) {
            // more spaces left; game continues
            return MOVES_LEFT;
        }
    }

    // stalemate
    return TIE;
}

void print_board(BOARD board) {
    char i, j;

    printf("\n");
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 3; j++) {
            printf("%d ", board[i][j]);
        }
        printf("\n");
    }
}

void opponent_move(BOARD board, DIFFICULTY difficulty) {
    char move, move_x, move_y;
    printf("Opponent is moving...");

    // take winning moves (medium)
    // if (difficulty > EASY) {
    // }

    // prevent winning move (hard)
    // if (difficulty > MEDIUM) {
    // }

    // take random move (easy)
    do {
        move = rand() % 9;
        move_x = move % 3;
        move_y = move / 3;
    } while (board[move_y][move_x] != EMPTY);

    board[move_y][move_x] = O;
}

void print_endgame(SOLUTION solution) {
    switch (solution) {
        case X_WON:
            printf("X won");
            break;
        case O_WON:
            printf("O won");
            break;
        case TIE:
            printf("Stalemate");
            break;
    }
    printf("\n");
}

void player_move(BOARD board) {
    char move = EMPTY;
    char move_x = EMPTY;
    char move_y = EMPTY;

    printf("Enter a move...");

    move = cgetc() - '0' - 1;
    // if move is not a number then bail
    // if (move < 1 || move > 8) { invalid! }
    move_x = move % 3;
    move_y = move / 3;
    // if move not already taken
    board[move_y][move_x] = X;
}

int main() {
    SOLUTION solution = MOVES_LEFT;
    char move = EMPTY;
    char move_x = EMPTY;
    char move_y = EMPTY;
    BOARD board = {{EMPTY}, {EMPTY}, {EMPTY}};

    cursor(1);

    while (solution == MOVES_LEFT) {
        print_board(board);
        player_move(board);

        if ((solution = is_board_solved(board)) != MOVES_LEFT) {
            print_endgame(solution);
            return 0;
        }

        print_board(board);
        opponent_move(board, EASY);

        if ((solution = is_board_solved(board)) != MOVES_LEFT) {
            print_endgame(solution);
            return 0;
        }
    }

    return 0;
}