Index: iagno/gnothello.h
===================================================================
--- iagno/gnothello.h	(リビジョン 6931)
+++ iagno/gnothello.h	(作業コピー)
@@ -1,6 +1,7 @@
+/* -*- mode:C; indent-tabs-mode:t; tab-width:8; c-basic-offset:8; -*- */
+
 /*
  * gnothello.h - Header for gnothello.c
- * written by Ian Peters <itp@gnu.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -14,74 +15,70 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307,
+ * USA
  *
  * For more details see the file COPYING.
  */
 
-#ifndef _GNOTHELLO_H_
-#define _GNOTHELLO_H_
 
-#define BLACK_TURN 1
-#define WHITE_TURN 31
-#define PIXMAP_FLIP_DELAY 20
-#define PIXMAP_STAGGER_DELAY 3
-#define COMPUTER_MOVE_DELAY 1000
+#define APP_NAME 		"iagno"
+#define APP_NAME_LONG 		N_("Iagno")
 
-#define OTHER_PLAYER(w) (((w) == WHITE_TURN) ? BLACK_TURN : WHITE_TURN)
+#define DEFAULT_TILESET		"sun_and_star.svg"
+#define DEFAULT_BGCOLOR		"#000066660000"
 
-#define TILEWIDTH   80
-#define TILEHEIGHT  80
-#define GRIDWIDTH   1
-#define BOARDWIDTH  ((TILEWIDTH+GRIDWIDTH)  * 8)
-#define BOARDHEIGHT ((TILEHEIGHT+GRIDWIDTH) * 8)
+#define PIXMAP_FLIP_DELAY	16
 
-#define MAIN_PAGE           	0
-#define NETWORK_PAGE           	1
+#define WINDOW_H_DEFAULT	340
+#define WINDOW_W_DEFAULT	336
+#define BOARD_MIN		263
+#define GRID_WIDTH		1
 
-gboolean ggz_network_mode;
-int player_id;
-int seat;
-int seats[2];
-char names[2][17];
+#define FLIP_PIXMAPS		1 << 2
+#define CHECK_COMPUTER_PLAYERS	1 << 4
+#define COMPUTER_MOVE		1 << 5
 
-extern GtkWidget *notebook;
-extern GtkWidget *window;
+// Takes a seat and transform into a player code
+#define SEAT2PLAYER(seat)	((seat == 0)? BLACK: WHITE)
 
-void new_game_cb (GtkWidget * widget, gpointer data);
-void new_network_game_cb (GtkWidget * widget, gpointer data);
-void on_network_leave (GObject * object, gpointer data);
-void on_player_list (void);
-void on_chat_window (void);
-void quit_game_cb (GtkWidget * widget, gpointer data);
-void undo_move_cb (GtkWidget * widget, gpointer data);
-void redo_move_cb (GtkWidget * widget, gpointer data);
-void about_cb (GtkWidget * widget, gpointer data);
-void comp_black_cb (GtkWidget * widget, gpointer data);
-void comp_white_cb (GtkWidget * widget, gpointer data);
-void quick_moves_cb (GtkWidget * widget, gpointer data);
-void anim_cb (GtkWidget * widget, gpointer data);
-void anim_stagger_cb (GtkWidget * widget, gpointer data);
-void load_tiles_cb (GtkWidget * widget, gpointer data);
-void set_selection (GtkWidget * widget, void *data);
-void free_str (GtkWidget * widget, void *data);
-void load_tiles_callback (GtkWidget * widget, void *data);
-void cancel (GtkWidget * widget, void *data);
-gint expose_event (GtkWidget * widget, GdkEventExpose * event);
-gint configure_event (GtkWidget * widget, GdkEventConfigure * event);
-gint button_press_event (GtkWidget * widget, GdkEventButton * event);
-void gui_draw_pixmap (gint which, gint x, gint y);
-void gui_draw_pixmap_buffer (gint which, gint x, gint y);
-gint flip_pixmaps (gpointer data);
-void init_new_game (void);
-void clear_board (void);
-void create_window (void);
-void gui_status (void);
-void gui_message (gchar * message);
-guint check_computer_players (void);
-void load_pixmaps (void);
-void properties_cb (GtkWidget * widget, gpointer data);
+// Takes a player code and transform into a seat index
+#define PLAYER2SEAT(player)	((player == BLACK)? 0: 1)
+
+struct _kifu {
+  gint8 who;
+  gint8 yx;
+};
+
+typedef struct _kifu kifu_t;
+
+gint clamp_int (gint input, gint low, gint high);
+
+void copy_board (void);
+
 void set_bg_color (void);
+
+void load_pixmaps (void);
+
 void gui_draw_grid (void);
 
-#endif
+void redraw_board (void);
+
+void gui_status (void);
+
+void gui_message (gchar *message);
+
+gboolean check_flags (gpointer data);
+
+void check_game_over (void);
+
+gboolean check_valid_move (gint who, gint yx);
+
+void move (gint yx);
+
+void stop_game (void);
+
+void init_game (void);
+
+void start_game (void);
+
Index: iagno/properties.h
===================================================================
--- iagno/properties.h	(リビジョン 6931)
+++ iagno/properties.h	(作業コピー)
@@ -1,7 +1,37 @@
-#ifndef _PROPERTIES_H_
-#define _PROPERTIES_H_
+/* -*- mode:C; indent-tabs-mode:t; tab-width:8; c-basic-offset:8; -*- */
 
+/*
+ * properties.h - Header for properties.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307,
+ * USA
+ *
+ * For more details see the file COPYING.
+ */
+
+
 void load_properties (void);
-void show_properties_dialog (void);
 
-#endif
+void save_properties (void);
+
+void reset_properties (void);
+
+void apply_changes (void);
+
+void on_ok_clicked (GtkButton *button, gpointer user_data);
+
+void on_preferences_activate (GtkMenuItem *menuitem, gpointer user_data);
+
+
Index: iagno/othello.c
===================================================================
--- iagno/othello.c	(リビジョン 6931)
+++ iagno/othello.c	(作業コピー)
@@ -1,8 +1,7 @@
-/* -*- mode:C; indent-tabs-mode:t; tab-width:4; c-basic-offset:8; -*- */
+/* -*- mode:C; indent-tabs-mode:t; tab-width:8; c-basic-offset:8; -*- */
 
 /*
  * othello.c - Othello support routines for iagno
- * written by Ian Peters <itp@gnu.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,38 +15,28 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307,
+ * USA
  *
  * For more details see the file COPYING.
  */
 
-#include <config.h>
 #include <gnome.h>
-#include <string.h>
-#include <games-clock.h>
-#include <games-sound.h>
 
 #include "othello.h"
-#include "gnothello.h"
 
-#define PERFECT   17
-#define VICTORY   19
-#define BEST      56
-#define MAX_DEPTH  7
+#define UL     -11
+#define UU     -10
+#define UR     -9
+#define LL     -1
+#define RR     +1
+#define DL     +9
+#define DD     +10
+#define DR     +11
+#define NDIRS  8
 
-#define BLANK 0
-#define OUTSIDE 128
-#define UL -11
-#define UU -10
-#define UR -9
-#define LL -1
-#define RR +1
-#define DL +9
-#define DD +10
-#define DR +11
-#define NDIRS 8
-
-gint8 squares[64] = { 44, 45, 54, 55, 23, 26, 73, 76,
+static const gint8 squares0[] = {
+  44, 45, 54, 55, 23, 26, 73, 76,
   32, 62, 37, 67, 13, 16, 31, 61,
   38, 68, 83, 86, 14, 15, 41, 51,
   48, 58, 84, 85, 24, 25, 42, 52,
@@ -57,104 +46,73 @@
   22, 27, 72, 77, 11, 18, 81, 88
 };
 
-static const gint heuristic[100] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-  0, 65, -3, 6, 4, 4, 6, -3, 65, 0,
-  0, -3, -29, 3, 1, 1, 3, -29, -3, 0,
-  0, 6, 3, 5, 3, 3, 5, 3, 6, 0,
-  0, 4, 1, 3, 1, 1, 3, 1, 4, 0,
-  0, 4, 1, 3, 1, 1, 3, 1, 4, 0,
-  0, 6, 3, 5, 3, 3, 5, 3, 6, 0,
-  0, -3, -29, 3, 1, 1, 3, -29, -3, 0,
-  0, 65, -3, 6, 4, 4, 6, -3, 65, 0,
-  0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+static const gint heuristic[] = {
+  0,   0,   0, 0, 0, 0, 0,   0,   0, 0,
+  0, 153, -33, 6, 4, 4, 6, -33, 153, 0,
+  0, -33, -73, 3, 2, 2, 3, -73, -33, 0,
+  0,   6,   3, 5, 3, 3, 5,   3,   6, 0,
+  0,   4,   2, 3, 1, 1, 3,   2,   4, 0,
+  0,   4,   2, 3, 1, 1, 3,   2,   4, 0,
+  0,   6,   3, 5, 3, 3, 5,   3,   6, 0,
+  0, -33, -73, 3, 2, 2, 3, -73, -33, 0,
+  0, 153, -33, 6, 4, 4, 6, -33, 153, 0,
+  0,   0,   0, 0, 0, 0, 0,   0,   0, 0
 };
 
-static const gint dirs[] = { UL, UU, UR, LL, RR, DL, DD, DR };
+static const gint8 dirs[] = { UL, UU, UR, LL, RR, DL, DD, DR };
+static gint8 squares[64];
+/* This array can probably be a lot smaller (< 300). */
+static gint8 history[MAX_MOVE_COUNT * 12];
+static gint8 *history_pointer;
+static GRand *rgen;
 
-guint flip_final_id = 0;
-gint flip_final;
+valid_square valid_squares[(VICTORY + 2) * (VICTORY + 3) / 2];
+gint8 	     board0[100];
+gint8 	     whose_turn;
+gint8 	     black_score;
+gint8 	     white_score;
+gint8 	     move_count;
+gint  	     s_kind;
 
-gint8 board0[100];
-/* This array can probably be a lot smaller (< 600). However, I am absolutely
- * certain that it cannot be more than 1200. So 1200 is what we use. */
-gint8 history[1200];
-gint hpointer;
-gint vsquares[280][2];
-gint vpointer;
-gint s_kind;
-GRand *rgen;
-
-extern guint black_computer_level;
-extern guint white_computer_level;
-
-extern gint animate;
-extern gint animate_stagger;
-extern guint game_in_progress;
-extern gint8 pixmaps[8][8];
-extern gint8 board[8][8];
-extern gint8 move_count;
-extern guint whose_turn;
-extern gint bcount;
-extern gint wcount;
-
-extern guint tiles_to_flip;
-
-/* Initialization of data */
+/* Initialization of data. */
 void
 init (void)
 {
-  gint i, j;
-  gint x;
+  guint i, j, ij = 0;
 
   rgen = g_rand_new ();
 
-  x = 0;
-  for (j = 0; j < 10; j++)
-    for (i = 0; i < 10; i++) {
-      if (j == 0 || j == 9)
-	board0[x] = OUTSIDE;
-      else if (i == 0 || i == 9)
-	board0[x] = OUTSIDE;
+  for (i = 0; i < 64; i++)
+    squares[i] = squares0[i];
+
+  for (i = 0; i < 10; i++)
+    for (j = 0; j < 10; j++) {
+      if (i == 0 || i == 9 || j == 0 || j == 9)
+	board0[ij++] = OUTSIDE;
       else
-	board0[x] = BLANK;
-      x++;
+	board0[ij++] = BLANK;
     }
+  board0[44] = WHITE;
+  board0[45] = BLACK;
+  board0[54] = BLACK;
+  board0[55] = WHITE;
 
-  board0[44] = WHITE_TURN;
-  board0[45] = BLACK_TURN;
-  board0[54] = BLACK_TURN;
-  board0[55] = WHITE_TURN;
-
-  hpointer = 0;
-  vpointer = 0;
+  move_count  = 4;
+  black_score = 2;
+  white_score = 2;
+  whose_turn  = BLACK;
+  history_pointer = &history[0];
 }
 
-/* Copy data from board0 to board */
-void
-board_copy (void)
-{
-  gint i, j;
-
-  for (j = 0; j < 8; j++)
-    for (i = 0; i < 8; i++)
-      board[i][j] = board0[(j + 1) * 10 + i + 1];
-}
-
 /* Check the validity of the move in a given direction. */
-static
-  gint
-is_valid0 (gint xy, gint dir, gint who)
+static gboolean
+check_valid0 (gint8 who, gint8 yx, gint8 dir)
 {
-  gint tmp;
-  gint8 not_me;
-
-  not_me = OTHER_PLAYER (who);
-
-  /* To be valid, the next counter should not be the current player ... */
-  tmp = xy + dir;
+  gint8 tmp    = yx + dir;
+  gint8 not_me = OTHER_PLAYER (who);
+  /* To be valid, the next counter should not be the current player .. */
   if (board0[tmp] != not_me)
     return FALSE;
-
   /* ... but eventually we must find a counter that is. */
   do {
     tmp += dir;
@@ -163,561 +121,377 @@
   return board0[tmp] == who;
 }
 
-/* Check if a given (empty) square can provide a valid move */
-static
-  gint
-is_valid (gint xy, gint who)
+/* Check if a given (empty) square can provide a valid move. */
+gboolean
+check_valid (gint who, gint yx)
 {
-  int i;
+  gint8 i;
 
   for (i = 0; i < NDIRS; i++)
-    if (is_valid0 (xy, dirs[i], who))
-      return (TRUE);
+    if (check_valid0 ((gint8) who, (gint8) yx, dirs[i]))
+      return TRUE;
 
   return FALSE;
 }
 
-/* Check whether the supplied move is a valid one. */
-gint
-is_valid_move (guint x, guint y, guint who)
+static void
+move_board0 (gint8 yx, gint8 dir)
 {
-  gint xy;
+  gint8 tmp    = yx + dir;
+  gint8 not_me = OTHER_PLAYER (whose_turn);
 
-  xy = (y + 1) * 10 + x + 1;
-  if (board0[xy] != BLANK)
-    return FALSE;
-
-  return is_valid (xy, who);
-}
-
-static
-  void
-move_board0 (gint xy, gint dir)
-{
-  gint8 tmp;
-  guint not_me;
-
-  not_me = OTHER_PLAYER (whose_turn);
-  tmp = xy + dir;
   if (board0[tmp] != not_me)
     return;
   /* Find the extent of the move in direction dir. */
   do {
     tmp += dir;
   } while (board0[tmp] == not_me);
+
   if (board0[tmp] != whose_turn)
     return;
-
   /* Now walk back to where we started flipping pieces over. */
   tmp -= dir;
-  while (tmp != xy) {
-    board0[tmp] = whose_turn;	/* Flip pieces */
-    history[hpointer++] = tmp;	/* Record history */
-    tmp -= dir;
+  while (tmp != yx) {
+    board0[tmp]        = whose_turn;	/* Flip pieces.    */
+    *history_pointer++ = tmp;		/* Record history. */
+    tmp               -= dir;
   }
 }
 
-/* reverse some pieces */
+/* Reverse some pieces. */
 void
-move_board (gint xy)
+move_board (gint yx)
 {
-  gint tmp, count;
-  int i;
+  gint8 i, count, tmp, *p_tmp;
 
-  count = hpointer;
-
+  p_tmp = history_pointer;
   for (i = 0; i < NDIRS; i++)
-    move_board0 (xy, dirs[i]);
+    move_board0 ((gint8) yx, dirs[i]);
 
-  board0[xy] = whose_turn;
-  count = hpointer - count;
-  history[hpointer++] = count;	/* make history */
-  history[hpointer++] = whose_turn;
+  count              = (gint8) (history_pointer - p_tmp) / sizeof (gint8);
+  *history_pointer++ = count;	/* history[f1,f2,,,fn,n,who] */
+  *history_pointer++ = whose_turn;
+  board0[yx]         = whose_turn;
 
-  if (whose_turn == WHITE_TURN) {
-    wcount += count + 1;
-    bcount -= count;
+  i = move_count++;		/* move_count = move_count + 1;         */
+  tmp = squares[i];		/* squares[0,1,2,,,,move_count,,,62,63] */
+  squares[i] = (gint8) yx;	/*        [-already puted-|-yet blank-] */
+  if (tmp != (gint8) yx) {	/* Sort squares. */
+    while (squares[++i] != (gint8) yx)
+      ;
+    squares[i] = tmp;
+  }
+
+  if (whose_turn == WHITE) {
+    white_score += count + 1;
+    black_score -= count;
   } else {
-    bcount += count + 1;
-    wcount -= count;
+    black_score += count + 1;
+    white_score -= count;
   }
-  tmp = squares[move_count];
-  squares[move_count++] = xy;
-  if (tmp != xy) {
-    count = move_count;
-    while (squares[count] != xy)
-      count++;
-    squares[count] = tmp;
-  }
+
   whose_turn = OTHER_PLAYER (whose_turn);
 }
 
-
-gint
-move (guint x, guint y, guint me)
-{
-  gint tmp;
-
-  tmp = (gint) ((y + 1) * 10 + x + 1);
-  if (board0[tmp] != BLANK)
-    return FALSE;
-  if (!is_valid (tmp, whose_turn))
-    return FALSE;
-  move_board (tmp);
-  board_copy ();
-
-  pixmaps[x][y] = (gint8) me;
-  gui_draw_pixmap (me, x, y);
-
-  gui_status ();
-
-  tiles_to_flip = 1;
-  check_valid_moves ();
-  check_computer_players ();
-
-  games_sound_play ("flip-piece");
-
-  return FALSE;
-}
-
-/* Back to before board0 */
+/* Back to the one previous board0. */
 void
-undo (void)
+back (void)
 {
   gint8 not_me, count;
 
-  whose_turn = history[--hpointer];	/* history[t1,t2,,,tn, n,who] */
-  count = history[--hpointer];
+  whose_turn = *--history_pointer;	/* history[f1,f2,,,fn,n,who] */
+  count      = *--history_pointer;
 
-  if (whose_turn == WHITE_TURN) {
-    wcount -= count + 1;
-    bcount += count;
+  if (whose_turn == WHITE) {
+    white_score -= count + 1;
+    black_score += count;
   } else {
-    bcount -= count + 1;
-    wcount += count;
+    black_score -= count + 1;
+    white_score += count;
   }
 
-  board0[squares[--move_count]] = BLANK;	/* decrease move_count    */
+  board0[squares[--move_count]] = BLANK; /* move_count = move_count - 1; */
 
   not_me = OTHER_PLAYER (whose_turn);
-  while (count > 0) {
-    board0[history[--hpointer]] = not_me;
-    count--;
-  }
+  while (count-- > 0)
+    board0[*--history_pointer] = not_me;
 }
 
-/* Sort vsquares by small order */
-static
-  void
-sort (gint l, gint r)
+static gint
+evaluate_heuristic (void)
 {
-  gint i, j, v, w, x;
-
-  i = l;
-  j = r;
-  x = vsquares[(l + r) / 2][1];
-  do {
-    while (vsquares[i][1] < x)
-      i++;
-    while (x < vsquares[j][1])
-      j--;
-    if (i < j) {
-      v = vsquares[i][0];
-      w = vsquares[i][1];
-      vsquares[i][0] = vsquares[j][0];
-      vsquares[i][1] = vsquares[j][1];
-      vsquares[j][0] = v;
-      vsquares[j][1] = w;
-    }
-    if (i <= j) {
-      i++;
-      j--;
-    }
-  } while (i <= j);
-
-  if (l < j)
-    sort (l, j);
-  if (i < r)
-    sort (i, r);
-}
-
-static
-  gint
-eval_heuristic (void)
-{
-  gint8 i, xy;
+  gint8 i, yx;
   gint count = 0;
 
   for (i = 0; i < move_count; i++) {
-    xy = squares[i];
-    count = (board0[xy] == whose_turn) ?
-      count + heuristic[xy] : count - heuristic[xy];
+    yx = squares[i];
+    if (board0[yx] == whose_turn)
+      count += heuristic[yx];
+    else
+      count -= heuristic[yx];
   }
 
   return count;
 }
 
-static
-  gint
-mobility (void)
+static gint
+mobility (gint who)
 {
-  gint8 i, xy;
+  gint8 i;
   gint count = 0;
 
   for (i = move_count; i < 64; i++) {
-    xy = squares[i];
-    if (is_valid (xy, whose_turn))
+    if (check_valid (who, (gint) squares[i]))
       count++;
   }
 
   return count;
 }
 
-static
-  gint
-around0 (gint xy)
+static gint
+around0 (gint8 yx)
 {
+  gint8 i;
   gint count = 0;
-  int i;
 
   for (i = 0; i < NDIRS; i++)
-    if (board0[xy + dirs[i]] == BLANK)
+    if (board0[yx + dirs[i]] == BLANK)
       count--;
 
-  if (!count)
-    count = 2;
-
   return count;
 }
 
-static
-  gint
+static gint
 around (void)
 {
-  gint8 i, xy;
+  gint8 i, yx;
   gint count = 0;
 
   for (i = 0; i < move_count; i++) {
-    xy = squares[i];
-    count = (board0[xy] == whose_turn) ?
-      count + around0 ((gint) xy) : count - around0 ((gint) xy);
+    yx = squares[i];
+    if (board0[yx] == whose_turn)
+      count += around0 (yx);
+    else
+      count -= around0 (yx);
   }
 
   return count;
 }
 
-/* Evaluate the board   */
-static
-  gint
-b_evaluation (void)
+static gint
+best_evaluation (void)
 {
-  gint score1, score2, score3;
+  gint score1, score2, score3, score4;
 
-  score1 = mobility ();
-  whose_turn = OTHER_PLAYER (whose_turn);
-  score1 -= mobility ();
-  whose_turn = OTHER_PLAYER (whose_turn);
-
+  score1 = mobility ((gint) whose_turn)
+    - mobility ((gint) OTHER_PLAYER (whose_turn));
   score2 = around ();
-  score3 = eval_heuristic ();
+  score3 = evaluate_heuristic ();
+  score4 = (whose_turn == BLACK) ? (gint) (white_score - black_score) :
+    (gint) (black_score - white_score);
 
-  return score1 + score2 + score3;
+  return score1 * 8 + score2 + score3 / 2 + score4 / 2;
 }
 
-/* Victory evaluation */
-static
-  gint
-v_evaluation (void)
+static gint
+perfect_evaluation (void)
 {
-  gint aa;
+  if (whose_turn == BLACK)
+    return (gint) (black_score - white_score);
 
-  aa = wcount - bcount;
-  if (whose_turn == BLACK_TURN)
+  return (gint) (white_score - black_score);
+}
+
+static gint
+victory_evaluation (void)
+{
+  gint8 aa;
+
+  aa = black_score - white_score;
+  if (whose_turn == WHITE)
     aa = -aa;
 
   if (aa > 0)
-    return 1;			/* win  */
+    return 1;			/* Win  */
   if (aa < 0)
-    return -1;			/* lose */
-  return 0;			/* draw */
+    return -1;			/* Lose */
+
+  return 0;			/* Draw */
 }
 
-static
-  gint
-p_evaluation (void)
+/* For the best search. */
+static gint
+win_evaluation (void)
 {
+  gint aa;
 
-  if (whose_turn == WHITE_TURN)
-    return wcount - bcount;
+  aa = (gint) (black_score - white_score);
+  if (whose_turn == WHITE)
+    aa = -aa;
 
-  return bcount - wcount;
+  if (!black_score || !white_score) {
+    if (aa > 0)
+      return aa + 10000;
+    return aa - 10000;
+  }
+
+  if (aa > 0)
+    return aa + 1000;
+  if (aa < 0)
+    return aa - 1000;
+
+  return 0;
 }
 
-static
-  gint
-w_evaluation (void)
+gint
+entry_valid_squares (gint pointer)
 {
-  gint aa;
+  gint j = pointer;
+  gint8 i, yx;
 
-  if (!bcount || !wcount) {
-    if (whose_turn == WHITE_TURN && !bcount)
-      return 10000;
-    if (whose_turn == BLACK_TURN && !wcount)
-      return 10000;
-    return -10000;
+  for (i = move_count; i < 64; i++) {
+    yx = squares[i];
+    if (check_valid ((gint) whose_turn, (gint) yx))
+      valid_squares[++j].square = yx;
   }
 
-  aa = wcount - bcount;
-  if (whose_turn == BLACK_TURN)
-    aa = -aa;
+  return j;
+}
 
-  if (aa > 0)
-    return aa + 100;
-  if (aa < 0)
-    return aa - 100;
-  return (0);
+/* Sort valid_squares by small order. */
+static void
+sort (gint l, gint r)
+{
+  gint i, j, v, x;
+  gint8 w;
+
+  i = l;
+  j = r;
+  x = valid_squares[(l + r) / 2].evaluation;
+
+  do {
+    while (valid_squares[i].evaluation < x)
+      i++;
+    while (x < valid_squares[j].evaluation)
+      j--;
+    if (i < j) {
+      v = valid_squares[i].evaluation;
+      w = valid_squares[i].square;
+      valid_squares[i].evaluation = valid_squares[j].evaluation;
+      valid_squares[i].square     = valid_squares[j].square;
+      valid_squares[j].evaluation = v;
+      valid_squares[j].square     = w;
+    }
+    if (i <= j) {
+      i++;
+      j--;
+    }
+  }
+  while (i <= j);
+
+  if (l < j)
+    sort (l, j);
+  if (i < r)
+    sort (i, r);
 }
 
-/* alpha-beta search */
-static
-  gint
-search (gint n, gint a, gint b)
+/* Alpha-beta search */
+static gint
+search (gint n, gint a, gint b, gint pointer)
 {
-  gint aa, bb, xy, i, j;
+  gint i, j, aa, bb;
 
-  if (!n) {
+  if (!n) {					/* Search end?         */
     switch (s_kind) {
     case PERFECT:
-      return (p_evaluation ());
+      return perfect_evaluation ();
     case VICTORY:
-      return (v_evaluation ());
+      return victory_evaluation ();
     default:
-      return (b_evaluation ());
+      return best_evaluation ();
     }
   }
 
-  aa = a;
-
-  j = vpointer;
-  for (i = (gint) move_count; i < 64; i++) {	/* entry valid squares */
-    xy = (gint) squares[i];
-    if (is_valid (xy, whose_turn)) {
-      vsquares[++j][0] = xy;
-      move_board (xy);
-      vsquares[j][1] = mobility ();
-      undo ();
-    }
-  }
-
-  if (j == vpointer) {		/* pass ?  */
-    whose_turn = (whose_turn == WHITE_TURN) ? BLACK_TURN : WHITE_TURN;
-    if (!mobility ()) {
-      whose_turn = OTHER_PLAYER (whose_turn);
-
+  j = entry_valid_squares (pointer);
+  if (j == pointer) {				/* Skip move?          */
+    whose_turn = OTHER_PLAYER (whose_turn);
+    if (!mobility ((gint) whose_turn)) {
+      whose_turn = OTHER_PLAYER (whose_turn);	/* No, the game is over. */
       switch (s_kind) {
       case PERFECT:
-	return (p_evaluation ());
+	return perfect_evaluation ();
       case VICTORY:
-	return (v_evaluation ());
+	return victory_evaluation ();
       default:
-	return (w_evaluation ());
+	return win_evaluation ();
       }
     }
-    aa = -search (n, -b, -aa);
+
+    aa = -search (n, -b, -a, pointer);		/* Yes, skip move.     */
     whose_turn = OTHER_PLAYER (whose_turn);
-    vsquares[j][0] = 0;		/* mark pass              */
+    valid_squares[pointer].square = 0;		/* Mark pass.          */
     return aa;
   }
 
-  sort (vpointer + 1, j);
+  for (i = j; i > pointer; i--) {		/* No, continue search. */
+    move_board ((gint) valid_squares[i].square); /* Simple evaluation */
+    valid_squares[i].evaluation = mobility ((gint) whose_turn);
+    back ();
+  }						/* i = pointer;        */
+  sort (i + 1, j);				/* Sort valid_squares. */
 
-  i = vpointer;			/* save old vpointer      */
-  vpointer = j + 1;		/* new vpointer           */
-
-  j = i + 1;
-  while (aa < b && j < vpointer) {
-    xy = vsquares[j][0];
-    move_board (xy);
-    bb = -search (n - 1, -b, -aa);	/* evaluate this square  */
-    undo ();
-    if (aa < bb) {
+  aa = a;
+  j++;						/* New pointer         */
+  while (aa < b && ++i < j) {			/* Evaluate squares.   */
+    move_board ((gint) valid_squares[i].square);
+    bb = -search (n - 1, -b, -aa, j);
+    back ();
+    if (bb > aa) { 				/* Save this square.   */
       aa = bb;
-      vsquares[i][0] = xy;	/* save this square       */
+      valid_squares[pointer].square = valid_squares[i].square;
     }
-    j++;
   }
-  vpointer = i;			/* pop vpointer           */
+
   return aa;
 }
 
-static
-  void
+/* For first several turns. */
+static gint
 random_select (void)
 {
-  gint xy, i, j;
+  gint j = entry_valid_squares (0);
+  gint i = g_rand_int_range (rgen, 1, j + 1);
 
-  vsquares[0][0] = 0;
-  j = 0;
-  for (i = move_count; i < 64; i++) {
-    xy = squares[i];
-    if (is_valid (xy, whose_turn))
-      vsquares[j++][0] = xy;
-  }
-  if (j) {
-    i = g_rand_int_range (rgen, 0, j);
-    vsquares[0][0] = vsquares[i][0];
-  }
+  if (heuristic[valid_squares[i].square] < 0)	// If the square is critical,
+    i = g_rand_int_range (rgen, 1, j + 1);	// then select once more. 
+
+  valid_squares[0].square = valid_squares[i].square;
+  return 0;
 }
 
-static
-  gint
+gint
 computer_move (gint level)
 {
-  gint nn, aa, kind, best_xy;
+  gint nn = (gint) (64 - move_count);
 
-  vsquares[0][0] = -1;
-  nn = 64 - move_count;
-  if (nn > BEST)
-    random_select ();
-  else {
-    if (nn <= PERFECT - level) {
-      kind = PERFECT;
-      aa = 127;
+  if (nn <= PERFECT - MAX_DEPTH + level) {
+    s_kind = PERFECT;
+    valid_squares[0].evaluation = search (nn, -127, 127, 0);
+  } else if (nn <= VICTORY - MAX_DEPTH + level) {
+    s_kind = VICTORY;
+    valid_squares[0].evaluation = search (nn, -1, 1, 0);
+    if (valid_squares[0].evaluation == -1) {	// If the computer can't win,
+      s_kind = BEST;				// then search the best again.
+      valid_squares[0].evaluation = search (level, -32767, 32767, 0);
     }
-    if (PERFECT - level < nn && nn <= VICTORY - level) {
-      kind = VICTORY;
-      aa = 2;
-    }
-    if (VICTORY - level < nn && nn <= BEST) {
-      kind = BEST;
-      aa = 32767;
-      nn = MAX_DEPTH - level;
-    }
-    s_kind = kind;
-    vsquares[0][1] = search (nn, -aa, aa);
-  }
-
-  best_xy = vsquares[0][0];
-
-  if (best_xy == -1) {		/* If I can't win, then search the best again. */
+  } else if (nn <= BEST - 8 + (level + 1) / 2 * 2) {
     s_kind = BEST;
-    vsquares[0][1] = search (MAX_DEPTH - level, -32767, 32767);
-    best_xy = vsquares[0][0];
+    valid_squares[0].evaluation = search (level, -32767, 32767, 0);
+  } else {
+    s_kind = RANDOM;
+    valid_squares[0].evaluation = random_select ();
   }
 
-  if (best_xy)
-    move (best_xy % 10 - 1, best_xy / 10 - 1, whose_turn);
-
-  return FALSE;
+  return (gint) valid_squares[0].square;
 }
 
-gint
-computer_move_1 (guint me)
-{
-  return computer_move (6);
-}
-
-gint
-computer_move_2 (guint me)
-{
-  return computer_move (4);
-}
-
-gint
-computer_move_3 (guint me)
-{
-  return computer_move (2);
-}
-
-gint
-computer_move_4 (guint me)
-{
-  return computer_move (0);
-}
-
-gboolean
-flip_final_results (gpointer data)
-{
-  guint i;
-  guint white_pieces;
-  guint black_pieces;
-  guint adder = 0;
-
-  white_pieces = wcount;
-  black_pieces = bcount;
-
-  i = 0;
-  for (; i < black_pieces; i++) {
-    board[i % 8][i / 8] = BLACK_TURN;
-    if (pixmaps[i % 8][i / 8] < 1)
-      pixmaps[i % 8][i / 8] = WHITE_TURN;
-    if (pixmaps[i % 8][i / 8] == WHITE_TURN) {
-      pixmaps[i % 8][i / 8] += adder;
-      if (animate_stagger)
-	adder++;
-    }
-  }
-  for (; i < 64 - white_pieces; i++) {
-    board[i % 8][i / 8] = 0;
-    pixmaps[i % 8][i / 8] = 100;
-  }
-  for (; i < 64; i++) {
-    board[i % 8][i / 8] = WHITE_TURN;
-    if (pixmaps[i % 8][i / 8] == 0)
-      pixmaps[i % 8][i / 8] = BLACK_TURN;
-    if (pixmaps[i % 8][i / 8] == BLACK_TURN) {
-      pixmaps[i % 8][i / 8] -= adder;
-      if (animate_stagger)
-	adder++;
-    }
-  }
-
-  tiles_to_flip = 1;
-
-  return FALSE;
-}
-
-gint
-check_valid_moves (void)
-{
-  guint white_moves = 0;
-  guint black_moves = 0;
-
-  if (!game_in_progress)
-    return TRUE;
-  if (mobility ())
-    return TRUE;
-
-  whose_turn = OTHER_PLAYER (whose_turn);
-
-  if (!mobility ()) {
-    white_moves = wcount;
-    black_moves = bcount;
-    if (white_moves > black_moves)
-      gui_message (_("Light player wins!"));
-    if (black_moves > white_moves)
-      gui_message (_("Dark player wins!"));
-    if (white_moves == black_moves)
-      gui_message (_("The game was a draw."));
-    whose_turn = 0;
-    game_in_progress = 0;
-    if (flip_final)
-      flip_final_id = g_timeout_add (100, flip_final_results, NULL);
-
-    games_sound_play ("gameover");
-
-    return TRUE;
-  }
-
-  if (whose_turn == BLACK_TURN) {
-    gui_message (_("Light must pass, Dark's move"));
-    return TRUE;
-  }
-
-  if (whose_turn == WHITE_TURN) {
-    gui_message (_("Dark must pass, Light's move"));
-    return TRUE;
-  }
-
-  return TRUE;
-}
Index: iagno/othello.h
===================================================================
--- iagno/othello.h	(リビジョン 6931)
+++ iagno/othello.h	(作業コピー)
@@ -1,6 +1,7 @@
+/* -*- mode:C; indent-tabs-mode:t; tab-width:8; c-basic-offset:8; -*- */
+
 /*
  * othello.h - Header for othello.c
- * written by Ian Peters <itp@gnu.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -14,25 +15,42 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307,
+ * USA
  *
  * For more details see the file COPYING.
  */
 
-#ifndef _OTHELLO_H_
-#define _OTHELLO_H_
+#define BLACK			49
+#define WHITE			79
+#define BLANK			1
+#define OUTSIDE			127
 
-gint is_valid_move (guint, guint, guint);
-gint move (guint, guint, guint);
-void move_board (gint);
-gboolean flip_final_results (gpointer data);
-gint check_valid_moves (void);
-gint computer_move_1 (guint);
-gint computer_move_2 (guint);
-gint computer_move_3 (guint);
-gint computer_move_4 (guint);
+#define OTHER_PLAYER(who)	(128 - who)
+
+#define PERFECT			17
+#define VICTORY			21
+#define BEST			56
+#define RANDOM			60
+#define MAX_DEPTH		8
+#define MAX_MOVE_COUNT		64
+
+struct _valid_square {
+  gint8 square;
+  gint  evaluation;
+};
+
+typedef struct _valid_square valid_square;
+
 void init (void);
-void board_copy (void);
-void undo (void);
 
-#endif
+gboolean check_valid (gint who, gint yx);
+
+void move_board (gint yx);
+
+void back (void);
+
+gint entry_valid_squares (gint pointer);
+
+gint computer_move (gint level);
+
Index: iagno/Makefile.am
===================================================================
--- iagno/Makefile.am	(リビジョン 6931)
+++ iagno/Makefile.am	(作業コピー)
@@ -6,53 +6,27 @@
 	$(WARN_CFLAGS)					\
 	$(GNOME_GAMES_CFLAGS)				\
 	-DDATADIR=\""$(datadir)"\"		   	\
-	-DGNOMELOCALEDIR=\""$(datadir)/locale"\"	\
-	$(GGZMOD_INCLUDES) $(GGZ_GTK_INCLUDES) $(GGZCORE_INCLUDES)\
-	$(LIBGGZ_INCLUDES) $(GGZCORE_INCLUDES) $(GGZDMOD_INCLUDES)
+	-DGNOMELOCALEDIR=\""$(datadir)/locale"\"
 
-if GGZ_SERVER
-bin_PROGRAMS = iagno iagnod
-iagnod_SOURCES = server.h   \
-		 server.c   
-
-iagnod_LDFLAGS = @GGZDMOD_LDFLAGS@
-
-iagnod_LDADD = \
-	$(GNOME_GAMES_LIBS)     \
-	$(INTLLIBS) 		\
-	@LIB_GGZDMOD@
-
-else
 bin_PROGRAMS = iagno 
-endif
 
-if GGZ_CLIENT
-GGZ_FILES =	ggz-network.h \
-		ggz-network.c \
-		$(NULL)
-endif
-
 iagno_SOURCES = \
 	gnothello.c \
 	gnothello.h \
 	othello.c \
 	othello.h \
 	properties.c \
-	properties.h \
-	$(GGZ_FILES)
+	properties.h
 
-iagno_LDFLAGS = $(GGZMOD_LDFLAGS)
-
 iagno_LDADD = \
 	../libgames-support/libgames-support.la \
 	$(GNOME_GAMES_LIBS) \
-	$(INTLLIBS) \
-	$(LIB_GGZMOD) \
-	$(LIB_GGZ_GTK)
+	$(INTLLIBS)
 
 pixmap_DATA = \
-	classic.png \
-	woodtrim.png
+	disk.svg \
+	marble.svg \
+   sun_and_star.svg
 
 Games_in_files = iagno.desktop.in.in
 Games_DATA = $(Games_in_files:.desktop.in.in=.desktop)
@@ -65,9 +39,6 @@
 
 EXTRA_DIST = \
 	AUTHORS \
-	iagno-client.dsc.in \
-	iagno-server.dsc.in \
-        iagno.room          \
 	$(pixmap_DATA)	\
 	$(schema_in_files)
 
@@ -75,25 +46,10 @@
 if GCONF_SCHEMAS_INSTALL
 	GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(top_builddir)/iagno/$(schema_DATA)
 endif
-if GGZ_CLIENT
-	$(GGZ_CONFIG) -D --install --modfile=iagno-client.dsc --force
-endif
 uninstall-local:
-if GGZ_CLIENT
-	-$(GGZ_CONFIG) -D --remove --modfile=iagno-client.dsc
-endif
 
 @INTLTOOL_SOUNDLIST_RULE@
 
 SUBDIRS= help
 
 DISTCLEANFILES = $(Games_DATA) $(schema_DATA) 
-
-if GGZ_SERVER
-ggzroom_DATA = iagno.room
-ggzroomdir = ${prefix}/etc/ggzd/rooms/
-
-ggzgame_DATA = iagno-server.dsc
-ggzgamedir = ${prefix}/etc/ggzd/games/
-endif
-
Index: iagno/gnothello.c
===================================================================
--- iagno/gnothello.c	(リビジョン 6931)
+++ iagno/gnothello.c	(作業コピー)
@@ -2,7 +2,6 @@
 
 /*
  * gnothello.c - Main GUI part of iagno
- * written by Ian Peters <itp@gnu.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -16,861 +15,740 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307,
+ * USA
  *
  * For more details see the file COPYING.
  */
 
-#include <config.h>
 #include <gnome.h>
-#include <gdk/gdkkeysyms.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <stdio.h>
 
-#include <string.h>
+#include <config.h>
 #include <games-stock.h>
-#include <games-sound.h>
+#include <games-preimage.h>
+#include <games-files.h>
 #include <games-conf.h>
 
-#ifdef GGZ_CLIENT
-#include <games-dlg-chat.h>
-#include <games-dlg-players.h>
-#include "ggz-network.h"
-#include <ggz-embed.h>
-#endif
-
-#include "gnothello.h"
 #include "othello.h"
+#include "gnothello.h"
 #include "properties.h"
 
-#define APP_NAME "iagno"
-#define APP_NAME_LONG N_("Iagno")
+static GdkPixmap *buffer_pixmap = NULL;
+static GdkPixmap *tiles_pixmap = NULL;
+static GdkGC     *gridGC[2] = { 0 };
+static GtkWidget *menubar;
+static GtkWidget *statusbar;
+static GtkWidget *score[4];
+static GtkActionGroup *action_group;
+static GtkUIManager *manager;
+static gint8     pixmaps[8][8];
+static gint8     board[8][8];
+static gint      board_width;
+static gint      board_height;
+static gint      tile_width;
+static gint      tile_height;
+static guint     context_id = 0;
 
-GnomeAppBar *appbar;
-GtkWidget *window;
-GtkWidget *notebook;
-GtkWidget *drawing_area;
-GtkWidget *tile_dialog;
-GtkWidget *black_score;
-GtkWidget *white_score;
+GtkWidget        *window;
+GtkWidget        *notebook;
+GtkWidget        *drawing_area;
+GdkColor         bg_color[3] = {
+                   {0, 0, 0, 0},			 // background color
+                   {0xffffffff, 0xffff, 0xffff, 0xffff}, // grid color
+                   {0, 0, 0, 0}				 // tmp color
+                 };
+kifu_t           kifu[MAX_MOVE_COUNT + 1];
+guint            flags = 0;
+gboolean         game_in_progress = FALSE;
 
-GdkPixmap *buffer_pixmap = NULL;
-GdkPixmap *tiles_pixmap = NULL;
-GdkPixmap *tiles_mask = NULL;
+extern valid_square valid_squares[];
+extern gint8     board0[];
+extern gint8     move_count;
+extern gint8     whose_turn;
+extern gint8     black_score;
+extern gint8     white_score;
+extern gint      s_kind;
 
-gint flip_pixmaps_id = 0;
-gint statusbar_id;
-guint black_computer_level;
-guint white_computer_level;
-guint black_computer_id = 0;
-guint white_computer_id = 0;
-guint computer_speed = COMPUTER_MOVE_DELAY;
-gint animate;
-gint animate_stagger;
-gint grid = 0;
-guint tiles_to_flip = 0;
+extern GtkWidget *properties_dialog;
+extern gint      window_width;
+extern gint      window_height;
+extern gint      computer_level[];
+extern gchar     *tile_set;
+extern gchar     *bg_color_name;
+extern guint     check_flags_id;
+extern guint     flip_delay;
 
-gint64 milliseconds_total = 0;
-gint64 milliseconds_current_start = 0;
-
-guint game_in_progress;
-
-gint8 pixmaps[8][8] = { {0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-};
-
-gint8 board[8][8] = { {0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-,
-{0, 0, 0, 0, 0, 0, 0, 0}
-};
-guint whose_turn;
-gint8 move_count;
-gint bcount;
-gint wcount;
-
-extern guint flip_final_id;
-extern gint8 squares[64];
-
-int session_flag = 0;
-int session_xpos = -1;
-int session_ypos = -1;
-int session_position = 0;
-
-gchar *tile_set = NULL;
-gchar *tile_set_tmp = NULL;
-
-GdkGC *gridGC[2] = { 0 };
-
+int              session_xpos = -1;
+int              session_ypos = -1;
 static const GOptionEntry options[] = {
-  {"x", 'x', 0, G_OPTION_ARG_INT, &session_xpos, N_("X location of window"),
-   N_("X")},
-  {"y", 'y', 0, G_OPTION_ARG_INT, &session_ypos, N_("Y location of window"),
-   N_("Y")},
+  {"x", 'x', 0, G_OPTION_ARG_INT, &session_xpos,
+   N_("X location of window"), N_("X")},
+  {"y", 'y', 0, G_OPTION_ARG_INT, &session_ypos,
+   N_("Y location of window"), N_("Y")},
   {NULL}
 };
 
-GnomeUIInfo game_menu[] = {
-  GNOMEUIINFO_MENU_NEW_GAME_ITEM (new_game_cb, NULL),
+/**** Basic routines ****/
 
-  GNOMEUIINFO_ITEM (N_("Net_work Game"), NULL, new_network_game_cb, NULL),
-
-  GNOMEUIINFO_SEPARATOR,
-
-  GNOMEUIINFO_MENU_UNDO_MOVE_ITEM (undo_move_cb, NULL),
-
-  GNOMEUIINFO_ITEM (N_("_Player list"), NULL, on_player_list, NULL),
-
-  GNOMEUIINFO_ITEM (N_("_Chat Window"), NULL, on_chat_window, NULL),
-
-  GNOMEUIINFO_SEPARATOR,
-
-  GNOMEUIINFO_ITEM (N_("_Leave Game"), NULL, on_network_leave, NULL),
-
-  GNOMEUIINFO_MENU_QUIT_ITEM (quit_game_cb, NULL),
-
-  GNOMEUIINFO_END
-};
-
-GnomeUIInfo settings_menu[] = {
-  GNOMEUIINFO_MENU_PREFERENCES_ITEM (properties_cb, NULL),
-  GNOMEUIINFO_END
-};
-
-GnomeUIInfo help_menu[] = {
-  GNOMEUIINFO_HELP ("iagno"),
-  GNOMEUIINFO_MENU_ABOUT_ITEM (about_cb, NULL),
-  GNOMEUIINFO_END
-};
-
-GnomeUIInfo mainmenu[] = {
-  GNOMEUIINFO_MENU_GAME_TREE (game_menu),
-  GNOMEUIINFO_MENU_SETTINGS_TREE (settings_menu),
-  GNOMEUIINFO_MENU_HELP_TREE (help_menu),
-  GNOMEUIINFO_END
-};
-
-static void
-undo_set_sensitive (gboolean state)
+gint
+clamp_int (gint input, gint low, gint high)
 {
-  gtk_widget_set_sensitive (game_menu[3].widget, state);
-}
+  if (input < low)
+    input = low;
+  if (input > high)
+    input = high;
 
-void
-quit_game_cb (GtkWidget * widget, gpointer data)
-{
-  gtk_main_quit ();
+  return input;
 }
 
 void
-new_game_cb (GtkWidget * widget, gpointer data)
+copy_board (void)
 {
-  init_new_game ();
-}
+  gint i, j;
 
-void
-on_player_list (void)
-{
-#ifdef GGZ_CLIENT
-  create_or_raise_dlg_players (GTK_WINDOW (window));
-#endif
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      board[i][j] = board0[(i + 1) * 10 + j + 1];
 }
 
-void
-on_chat_window (void)
+static void
+copy_pixmaps (void)
 {
-#ifdef GGZ_CLIENT
-  create_or_raise_dlg_chat (GTK_WINDOW (window));
-#endif
-}
+  gint i, j;
 
-void
-new_network_game_cb (GtkWidget * widget, gpointer data)
-{
-#ifdef GGZ_CLIENT
-  on_network_game ();
-  gtk_widget_hide (mainmenu[0].widget);
-  gtk_widget_hide (mainmenu[1].widget);
-#endif
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++)
+      pixmaps[i][j] = board[i][j];
 }
 
-void
-on_network_leave (GObject * object, gpointer data)
+static void
+set_board_size (void)
 {
-#ifdef GGZ_CLIENT
-  ggz_embed_leave_table ();
-  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), NETWORK_PAGE);
-#endif
+  gint depth = -1;
+
+  tile_width   = (board_width  - GRID_WIDTH * 7) / 8;
+  tile_height  = (board_height - GRID_WIDTH * 7) / 8;
+  board_width  = (tile_width  + GRID_WIDTH) * 8 - GRID_WIDTH;
+  board_height = (tile_height + GRID_WIDTH) * 8 - GRID_WIDTH;
+
+  if (buffer_pixmap) {
+    g_object_unref (buffer_pixmap);
+    depth = gdk_drawable_get_depth ((GdkDrawable *) drawing_area->window);
+  }
+  buffer_pixmap = gdk_pixmap_new (drawing_area->window,
+				  board_width, board_height, depth);
+
+  return set_bg_color ();
 }
 
 void
-undo_move_cb (GtkWidget * widget, gpointer data)
+set_bg_color (void)
 {
-  gint8 which_computer, xy;
+  gint i;
 
-  if ((black_computer_level && white_computer_level) || move_count == 4)
-    return;
-   
-  /* Cancel any pending AI operations */
-  if (black_computer_id) {
-    g_source_remove (black_computer_id);
-    black_computer_id = 0;
-  }
-  if (white_computer_id) {
-    g_source_remove (white_computer_id);
-    white_computer_id = 0;
-  }
+  gdk_color_parse (bg_color_name, &bg_color[0]);
+  gdk_colormap_alloc_color (gtk_widget_get_colormap (drawing_area),
+			    &bg_color[0], FALSE, TRUE);
 
-  if (flip_final_id) {
-    g_source_remove (flip_final_id);
-    flip_final_id = 0;
+  for (i = 0; i < 2; i++) {
+    if (gridGC[i])
+      g_object_unref (gridGC[i]);
+    gridGC[i] = gdk_gc_new (drawing_area->window);
+    gdk_gc_copy (gridGC[i], drawing_area->style->bg_gc[0]);
+    gdk_gc_set_background (gridGC[i], &bg_color[i]);
+    gdk_gc_set_foreground (gridGC[i], &bg_color[i]);
   }
+  gdk_draw_rectangle (buffer_pixmap, gridGC[0], TRUE, 0, 0,
+		      board_width, board_height);
 
-  game_in_progress = 1;
-
-  which_computer = OTHER_PLAYER (whose_turn);
-  undo ();
-  board_copy ();
-  xy = squares[move_count];
-  pixmaps[xy % 10 - 1][xy / 10 - 1] = 100;
-  if ((((whose_turn == WHITE_TURN) && white_computer_level) ||
-       ((whose_turn == BLACK_TURN) && black_computer_level))
-      && (move_count > 4)) {
-    undo ();
-    board_copy ();
-    xy = squares[move_count];
-    pixmaps[xy % 10 - 1][xy / 10 - 1] = 100;
-  }
-
-  gui_status ();
-  tiles_to_flip = 1;
-  check_computer_players ();
+  return gui_draw_grid ();
 }
 
 void
-about_cb (GtkWidget * widget, gpointer data)
+gui_draw_grid (void)
 {
-  const gchar *authors[] = { "Ian Peters", NULL };
+  gint i;
 
-  const gchar *documenters[] = { "Eric Baudais", NULL };
+  gdk_gc_set_line_attributes (gridGC[1], GRID_WIDTH, GDK_LINE_ON_OFF_DASH,
+			      GDK_CAP_BUTT, GDK_JOIN_MITER);
 
-  gchar *license = games_get_license (_(APP_NAME_LONG));
+  for (i = tile_height; i < board_height; i += tile_height + GRID_WIDTH)
+    gdk_draw_line (buffer_pixmap, gridGC[1], 0, i, board_width, i);
+  for (i = tile_width;  i < board_width;  i += tile_width  + GRID_WIDTH)
+    gdk_draw_line (buffer_pixmap, gridGC[1], i, 0, i, board_height);
 
-  gtk_show_about_dialog (GTK_WINDOW (window),
-			 "name", _(APP_NAME_LONG),
-			 "version", VERSION,
-			 "copyright",
-			 "Copyright \xc2\xa9 1998-2007 Ian Peters",
-                         "license", license,
-                         "comments", _("A disk flipping game derived from Reversi.\n\nIagno is a part of GNOME Games."),
-			 "authors", authors,
-                         "documenters", documenters,
-			 "translator-credits", _("translator-credits"),
-			 "logo-icon-name", "gnome-iagno",
-			 "website-label", _("GNOME Games web site"),
-                         "website", "http://www.gnome.org/projects/gnome-games/",
-			 "wrap-license", TRUE,
-                         NULL);
-  g_free (license);
+  return load_pixmaps ();
 }
 
-void
-properties_cb (GtkWidget * widget, gpointer data)
+static GamesPreimage *
+load_image (gchar *tileset)
 {
-  show_properties_dialog ();
-}
+  GError *error = NULL;
+  gchar *fname;
+  gchar *pathname;
+  GamesPreimage *preimage;
 
-gint
-expose_event (GtkWidget * widget, GdkEventExpose * event)
-{
-  gdk_draw_drawable (widget->window,
-		     widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-		     buffer_pixmap,
-		     event->area.x, event->area.y,
-		     event->area.x, event->area.y,
-		     event->area.width, event->area.height);
+  fname    = g_build_filename (APP_NAME, tileset, NULL);
+  pathname = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_APP_PIXMAP,
+					fname, TRUE, NULL);
+  preimage = games_preimage_new_from_file (pathname, &error);
 
-  return (FALSE);
+  g_free (fname);
+  g_free (pathname);
+  return preimage;
 }
 
-gboolean
-configure_event (GtkWidget * widget, GdkEventConfigure * event)
+void
+load_pixmaps (void)
 {
-  static int old_width = 0, old_height = 0;
-  guint i, j;
+  GamesPreimage *t_image;
+  GdkPixbuf *image;
+  gint depth = -1;
+  GdkGC *gc;
 
-  if (old_width == event->width && old_height == event->height) {
-    return TRUE;
-  } else {
-    old_width = event->width;
-    old_height = event->height;
+  t_image = load_image (tile_set);
+  if (!t_image) {
+    if (tile_set)
+      g_free (tile_set);
+    tile_set = g_strdup (DEFAULT_TILESET);
+    t_image = load_image (tile_set);
+    if (!t_image) {
+      g_print (_("Could not find \'%s\' pixmap file\n"), DEFAULT_TILESET);
+      exit (1);
+    }
+    reset_properties ();
   }
 
-  if (gridGC[0] != 0) {
-    gdk_draw_rectangle (buffer_pixmap, gridGC[0], 1,
-			0, 0, BOARDWIDTH, BOARDHEIGHT);
-    for (i = 0; i < 8; i++)
-      for (j = 0; j < 8; j++)
-	gui_draw_pixmap_buffer (pixmaps[i][j], i, j);
-    gui_draw_grid ();
+  image = games_preimage_render (t_image, tile_width * 8, tile_height * 4);
+
+  if (tiles_pixmap) {
+    g_object_unref (tiles_pixmap);
+    depth = gdk_drawable_get_depth ((GdkDrawable *) drawing_area->window);
   }
+  tiles_pixmap = gdk_pixmap_new (drawing_area->window,
+				 tile_width * 8, tile_height * 4, depth);
 
-  return TRUE;
+  gc = gdk_gc_new (tiles_pixmap);
+  gdk_gc_set_foreground (gc, &bg_color[0]);
+  gdk_gc_set_background (gc, &bg_color[0]);
+
+  gdk_draw_rectangle (tiles_pixmap, gc, TRUE, 0, 0,
+		      tile_width * 8, tile_height * 4);
+  gdk_draw_pixbuf (tiles_pixmap, gc, image, 0, 0, 0, 0,
+		   tile_width * 8, tile_height * 4,
+		   GDK_RGB_DITHER_NONE, 0, 0);
+
+  g_object_unref (t_image);
+  g_object_unref (image);
+  return redraw_board ();
 }
 
-gint
-button_press_event (GtkWidget * widget, GdkEventButton * event)
+static void
+gui_draw_pixmap_buffer (gint which, gint x, gint y)
 {
-  guint x, y;
+  gdk_draw_drawable (buffer_pixmap, gridGC[0], tiles_pixmap,
+		     tile_width * (which % 8), tile_height * (which / 8),
+		     (tile_width  + GRID_WIDTH) * x,
+		     (tile_height + GRID_WIDTH) * y,
+ 		     tile_width, tile_height);
+}
 
-  if (game_in_progress == 0)
-    return TRUE;
+static void
+gui_draw_pixmap (gint which, gint x, gint y)
+{
+  gdk_draw_drawable (drawing_area->window, gridGC[0], tiles_pixmap,
+		     tile_width * (which % 8), tile_height * (which / 8),
+		     (tile_width  + GRID_WIDTH) * x,
+		     (tile_height + GRID_WIDTH) * y,
+		     tile_width, tile_height);
+  return gui_draw_pixmap_buffer (which, x, y);
+}
 
-  if (!ggz_network_mode && (whose_turn == WHITE_TURN) && white_computer_level)
-    return TRUE;
+void
+redraw_board (void)
+{
+  gint i, j, which;
 
-  if (!ggz_network_mode && (whose_turn == BLACK_TURN) && black_computer_level)
-    return TRUE;
+  copy_pixmaps ();
 
-  if (event->button == 1) {
-    x = event->x / (TILEWIDTH + GRIDWIDTH);
-    y = event->y / (TILEHEIGHT + GRIDWIDTH);
-    if (ggz_network_mode && player_id == whose_turn
-	&& is_valid_move (x, y, whose_turn)) {
-#ifdef GGZ_CLIENT
-      send_my_move (CART (x + 1, y + 1), whose_turn);
-#endif
-    } else if (!ggz_network_mode && is_valid_move (x, y, whose_turn)) {
-      move (x, y, whose_turn);
-    } else {
-      gui_message (_("Invalid move."));
+  for (i = 0; i < 8; i++)
+    for (j = 0; j < 8; j++) {
+      which = (gint) pixmaps[i][j];
+      if (which == BLANK)
+	which = 0;
+      else
+	which = clamp_int (which, BLACK, WHITE) - BLACK + 1;
+      gui_draw_pixmap_buffer (which, j, i);
     }
 
-  }
+  gtk_widget_queue_draw_area (drawing_area, 0, 0, board_width, board_height);
 
-  return TRUE;
+  return gui_status ();
 }
 
 void
-gui_draw_pixmap (gint which, gint x, gint y)
+gui_status (void)
 {
-  gdk_draw_drawable (drawing_area->window, gridGC[0], tiles_pixmap,
-		     (which % 8) * TILEWIDTH, (which / 8) * TILEHEIGHT,
-		     x * (TILEWIDTH + GRIDWIDTH),
-		     y * (TILEHEIGHT + GRIDWIDTH), TILEWIDTH, TILEHEIGHT);
-  gdk_draw_drawable (buffer_pixmap, gridGC[0], tiles_pixmap,
-		     (which % 8) * TILEWIDTH, (which / 8) * TILEHEIGHT,
-		     x * (TILEWIDTH + GRIDWIDTH),
-		     y * (TILEHEIGHT + GRIDWIDTH), TILEWIDTH, TILEHEIGHT);
+  gchar message[5];
+
+  sprintf (message, "%.2d", (int) black_score);
+  gtk_label_set_text (GTK_LABEL (score[0]), message);
+  sprintf (message, "%.2d", (int) white_score);
+  gtk_label_set_text (GTK_LABEL (score[1]), message);
 }
 
 void
-gui_draw_pixmap_buffer (gint which, gint x, gint y)
+gui_message (gchar *message)
 {
-  gdk_draw_drawable (buffer_pixmap, gridGC[0], tiles_pixmap,
-		     (which % 8) * TILEWIDTH, (which / 8) * TILEHEIGHT,
-		     x * (TILEWIDTH + GRIDWIDTH),
-		     y * (TILEHEIGHT + GRIDWIDTH), TILEWIDTH, TILEHEIGHT);
+  if (context_id)
+    gtk_statusbar_pop (GTK_STATUSBAR (statusbar), context_id);
+
+  context_id =
+    gtk_statusbar_get_context_id (GTK_STATUSBAR (statusbar), message);
+  gtk_statusbar_push (GTK_STATUSBAR (statusbar), context_id, message);
 }
 
-void
-gui_draw_grid (void)
+static gboolean
+t_computer_move (void)
 {
-  int i;
+  flags ^= COMPUTER_MOVE;
 
-  for (i = 1; i < 8; i++) {
-    gdk_draw_line (buffer_pixmap, gridGC[grid],
-		   i * BOARDWIDTH / 8 - 1, 0,
-		   i * BOARDWIDTH / 8 - 1, BOARDHEIGHT);
-    gdk_draw_line (buffer_pixmap, gridGC[grid],
-		   0, i * BOARDHEIGHT / 8 - 1,
-		   BOARDWIDTH, i * BOARDHEIGHT / 8 - 1);
-  }
+  move (computer_move (computer_level[PLAYER2SEAT (whose_turn)] * 2 - 1));
 
-  gdk_draw_drawable (drawing_area->window, gridGC[0], buffer_pixmap,
-		     0, 0, 0, 0, BOARDWIDTH, BOARDHEIGHT);
+  return TRUE;
 }
 
-void
-load_pixmaps (void)
+static gboolean
+check_computer_players  (void)
 {
-  GdkPixbuf *image;
-  GError *error = NULL;
-  gchar *tmp;
-  gchar *fname;
+  flags ^= CHECK_COMPUTER_PLAYERS;
 
-  g_return_if_fail (tile_set != NULL && tile_set[0] != '0');
+  if (!game_in_progress)
+    return TRUE;
 
-  tmp = g_build_filename ("iagno", tile_set, NULL);
-  fname = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_APP_PIXMAP,
-				     tmp, FALSE, NULL);
-  g_free (tmp);
+  if (!computer_level[PLAYER2SEAT (whose_turn)])
+    return TRUE;
 
-  if (!g_file_test (fname, G_FILE_TEST_EXISTS)) {
-    g_free (fname);
-    fname = gnome_program_locate_file (NULL,
-				       GNOME_FILE_DOMAIN_APP_PIXMAP,
-				       "iagno/classic.png", FALSE, NULL);
-  }
-
-  if (!g_file_test (fname, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
-    g_print (_("Could not find \'%s\' pixmap file\n"), fname);
-    exit (1);
-  }
-
-  image = gdk_pixbuf_new_from_file (fname, &error);
-  if (error) {
-    g_warning (G_STRLOC ": gdk-pixbuf error %s\n", error->message);
-    g_error_free (error);
-    error = NULL;
-  }
-
-  gdk_pixbuf_render_pixmap_and_mask_for_colormap (image,
-						  gdk_colormap_get_system (),
-						  &tiles_pixmap,
-						  &tiles_mask, 127);
-
-  gdk_pixbuf_unref (image);
-  g_free (fname);
+  gui_message (_("Now thinking."));
+  flags |= COMPUTER_MOVE;
+  return TRUE;
 }
 
-gint
-flip_pixmaps (gpointer data)
+static gboolean
+flip_pixmaps (void)
 {
-  guint i, j;
-  guint flipped_tiles = 0;
+  gint i, j, which;
 
-  if (!tiles_to_flip)
-    return TRUE;
+  flags ^= FLIP_PIXMAPS;
 
   for (i = 0; i < 8; i++)
     for (j = 0; j < 8; j++) {
-      /* This first case only happens when undoing the "final flip". */
-      if ((pixmaps[i][j] == 101) && (board[i][j] != 0)) {
+      if (pixmaps[i][j] == board[i][j])
+	continue;
+
+      if (pixmaps[i][j] < -BLANK && board[i][j] > BLANK)
+	pixmaps[i][j] *= -1;
+      if (pixmaps[i][j] < board[i][j] && pixmaps[i][j] > BLANK)
+	pixmaps[i][j]++;
+      else if (pixmaps[i][j] > board[i][j] && board[i][j] > BLANK)
+	pixmaps[i][j]--;
+      else
 	pixmaps[i][j] = board[i][j];
-	gui_draw_pixmap (pixmaps[i][j], i, j);
-	flipped_tiles = 1;
-      } else if ((pixmaps[i][j] == 100)
-		 || ((pixmaps[i][j] != 101) && (board[i][j] == 0))) {
-	pixmaps[i][j] = 101;
-	gui_draw_pixmap (0, i, j);
-	flipped_tiles = 1;
-      } else if (pixmaps[i][j] < board[i][j]) {
-	if (animate == 0) {
-	  if (pixmaps[i][j] == BLACK_TURN)
-	    pixmaps[i][j] = board[i][j];
-	  else
-	    pixmaps[i][j]++;
-	} else if (animate == 1) {
-	  if (pixmaps[i][j] < 1)
-	    pixmaps[i][j] += 2;
-	  else if (pixmaps[i][j] >= 1 && pixmaps[i][j] < 8)
-	    pixmaps[i][j] = 8;
-	  else if (pixmaps[i][j] >= 8 && pixmaps[i][j] < 16)
-	    pixmaps[i][j] = 16;
-	  else if (pixmaps[i][j] >= 16 && pixmaps[i][j] < 23)
-	    pixmaps[i][j] = 23;
-	  else if (pixmaps[i][j] >= 23 && pixmaps[i][j] < 31)
-	    pixmaps[i][j] = 31;
-	  else if (pixmaps[i][j] > 31)
-	    pixmaps[i][j] = 31;
-	} else if (animate == 2)
-	  pixmaps[i][j]++;
-	if (pixmaps[i][j] > 0)
-	  gui_draw_pixmap (pixmaps[i][j], i, j);
-	flipped_tiles = 1;
-      } else if (pixmaps[i][j] > board[i][j] && pixmaps[i][j] != 101) {
-	if (animate == 0) {
-	  if (pixmaps[i][j] == WHITE_TURN)
-	    pixmaps[i][j] = board[i][j];
-	  else
-	    pixmaps[i][j]--;
-	} else if (animate == 1) {
-	  if (pixmaps[i][j] > 31)
-	    pixmaps[i][j] -= 2;
-	  else if (pixmaps[i][j] <= 31 && pixmaps[i][j] > 23)
-	    pixmaps[i][j] = 23;
-	  else if (pixmaps[i][j] <= 23 && pixmaps[i][j] > 16)
-	    pixmaps[i][j] = 16;
-	  else if (pixmaps[i][j] <= 16 && pixmaps[i][j] > 8)
-	    pixmaps[i][j] = 8;
-	  else if (pixmaps[i][j] <= 8 && pixmaps[i][j] > 1)
-	    pixmaps[i][j] = 1;
-	  else if (pixmaps[i][j] < 1)
-	    pixmaps[i][j] = 1;
-	} else if (animate == 2)
-	  pixmaps[i][j]--;
-	if (pixmaps[i][j] < 32)
-	  gui_draw_pixmap (pixmaps[i][j], i, j);
-	flipped_tiles = 1;
-      }
-    }
 
-  if (!flipped_tiles)
-    tiles_to_flip = 0;
+      which = pixmaps[i][j];
+      if (which == BLANK)
+	which = 0;
+      else
+	which = clamp_int (which, BLACK, WHITE) - BLACK + 1;
+      gui_draw_pixmap (which, j, i);
 
+      flags |= FLIP_PIXMAPS;
+    }
+
   return TRUE;
 }
 
-static void
-redraw_board (void)
+/**** For game ****/
+
+gboolean
+check_flags (gpointer data)
 {
-  guint i, j;
+  if (flags & FLIP_PIXMAPS)
+    return flip_pixmaps ();
+  if (flags & CHECK_COMPUTER_PLAYERS)
+    return check_computer_players ();
+  if (flags & COMPUTER_MOVE)
+    return t_computer_move ();
 
-  gui_status ();
-
-  for (i = 0; i < 8; i++)
-    for (j = 0; j < 8; j++)
-      gui_draw_pixmap_buffer (pixmaps[i][j], i, j);
-
-  gui_draw_grid ();
+  return TRUE;
 }
 
 void
-clear_board (void)
+check_game_over (void)
 {
-  guint i, j;
+  gint i;
 
-  if (flip_final_id) {
-    g_source_remove (flip_final_id);
-    flip_final_id = 0;
+  flags |= FLIP_PIXMAPS;
+  /* Continue? */
+  i = entry_valid_squares (0);
+  if (i) {
+    if (whose_turn == BLACK)
+      gui_message (_("Dark's move"));
+    else
+      gui_message (_("Light's move"));
+    return;
   }
-
-  if (black_computer_id) {
-    g_source_remove (black_computer_id);
-    black_computer_id = 0;
+  /* Pass? */
+  whose_turn = OTHER_PLAYER (whose_turn);
+  i = entry_valid_squares (0);
+  if (i) {
+    if (whose_turn == BLACK)
+      gui_message (_("Light must pass, Dark's move"));
+    else
+      gui_message (_("Dark must pass, Light's move"));
+    return;
   }
+  /* The game is over. */
+  if (black_score > white_score)
+    gui_message (_("Dark player wins!"));
+  else if (white_score > black_score)
+    gui_message (_("Light player wins!"));
+  else
+    gui_message (_("The game was a draw."));
 
-  if (white_computer_id) {
-    g_source_remove (white_computer_id);
-    white_computer_id = 0;
-  }
+  whose_turn       = 0;
+  game_in_progress = FALSE;
 
-  game_in_progress = 0;
-  move_count = 0;
-  for (i = 0; i < 8; i++)
-    for (j = 0; j < 8; j++)
-      board[i][j] = 0;
+  return;
+}
 
-  memcpy (pixmaps, board, sizeof (gint8) * 8 * 8);
+gboolean
+check_valid_move (gint who, gint yx)
+{
+  if (who != (gint) whose_turn)
+    return FALSE;
+  if (yx < 11 || yx > 88)
+    return FALSE;
+  if (board0[yx] != BLANK)
+    return FALSE;	
+  if (!check_valid (who, yx))
+    return FALSE;
 
-  bcount = 0;
-  wcount = 0;
-
-  redraw_board ();
+  return TRUE;
 }
 
 void
-init_new_game (void)
+move (gint yx)
 {
-  clear_board ();
-  game_in_progress = 1;
-  move_count = 4;
+  if (game_in_progress) {
+    kifu[move_count].who     = whose_turn;
+    kifu[move_count].yx      = (gint8) yx;
+    kifu[move_count + 1].who = 0;
+  }
 
-  undo_set_sensitive (FALSE);
-
-  board[3][3] = WHITE_TURN;
-  board[3][4] = BLACK_TURN;
-  board[4][3] = BLACK_TURN;
-  board[4][4] = WHITE_TURN;
-
-  bcount = 2;
-  wcount = 2;
-  init ();
-
-  memcpy (pixmaps, board, sizeof (gint8) * 8 * 8);
-
-  redraw_board ();
-
-  whose_turn = BLACK_TURN;
+  move_board (yx);
+  copy_board ();
   gui_status ();
-  gtk_widget_show (mainmenu[0].widget);
-  gtk_widget_show (mainmenu[1].widget);
+  check_game_over ();
+  if (!game_in_progress)
+    return;
 
-  check_computer_players ();
+  flags |= CHECK_COMPUTER_PLAYERS;
 }
 
 void
-create_window (void)
+stop_game (void)
 {
-  GtkWidget *table;
+  flags = 0;
+  if (!game_in_progress)
+    return;
 
-  window = gnome_app_new ("iagno", _(APP_NAME_LONG));
+  game_in_progress = FALSE;
+}
 
-  games_conf_add_window (GTK_WINDOW (window), NULL);
-
-  notebook = gtk_notebook_new ();
-  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
-
-  gtk_widget_realize (window);
-  gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
-  g_signal_connect (G_OBJECT (window), "delete_event",
-		    G_CALLBACK (quit_game_cb), NULL);
-
-  gnome_app_create_menus (GNOME_APP (window), mainmenu);
-
-  drawing_area = gtk_drawing_area_new ();
-
-  gtk_widget_pop_colormap ();
-
-  gnome_app_set_contents (GNOME_APP (window), notebook);
-  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), drawing_area, NULL);
-  gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), MAIN_PAGE);
-
-  gtk_widget_set_size_request (GTK_WIDGET (drawing_area),
-			       BOARDWIDTH, BOARDHEIGHT);
-  g_signal_connect (G_OBJECT (drawing_area), "expose_event",
-		    G_CALLBACK (expose_event), NULL);
-  g_signal_connect (G_OBJECT (window), "configure_event",
-		    G_CALLBACK (configure_event), NULL);
-  g_signal_connect (G_OBJECT (drawing_area), "button_press_event",
-		    G_CALLBACK (button_press_event), NULL);
-  gtk_widget_set_events (drawing_area,
-			 GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
-  /* We do our own double-buffering. */
-  gtk_widget_set_double_buffered (drawing_area, FALSE);
-
-  gtk_widget_show (drawing_area);
-
-  appbar = GNOME_APPBAR (gnome_appbar_new (FALSE, TRUE, FALSE));
-  gnome_app_set_statusbar (GNOME_APP (window), GTK_WIDGET (appbar));
-  gnome_app_install_menu_hints (GNOME_APP (window), mainmenu);
-
-  table = gtk_table_new (1, 8, FALSE);
-
-  black_score = gtk_label_new (_("Dark:"));
-  gtk_widget_show (black_score);
-
-  gtk_table_attach (GTK_TABLE (table), black_score, 1, 2, 0, 1, 0, 0, 3, 1);
-
-  black_score = gtk_label_new ("00");
-  gtk_widget_show (black_score);
-
-  gtk_table_attach (GTK_TABLE (table), black_score, 2, 3, 0, 1, 0, 0, 3, 1);
-
-  white_score = gtk_label_new (_("Light:"));
-  gtk_widget_show (white_score);
-
-  gtk_table_attach (GTK_TABLE (table), white_score, 4, 5, 0, 1, 0, 0, 3, 1);
-
-  white_score = gtk_label_new ("00");
-  gtk_widget_show (white_score);
-
-  gtk_table_attach (GTK_TABLE (table), white_score, 5, 6, 0, 1, 0, 0, 3, 1);
-  undo_set_sensitive (FALSE);
-
-  gtk_widget_show (table);
-
-  gtk_box_pack_start (GTK_BOX (appbar), table, FALSE, TRUE, 0);
-
-  gnome_appbar_set_status (GNOME_APPBAR (appbar), _("Welcome to Iagno!"));
+void
+init_game (void)
+{
+  stop_game ();
+  init ();
+  copy_board ();
+  kifu[move_count].who = 0;
+  redraw_board ();
 }
 
 void
-gui_status (void)
+start_game (void)
 {
-  gchar message[3];
+  if (game_in_progress)
+    return;
+  check_game_over ();
+  if (!whose_turn)
+    return;
 
-  sprintf (message, _("%.2d"), bcount);
-  gtk_label_set_text (GTK_LABEL (black_score), message);
-  sprintf (message, _("%.2d"), wcount);
-  gtk_label_set_text (GTK_LABEL (white_score), message);
-  undo_set_sensitive (move_count > 0);
+  kifu[move_count].who = 0;
+  game_in_progress     = TRUE;
+  flags |= CHECK_COMPUTER_PLAYERS;
+}
 
-  if (ggz_network_mode) {
-    gtk_widget_hide (game_menu[0].widget);
-    gtk_widget_hide (game_menu[1].widget);
-    gtk_widget_hide (game_menu[2].widget);
-    gtk_widget_hide (game_menu[3].widget);
-    gtk_widget_show (game_menu[4].widget);
-    gtk_widget_show (game_menu[5].widget);
-    gtk_widget_show (game_menu[7].widget);
-  } else {
-    gtk_widget_show (game_menu[0].widget);
-    gtk_widget_show (game_menu[1].widget);
-    gtk_widget_show (game_menu[2].widget);
-    gtk_widget_show (game_menu[3].widget);
-    gtk_widget_hide (game_menu[4].widget);
-    gtk_widget_hide (game_menu[5].widget);
-    gtk_widget_hide (game_menu[7].widget);
-  }
+/****  Callbacks  ****/
 
-  gtk_widget_set_sensitive (settings_menu[0].widget, !ggz_network_mode);
+static void
+on_newgame_activate (GtkMenuItem *menuitem, gpointer user_data)
+{
 
-#ifndef GGZ_CLIENT
-  gtk_widget_set_sensitive (game_menu[1].widget, FALSE);
-#endif
+  init_game ();
+  start_game ();
+}
 
-  if (ggz_network_mode) {
-    if (whose_turn == player_id && whose_turn == BLACK_TURN) {
-      gui_message (_("It is your turn to place a dark piece"));
-    } else if (whose_turn == player_id && whose_turn == WHITE_TURN) {
-      gui_message (_("It is your turn to place a light piece"));
-    } else {
-      gchar *str;
-      str = g_strdup_printf (_("Waiting for %s to move"),
-			     names[(seat + 1) % 2]);
-      gui_message (str);
-      g_free (str);
-    }
-  } else {
-    if (whose_turn == BLACK_TURN) {
-      gui_message (_("Dark's move"));
-    } else if (whose_turn == WHITE_TURN) {
-      gui_message (_("Light's move"));
-    }
+static void
+on_quit_activate (GtkMenuItem *menuitem, gpointer user_data)
+{
+  // For flip_pixmaps dosn't draw drawing_area after destroy window.
+  g_source_remove (check_flags_id);
+  gtk_window_get_position (GTK_WINDOW (window), &session_xpos, &session_ypos);
+  save_properties ();
+  gtk_main_quit ();
+}
 
-  }
-
-
+static void
+on_help_activate (GtkMenuItem *menuitem, gpointer user_data)
+{
+  gnome_help_display ("iagno.xml", NULL, NULL);
 }
 
-void
-gui_message (gchar * message)
+static void
+on_about_activate (GtkMenuItem *menuitem, gpointer user_data)
 {
-  gnome_appbar_pop (GNOME_APPBAR (appbar));
-  gnome_appbar_push (GNOME_APPBAR (appbar), message);
+  const gchar *authors[] = { "Ian Peters", NULL };
+  const gchar *documenters[] = { "Eric Baudais", NULL };
+  gchar *license = games_get_license (_(APP_NAME_LONG));
+
+  gtk_show_about_dialog (GTK_WINDOW (window),
+			 "name", _(APP_NAME_LONG),
+			 "version", VERSION,
+			 "copyright",
+			 "Copyright \xc2\xa9 1998-2007 Ian Peters",
+			 "license", license,
+			 "comments",
+			 _("A disk flipping game derived from Reversi."),
+			 "authors", authors, "documenters", documenters,
+			 "translator-credits", _("translator-credits"),
+			 "logo-icon-name", "gnome-iagno", "website",
+			 "http://www.gnome.org/projects/gnome-games/",
+			 "wrap-license", TRUE, NULL);
+  g_free (license);
 }
 
-guint
-check_computer_players (void)
+static gboolean
+check_event_move (gint x, gint y)
 {
+  gint yx = y * 10 + x;
 
-  if (ggz_network_mode) {
-    black_computer_id = 0;
-    white_computer_id = 0;
-    return TRUE;
+  if (!check_valid_move ((gint) whose_turn, yx)) {
+    gui_message (_("Invalid move."));
+    return FALSE;
   }
-  if (black_computer_level && whose_turn == BLACK_TURN)
-    switch (black_computer_level) {
-    case 1:
-      black_computer_id =
-	g_timeout_add (computer_speed, (GSourceFunc) computer_move_1,
-		       (gpointer) BLACK_TURN);
-      break;
-    case 2:
-      black_computer_id =
-	g_timeout_add (computer_speed, (GSourceFunc) computer_move_2,
-		       (gpointer) BLACK_TURN);
-      break;
-    case 3:
-      black_computer_id =
-	g_timeout_add (computer_speed, (GSourceFunc) computer_move_3,
-		       (gpointer) BLACK_TURN);
-      break;
-    }
 
-  if (white_computer_level && whose_turn == WHITE_TURN)
-    switch (white_computer_level) {
-    case 1:
-      white_computer_id =
-	g_timeout_add (computer_speed, (GSourceFunc) computer_move_1,
-		       (gpointer) WHITE_TURN);
-      break;
-    case 2:
-      white_computer_id =
-	g_timeout_add (computer_speed, (GSourceFunc) computer_move_2,
-		       (gpointer) WHITE_TURN);
-      break;
-    case 3:
-      white_computer_id =
-	g_timeout_add (computer_speed, (GSourceFunc) computer_move_3,
-		       (gpointer) WHITE_TURN);
-      break;
-    }
-
-  return TRUE;
+  if (!game_in_progress)
+    start_game ();
+  move (yx);
+  return FALSE;
 }
 
-void
-set_bg_color (void)
+static gboolean
+on_drawing_area_button_press_event (GtkWidget *widget, GdkEventButton *event,
+				    gpointer user_data)
 {
-  GdkImage *tmpimage;
-  GdkColor bgcolor;
+  if (event->button != 1)	/* The left mouse button was pressed. */
+    return FALSE;
 
-  tmpimage = gdk_drawable_get_image (tiles_pixmap, 0, 0, 1, 1);
-  bgcolor.pixel = gdk_image_get_pixel (tmpimage, 0, 0);
-  gdk_window_set_background (drawing_area->window, &bgcolor);
+  return check_event_move (event->x / (tile_width  + GRID_WIDTH) + 1,
+			   event->y / (tile_height + GRID_WIDTH) + 1);
+}
 
-  if (gridGC[0])
-    g_object_unref (gridGC[0]);
-  gridGC[0] = gdk_gc_new (drawing_area->window);
-  if (gridGC[1])
-    g_object_unref (gridGC[1]);
-  gridGC[1] = gdk_gc_new (drawing_area->window);
+static gboolean
+on_drawing_area_expose_event (GtkWidget *widget, GdkEventExpose *event,
+			      gpointer user_data)
+{
+  gdk_draw_drawable (drawing_area->window, gridGC[0], buffer_pixmap,
+		     event->area.x, event->area.y,
+		     event->area.x, event->area.y,
+		     event->area.width, event->area.height);
+  return FALSE;
+}
 
-  gdk_gc_copy (gridGC[0], drawing_area->style->bg_gc[0]);
-  gdk_gc_copy (gridGC[1], drawing_area->style->bg_gc[0]);
+static gboolean
+on_drawing_area_configure_event (GtkWidget *widget, GdkEventConfigure *event,
+				 gpointer user_data)
+{
+  board_width  = event->width;
+  board_height = event->height;
 
-  gdk_gc_set_background (gridGC[0], &bgcolor);
-  gdk_gc_set_foreground (gridGC[0], &bgcolor);
+/* configure board */
+  set_board_size ();
+  return FALSE;
+}
 
-  /* Create a complementary color to use for the ON state */
-  bgcolor.pixel = 0xFFFFFF - bgcolor.pixel;
-  gdk_gc_set_background (gridGC[1], &bgcolor);
-  gdk_gc_set_foreground (gridGC[1], &bgcolor);
+/**** Main window ****/
 
-  gdk_gc_set_line_attributes (gridGC[1], 0,
-			      GDK_LINE_ON_OFF_DASH,
-			      GDK_CAP_BUTT, GDK_JOIN_MITER);
+static const char manager_definition[] = {
+    "<ui>"
+    "  <menubar name='MenuBar'>"
+    "    <menu name='GameMenu' action='game_menu'>"
+    "      <menuitem action='newgame'/>"
+    "      <menuitem action='quit'/>"
+    "    </menu>"
+    "    <menu name='SettingsMenu' action='settings_menu'>"
+    "      <menuitem action='preferences'/>"
+    "    </menu>"
+    "    <menu name='HelpMenu' action='help_menu'>"
+    "      <menuitem action='help'/>"
+    "      <menuitem action='about'/>"
+    "    </menu>"
+    "  </menubar>"
+    "</ui>"
+};
 
-  g_object_unref (tmpimage);
-}
+static GtkActionEntry action_entries[] = {
+  {"game_menu", NULL, N_("_Game")},
+  {"newgame", GAMES_STOCK_NEW_GAME, NULL, NULL,
+   N_("Start a new game"),
+   G_CALLBACK (on_newgame_activate)},
+  {"quit", GTK_STOCK_QUIT, NULL, NULL,
+   N_("Quit this game"),
+   G_CALLBACK (on_quit_activate)},
+  {"settings_menu", NULL, N_("_Settings")},
+  {"preferences", GTK_STOCK_PREFERENCES, NULL, NULL,
+   NULL,
+   G_CALLBACK (on_preferences_activate)},
+  {"help_menu", NULL, N_("_Help")},
+  {"help", GAMES_STOCK_CONTENTS, NULL, NULL,
+   NULL,
+   G_CALLBACK (on_help_activate)},
+  {"about", GTK_STOCK_ABOUT, NULL, NULL,
+   NULL,
+   G_CALLBACK (on_about_activate)}
+};
 
-static int
-save_state (GnomeClient * client, gint phase, GnomeRestartStyle save_style,
-	    gint shutdown, GnomeInteractStyle interact_style,
-	    gint fast, gpointer client_data)
+static GtkWidget *
+create_window (void)
 {
-  char *argv[20];
-  int i;
-  gint xpos, ypos;
+  const gchar *strs[] = {
+    _("Dark:"),			/* 0 */
+    _("Light:"),		/* 1 */
+    _("00"),			/* 2 */
+    _("00:00"),			/* 3 */
+  };
 
-  gdk_window_get_origin (window->window, &xpos, &ypos);
+  GtkWidget *window;
+  GtkWidget *vbox;
+  GtkWidget *table;
+  GtkWidget *label;
+  GError *error = NULL;
+  gchar name[2] = { 0, 0 };
+  gchar *markup;
+  gint i;
 
-  i = 0;
-  argv[i++] = (char *) client_data;
-  argv[i++] = "-x";
-  argv[i++] = g_strdup_printf ("%d", xpos);
-  argv[i++] = "-y";
-  argv[i++] = g_strdup_printf ("%d", ypos);
+/**** Main window ****/
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), APP_NAME_LONG);
+  gtk_window_set_default_size (GTK_WINDOW (window),
+			       window_width, window_height);
+  games_conf_add_window (GTK_WINDOW (window), NULL);
+  g_signal_connect (G_OBJECT (window), "delete_event",
+		    G_CALLBACK (on_quit_activate), NULL);
+/**** UI manager ****/
+  manager = gtk_ui_manager_new ();
+  gtk_ui_manager_add_ui_from_string (manager, manager_definition, -1, &error);
+  action_group = gtk_action_group_new ("ActionGroup");
+  gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
+  gtk_action_group_add_actions (action_group, action_entries,
+				G_N_ELEMENTS (action_entries), window);
+  gtk_ui_manager_insert_action_group (manager, action_group, 0);
+  gtk_window_add_accel_group (GTK_WINDOW (window),
+			      gtk_ui_manager_get_accel_group (manager));
+/**** Notebook ****/
+  notebook = gtk_notebook_new ();
+  gtk_container_add (GTK_CONTAINER (window), notebook);
+  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
+  vbox = gtk_vbox_new (FALSE, 0);
+  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, NULL);
+/**** Menubar ****/
+  menubar = gtk_ui_manager_get_widget (manager, "/MenuBar");
+  gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
 
-  gnome_client_set_restart_command (client, i, argv);
-  gnome_client_set_clone_command (client, 0, NULL);
-
-  g_free (argv[2]);
-  g_free (argv[4]);
-
-  return TRUE;
+  table = gtk_table_new (9, 9, FALSE);
+  gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
+/**** Label. A,B,C.. ****/
+  for (i = 1; i < 9; i++) {
+    name[0] = (gchar) (0x40 + i);
+    label = gtk_label_new (name);
+    gtk_table_attach (GTK_TABLE (table), label, i, i + 1, 0, 1,
+		      (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0, 0);
+    gtk_widget_set_size_request (label, -1, 19);
+    markup =
+      g_markup_printf_escaped ("<span foreground=\"red\">%s</span>", name);
+    gtk_label_set_markup_with_mnemonic ((GtkLabel *) label, markup);
+    g_free (markup);
+  }
+/**** Label. 1,2,3.. ****/
+  for (i = 1; i < 9; i++) {
+    name[0] = (gchar) (0x30 + i);
+    label = gtk_label_new (name);
+    gtk_table_attach (GTK_TABLE (table), label, 0, 1, i, i + 1,
+		      0, (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+    gtk_widget_set_size_request (label, 19, -1);
+    markup =
+      g_markup_printf_escaped ("<span foreground=\"red\">%s</span>", name);
+    gtk_label_set_markup_with_mnemonic ((GtkLabel *) label, markup);
+    g_free (markup);
+  }
+/**** Drawing area ****/
+  drawing_area = gtk_drawing_area_new ();
+  gtk_widget_set_double_buffered (drawing_area, FALSE);
+  gtk_widget_set_size_request (drawing_area, BOARD_MIN, BOARD_MIN);
+  gtk_table_attach (GTK_TABLE (table), drawing_area, 1, 9, 1, 9,
+		    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+		    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+  gtk_widget_set_events (drawing_area,
+			 GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
+  g_signal_connect ((gpointer) drawing_area, "expose_event",
+		    G_CALLBACK (on_drawing_area_expose_event), NULL);
+  g_signal_connect ((gpointer) drawing_area, "button_press_event",
+		    G_CALLBACK (on_drawing_area_button_press_event), NULL);
+  g_signal_connect ((gpointer) drawing_area, "configure_event",
+		    G_CALLBACK (on_drawing_area_configure_event), NULL);
+/**** Statusbar ****/
+  statusbar = gtk_statusbar_new ();
+  gtk_box_pack_start (GTK_BOX (vbox), statusbar, FALSE, FALSE, 0);
+  gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbar), FALSE);
+/**** Scores ****/
+  table = gtk_table_new (1, 4, FALSE);
+  gtk_box_pack_start (GTK_BOX (statusbar), table, FALSE, TRUE, 0);
+  for (i = 0; i < 2; i++) {
+    label = gtk_label_new (strs[i]);
+    gtk_table_attach (GTK_TABLE (table), label, i * 2, i * 2 + 1, 0, 1,
+		      (GtkAttachOptions) (GTK_FILL),
+		      (GtkAttachOptions) (GTK_FILL), 5, 0);
+    markup =
+     g_markup_printf_escaped ("<span foreground=\"blue\">%s</span>", strs[i]);
+    gtk_label_set_markup_with_mnemonic ((GtkLabel *) label, markup);
+    g_free (markup);
+    score[i] = gtk_label_new (strs[1]);
+    gtk_table_attach (GTK_TABLE (table), score[i], i * 2 + 1, i * 2 + 2, 0, 1,
+		      (GtkAttachOptions) (GTK_FILL),
+		      (GtkAttachOptions) (GTK_FILL), 5, 0);
+  }
+/******************/
+  gtk_widget_show_all (window);
+  return window;
 }
 
+/**** Main ****/
 int
 main (int argc, char **argv)
 {
-  GnomeClient *client;
   GnomeProgram *program;
   GOptionContext *context;
 
@@ -882,53 +760,32 @@
 
   context = g_option_context_new (NULL);
   g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
-  games_sound_add_option_group (context);
 
-  program = gnome_program_init ("iagno", VERSION,
+  program = gnome_program_init (APP_NAME, VERSION,
 				LIBGNOMEUI_MODULE,
 				argc, argv,
 				GNOME_PARAM_GOPTION_CONTEXT, context,
 				GNOME_PARAM_APP_DATADIR, DATADIR, NULL);
 
+  games_stock_init ();
   gtk_window_set_default_icon_name ("gnome-iagno");
-
   games_conf_initialise (APP_NAME);
 
-  client = gnome_master_client ();
-
-  g_signal_connect (G_OBJECT (client), "save_yourself",
-		    G_CALLBACK (save_state), argv[0]);
-  g_signal_connect (G_OBJECT (client), "die",
-		    G_CALLBACK (quit_game_cb), argv[0]);
-
-  create_window ();
-
+  init ();
+  copy_board ();
   load_properties ();
+  window = create_window ();
+  if (session_xpos > 0 && session_ypos > 0)
+    gtk_window_move (GTK_WINDOW (window), session_xpos, session_ypos);
+  reset_properties ();
+  apply_changes ();
 
-  load_pixmaps ();
-
-  gtk_widget_show (window);
-
-#ifdef GGZ_CLIENT
-  network_init ();
-#endif
-
-  if (session_xpos >= 0 && session_ypos >= 0) {
-    gdk_window_move (window->window, session_xpos, session_ypos);
-  }
-
-  buffer_pixmap = gdk_pixmap_new (drawing_area->window,
-				  BOARDWIDTH, BOARDHEIGHT, -1);
-
-  set_bg_color ();
-
-  init_new_game ();
-
+  init_game ();
+  start_game ();
+  gui_message (_("Welcome to Iagno!"));
   gtk_main ();
 
   games_conf_shutdown ();
-
   g_object_unref (program);
-
   return 0;
 }
Index: iagno/properties.c
===================================================================
--- iagno/properties.c	(リビジョン 6931)
+++ iagno/properties.c	(作業コピー)
@@ -15,607 +15,328 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307,
+ * USA
  *
  * For more details see the file COPYING.
  */
 
-#include <config.h>
 #include <gnome.h>
-#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <config.h>
 #include <games-conf.h>
-#include <games-frame.h>
-#include <games-files.h>
 #include <games-sound.h>
+#include <games-files.h>
+#include <games-frame.h>
 
-#include "properties.h"
-#include "gnothello.h"
 #include "othello.h"
+#include "gnothello.h"
+#include "properties.h"
 
-#define KEY_TILESET             "tileset"
-#define KEY_BLACK_LEVEL         "black_level"
-#define KEY_WHITE_LEVEL         "white_level"
-#define KEY_QUICK_MOVES         "quick_moves"
-#define KEY_ANIMATE             "animate"
-#define KEY_ANIMATE_STAGGER     "animate_stagger"
-#define KEY_SHOW_GRID           "show_grid"
-#define KEY_FLIP_FINAL_RESULTS "flip_final_results"
-#define KEY_SOUND               "sound"
+#define MAX_OPTIONS		1
 
-#define DEFAULT_TILESET "classic.png"
+static const gchar *keys[] = {
+  "fullscreen",		/* 0 */
+  "width",		/* 1 */
+  "height",		/* 2 */
+  "x_position",		/* 3 */
+  "y_position",		/* 4 */
+  "black_level",	/* 5 */
+  "white_level",	/* 6 */
+  "tileset",		/* 7 */
+  "bg_color_name",	/* 8 */
+  "quick_moves",	/* 9 */
+};
 
+static const gchar *tiles_name[] = {
+  N_("disk"),
+  N_("marble"),
+  N_("sun and star")
+};
 
-extern GtkWidget *window;
-extern guint black_computer_level;
-extern guint white_computer_level;
-extern guint computer_speed;
-extern guint black_computer_id;
-extern guint white_computer_id;
-extern gchar *tile_set;
-extern gchar *tile_set_tmp;
-extern gint8 pixmaps[8][8];
-extern gint animate;
-extern gint animate_stagger;
-extern gint flip_pixmaps_id;
-extern gint flip_final;
-extern gint grid;
-gint sound;
+static const gchar *tiles_svg[] = {
+  "disk.svg",
+  "marble.svg",
+  "sun_and_star.svg"
+};
 
-guint t_black_computer_level;
-guint t_white_computer_level;
-gint t_animate;
-gint t_quick_moves;
-gint t_animate_stagger;
-gint t_flip_final;
-gint t_grid;
+static gint      t_computer_level[2];
+static gint      t_tile_set = 0;
+static gchar     *t_bg_color_name;
+static gboolean  t_options[MAX_OPTIONS];
+static gboolean  _quick_moves;
 
-static GamesFileList *theme_file_list = NULL;
+GtkWidget        *properties_dialog = NULL;
+gint             window_width;
+gint             window_height;
+gint             computer_level[2];
+gchar            *tile_set;
+gchar            *bg_color_name;
+guint            check_flags_id = 0;
+guint            flip_delay;
 
-static void apply_changes (void);
+extern GtkWidget *window;
+extern GtkWidget *drawing_area;
+extern GdkColor  bg_color[];
+extern kifu_t    kifu[];
+extern guint     flags;
+extern int       session_xpos;
+extern int       session_ypos;
 
-/*
- * FIXME:
- *	It doesn't abide by the HIG.
- */
 
-static gint
-clamp_int (gint input, gint low, gint high)
+void
+load_properties (void)
 {
-  if (input < low)
-    input = low;
-  if (input > high)
-    input = high;
+  window_width       = games_conf_get_integer_with_default (NULL, keys[1],
+							    WINDOW_W_DEFAULT);
+  window_height      = games_conf_get_integer_with_default (NULL, keys[2],
+							    WINDOW_H_DEFAULT);
+  session_xpos       = games_conf_get_integer (NULL, keys[3], NULL);
+  session_ypos       = games_conf_get_integer (NULL, keys[4], NULL);
+  computer_level[0]  = games_conf_get_integer (NULL, keys[5], NULL);
+  computer_level[1]  = games_conf_get_integer (NULL, keys[6], NULL);
+  tile_set           = games_conf_get_string_with_default (NULL, keys[7],
+						 	   DEFAULT_TILESET);
+  bg_color_name      = games_conf_get_string_with_default (NULL, keys[8],
+						      	   DEFAULT_BGCOLOR);
+  _quick_moves       = games_conf_get_boolean (NULL, keys[9],  NULL);
 
-  return input;
+  computer_level[0]  = clamp_int (computer_level[0], 0, 4);
+  computer_level[1]  = clamp_int (computer_level[1], 0, 4);
 }
 
 void
-load_properties (void)
+save_properties (void)
 {
-  black_computer_level = games_conf_get_integer (NULL, KEY_BLACK_LEVEL, NULL);
-  black_computer_level = clamp_int (black_computer_level, 0, 3);
-
-  white_computer_level = games_conf_get_integer (NULL, KEY_WHITE_LEVEL, NULL);
-  white_computer_level = clamp_int (white_computer_level, 0, 3);
-
-  if (games_conf_get_boolean (NULL, KEY_QUICK_MOVES, NULL))
-    computer_speed = COMPUTER_MOVE_DELAY / 2;
-  else
-    computer_speed = COMPUTER_MOVE_DELAY;
-
-  if (tile_set)
-    g_free (tile_set);
-
-  tile_set = games_conf_get_string_with_default (NULL, KEY_TILESET, DEFAULT_TILESET);
-
-  animate = games_conf_get_integer (NULL, KEY_ANIMATE, NULL);
-  animate = clamp_int (animate, 0, 2);
-
-  animate_stagger = games_conf_get_boolean (NULL, KEY_ANIMATE_STAGGER, NULL);
-
-  sound = games_conf_get_boolean (NULL, KEY_SOUND, NULL);
-  games_sound_enable (sound);
-
-  grid = games_conf_get_boolean (NULL, KEY_SHOW_GRID, NULL);
-
-  flip_final = games_conf_get_boolean (NULL, KEY_FLIP_FINAL_RESULTS, NULL);
-
-  switch (animate) {
-  case 0:
-    flip_pixmaps_id = g_timeout_add (100, flip_pixmaps, NULL);
-    break;
-  case 1:
-    flip_pixmaps_id =
-      g_timeout_add (PIXMAP_FLIP_DELAY * 8, flip_pixmaps, NULL);
-    break;
-  default:
-  case 2:
-    flip_pixmaps_id = g_timeout_add (PIXMAP_FLIP_DELAY, flip_pixmaps, NULL);
-    break;
-  }
+  games_conf_set_integer (NULL, keys[1],  window_width);
+  games_conf_set_integer (NULL, keys[2],  window_height);
+  games_conf_set_integer (NULL, keys[3],  session_xpos);
+  games_conf_set_integer (NULL, keys[4],  session_ypos);
+  games_conf_set_integer (NULL, keys[5],  computer_level[0]);
+  games_conf_set_integer (NULL, keys[6],  computer_level[1]);
+  games_conf_set_string  (NULL, keys[7],  tile_set);
+  games_conf_set_string  (NULL, keys[8],  bg_color_name);
+  games_conf_set_boolean (NULL, keys[9],  _quick_moves);
 }
 
-static void
+void
 reset_properties (void)
 {
-  black_computer_level = games_conf_get_integer (NULL, KEY_BLACK_LEVEL, NULL);
-  black_computer_level = clamp_int (black_computer_level, 0, 3);
+  t_computer_level[0] = computer_level[0];
+  t_computer_level[1] = computer_level[1];
+  t_bg_color_name     = g_strdup (bg_color_name);
+  t_options[0]        = _quick_moves;
+  while (t_tile_set < 2 && strcmp (tile_set, tiles_svg[t_tile_set]))
+    t_tile_set++;
+  gdk_color_parse (bg_color_name, &bg_color[2]);
+  gdk_colormap_alloc_color (gtk_widget_get_colormap (drawing_area),
+			    &bg_color[2], FALSE, TRUE);
+}
 
-  white_computer_level = games_conf_get_integer (NULL, KEY_WHITE_LEVEL, NULL);
-  white_computer_level = clamp_int (white_computer_level, 0, 3);
-      
-  t_black_computer_level = black_computer_level;
-  t_white_computer_level = white_computer_level;
+void
+apply_changes (void)
+{
+  flags = 0;
 
-  t_quick_moves = games_conf_get_boolean (NULL, KEY_QUICK_MOVES, NULL);
+  _quick_moves    = t_options[0];
 
-  if (tile_set_tmp)
-    g_free (tile_set_tmp);
+  flip_delay = PIXMAP_FLIP_DELAY * (_quick_moves ? 1 : 2);
+  if (check_flags_id)
+    g_source_remove (check_flags_id);
+  check_flags_id = g_timeout_add (flip_delay, (GSourceFunc)check_flags, NULL);
 
-  tile_set_tmp = games_conf_get_string_with_default (NULL, KEY_TILESET, DEFAULT_TILESET);
-
-  t_animate = animate;
-  t_animate_stagger = animate_stagger;
-  t_grid = grid;
-  t_flip_final = flip_final;
-}
-
-static void
-black_computer_level_select (GtkWidget * widget, gpointer data)
-{
-  if ((GPOINTER_TO_INT (data) != t_black_computer_level)
-      && (GTK_TOGGLE_BUTTON (widget)->active)) {
-    t_black_computer_level = GPOINTER_TO_INT (data);
-    apply_changes ();
+  if (strcmp (bg_color_name, t_bg_color_name)) {
+    g_free (bg_color_name);
+    bg_color_name = g_strdup (t_bg_color_name);
+    set_bg_color ();
   }
-}
 
-static void
-white_computer_level_select (GtkWidget * widget, gpointer data)
-{
-  if ((GPOINTER_TO_INT (data) != t_white_computer_level)
-      && (GTK_TOGGLE_BUTTON (widget)->active)) {
-    t_white_computer_level = GPOINTER_TO_INT (data);
-    apply_changes ();
+  if (strcmp (tile_set, tiles_svg[t_tile_set])) {
+    g_free (tile_set);
+    tile_set = g_strdup (tiles_svg[t_tile_set]);
+    load_pixmaps ();
   }
-}
 
-static void
-sound_select (GtkWidget * widget, gpointer data)
-{
-  sound = GTK_TOGGLE_BUTTON (widget)->active;
-  apply_changes ();
+  check_game_over ();
+  flags |= CHECK_COMPUTER_PLAYERS;
 }
 
-static void
-quick_moves_select (GtkWidget * widget, gpointer data)
-{
-  if (GTK_TOGGLE_BUTTON (widget)->active)
-    t_quick_moves = 1;
-  else
-    t_quick_moves = 0;
-  apply_changes ();
-}
+/**** Properties dialogs callbacks ****/
 
 static void
-flip_final_select (GtkWidget * widget, gpointer data)
+on_computer_level_changed (GtkToggleButton *togglebutton, gpointer user_data)
 {
-  if (GTK_TOGGLE_BUTTON (widget)->active)
-    t_flip_final = 1;
-  else
-    t_flip_final = 0;
-  apply_changes ();
+  if (togglebutton->active) {
+    t_computer_level[GPOINTER_TO_INT (user_data) / 16] =
+      GPOINTER_TO_INT (user_data) % 16;
+    stop_game ();
+    computer_level[0] = t_computer_level[0];
+    computer_level[1] = t_computer_level[1];
+    start_game ();
+  }
 }
 
 static void
-animate_stagger_select (GtkWidget * widget, gpointer data)
+on_options_toggled (GtkToggleButton *togglebutton, gpointer user_data)
 {
-  if (GTK_TOGGLE_BUTTON (widget)->active)
-    t_animate_stagger = 1;
-  else
-    t_animate_stagger = 0;
+  t_options[GPOINTER_TO_INT (user_data)] = togglebutton->active;
   apply_changes ();
 }
 
 static void
-grid_select (GtkWidget * widget, gpointer data)
+on_tile_set_box_changed (GtkComboBox *combobox, gpointer user_data)
 {
-  if (GTK_TOGGLE_BUTTON (widget)->active)
-    t_grid = 1;
-  else
-    t_grid = 0;
+  t_tile_set = gtk_combo_box_get_active (combobox);
   apply_changes ();
 }
 
 static void
-animate_select (GtkWidget * widget, gpointer data)
+on_color_button_color_set (GtkColorButton *colorbutton, gpointer user_data)
 {
-  if (GTK_TOGGLE_BUTTON (widget)->active) {
-    t_animate = GPOINTER_TO_INT (data);
-  }
+  gtk_color_button_get_color (colorbutton, &bg_color[2]);
+  g_free (t_bg_color_name);
+  t_bg_color_name = g_strdup_printf ("#%04X%04X%04X",
+				     bg_color[2].red, bg_color[2].green,
+				     bg_color[2].blue);
   apply_changes ();
 }
 
-static void
-save_properties (void)
-{
-  games_conf_set_integer (NULL, KEY_BLACK_LEVEL, black_computer_level);
-  games_conf_set_integer (NULL, KEY_WHITE_LEVEL, white_computer_level);
-
-  games_conf_set_boolean (NULL, KEY_QUICK_MOVES, t_quick_moves);
-
-  games_conf_set_string (NULL, KEY_TILESET, tile_set_tmp);
-
-  games_conf_set_integer (NULL, KEY_ANIMATE, animate);
-
-  games_conf_set_boolean (NULL, KEY_ANIMATE_STAGGER, animate_stagger);
-  games_conf_set_boolean (NULL, KEY_SHOW_GRID, grid);
-  games_conf_set_boolean (NULL, KEY_FLIP_FINAL_RESULTS, flip_final);
-  games_conf_set_boolean (NULL, KEY_SOUND, sound);
-}
-
-static void
-apply_changes (void)
-{
-  guint i, j;
-
-  black_computer_level = t_black_computer_level;
-  white_computer_level = t_white_computer_level;
-
-  if (black_computer_id) {
-    g_source_remove (black_computer_id);
-    black_computer_id = 0;
-  }
-
-  if (white_computer_id) {
-    g_source_remove (white_computer_id);
-    white_computer_id = 0;
-  }
-
-  if (t_quick_moves)
-    computer_speed = COMPUTER_MOVE_DELAY / 2;
-  else
-    computer_speed = COMPUTER_MOVE_DELAY;
-
-  if (strcmp (tile_set, tile_set_tmp)) {
-    g_free (tile_set);
-    tile_set = g_strdup (tile_set_tmp);
-    load_pixmaps ();
-    set_bg_color ();
-    for (i = 0; i < 8; i++)
-      for (j = 0; j < 8; j++)
-	if (pixmaps[i][j] >= BLACK_TURN && pixmaps[i][j] <= WHITE_TURN)
-	  gui_draw_pixmap_buffer (pixmaps[i][j], i, j);
-	else
-	  gui_draw_pixmap_buffer (0, i, j);
-    gui_draw_grid ();
-  }
-
-  animate = t_animate;
-
-  if (flip_pixmaps_id) {
-    g_source_remove (flip_pixmaps_id);
-    flip_pixmaps_id = 0;
-  }
-
-  switch (animate) {
-  case 0:
-    flip_pixmaps_id = g_timeout_add (100, flip_pixmaps, NULL);
-    break;
-  case 1:
-    flip_pixmaps_id = g_timeout_add (PIXMAP_FLIP_DELAY * 8,
-				     flip_pixmaps, NULL);
-    break;
-  case 2:
-    flip_pixmaps_id = g_timeout_add (PIXMAP_FLIP_DELAY, flip_pixmaps, NULL);
-    break;
-  }
-
-  animate_stagger = t_animate_stagger;
-
-  flip_final = t_flip_final;
-
-  if (grid != t_grid) {
-    grid = t_grid;
-    gui_draw_grid ();
-  }
-
-  games_sound_enable (sound);
-
-  check_computer_players ();
-
-  save_properties ();
-}
-
-static gboolean
-close_cb (GtkWidget * widget)
-{
-  gtk_widget_hide (widget);
-
-  return TRUE;
-}
-
 void
-set_selection (GtkWidget * widget, gpointer data)
+on_ok_clicked (GtkButton *button, gpointer user_data)
 {
-  gchar *filename;
-
-  if (tile_set_tmp)
-    g_free (tile_set_tmp);
-
-  filename = games_file_list_get_nth (theme_file_list,
-				      gtk_combo_box_get_active (GTK_COMBO_BOX
-								(widget)));
-
-  tile_set_tmp = g_strdup (filename);
-
-  apply_changes ();
+  gtk_widget_destroy (properties_dialog);
+  properties_dialog = NULL;
 }
 
-void
-free_str (GtkWidget * widget, void *data)
-{
-  g_free (data);
-}
+/**** Properties dialog *****/
 
-static GtkWidget *
-fill_menu (void)
-{
-  gchar *dname = NULL;
-
-  /* FIXME: we need to check that both dname is valid and that
-   * games_file_list_new_images returns something. */
-
-  dname = gnome_program_locate_file (NULL,
-				     GNOME_FILE_DOMAIN_APP_PIXMAP,
-				     "iagno", FALSE, NULL);
-
-  if (theme_file_list)
-    g_object_unref (theme_file_list);
-
-  theme_file_list = games_file_list_new_images (dname, NULL);
-  g_free (dname);
-
-  games_file_list_transform_basename (theme_file_list);
-
-  return games_file_list_create_widget (theme_file_list, tile_set,
-					GAMES_FILE_LIST_REMOVE_EXTENSION |
-					GAMES_FILE_LIST_REPLACE_UNDERSCORES);
-}
-
 void
-show_properties_dialog (void)
+on_preferences_activate (GtkMenuItem *menuitem, gpointer user_data)
 {
+  const gchar *strs[] = {
+    _("Dark"),			/* 0 */
+    _("Light"),			/* 1 */
+    _("Human"),			/* 2 */
+    _("Level one"),		/* 3 */
+    _("Level two"),		/* 4 */
+    _("Level three"),		/* 5 */
+    _("Level four"),		/* 6 */
+    _("_Use quick moves"),	/* 7 */
+  };
+
   GtkWidget *notebook;
-  GtkWidget *hbox;
+  GtkWidget *vbox, *vbox1;
   GtkWidget *label;
-  GtkWidget *label2;
   GtkWidget *table;
   GtkWidget *button;
   GtkWidget *frame;
-  GtkWidget *vbox, *vbox2;
-  GtkWidget *propbox = NULL;
-  GtkWidget *option_menu;
+  GtkWidget *hbox;
+  GtkWidget *tile_set_box;
+  GtkWidget *color_button;
+  GSList *human_group[2] = { NULL, NULL };
+  gint f, v;
 
-  if (propbox) {
-    gtk_window_present (GTK_WINDOW (propbox));
+  if (properties_dialog) {
+    gtk_window_present (GTK_WINDOW (properties_dialog));
     return;
   }
 
-  reset_properties ();
-
-  propbox = gtk_dialog_new_with_buttons (_("Iagno Preferences"),
-					 GTK_WINDOW (window),
-					 0,
-					 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
-					 NULL);
-
-  gtk_dialog_set_has_separator (GTK_DIALOG (propbox), FALSE);
-  gtk_container_set_border_width (GTK_CONTAINER (propbox), 5);
-  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (propbox)->vbox), 2);
-  gtk_window_set_resizable (GTK_WINDOW (propbox), FALSE);
+  properties_dialog = gtk_dialog_new_with_buttons (_("Iagno Preferences"),
+						   GTK_WINDOW (window), 0,
+						   GTK_STOCK_CLOSE,
+						   GTK_RESPONSE_CLOSE, NULL);
+  gtk_dialog_set_has_separator (GTK_DIALOG (properties_dialog), FALSE);
+  gtk_container_set_border_width (GTK_CONTAINER (properties_dialog), 5);
+  gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (properties_dialog)->vbox), 2);
+  gtk_window_set_resizable (GTK_WINDOW (properties_dialog), FALSE);
+/*** Notebook ***/
   notebook = gtk_notebook_new ();
   gtk_container_set_border_width (GTK_CONTAINER (notebook), 5);
-  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (propbox)->vbox), notebook);
-
+  gtk_container_add (GTK_CONTAINER (GTK_DIALOG (properties_dialog)->vbox),
+		     notebook);
+/*** Game page ***/
   label = gtk_label_new (_("Game"));
-
   vbox = gtk_vbox_new (FALSE, 18);
   gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
   gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, label);
-
   table = gtk_table_new (1, 2, FALSE);
   gtk_table_set_col_spacings (GTK_TABLE (table), 18);
   gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
-
-  vbox2 = gtk_vbox_new (FALSE, 0);
-  gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
-
-  button = gtk_check_button_new_with_mnemonic (_("_Use quick moves"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
-				(computer_speed == COMPUTER_MOVE_DELAY / 2));
-  g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK
-		    (quick_moves_select), NULL);
-
-  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
-
-  button = gtk_check_button_new_with_mnemonic (_("E_nable sounds"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), sound);
-  g_signal_connect (G_OBJECT (button), "toggled", G_CALLBACK
-		    (sound_select), NULL);
-
-  gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
-
-  frame = games_frame_new (_("Dark"));
-  gtk_table_attach_defaults (GTK_TABLE (table), frame, 0, 1, 0, 1);
-
-  vbox = gtk_vbox_new (FALSE, 6);
-
-  button = gtk_radio_button_new_with_label (NULL, _("Human"));
-  if (black_computer_level == 0)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (black_computer_level_select), (gpointer) 0);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-  button = gtk_radio_button_new_with_label (gtk_radio_button_get_group
-					    (GTK_RADIO_BUTTON (button)),
-					    _("Level one"));
-  if (black_computer_level == 1)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (black_computer_level_select), (gpointer) 1);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-  button = gtk_radio_button_new_with_label (gtk_radio_button_get_group
-					    (GTK_RADIO_BUTTON (button)),
-					    _("Level two"));
-  if (black_computer_level == 2)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (black_computer_level_select), (gpointer) 2);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-  button = gtk_radio_button_new_with_label (gtk_radio_button_get_group
-					    (GTK_RADIO_BUTTON (button)),
-					    _("Level three"));
-  if (black_computer_level == 3)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (black_computer_level_select), (gpointer) 3);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-  gtk_container_add (GTK_CONTAINER (frame), vbox);
-
-  frame = games_frame_new (_("Light"));
-  gtk_table_attach_defaults (GTK_TABLE (table), frame, 1, 2, 0, 1);
-
-  vbox = gtk_vbox_new (FALSE, 6);
-
-  button = gtk_radio_button_new_with_label (NULL, _("Human"));
-  if (white_computer_level == 0)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (white_computer_level_select), (gpointer) 0);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-  button = gtk_radio_button_new_with_label (gtk_radio_button_get_group
-					    (GTK_RADIO_BUTTON (button)),
-					    _("Level one"));
-  if (white_computer_level == 1)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (white_computer_level_select), (gpointer) 1);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-  button = gtk_radio_button_new_with_label (gtk_radio_button_get_group
-					    (GTK_RADIO_BUTTON (button)),
-					    _("Level two"));
-  if (white_computer_level == 2)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (white_computer_level_select), (gpointer) 2);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-  button = gtk_radio_button_new_with_label (gtk_radio_button_get_group
-					    (GTK_RADIO_BUTTON (button)),
-					    _("Level three"));
-  if (white_computer_level == 3)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (white_computer_level_select), (gpointer) 3);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
-  gtk_container_add (GTK_CONTAINER (frame), vbox);
-
-
+/*** Dark and Light frame ***/
+  for (f = 0; f < 2; f++) {
+    frame = games_frame_new (strs[f]);
+    gtk_table_attach_defaults (GTK_TABLE (table), frame, f, f + 1, 0, 1);
+    vbox1 = gtk_vbox_new (FALSE, 6);
+    gtk_container_add (GTK_CONTAINER (frame), vbox1);
+/*** Human and Level one ... ***/
+    for (v = 0; v < 5; v++) {
+      button = gtk_radio_button_new_with_mnemonic (NULL, strs[v + 2]);
+      gtk_box_pack_start (GTK_BOX (vbox1), button, FALSE, FALSE, 0);
+      gtk_radio_button_set_group (GTK_RADIO_BUTTON (button), human_group[f]);
+      human_group[f] = gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+				    (t_computer_level[f] == v));
+      g_signal_connect ((gpointer) button, "toggled",
+			G_CALLBACK (on_computer_level_changed),
+			GINT_TO_POINTER (f * 16 + v));
+    }
+  }
+/**** Use quick moves and Enable sounds ****/
+  vbox1 = gtk_vbox_new (FALSE, 0);
+  gtk_box_pack_start (GTK_BOX (vbox), vbox1, FALSE, FALSE, 0);
+  for (v = 0; v < 1; v++) {
+    button = gtk_check_button_new_with_mnemonic (strs[v + 7]);
+    gtk_box_pack_start (GTK_BOX (vbox1), button, FALSE, FALSE, 0);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), t_options[v]);
+    g_signal_connect ((gpointer) button, "toggled",
+		      G_CALLBACK (on_options_toggled), GINT_TO_POINTER (v));
+  }
+/***  Appearance page ***/
   label = gtk_label_new (_("Appearance"));
-
   table = gtk_table_new (1, 2, FALSE);
+  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), table, label);
   gtk_table_set_col_spacings (GTK_TABLE (table), 18);
   gtk_container_set_border_width (GTK_CONTAINER (table), 12);
-
-  frame = games_frame_new (_("Animation"));
-
-  vbox = gtk_vbox_new (FALSE, 6);
-
-  button = gtk_radio_button_new_with_label (NULL, _("None"));
-  if (animate == 0)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (animate_select), (gpointer) 0);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-  button = gtk_radio_button_new_with_label (gtk_radio_button_get_group
-					    (GTK_RADIO_BUTTON (button)),
-					    _("Partial"));
-  if (animate == 1)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (animate_select), (gpointer) 1);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-  button = gtk_radio_button_new_with_label (gtk_radio_button_get_group
-					    (GTK_RADIO_BUTTON (button)),
-					    _("Complete"));
-  if (animate == 2)
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (animate_select), (gpointer) 2);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
-  gtk_container_add (GTK_CONTAINER (frame), vbox);
-  gtk_table_attach_defaults (GTK_TABLE (table), frame, 0, 1, 0, 1);
-
+/*** Options frame ***/
   frame = games_frame_new (_("Options"));
+  gtk_table_attach_defaults (GTK_TABLE (table), frame, 1, 2, 0, 1);
   vbox = gtk_vbox_new (FALSE, 6);
   gtk_container_add (GTK_CONTAINER (frame), vbox);
-  button = gtk_check_button_new_with_mnemonic (_("_Stagger flips"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
-				t_animate_stagger);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (animate_stagger_select), NULL);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
-  button = gtk_check_button_new_with_mnemonic (_("S_how grid"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), t_grid);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (grid_select), NULL);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
-  button = gtk_check_button_new_with_mnemonic (_("_Flip final results"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), t_flip_final);
-  g_signal_connect (G_OBJECT (button), "toggled",
-		    G_CALLBACK (flip_final_select), NULL);
-
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
+/*** Tile set ***/
   hbox = gtk_hbox_new (FALSE, 12);
-
-  label2 = gtk_label_new_with_mnemonic (_("_Tile set:"));
-
-  gtk_box_pack_start (GTK_BOX (hbox), label2, FALSE, FALSE, 0);
-
-  option_menu = fill_menu ();
-  gtk_label_set_mnemonic_widget (GTK_LABEL (label2), option_menu);
-  g_signal_connect (G_OBJECT (option_menu), "changed",
-		    G_CALLBACK (set_selection), NULL);
-  gtk_box_pack_start (GTK_BOX (hbox), option_menu, TRUE, TRUE, 0);
-
   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+  label = gtk_label_new_with_mnemonic (_("_Tile set:"));
+  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+  tile_set_box = gtk_combo_box_new_text ();
+  gtk_box_pack_start (GTK_BOX (hbox), tile_set_box, TRUE, TRUE, 0);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), tile_set_box);
+  for (f = 0; f < 3; f++) {
+    gtk_combo_box_append_text (GTK_COMBO_BOX (tile_set_box), tiles_name[f]);
+  }
+  gtk_combo_box_set_active (GTK_COMBO_BOX (tile_set_box), t_tile_set);
+  g_signal_connect (G_OBJECT (tile_set_box), "changed",
+		    G_CALLBACK (on_tile_set_box_changed), NULL);
+/*** Background color ***/
+  hbox = gtk_hbox_new (FALSE, 12);
+  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+  label = gtk_label_new_with_mnemonic (_("_Background color:"));
+  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+  color_button = gtk_color_button_new ();
+  gtk_box_pack_start (GTK_BOX (hbox), color_button, TRUE, TRUE, 0);
+  gtk_label_set_mnemonic_widget (GTK_LABEL (label), color_button);
+  gtk_color_button_set_color ((GtkColorButton *) color_button, &bg_color[2]);
+  g_signal_connect ((gpointer) color_button, "color_set",
+		    G_CALLBACK (on_color_button_color_set), NULL);
+/******************/
+  g_signal_connect (G_OBJECT (properties_dialog), "response",
+		    G_CALLBACK (on_ok_clicked), NULL);
+  g_signal_connect (G_OBJECT (properties_dialog), "delete_event",
+		    G_CALLBACK (on_ok_clicked), NULL);
+  gtk_widget_show_all (properties_dialog);
+}
 
-  gtk_table_attach_defaults (GTK_TABLE (table), frame, 1, 2, 0, 1);
 
-  gtk_notebook_append_page (GTK_NOTEBOOK (notebook), table, label);
-
-  g_signal_connect (G_OBJECT (propbox), "response", G_CALLBACK
-		    (close_cb), NULL);
-  g_signal_connect (G_OBJECT (propbox), "delete_event", G_CALLBACK
-		    (close_cb), NULL);
-
-  gtk_widget_show_all (propbox);
-}
