~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-2/src/kttour.c

  • Committer: Bazaar Package Importer
  • Author(s): Barak A. Pearlmutter
  • Date: 2011-02-28 11:25:02 UTC
  • mto: This revision was merged to the branch mainline in revision 10.
  • Revision ID: james.westby@ubuntu.com-20110228112502-e9aah248wxelm7ao
Tags: 0.11pre0+cvs.2003.11.02-2
autotools tweaks, most notably -lSDL to supplement -lSDL_mixer

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
#include <stdio.h>
 
20
#include <string.h>
 
21
#include <assert.h>
 
22
#include <stdlib.h>
 
23
#include <time.h>
 
24
 
 
25
#include "game.h"
 
26
#include "aaball.h"
 
27
#include "../pixmaps/chess.xpm"
 
28
#include "../pixmaps/misc.xpm"
 
29
 
 
30
#define KTTOUR_CELL_SIZE 54
 
31
#define KTTOUR_NUM_PIECES 4
 
32
 
 
33
#define KTTOUR_BOARD_WID 8
 
34
#define KTTOUR_BOARD_HEIT 8
 
35
 
 
36
#define KTTOUR_EMPTY 0
 
37
#define KTTOUR_CUR 1
 
38
#define KTTOUR_START 2
 
39
#define KTTOUR_USED 3
 
40
#define KTTOUR_HINT 4
 
41
 
 
42
char kttour_colors[6] = {200, 200, 160, 200, 200, 160};
 
43
 
 
44
void kttour_init ();
 
45
 
 
46
Game Kttour = { KTTOUR_CELL_SIZE, KTTOUR_BOARD_WID, KTTOUR_BOARD_HEIT, 
 
47
        KTTOUR_NUM_PIECES, 
 
48
        kttour_colors, NULL, /*kttour_pixmaps,*/ NULL, "Knight's Tour", NULL,
 
49
        kttour_init};
 
50
 
 
51
SCORE_FIELD kttour_score_fields[] = {SCORE_FIELD_RANK, SCORE_FIELD_USER, SCORE_FIELD_TIME, SCORE_FIELD_DATE, SCORE_FIELD_NONE};
 
52
char *kttour_score_field_names[] = {"Rank", "User", "Time", "Date", NULL};
 
53
 
 
54
static int kttour_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
 
55
static ResultType kttour_who_won (Pos *, Player, char **);
 
56
static char **kttour_get_pixmap (int , int);
 
57
 
 
58
void kttour_init ()
 
59
{
 
60
        game_single_player = 1;
 
61
        game_getmove = kttour_getmove;
 
62
        game_get_pixmap = kttour_get_pixmap;
 
63
        game_who_won = kttour_who_won;
 
64
        game_scorecmp = game_scorecmp_def_time;
 
65
        game_score_fields =  kttour_score_fields;
 
66
        game_score_field_names = kttour_score_field_names;
 
67
        game_draw_cell_boundaries = TRUE;
 
68
        game_allow_undo = TRUE;
 
69
        game_doc_about_status = STATUS_COMPLETE;
 
70
        game_doc_about = 
 
71
                "Kttour\n"
 
72
                "Single player game\n"
 
73
                "Status: Partially implemented\n"
 
74
                "URL: "GAME_DEFAULT_URL("kttour");
 
75
        game_doc_rules = 
 
76
                "  Complete the knight's tour of the chessboard.\n"
 
77
                "\n"
 
78
                "  In the initial position click on any square to start the tour on that square. "
 
79
                "Next click on the square you want the knight to move to, and so on. "
 
80
                "The square where you started will be shown in green and the other squares in the tour will be grey. "
 
81
                "At any point you can click on the green square to make it the current square, in which case the current square will become the \"start\" square. "
 
82
                "\n\n"
 
83
                "  The objective is to fill all 64 squares in such a way that the last square is one knight-move away from the first, in as little time as possible. "
 
84
                "In this game, you can undo your moves freely. This won't prevent you from getting a highscore. "
 
85
                "\n\n"
 
86
                "  The blue balls that you see are hints. They are there to make your life easier, but you don't have to necessarily click on a ball."
 
87
                ;
 
88
}
 
89
 
 
90
static char **kttour_get_pixmap (int idx, int color)
 
91
{
 
92
        static char pixbuf[KTTOUR_CELL_SIZE*(KTTOUR_CELL_SIZE+1)];
 
93
        int i, bg;
 
94
        for(i=0, bg=0;i<3;i++) 
 
95
        { int col = kttour_colors[i]; if (col<0) col+=256; bg += col * (1 << (16-8*i));}
 
96
        switch (idx)
 
97
        {
 
98
                case KTTOUR_CUR:
 
99
                        return chess_wn_54_xpm;
 
100
                        
 
101
                // simulate square using ball of large radius
 
102
                case KTTOUR_START:
 
103
                        return pixmap_ball_gen (KTTOUR_CELL_SIZE, pixbuf, 0x80ff80, bg,
 
104
                                        KTTOUR_CELL_SIZE, 1);
 
105
                case KTTOUR_USED:
 
106
                        return pixmap_ball_gen (KTTOUR_CELL_SIZE, pixbuf, 0x808080, bg,
 
107
                                        KTTOUR_CELL_SIZE, 1);
 
108
                        
 
109
                case KTTOUR_HINT:
 
110
                        return pixmap_ball_gen (KTTOUR_CELL_SIZE, pixbuf, 0x8080ff, bg,
 
111
                                        KTTOUR_CELL_SIZE/4, 30.0);
 
112
                default: return NULL;
 
113
        }
 
114
}
 
115
 
 
116
#define abs(x) ((x)<0?-(x):(x))
 
117
 
 
118
static gboolean are_nbrs (int x1, int y1, int x2, int y2)
 
119
{
 
120
        return abs ((x1 - x2) * (y1 - y2)) == 2 ? TRUE : FALSE;
 
121
}
 
122
 
 
123
/* TODO: this should be implemented in game_common.c or something like that so that
 
124
all games can access it */
 
125
static void find_xy (byte *board, int *x, int *y, int val)
 
126
{
 
127
        int i, j;
 
128
        *x = -1;
 
129
        *y = -1;
 
130
        for (i=0; i<board_wid; i++)
 
131
        for (j=0; j<board_wid; j++)
 
132
                if (board[j * board_wid + i] == val)
 
133
                {
 
134
                        *x = i;
 
135
                        *y = j;
 
136
                        return;
 
137
                }
 
138
}
 
139
 
 
140
ResultType kttour_who_won (Pos *pos, Player to_play, char **commp)
 
141
{
 
142
        int x1, y1, x2, y2;
 
143
        int i;
 
144
        gboolean found = FALSE;
 
145
        for (i=0; i<board_wid*board_heit; i++)
 
146
                if (pos->board [i] == KTTOUR_EMPTY)
 
147
                        return RESULT_NOTYET;
 
148
        find_xy (pos->board, &x1, &y1, KTTOUR_CUR);
 
149
        find_xy (pos->board, &x2, &y2, KTTOUR_START);
 
150
        return are_nbrs (x1, y1, x2, y2) ? RESULT_WON : RESULT_NOTYET;
 
151
}
 
152
 
 
153
static int incx[] = {-2, -2, -1, -1, 1, 1, 2, 2};
 
154
static int incy[] = {-1, 1, -2, 2, -2, 2, -1, 1};
 
155
 
 
156
#define IS_FREE(x) ((x) == KTTOUR_EMPTY || (x) == KTTOUR_HINT)
 
157
 
 
158
static int get_degree (byte *board, int i, int j)
 
159
{
 
160
        int k, x, y;
 
161
        int count = 0;
 
162
        for (k=0; k<8; k++)
 
163
        {
 
164
                x = i + incx[k];
 
165
                y = j + incy[k];
 
166
                if (ISINBOARD (x, y) && IS_FREE(board [y * board_wid + x]))
 
167
                        count++;
 
168
        }
 
169
        return count;
 
170
}
 
171
 
 
172
static int get_min_degree (byte *board, int i, int j)
 
173
{
 
174
        int k, x, y;
 
175
        int min_deg = 8;
 
176
        for (k=0; k<8; k++)
 
177
        {
 
178
                int deg;
 
179
                x = i + incx[k];
 
180
                y = j + incy[k];
 
181
                if (ISINBOARD (x, y) && IS_FREE(board [y * board_wid + x]))
 
182
                        if ((deg = get_degree (board, x, y)) < min_deg)
 
183
                                min_deg = deg;
 
184
        }
 
185
        return min_deg;
 
186
}
 
187
 
 
188
static void add_hints 
 
189
        (byte *board, int new_x, int new_y, byte **mp)
 
190
{
 
191
        int min_deg_new, min_deg_old;
 
192
        int k, x, y;
 
193
        min_deg_new = get_min_degree (board, new_x, new_y);
 
194
        
 
195
        for (k=0; k<8; k++)
 
196
        {
 
197
                x = new_x + incx[k];
 
198
                y = new_y + incy[k];
 
199
                if (!ISINBOARD (x, y) || board [y * board_wid + x] != KTTOUR_EMPTY)
 
200
                                continue;
 
201
                if (get_degree (board, x, y) == min_deg_new)
 
202
                {
 
203
                        *(*mp)++ = x;
 
204
                        *(*mp)++ = y;
 
205
                        *(*mp)++ = KTTOUR_HINT;
 
206
                }
 
207
        }
 
208
        
 
209
        for (x=0; x<board_wid; x++)
 
210
        for (y=0; y<board_heit; y++)
 
211
        {
 
212
                if (board [y * board_wid + x] != KTTOUR_HINT)
 
213
                        continue;
 
214
                if (x == new_x && y == new_y)
 
215
                        continue;
 
216
                if (are_nbrs (x, y, new_x, new_y) && get_degree (board, x, y) == min_deg_new)
 
217
                        continue;
 
218
                *(*mp)++ = x;
 
219
                *(*mp)++ = y;
 
220
                *(*mp)++ = KTTOUR_EMPTY;
 
221
        }
 
222
}
 
223
 
 
224
int kttour_getmove 
 
225
        (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, byte **movp, int ** rmovep)
 
226
{
 
227
        static byte move[7];
 
228
        byte *mp = move;
 
229
        int val;
 
230
        int cur_x, cur_y;
 
231
        if (type != GTKBOARD_BUTTON_RELEASE)
 
232
                return 0;
 
233
        val = pos->board[y * board_wid + x];
 
234
        if (val == KTTOUR_CUR)
 
235
                return 0;
 
236
        if (val == KTTOUR_USED)
 
237
                return -1;
 
238
        find_xy (pos->board, &cur_x, &cur_y, KTTOUR_CUR);
 
239
        if (val == KTTOUR_START)
 
240
        {
 
241
                *mp++ = x;
 
242
                *mp++ = y;
 
243
                *mp++ = KTTOUR_CUR;
 
244
                *mp++ = cur_x;
 
245
                *mp++ = cur_y;
 
246
                *mp++ = KTTOUR_START;
 
247
                add_hints (pos->board, x, y, &mp);
 
248
                *mp++ = -1;
 
249
                *movp = move;
 
250
                return 1;
 
251
        }
 
252
        if (cur_x >= 0 && !are_nbrs (cur_x, cur_y, x, y))
 
253
                return -1;
 
254
        *mp++ = x;
 
255
        *mp++ = y;
 
256
        *mp++ = KTTOUR_CUR;
 
257
        if (cur_x >= 0)
 
258
        {
 
259
                *mp++ = cur_x;
 
260
                *mp++ = cur_y;
 
261
                *mp++ = pos->num_moves == 1 ? KTTOUR_START : KTTOUR_USED;
 
262
        }
 
263
        add_hints (pos->board, x, y, &mp);
 
264
        *mp++ = -1;
 
265
        *movp = move;
 
266
        return 1;
 
267
}
 
268