-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathboard.c
125 lines (120 loc) · 2.76 KB
/
board.c
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
#include "board.h"
#include "fourgo.h"
static uint8_t _board[BOARD_HEIGHT][BOARD_WIDTH];
Board* init_board(void)
{
uint8_t w, h;
for (w = 0; w < BOARD_WIDTH; w++)
for (h = 0; h < BOARD_HEIGHT; h++)
_board[h][w] = PX;
return _board;
}
/* Check board for a win.
* If a win is found, sets x1... to the coordinates
* of the start and end of the winning move
* and returns the winning player.
* Otherwise, returns PX (0).
*/
uint8_t check_win(Board* board, uint8_t* x1, uint8_t* y1, uint8_t* x2, uint8_t* y2)
{
uint8_t w, h, p, i;
for (p = P1; p <= P2; p++)
{
/* check vertical */
for (w = 0; w < BOARD_WIDTH; w++)
for (h = 0; h < BOARD_HEIGHT - WIN_LENGTH + 1; h++)
{
for (i = 0; i < WIN_LENGTH; i++)
if (board[h+i][w] != p)
break;
if (i == WIN_LENGTH)
{
*x1 = w;
*x2 = w;
*y1 = h;
*y2 = h+i-1;
return p;
}
}
/* check horizontal */
for (h = 0; h < BOARD_HEIGHT; h++)
for (w = 0; w < BOARD_WIDTH - WIN_LENGTH + 1; w++)
{
for (i = 0; i < WIN_LENGTH; i++)
if (board[h][w+i] != p)
break;
if (i == WIN_LENGTH)
{
*y1 = h;
*y2 = h;
*x1 = w;
*x2 = w+i-1;
return p;
}
}
/* check up-right diagonal / */
for (w = 0; w < BOARD_WIDTH - WIN_LENGTH + 1; w++)
for (h = BOARD_HEIGHT - WIN_LENGTH + 1; h < BOARD_HEIGHT; h++)
{
for (i = 0; i < WIN_LENGTH; i++)
if (board[h-i][w+i] != p)
break;
if (i == WIN_LENGTH)
{
*x1 = w;
*y1 = h;
*x2 = w+i-1;
*y2 = h-i+1;
return p;
}
}
/* check down-right diagonal \ */
for (w = 0; w < BOARD_WIDTH - WIN_LENGTH + 1; w++)
for (h = 0; h < BOARD_HEIGHT - WIN_LENGTH + 1; h++)
{
for (i = 0; i < WIN_LENGTH; i++)
if (board[h+i][w+i] != p)
break;
if (i == WIN_LENGTH)
{
*x1 = w;
*y1 = h;
*x2 = w+i-1;
*y2 = h+i-1;
return p;
}
}
}
return PX;
}
uint8_t is_valid_move(Board* board, uint8_t column, uint8_t* row_out)
{
int16_t row = 0;
while (board[row][column] == PX && row < BOARD_HEIGHT)
row++;
row--;
if (row >= 0)
{
*row_out = row;
return TRUE;
}
return FALSE;
}
/*
* Tries to make a move on the board.
* If the move is invalid, returns FALSE.
* Otherwise, returns TRUE.
*/
uint8_t make_move(Board* board, Player player, uint8_t column)
{
int16_t row = 0;
while (board[row][column] == PX && row < BOARD_HEIGHT)
row++;
row--;
if (row >= 0)
{
board[row][column] = player;
return TRUE;
}
return FALSE;
}