~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/othello.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 <stdlib.h>
 
21
#include <string.h>
 
22
#include <assert.h>
 
23
#include <gdk/gdkkeysyms.h>
 
24
 
 
25
#include "game.h"
 
26
#include "aaball.h"
 
27
 
 
28
#define OTHELLO_CELL_SIZE 55
 
29
#define OTHELLO_NUM_PIECES 2
 
30
 
 
31
char othello_colors[6] = {200, 200, 200, 140, 140, 140};
 
32
 
 
33
int othello_init_pos [8*8] = 
 
34
{
 
35
        0 , 0 , 0 , 0 , 0 , 0 , 0 , 0  ,
 
36
        0 , 0 , 0 , 0 , 0 , 0 , 0 , 0  ,
 
37
        0 , 0 , 0 , 0 , 0 , 0 , 0 , 0  ,
 
38
        0 , 0 , 0 , 2 , 1 , 0 , 0 , 0  ,
 
39
        0 , 0 , 0 , 1 , 2 , 0 , 0 , 0  ,
 
40
        0 , 0 , 0 , 0 , 0 , 0 , 0 , 0  ,
 
41
        0 , 0 , 0 , 0 , 0 , 0 , 0 , 0  ,
 
42
        0 , 0 , 0 , 0 , 0 , 0 , 0 , 0  ,
 
43
};
 
44
 
 
45
int othello6x6_init_pos [6*6] = 
 
46
{
 
47
        0 , 0 , 0 , 0 , 0 , 0  ,
 
48
        0 , 0 , 0 , 0 , 0 , 0  ,
 
49
        0 , 0 , 2 , 1 , 0 , 0  ,
 
50
        0 , 0 , 1 , 2 , 0 , 0  ,
 
51
        0 , 0 , 0 , 0 , 0 , 0  ,
 
52
        0 , 0 , 0 , 0 , 0 , 0  ,
 
53
};
 
54
 
 
55
#define OTHELLO_WP 1
 
56
#define OTHELLO_BP 2
 
57
#define OTHELLO_EMPTY 0
 
58
 
 
59
 
 
60
int othello_getmove (Pos *, int, int, GtkboardEventType, Player, byte **, int **);
 
61
int othello_getmove_kb (Pos *pos, int key, byte **movp, int **rmovp);
 
62
void othello_init ();
 
63
ResultType othello_who_won (Pos *, Player, char **);
 
64
ResultType othello_eval (Pos *, Player, float *);
 
65
ResultType othello_eval_incr (Pos *, byte *, float *);
 
66
byte * othello_movegen (Pos *);
 
67
char ** othello_get_pixmap (int, int);
 
68
guchar *othello_get_rgbmap (int, int);
 
69
gboolean othello_use_incr_eval (Pos *pos);
 
70
 
 
71
Game Othello = { OTHELLO_CELL_SIZE, 8, 8,
 
72
        OTHELLO_NUM_PIECES, 
 
73
        othello_colors, othello_init_pos, NULL, "Othello", "Othello", othello_init};
 
74
 
 
75
Game Othello6x6 = { OTHELLO_CELL_SIZE, 6, 6,
 
76
        OTHELLO_NUM_PIECES, 
 
77
        othello_colors, othello6x6_init_pos, NULL, "Othello 6x6", "Othello", othello_init};
 
78
 
 
79
 
 
80
void othello_init (Game *game)
 
81
{
 
82
        game_getmove = othello_getmove;
 
83
        game_getmove_kb = othello_getmove_kb;
 
84
        game_who_won = othello_who_won;
 
85
        game_eval = othello_eval;
 
86
        game_eval_incr = othello_eval_incr;
 
87
        game_use_incr_eval = othello_use_incr_eval;
 
88
        game_movegen = othello_movegen;
 
89
        game_get_rgbmap = othello_get_rgbmap;
 
90
        game_white_string = "Red";
 
91
        game_black_string = "Blue";
 
92
        game_file_label = FILERANK_LABEL_TYPE_ALPHA;
 
93
        game_rank_label = FILERANK_LABEL_TYPE_NUM | FILERANK_LABEL_DESC;
 
94
        
 
95
        game_doc_about_status = STATUS_COMPLETE;
 
96
        if (game == &Othello)
 
97
                game_doc_about =
 
98
                        "Othello\n"
 
99
                        "Two player game\n"
 
100
                        "Status: Fully implemented\n"
 
101
                        "URL: "GAME_DEFAULT_URL ("othello");
 
102
        else
 
103
                game_doc_about =
 
104
                        "Othello 6x6\n"
 
105
                        "Two player game\n"
 
106
                        "Status: Fully implemented\n"
 
107
                        "URL: "GAME_DEFAULT_URL ("othello6x6");
 
108
        game_doc_rules = 
 
109
                "Two players take turns in placing balls of either color. The objective is to get as many balls of your color as possible.\n"
 
110
                "\n"
 
111
                "When you place a ball in such a way that two of your balls sandwich one or more of the opponent's balls along a line (horizontal, vertical, or diagonal), then the sandwiched balls change to your color. You must move in such a way that at least one switch happens.\n"
 
112
                "\n"
 
113
                "If you don't have a move, you pass by hitting space or clicking on an empty square."
 
114
                ;
 
115
        game_doc_strategy = 
 
116
                "The number of balls of either color at a given time is, paradoxically, a _very_ poor indicator of who has the advantage. This is because balls can flip color en masse and wildly, especially during the last few moves.\n"
 
117
                "\n"
 
118
                "Indeed, in the beginning you should try to minimize the number of balls you have. The key is mobility. You must strive to maximize your number of legal moves so that you can try to force your opponent into making bad moves.\n"
 
119
                "\n"
 
120
                "The corners are key squares, because corner balls never flip. If your opponent blunders into giving you a corner before the final stages of the game, you are practically assured of a win.\n";
 
121
}
 
122
 
 
123
char ** othello_get_pixmap (int idx, int color)
 
124
{
 
125
        int fg, bg, i;
 
126
        char *colors;
 
127
        static char pixbuf[OTHELLO_CELL_SIZE*(OTHELLO_CELL_SIZE)+1];
 
128
        colors = othello_colors;
 
129
        fg = (idx == OTHELLO_WP ? 0xee << 16 : 0xee);
 
130
        if (color == BLACK) colors += 3;
 
131
        for(i=0, bg=0;i<3;i++) 
 
132
        { int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));}
 
133
        return pixmap_ball_gen(55, pixbuf, fg, bg, 17.0, 30.0);
 
134
}
 
135
 
 
136
guchar *othello_get_rgbmap (int idx, int color)
 
137
{
 
138
        static guchar rgbbuf[3*OTHELLO_CELL_SIZE*OTHELLO_CELL_SIZE];
 
139
        int fg, bg, i;
 
140
        char *colors;
 
141
        colors = othello_colors;
 
142
        fg = (idx == OTHELLO_WP ? 0xee << 16 : 0xee);
 
143
        if (color == BLACK) colors += 3;
 
144
        for(i=0, bg=0;i<3;i++) 
 
145
        { int col = colors[i]; if (col<0) col += 256; bg += col * (1 << (16-8*i));}
 
146
        rgbmap_ball_shadow_gen(OTHELLO_CELL_SIZE, rgbbuf, fg, bg, 17.0, 30.0, 3);
 
147
        return rgbbuf;
 
148
}
 
149
 
 
150
static int incx[] = { -1, -1, -1, 0, 0, 1, 1, 1};
 
151
static int incy[] = { -1, 0, 1, -1, 1, -1, 0, 1};
 
152
 
 
153
static int get_sandwich_len (Pos *pos, int x0, int y0, int dx, int dy, byte player)
 
154
{
 
155
        int x = x0 + dx, y = y0+dy, len=0;
 
156
        byte state;
 
157
        for (; x >= 0 && y >= 0 && x < board_wid && y < board_heit; 
 
158
                        x+=dx, y+=dy, len++)
 
159
        {
 
160
                if ((state = pos->board[y * board_wid + x]) == 0)
 
161
                        return -1;
 
162
                else if (state == player)
 
163
                        return len;
 
164
        }
 
165
        return -1;
 
166
}
 
167
 
 
168
// does player have a move in this position
 
169
static gboolean hasmove (Pos *pos, Player player)
 
170
{
 
171
        int i, x, y, found = FALSE;
 
172
        for (x=0; x<board_wid && !found; x++)
 
173
                for (y=0; y<board_heit && !found; y++)
 
174
                {
 
175
                        if (pos->board [y * board_wid + x] != OTHELLO_EMPTY)
 
176
                                continue;
 
177
                        for (i=0; i<8; i++)
 
178
                        {
 
179
                                if (get_sandwich_len (pos, x, y ,incx[i], incy[i], 
 
180
                                                player == WHITE ? OTHELLO_WP : OTHELLO_BP) > 0)
 
181
                                {
 
182
                                        found = TRUE;
 
183
                                        break;
 
184
                                }
 
185
                        }
 
186
                }
 
187
        return found;
 
188
}
 
189
 
 
190
int othello_getmove_kb (Pos *pos, int key,  byte **movp, int **rmovp)
 
191
{
 
192
        static byte move[1];
 
193
        if (key != GDK_space) return -1;
 
194
        if (hasmove (pos, pos->player)) return -1;
 
195
        move[0] = -1;
 
196
        *movp = move;
 
197
        return 1;       
 
198
}
 
199
        
 
200
int othello_getmove (Pos *pos, int x, int y, GtkboardEventType type, Player to_play, 
 
201
                byte **movp, int ** rmovep)
 
202
{
 
203
        int i, j, sw_len, found=0;
 
204
        static byte move[128];
 
205
        byte *temp = move;
 
206
        byte our   = to_play == WHITE ? OTHELLO_WP : OTHELLO_BP;
 
207
        if (type != GTKBOARD_BUTTON_RELEASE)
 
208
                return 0;
 
209
        if (pos->board [y * board_wid + x] != OTHELLO_EMPTY)
 
210
                return -1;
 
211
        for (i=0; i<8; i++)
 
212
        {
 
213
                sw_len = get_sandwich_len (pos, x, y ,incx[i], incy[i], 
 
214
                                to_play == WHITE ? OTHELLO_WP : OTHELLO_BP);
 
215
                if (sw_len > 0) found = 1;
 
216
                for (j=1; j<=sw_len; j++)
 
217
                {
 
218
                        *temp++ = x + incx[i] * j;
 
219
                        *temp++ = y + incy[i] * j;
 
220
                        *temp++ = our;
 
221
                }               
 
222
        }
 
223
        if (!found)
 
224
        {
 
225
                if (hasmove (pos, to_play)) return -1;
 
226
                *temp++ = -1;
 
227
                *movp = move;
 
228
        }
 
229
        *temp++ = x;
 
230
        *temp++ = y;
 
231
        *temp++ = our;
 
232
        *temp++ = -1;
 
233
        *movp = move;
 
234
        return 1;
 
235
}
 
236
 
 
237
ResultType othello_who_won (Pos *pos, Player to_play, char **commp)
 
238
{
 
239
        static char comment[32];
 
240
        int i, wscore = 0, bscore = 0, who_idx ,x, y;
 
241
        char *who_str [3] = { "Red won", "Blue won", "its a tie" };
 
242
        int found = 0;
 
243
        for (i=0; i<board_wid * board_heit; i++)
 
244
                if (pos->board[i] == OTHELLO_WP)
 
245
                        wscore++;
 
246
                else if (pos->board[i] == OTHELLO_BP)
 
247
                        bscore++;
 
248
        if (! (wscore == 0 || bscore == 0 
 
249
                                || wscore + bscore == board_wid * board_heit))
 
250
        {
 
251
                snprintf (comment, 32, "%d : %d", wscore, bscore);
 
252
                *commp = comment;
 
253
                return RESULT_NOTYET;
 
254
        }
 
255
        if (wscore > bscore) who_idx = 0;
 
256
        else if (wscore < bscore) who_idx = 1;
 
257
        else who_idx = 2;
 
258
        snprintf (comment, 32, "%s (%d : %d)", who_str [who_idx], wscore, bscore);
 
259
        *commp = comment;
 
260
        if (wscore > bscore)
 
261
                return RESULT_WHITE;
 
262
        if (wscore < bscore)
 
263
                return RESULT_BLACK;
 
264
        return RESULT_TIE;
 
265
}
 
266
 
 
267
byte * othello_movegen (Pos *pos)
 
268
{
 
269
        int i, j, x, y, sw_len;
 
270
        byte movbuf [4096];
 
271
        byte *movlist, *movp = movbuf;
 
272
        Player player = pos->player;
 
273
        byte our = player == WHITE ? OTHELLO_WP : OTHELLO_BP;
 
274
        gboolean game_over = TRUE;
 
275
        for (x=0; x<board_wid; x++)
 
276
                for (y=0; y<board_wid; y++)
 
277
                {
 
278
                        gboolean found = FALSE;
 
279
                        if (pos->board [y * board_wid + x] != OTHELLO_EMPTY)
 
280
                                continue;
 
281
                        game_over = FALSE;
 
282
                        for (i=0; i<8; i++)
 
283
                        {
 
284
                                sw_len = get_sandwich_len (pos, x, y ,incx[i], incy[i], 
 
285
                                                player == WHITE ? OTHELLO_WP : OTHELLO_BP);
 
286
                                if (sw_len > 0) found = TRUE;
 
287
                                for (j=1; j<=sw_len; j++)
 
288
                                {
 
289
                                        *movp++ = x + incx[i] * j;
 
290
                                        *movp++ = y + incy[i] * j;
 
291
                                        *movp++ = our;
 
292
                                }               
 
293
                        }
 
294
                        if (!found)
 
295
                                continue;
 
296
                        *movp++ = x;
 
297
                        *movp++ = y;
 
298
                        *movp++ = our;
 
299
                        *movp++ = -1;
 
300
                }
 
301
        /* if we want to pass, we must return an empty move, NOT no move */
 
302
        if (movp == movbuf && !game_over)
 
303
                *movp++ = -1;
 
304
        *movp++ = -2;
 
305
        movlist = (byte *) (malloc (movp - movbuf));
 
306
        memcpy (movlist, movbuf, (movp - movbuf));
 
307
        return movlist;
 
308
}
 
309
 
 
310
static float othello_eval_count (Pos *pos)
 
311
{
 
312
        int i, sum=0;
 
313
        for (i=0; i<board_wid * board_heit; i++)
 
314
                if (pos->board [i] == OTHELLO_WP)
 
315
                        sum++;
 
316
                else if (pos->board [i] == OTHELLO_BP)
 
317
                        sum--;
 
318
        return sum;
 
319
}
 
320
 
 
321
static int othello_eval_mobility_count (Pos *pos, int color)
 
322
{
 
323
        int i, x, y, found, sum = 0;
 
324
        byte our = (color == WHITE ? OTHELLO_WP : OTHELLO_BP);
 
325
        for (x=0; x<board_wid; x++)
 
326
                for (y=0; y<board_heit; y++)
 
327
                {
 
328
                        if (pos->board [y * board_wid + x] != our)
 
329
                                continue;
 
330
                        found = 0;
 
331
                        for (i=0; i<8; i++)
 
332
                                if (get_sandwich_len (pos, x, y ,incx[i], incy[i], our) > 0)
 
333
                                {
 
334
                                        found = 1;
 
335
                                        break;
 
336
                                }
 
337
                        if (found)
 
338
                                sum++;
 
339
                }
 
340
        return sum;
 
341
}
 
342
 
 
343
static float othello_eval_mobility (Pos *pos)
 
344
{
 
345
        return othello_eval_mobility_count (pos, WHITE) - 
 
346
                othello_eval_mobility_count (pos, BLACK);
 
347
}
 
348
 
 
349
//! Faster approxmiation for mobility
 
350
static float othello_eval_liberty (Pos *pos)
 
351
{
 
352
        int i, j, k;
 
353
        int liberty = 0;
 
354
        for (i=0; i<board_wid; i++)
 
355
        for (j=0; j<board_heit; j++)
 
356
        {
 
357
                if (pos->board [j * board_wid + i] != OTHELLO_EMPTY)
 
358
                        continue;
 
359
                for (k=0; k<8; k++)
 
360
                {
 
361
                        int x = i + incx[k], y = j + incy[k];
 
362
                        int val;
 
363
                        if (!ISINBOARD (x, y)) continue;
 
364
                        if ((val = pos->board [y * board_wid + x]) == OTHELLO_EMPTY)
 
365
                                continue;
 
366
                        liberty += (val == OTHELLO_WP ? -1 : 1);
 
367
                }
 
368
        }
 
369
        return liberty;
 
370
}
 
371
 
 
372
static int othello_eval_num_moves (Pos *pos)
 
373
{
 
374
        int i, sum=0;
 
375
        for (i=0; i<board_wid * board_heit; i++)
 
376
                if (pos->board [i] != OTHELLO_EMPTY)
 
377
                        sum++;
 
378
        return sum;
 
379
}
 
380
 
 
381
enum { SAFE, UNSAFE, UNKNOWN };
 
382
 
 
383
static byte * safe_cached;
 
384
 
 
385
 
 
386
/* TODO recursion sucks. reimplement this */
 
387
static int othello_eval_is_safe (Pos *pos, int x, int y, byte our)
 
388
{
 
389
        if (x < 0 || y < 0 || x >= board_wid || y >= board_heit)
 
390
                return SAFE;
 
391
        if (pos->board [y * board_wid + x] != our)
 
392
                { return (safe_cached [y * board_wid + x] = UNSAFE);}
 
393
        if (safe_cached [y * board_wid + x] != UNKNOWN)
 
394
                return safe_cached [y * board_wid + x];
 
395
 
 
396
        /* crucial to avoid infinite recursion */
 
397
        safe_cached [y * board_wid + x] = UNSAFE;
 
398
        if (othello_eval_is_safe (pos, x - 1, y - 1, our) == UNSAFE
 
399
                        && othello_eval_is_safe (pos, x + 1, y + 1, our) == UNSAFE)
 
400
                { return (safe_cached [y * board_wid + x] = UNSAFE);}
 
401
        if (othello_eval_is_safe (pos, x + 1, y - 1, our) == UNSAFE
 
402
                        && othello_eval_is_safe (pos, x - 1, y + 1, our) == UNSAFE)
 
403
                { return (safe_cached [y * board_wid + x] = UNSAFE);}
 
404
        if (othello_eval_is_safe (pos, x - 1, y, our) == UNSAFE
 
405
                        && othello_eval_is_safe (pos, x + 1, y, our) == UNSAFE)
 
406
                { return (safe_cached [y * board_wid + x] = UNSAFE);}
 
407
        if (othello_eval_is_safe (pos, x, y - 1, our) == UNSAFE
 
408
                        && othello_eval_is_safe (pos, x, y + 1, our) == UNSAFE)
 
409
                { return (safe_cached [y * board_wid + x] = UNSAFE);}
 
410
        return (safe_cached [y * board_wid + x] = SAFE);
 
411
}
 
412
 
 
413
static float othello_eval_safe (Pos *pos)
 
414
{
 
415
        int i, x, y, sum=0;
 
416
        if (pos->board [0 * board_wid + 0] == OTHELLO_EMPTY &&
 
417
                pos->board [0 * board_wid + board_wid - 1] == OTHELLO_EMPTY &&
 
418
                pos->board [(board_heit - 1) * board_wid + 0] == OTHELLO_EMPTY &&
 
419
                pos->board [(board_heit - 1) * board_wid + board_wid - 1] == OTHELLO_EMPTY )
 
420
                return 0;
 
421
        safe_cached = (byte *) malloc (board_wid * board_heit);
 
422
        assert (safe_cached);
 
423
        for (i=0; i<board_wid * board_heit; i++)
 
424
                safe_cached [i] = UNKNOWN;
 
425
        
 
426
        for (x=0; x<board_wid; x++)
 
427
                for (y=0; y<board_heit; y++)
 
428
                        if (pos->board [y * board_wid + x] == OTHELLO_WP &&
 
429
                                        othello_eval_is_safe (pos, x, y, OTHELLO_WP) == SAFE)
 
430
                                sum++;
 
431
                        else if (pos->board [y * board_wid + x] == OTHELLO_BP &&
 
432
                                        othello_eval_is_safe (pos, x, y, OTHELLO_BP) == SAFE)
 
433
                                sum --;
 
434
        free (safe_cached);
 
435
        return sum;             
 
436
}
 
437
 
 
438
/*static float othello_eval_dangerous (Pos *pos)
 
439
{
 
440
        int i, j;
 
441
        float danger = 0;
 
442
        for (i=1; i<=6; i+=5)
 
443
        for (j=1; j<=6; j+=5)
 
444
        {
 
445
                if (pos->board[j * board_wid + i] == OTHELLO_WP) danger++;
 
446
                else if (pos->board[j * board_wid + i] == OTHELLO_BP) danger--;
 
447
        }
 
448
        for (i=1; i<=6; i+=5)
 
449
        for (j=0; j<=7; j+=7)
 
450
        {
 
451
                if (pos->board[j * board_wid + i] == OTHELLO_WP) danger += 0.3;
 
452
                else if (pos->board[j * board_wid + i] == OTHELLO_BP) danger -= 0.3;
 
453
        }
 
454
        for (i=0; i<=7; i+=7)
 
455
        for (j=1; j<=6; j+=5)
 
456
        {
 
457
                if (pos->board[j * board_wid + i] == OTHELLO_WP) danger += 0.3;
 
458
                else if (pos->board[j * board_wid + i] == OTHELLO_BP) danger -= 0.3;
 
459
        }
 
460
        return -danger;         
 
461
}*/
 
462
 
 
463
static float othello_eval_material (Pos *pos)
 
464
{
 
465
        int i, material = 0;
 
466
        for (i=0; i<board_wid * board_heit; i++)
 
467
        {
 
468
                if (pos->board[i] == OTHELLO_WP)
 
469
                        material++;
 
470
                else if (pos->board[i] == OTHELLO_BP)
 
471
                        material--;
 
472
        }
 
473
        return material;
 
474
}
 
475
 
 
476
static float othello_eval_weights (Pos *pos)
 
477
{
 
478
        static int weights8 [4][4] = 
 
479
        {
 
480
                { 500, -240, 85, 69 },
 
481
                { 0  , -130, 49, 23 },
 
482
                { 0  ,    0,  1,  9 },
 
483
                { 0  ,    0,  0, 32 },
 
484
        };
 
485
        
 
486
        // FIXME: find a decent weight set
 
487
        static int weights6 [3][3] = 
 
488
        {
 
489
                { 500, -200, 80},
 
490
                { 0  , -300, 50},
 
491
                { 0  ,    0, 20},
 
492
        };
 
493
 
 
494
        int i, j, wtsum = 0;
 
495
 
 
496
        for (i=0; i<board_wid; i++)
 
497
        for (j=0; j<board_heit; j++)
 
498
        {
 
499
                int val = pos->board[j * board_wid + i];
 
500
                int x = i, y = j;
 
501
                if (val == OTHELLO_EMPTY)
 
502
                        continue;
 
503
 
 
504
                if (pos->game == &Othello)
 
505
                {
 
506
                        if (x > 3) x = 7-x;
 
507
                        if (y > 3) y = 7-y;
 
508
                }
 
509
                else //if (pos->game == Othello6x6)
 
510
                {
 
511
                        if (x > 2) x = 5-x;
 
512
                        if (y > 2) y = 5-y;
 
513
                }
 
514
                
 
515
                if (x > y)  {int tmp = y; y = x; x = tmp;}
 
516
                
 
517
                wtsum += (pos->game == &Othello ? weights8 [x][y] : weights6[x][y])  
 
518
                        * (val == OTHELLO_WP ? 1 : -1);
 
519
        }
 
520
        return wtsum;   
 
521
}
 
522
 
 
523
ResultType othello_eval (Pos *pos, Player player, float *eval)
 
524
{
 
525
        int i;
 
526
        gboolean found;
 
527
 
 
528
        if (pos->num_moves >= board_wid * board_heit)
 
529
        {
 
530
                for (i=0, found=FALSE; i<board_wid*board_heit; i++)
 
531
                        if (pos->board [i] == OTHELLO_EMPTY) {found = TRUE; break;}
 
532
                if (!found)
 
533
                {
 
534
                        *eval = othello_eval_material (pos);
 
535
                        *eval *= GAME_EVAL_INFTY;
 
536
                        if (*eval > 0) return RESULT_WHITE;
 
537
                        if (*eval < 0) return RESULT_BLACK;
 
538
                        return RESULT_NOTYET;
 
539
                }
 
540
        }
 
541
 
 
542
        *eval = 
 
543
                10 * othello_eval_liberty (pos) 
 
544
                //10 * othello_eval_mobility (pos) 
 
545
                + 100 * othello_eval_safe (pos) 
 
546
                + othello_eval_weights (pos);
 
547
        return RESULT_NOTYET;
 
548
}
 
549
 
 
550
ResultType othello_eval_incr (Pos *pos, byte *move, float *eval)
 
551
{
 
552
        int i;
 
553
        for (i=0; move[3*i] != -1; i++)
 
554
                ;
 
555
        if (i == 0) 
 
556
                *eval = 0;
 
557
        else
 
558
                *eval = (pos->player == WHITE ? (2 * i - 1) : - (2 * i - 1));
 
559
        return RESULT_NOTYET;
 
560
}
 
561
 
 
562
gboolean othello_use_incr_eval (Pos *pos)
 
563
{
 
564
        // TODO: use different threshold for Othello6x6
 
565
        return pos->num_moves > 50 ? TRUE : FALSE;
 
566
}