]> git.cworth.org Git - dvonn/blob - dvonn-board.c
Initial import of DVONN game
[dvonn] / dvonn-board.c
1 /*
2  * Copyright (C) 2009 Carl Worth
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see http://www.gnu.org/licenses/ .
16  *
17  * Author: Carl Worth <cworth@cworth.org>
18  */
19
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <assert.h>
23
24 #include <glib.h>
25
26 #include "dvonn-board.h"
27
28 /* Just a diagram to help start thinking about data structures:
29  *
30  * Played/drawn as:
31  *
32  *   1 ○ ○ ○ ○ ○ ○ ○ ○ ○
33  *  2 ○ ● ● ○ ○ ○ ○ ○ ○ ○
34  * 3 ○ ● ○ ● ○ ○ ○ ○ ○ ○ ○
35  *  4 ○ ● ● ○ ○ ○ ○ ○ ○ ○ K
36  *   5 ○ ○ ○ ○ ○ ○ ○ ○ ○ J
37  *      A B C D E F G H I
38  *
39  * Stored as:
40  *
41  * 1 x x ○ ○ ○ ○ ○ ○ ○ ○ ○
42  * 2 x ○ ● ● ○ ○ ○ ○ ○ ○ ○
43  * 3 ○ ● ○ ● ○ ○ ○ ○ ○ ○ ○
44  * 4 ○ ● ● ○ ○ ○ ○ ○ ○ ○ x
45  * 5 ○ ○ ○ ○ ○ ○ ○ ○ ○ x x
46  *   A B C D E F G H I J K
47  *
48  * With connections as:
49  *
50  *         C2  D2
51  *          | /
52  *  B3 <-> C3 <-> D3
53  *        / |
54  *      B2 C4
55  */
56
57 void
58 dvonn_board_init (dvonn_board_t *board)
59 {
60     int x, y;
61
62     for (x = 0; x < DVONN_BOARD_X_SIZE; x++) {
63         for (y = 0; y < DVONN_BOARD_Y_SIZE; y++) {
64             board->cells[x][y].type = DVONN_CELL_EMPTY;
65             board->cells[x][y].height = 0;
66         }
67     }
68
69     /* Cut out the unplayable "corners" of the board. */
70     for (x = 0; x < DVONN_BOARD_Y_SIZE / 2; x++) {
71         for (y = 0; y < (DVONN_BOARD_Y_SIZE / 2) - x; y++) {
72             board->cells[x][y].type = DVONN_CELL_INVALID;
73             board->cells
74                 [DVONN_BOARD_X_SIZE-1-x]
75                 [DVONN_BOARD_Y_SIZE-1-y].type = DVONN_CELL_INVALID;
76         }
77     }
78
79     board->player = DVONN_PLAYER_WHITE;
80 }
81
82 static dvonn_bool_t
83 dvonn_board_move_legal (dvonn_board_t *board,
84                         int x1, int y1,
85                         int x2, int y2,
86                         char **error)
87 {
88     if (x1 < 0 || x1 >= DVONN_BOARD_X_SIZE ||
89         y1 < 0 || y1 >= DVONN_BOARD_Y_SIZE ||
90         x2 < 0 || x2 >= DVONN_BOARD_X_SIZE ||
91         y2 < 0 || y2 >= DVONN_BOARD_Y_SIZE)
92     {
93         *error = "Invalid coordinates (not on board)";
94         return FALSE;
95     }
96
97     if (board->cells[x1][y1].type == DVONN_CELL_INVALID) {
98         *error = "Not a valid board space";
99         return FALSE;
100     }
101
102     if (board->cells[x1][y1].type == DVONN_CELL_EMPTY) {
103         *error = "There is no piece there to move";
104         return FALSE;
105     }
106
107     if (board->cells[x1][y1].type != board->player) {
108         *error = "You cannot move your opponent's piece";
109         return FALSE;
110     }
111
112     /* XXX: Need to code up DVONN-legal move calculation here. */
113
114     return TRUE;
115 }
116
117 static void
118 dvonn_board_next_player (dvonn_board_t *board)
119 {
120     if (board->player == DVONN_PLAYER_BLACK)
121         board->player = DVONN_PLAYER_WHITE;
122     else
123         board->player = DVONN_PLAYER_BLACK;
124 }
125
126 int
127 dvonn_board_move (dvonn_board_t *board,
128                   int x1, int y1,
129                   int x2, int y2,
130                   char **error)
131 {
132     if (! dvonn_board_move_legal (board, x1, y1, x2, y2, error))
133         return FALSE;
134
135     /* XXX: Need to execute the move here. */
136
137     dvonn_board_next_player (board);
138
139     return TRUE;
140 }