~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-1/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
 
}