~ubuntu-branches/ubuntu/natty/gtkboard/natty

« back to all changes in this revision

Viewing changes to .pc/debian-changes-0.11pre0+cvs.2003.11.02-3/src/plot4.c

  • Committer: Bazaar Package Importer
  • Author(s): Barak A. Pearlmutter
  • Date: 2011-03-15 12:43:00 UTC
  • mfrom: (3.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110315124300-zf9hkdc5vjyqge7e
Tags: 0.11pre0+cvs.2003.11.02-3
static size unknown gcc-4.5 fix src/{menu,wordtris}.c (closes: #564999)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*  This file is a part of gtkboard, a board games system.
 
2
    Copyright (C) 2003, Arvind Narayanan <arvindn@users.sourceforge.net>
 
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 2 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, write to the Free Software
 
16
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
 
17
 
 
18
*/
 
19
 
 
20
/** \file plot4.c */
 
21
 
 
22
#include <stdio.h>
 
23
#include <string.h>
 
24
#include <assert.h>
 
25
#include <stdlib.h>
 
26
 
 
27
#include "game.h"
 
28
#include "aaball.h"
 
29
 
 
30
#define PLOT4_CELL_SIZE 55
 
31
#define PLOT4_NUM_PIECES 3
 
32
 
 
33
#define PLOT4_BOARD_WID 7
 
34
#define PLOT4_BOARD_HEIT 6
 
35
 
 
36
char plot4_colors[6] = {160, 140, 100, 160, 140, 100};
 
37
 
 
38
int * plot4_init_pos = NULL;
 
39
 
 
40
#define PLOT4_WP 1
 
41
#define PLOT4_BP 2
 
42
#define PLOT4_EMPTY 3
 
43
 
 
44
 
 
45
void plot4_init ();
 
46
 
 
47
Game Plot4 = { PLOT4_CELL_SIZE, PLOT4_BOARD_WID, PLOT4_BOARD_HEIT, 
 
48
        PLOT4_NUM_PIECES,
 
49
        plot4_colors,  NULL, NULL, "Plot 4", "k-in-a-row", plot4_init};
 
50
 
 
51
 
 
52
 
 
53
static int eval_runs (Pos *, int);
 
54
static int find_runs (byte *, int, int, int , int, int, int);
 
55
static int plot4_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
 
56
static ResultType plot4_who_won (Pos *, Player , char **);
 
57
static void plot4_set_init_pos (Pos *pos);
 
58
static char ** plot4_get_pixmap (int, int);
 
59
static byte * plot4_movegen (Pos *);
 
60
static ResultType plot4_eval (Pos *, Player, float *);
 
61
 
 
62
 
 
63
static const int RUN_WT = 20;
 
64
 
 
65
 
 
66
void plot4_init ()
 
67
{
 
68
        game_eval = plot4_eval;
 
69
        game_movegen = plot4_movegen;
 
70
        game_getmove = plot4_getmove;
 
71
        game_who_won = plot4_who_won;
 
72
        game_set_init_pos = plot4_set_init_pos;
 
73
        game_get_pixmap = plot4_get_pixmap;
 
74
        game_white_string = "Green";
 
75
        game_black_string = "Yellow";
 
76
        game_doc_about_status = STATUS_COMPLETE;
 
77
        game_doc_about = 
 
78
                "Plot4\n"
 
79
                "Two player game\n"
 
80
                "Status: Fully implemented\n"
 
81
                "URL: "GAME_DEFAULT_URL ("plot4");
 
82
        game_doc_rules = 
 
83
                "Two players alternate in placing balls of either color on a 7x6 board. Not exactly placing, because the balls have gravity and fall down to the lowest unoccupied square on the column. The goal is to get as many 4-in-a-row's as possible. A 5-in-a-row counts as two, 6 as 3, and 7 as 4.\n";
 
84
}
 
85
 
 
86
void plot4_set_init_pos (Pos *pos)
 
87
{
 
88
        int i;
 
89
        for (i=0; i<board_wid * board_heit; i++)
 
90
                pos->board [i] = PLOT4_EMPTY;
 
91
}
 
92
 
 
93
ResultType plot4_who_won (Pos *pos, Player to_play, char **commp)
 
94
{
 
95
        static char comment[32];
 
96
        char *who_str [3] = { "Green won", "Yellow won", "Its a tie" };
 
97
        int i, wscore, bscore, who_idx;
 
98
        wscore = eval_runs (pos, WHITE) / RUN_WT;
 
99
        bscore = eval_runs (pos, BLACK) / RUN_WT * -1;
 
100
        *commp = comment;
 
101
        for (i=0; i<board_wid * board_heit; i++)
 
102
                if (pos->board[i] == PLOT4_EMPTY) 
 
103
                {
 
104
                        snprintf (comment, 32, "%d : %d", wscore, bscore);
 
105
                        return RESULT_NOTYET;
 
106
                }
 
107
        if (wscore > bscore) who_idx = 0;
 
108
        else if (wscore < bscore) who_idx = 1;
 
109
        else who_idx = 2;
 
110
        snprintf (comment, 32, "%s (%d : %d)", who_str[who_idx], wscore, bscore);
 
111
        if (wscore > bscore)
 
112
                return RESULT_WHITE;
 
113
        if (wscore < bscore)
 
114
                return RESULT_BLACK;
 
115
        return RESULT_TIE;
 
116
}
 
117
 
 
118
int plot4_islegal (byte *board, int x, int y)
 
119
        /* check bounds
 
120
           check if (x,y) is empty
 
121
           check if (x, y-1) is not empty */
 
122
{
 
123
        return (x >= 0 && x < board_wid && y >= 0 && y < board_heit
 
124
                        && (board[y * board_wid + x] == PLOT4_EMPTY) && 
 
125
                        ((y == 0) || (board [(y-1) * board_wid + x] != PLOT4_EMPTY)));
 
126
}
 
127
 
 
128
int plot4_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, byte **movp, int ** rmovep)
 
129
        /* translate a sequence of mouse clicks into a cbgf move.
 
130
           pos is the current position, x and y are the square which was
 
131
           clicked, type is the event type: MOUSE_PRESSED, MOUSE_RELEASED
 
132
           to_play is who has the move, movp is used to return the move
 
133
 
 
134
           the return value is 1 if the clicks were successfully translated
 
135
           into a move; -1 if the move is illegal, and 0 if further clicks
 
136
           are required to determine the move. In the latter case, this 
 
137
           function is responsible for keeping track of the current state.
 
138
         */
 
139
{
 
140
        static byte move[4];
 
141
        if (type != GTKBOARD_BUTTON_RELEASE)
 
142
                return 0;
 
143
        /* OK to click anywhere in the column */
 
144
        for (y = 0; y < board_heit; y++)
 
145
                if (pos->board[y * board_wid + x] == PLOT4_EMPTY)
 
146
                        break;
 
147
        if (y == board_heit)
 
148
                return -1;
 
149
        move[0] = x;
 
150
        move[1] = y;
 
151
        move[2] = to_play == WHITE ? PLOT4_WP : PLOT4_BP;
 
152
        move[3] = -1;
 
153
        if (movp)
 
154
                *movp = move;   
 
155
        return 1;
 
156
}
 
157
 
 
158
ResultType plot4_eval (Pos *pos, Player to_play, float *eval)
 
159
        /* always eval from POV of white */
 
160
{
 
161
        /* TODO : add some weights */
 
162
        *eval = eval_runs (pos, -1);
 
163
        return RESULT_NOTYET;
 
164
}
 
165
 
 
166
 
 
167
 
 
168
static int eval_runs (Pos *pos, int forwhom)
 
169
        /* sum of all the runs of forwhom (both if -1) from POV of WHITE */
 
170
{
 
171
        int sum = 0;
 
172
        int i, board_min, min;
 
173
        byte *board = pos->board;
 
174
        board_min = board_wid < board_heit ? board_wid : board_heit;
 
175
        for (i=0; i<board_wid; i++)
 
176
                sum += find_runs (board, i, 0, 0, 1, board_heit, forwhom);
 
177
        for (i=0; i<board_heit; i++)
 
178
                sum += find_runs (board, 0, i, 1, 0, board_wid, forwhom);
 
179
        for (i=0; i<board_wid; i++)
 
180
        {
 
181
                min = (board_wid - i) < board_min ? (board_wid - i) : board_min;
 
182
                sum += find_runs (board, i, 0, 1, 1, min, forwhom);
 
183
                sum += find_runs (board, board_wid - i - 1, 0, -1, 1, min, forwhom);
 
184
        }
 
185
        for (i=1; i<board_heit; i++)
 
186
        {
 
187
                min = (board_heit - i) < board_min ? (board_heit - i) : board_min;
 
188
                sum += find_runs (board, 0, i, 1, 1, min, forwhom);
 
189
                sum += find_runs (board, board_wid - 1, i, -1, 1, min, forwhom);
 
190
        }
 
191
        return sum;
 
192
}
 
193
 
 
194
static int find_runs (byte *board, int x0, int y0, int dx, int dy, int len,
 
195
                int forwhom)
 
196
        /* OK this function is very ugly. if forwhom is -1 it returns an
 
197
        * eval of the given line. If not it returns a count forwhom's 
 
198
        * score on that line, multiplied by RUN_WT */
 
199
{
 
200
        int sum = 0, i, cur = 0; /* cur = current run length */
 
201
        int x = x0, y = y0;
 
202
        char prev = -1, cell;
 
203
        int lopen = 0, ropen = 0; /* can we extend this run in either direction*/
 
204
        for (i=0; i<len; i++, x += dx, y += dy, prev = cell)
 
205
        {
 
206
                cell = board[y * board_wid + x];
 
207
                if (cell == PLOT4_EMPTY)
 
208
                {
 
209
                        cur=0;
 
210
                        lopen = 1;
 
211
                        continue;
 
212
                }
 
213
                if (cell != prev)
 
214
                        cur = 0;
 
215
                cur ++;
 
216
                if (i < len - 1 && 
 
217
                                board [(y + dy) * board_wid + (x + dx)] == PLOT4_EMPTY)
 
218
                        ropen = 1;
 
219
                else ropen = 0;
 
220
                if (cell == PLOT4_WP)
 
221
                {
 
222
                        if (forwhom == -1)
 
223
                                sum += ((ropen + lopen) * (cur * cur));
 
224
                        if (forwhom != BLACK && cur >= 4)
 
225
                                sum += RUN_WT;
 
226
                }
 
227
                if (cell == PLOT4_BP)
 
228
                {
 
229
                        if (forwhom == -1)
 
230
                                sum -= ((ropen + lopen) * (cur * cur));
 
231
                        if (forwhom != WHITE && cur >= 4)
 
232
                                sum -= RUN_WT;
 
233
                }
 
234
                lopen = 0;
 
235
        }
 
236
        return sum;
 
237
}
 
238
 
 
239
byte * plot4_movegen_single (char *pos, int player, int reset)
 
240
        /* return a move terminated by -1 */
 
241
        /* NULL ==> no more moves */
 
242
{
 
243
        static int row;
 
244
        static byte movbuf[4];
 
245
        if (reset)
 
246
                row = 0;
 
247
        while (row < board_wid)
 
248
        {
 
249
                int j;
 
250
                for (j=board_heit-1; j>=0; j--)
 
251
                        if (pos[j * board_wid + row] == PLOT4_EMPTY)
 
252
                        {
 
253
                                movbuf[0] = row;
 
254
                                movbuf[1] = j;
 
255
                                movbuf[2] = (player == WHITE ? PLOT4_WP : PLOT4_BP);
 
256
                                movbuf[3] = -1;
 
257
                                row++;
 
258
                                return movbuf;
 
259
                        }
 
260
                row++;
 
261
        }
 
262
        /*movbuf[0] = -1;*/
 
263
        row = 0;
 
264
        return NULL;
 
265
}
 
266
 
 
267
//! movegen function
 
268
byte *plot4_movegen (Pos *pos)
 
269
{
 
270
        byte movbuf[256];
 
271
        byte *movp = movbuf;
 
272
        byte *movlist;
 
273
        int i, j;
 
274
        for (i=0; i<board_wid; i++)
 
275
        {
 
276
                for (j=0; j<board_heit; j++)
 
277
                        if (pos->board[j * board_wid + i] == PLOT4_EMPTY)
 
278
                        {
 
279
                                *movp++ = i;
 
280
                                *movp++ = j;
 
281
                                *movp++ = (pos->player == WHITE ? PLOT4_WP : PLOT4_BP);
 
282
                                *movp++ = -1;
 
283
                                break;
 
284
                        }
 
285
        }
 
286
        *movp++ = -2;
 
287
        movlist = (byte *) (malloc (movp - movbuf));
 
288
        memcpy (movlist, movbuf, (movp - movbuf));
 
289
        return movlist;
 
290
}
 
291
 
 
292
char ** plot4_get_pixmap (int idx, int color)
 
293
{
 
294
        int fg, bg, i;
 
295
        char *colors = plot4_colors;
 
296
        static char pixbuf[PLOT4_CELL_SIZE*(PLOT4_CELL_SIZE)+1];
 
297
        if (idx == PLOT4_WP) fg = 0xee << 8;
 
298
        else if (idx == PLOT4_BP) fg = (0xee << 16) + (0xee << 8);
 
299
        else fg = 0xd7d7d7;
 
300
        for(i=0, bg=0;i<3;i++) 
 
301
        { int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));}
 
302
        return pixmap_ball_gen(55, pixbuf, fg, bg, 17.0, 30.0);
 
303
}
 
304