Index: gnome-games/configure.in
===================================================================
RCS file: /cvs/gnome/gnome-games/configure.in,v
retrieving revision 1.362
diff -u -r1.362 configure.in
--- gnome-games/configure.in	5 Sep 2006 16:36:23 -0000	1.362
+++ gnome-games/configure.in	3 Oct 2006 04:55:12 -0000
@@ -219,7 +219,7 @@
 ## Handle the disabling and enabling of games
 
 # This is the canonical list of all game subdirectories.
-allgames="aisleriot blackjack gnometris gnect gnomine same-gnome mahjongg gtali gataxx gnotravex gnotski glines iagno gnobots2 gnibbles"
+allgames="aisleriot blackjack gnometris gnect gnomine same-gnome mahjongg gtali gnotravex gnotski glines iagno gnobots2 gnibbles"
 
 gamelist=""
 
@@ -308,11 +308,10 @@
 iagno/iagno-client.dsc
 iagno/iagno-server.dsc
 iagno/sounds/Makefile
-iagno/help/Makefile
-iagno/help/C/Makefile
-gataxx/Makefile
-gataxx/help/Makefile
-gataxx/help/C/Makefile
+iagno/iagno-help/Makefile
+iagno/iagno-help/C/Makefile
+iagno/gataxx-help/Makefile
+iagno/gataxx-help/C/Makefile
 gnotravex/Makefile
 gnotravex/help/Makefile
 gnotravex/help/C/Makefile
Index: gnome-games/iagno/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/Makefile.am,v
retrieving revision 1.69
diff -u -r1.69 Makefile.am
--- gnome-games/iagno/Makefile.am	2 Oct 2006 03:40:46 -0000	1.69
+++ gnome-games/iagno/Makefile.am	3 Oct 2006 04:55:36 -0000
@@ -10,9 +10,11 @@
 	@LIBGGZ_INCLUDES@ @GGZDMOD_INCLUDES@ @GGZ_GTK_INCLUDES@
 
 if GGZ_SERVER
-bin_PROGRAMS = iagno iagnod
+bin_PROGRAMS = iagno iagnod gataxx
 iagnod_SOURCES = server.h   \
-		 server.c   
+		 server.c   \
+		 othello.h  \
+		 othello.c
 
 iagnod_LDFLAGS = @GGZDMOD_LDFLAGS@
 
@@ -22,7 +24,7 @@
 	@LIB_GGZDMOD@
 
 else
-bin_PROGRAMS = iagno 
+bin_PROGRAMS = iagno gataxx
 endif
 
 if GGZ_CLIENT
@@ -40,6 +42,14 @@
 	properties.h \
 	$(GGZ_FILES)
 
+gataxx_SOURCES = \
+	ai.c \
+	ai.h \
+	gataxx.c \
+	gataxx.h \
+	gataxx-properties.c \
+	properties.h
+
 iagno_LDFLAGS = $(GGZMOD_LDFLAGS)
 
 iagno_LDADD = \
@@ -49,27 +59,33 @@
 	$(LIB_GGZMOD) \
 	$(LIB_GGZ_GTK)
 
+gataxx_LDADD = \
+	../libgames-support/libgames-support.la \
+	$(GNOME_GAMES_LIBS) \
+	$(INTLLIBS)
+
 pixmap_DATA = \
-	classic.png \
-	woodtrim.png
+	coin.svg \
+	marble.svg \
+	sun_and_star.svg
 
 icon16dir = $(datadir)/icons/hicolor/16x16/apps/
-icon16_DATA = 16x16/gnome-iagno.png
+icon16_DATA = 16x16/gnome-iagno.png 16x16/gnome-ataxx.png
 icon22dir = $(datadir)/icons/hicolor/22x22/apps/
-icon22_DATA = 22x22/gnome-iagno.png
+icon22_DATA = 22x22/gnome-iagno.png 22x22/gnome-ataxx.png
 icon32dir = $(datadir)/icons/hicolor/32x32/apps/
-icon32_DATA = 32x32/gnome-iagno.png
+icon32_DATA = 32x32/gnome-iagno.png 32x32/gnome-ataxx.png
 icon48dir = $(datadir)/icons/hicolor/48x48/apps/
-icon48_DATA = 48x48/gnome-iagno.png
+icon48_DATA = 48x48/gnome-iagno.png 48x48/gnome-ataxx.png
 svgicondir = $(datadir)/icons/hicolor/scalable/apps/
-svgicon_DATA = scalable/gnome-iagno.svg
+svgicon_DATA = scalable/gnome-iagno.svg scalable/gnome-ataxx.svg
 
-Games_in_files = iagno.desktop.in
+Games_in_files = iagno.desktop.in gataxx.desktop.in
 Games_DATA = $(Games_in_files:.desktop.in=.desktop)
 @INTLTOOL_DESKTOP_RULE@
 
 schemadir   = @GCONF_SCHEMA_FILE_DIR@
-schema_in_files = iagno.schemas.in
+schema_in_files = iagno.schemas.in gataxx.schemas.in
 schema_DATA = $(schema_in_files:.schemas.in=.schemas)
 @INTLTOOL_SCHEMAS_RULE@
 
@@ -79,6 +95,7 @@
 	iagno-server.dsc.in \
         iagno.room          \
 	iagno.desktop.in 	\
+	gataxx.desktop.in 	\
 	iagno.soundlist.in \
 	$(pixmap_DATA)	\
 	$(icon16_DATA)	\
@@ -105,7 +122,7 @@
 soundlist_DATA = $(soundlist_in_files:.soundlist.in=.soundlist)
 @INTLTOOL_SOUNDLIST_RULE@
 
-SUBDIRS=sounds help
+SUBDIRS=sounds iagno-help gataxx-help
 
 DISTCLEANFILES = $(Games_DATA) $(schema_DATA) $(soundlist_DATA)
 
Index: gnome-games/iagno/ggz-network.c
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/ggz-network.c,v
retrieving revision 1.2
diff -u -r1.2 ggz-network.c
--- gnome-games/iagno/ggz-network.c	30 Sep 2006 09:02:52 -0000	1.2
+++ gnome-games/iagno/ggz-network.c	3 Oct 2006 04:55:38 -0000
@@ -20,285 +20,229 @@
 
 #include "config.h"
 #include <gnome.h>
-#include <gconf/gconf-client.h>
 
 #include <ggzmod.h>
-#include <ggz-embed.h>
 #include <ggz-gtk.h>
 
-#include "games-dlg-chat.h"
-#include "games-dlg-players.h"
-
 #include "gnothello.h"
-#include "ggz-network.h"
 #include "othello.h"
+#include "properties.h"
+#include "ggz-network.h"
 
-guint whose_turn = BLACK_TURN;
-
-static gboolean game_handle_io(GGZMod * mod)
-{
-  int op = -1;
-
-  fd = ggzmod_get_server_fd(mod);
-
-  // Read the fd
-  if (ggz_read_int(fd, &op) < 0) {
-    ggz_error_msg("Couldn't read the game fd");
-    return FALSE;
-  }
-
-  switch (op) {
-  case RVR_MSG_SEAT:
-    get_seat();
-    break;
-  case RVR_MSG_PLAYERS:
-    get_players();
-    /*game.state = RVR_STATE_WAIT; */
-    break;
-  case RVR_MSG_SYNC:
-    get_sync();
-    init_new_game();
-    break;
-  case RVR_MSG_START:
-    /*state = RVR_STATE_PLAYING; */
-    ggz_debug("main", "Game has started");
-    init_new_game();
-    break;
-  case RVR_MSG_MOVE:
-    get_move();
-    break;
-  case RVR_MSG_GAMEOVER:
-    get_gameover();
-    /*game.state = RVR_STATE_DONE; */
-    break;
-  default:
-    ggz_error_msg("Incorrect opcode\n");
-    break;
-  }
-
-  return TRUE;
-}
-
-
+int player_id;
+int seat;
+int seats[2];
+char names[2][17];
+int fd;
+GGZMod *ggzmod;
 
+extern GtkWidget *window;
+extern guint8 kifu[61][2];
+extern guint whose_turn;
+extern guint move_count;
 
-int get_seat(void)
+static int
+get_seat (void)
 {
+	if (ggz_read_int (fd, &seat) < 0)
+		return -1;
+	if (!seat)
+		gui_message ("Waiting for an opponent to join the game.");
 
-  if (ggz_read_int(fd, &seat) < 0)
-    return -1;
-
-  if (seat == 0) {
-    gui_message(_("Waiting for an opponent to join the game."));
-  }
-
-  player_id = SEAT2PLAYER(seat);
-
-  return 0;
+	player_id = SEAT2PLAYER (seat);
+	return 0;
 }
 
-int get_players(void)
+static int
+get_players (void)
 {
-  int i;
-
-  for (i = 0; i < 2; i++) {
-    if (ggz_read_int(fd, &seats[i]) < 0)
-      return -1;
-
-    if (seats[i] != GGZ_SEAT_OPEN) {
-      if (ggz_read_string(fd, (char *) &names[i], 17) < 0)
-	return -1;
-    }
-  }
-
-  return 0;
+	int i;
 
+	for (i = 0; i < 2; i++)
+	{
+		if (ggz_read_int (fd, &seats[i]) < 0)
+			return -1;
+		if (seats[i] != GGZ_SEAT_OPEN)
+			if (ggz_read_string (fd, (char *) &names[i], 17) < 0)
+				return -1;
+	}
+	return 0;
 }
 
-int get_gameover()
+// Get the move from the server and makes it
+static int
+get_move (void)
 {
-  int winner;
-
-  if (ggz_read_int(fd, &winner) < 0)
-    return -1;
+	int yx;
 
-  return 1;
+	if (ggz_read_int (fd, &yx) < 0 || yx < 0)
+		return -1;
+	if (yx == RVR_ERROR_CANTMOVE)
+		return 1;
 
+	move (yx);
+	return 0;
 }
 
-// Get the move from the server and makes it (don't check for validity!!)
-int get_move(void)
+static int
+get_gameover (void)
 {
-  int move;
-
-  if (ggz_read_int(fd, &move) < 0)
-    return -1;
-
-  if (move == RVR_ERROR_CANTMOVE) {
-    return 1;
-  }
+	int winner;
 
-  if (move < 0) {
-    return -1;
-  }
-  game_make_move(move);
-
-  return 0;
+	if (ggz_read_int (fd, &winner) < 0)
+		return -1;
 
+	return 1;
 }
 
-// make the move
-void game_make_move(int pos)
+void
+send_my_move (int move)
 {
-  int x = X(pos) - 1, y = Y(pos) - 1;
-
-  // iagno move
-  move(x, y, whose_turn);
-
-  return;
-
+	if (ggz_write_int (fd, RVR_REQ_MOVE) < 0 || ggz_write_int (fd, move) < 0)
+		gui_message ("Can't send move!");
 }
 
-
-
-void send_my_move(int move, guint turn)
+static int
+get_sync (void)
 {
-  if (ggz_write_int(fd, RVR_REQ_MOVE) < 0 || ggz_write_int(fd, move) < 0) {
-    gui_message("Can't send move!");
-    return;
-  }
+	int who, yx;
+	int i, count;
+	guint8 t_kifu[61][2];
+	
+	if (ggz_read_int (fd, &count) < 0 || count < 0 || count > 60)
+		return -1;
+	for (i = 0; i < count; i++)
+	{
+		if (ggz_read_int (fd, &who) < 0 || ggz_read_int (fd, &yx) < 0)
+			return -1;
+		t_kifu[i][0] = (guint8)who;
+		t_kifu[i][1] = (guint8)yx;
+	}
+	t_kifu[i][0] = 0;
+	t_kifu[i][1] = 0;
+	if (ggz_read_int (fd, &who) < 0)
+		return -1;
 
-  ggz_debug("main", "Sent move: %d", move);
-}
+	if (count != move_count - 4)
+		return -1;
+	for (i = 0; i < count; i++)
+	{
+		if (t_kifu[i][0] != kifu[i][0] || t_kifu[i][1] != kifu[i][1])
+			return -1;
+		
+	}
+	if (who != whose_turn)
+		return -1;
 
-int request_sync(void)
-{
-  if (ggz_write_int(fd, RVR_REQ_SYNC) < 0) {
-    // Not that someone would check this return value, but...
-    return -1;
-  } else {
-    gui_message("Requesting sync from the server");
-  }
-  return 0;
+	return 0;
 }
 
-int get_sync(void)
+static int
+game_handle_io (GGZMod *mod)
 {
-/* FIXME: Not supported yet. */
-  return 0;
-}
+	int op = -1;
 
+	fd = ggzmod_get_server_fd (mod);
 
+	// Read the fd
+	if (ggz_read_int (fd, &op) < 0)
+	{
+		gui_message ("Can't read the game fd!");
+		return FALSE;
+	}
 
+	switch (op)
+	{
+		case RVR_MSG_SEAT: /* 0 */
+			get_seat ();
+			break;
+		case RVR_MSG_PLAYERS: /*game.state = RVR_STATE_WAIT; */
+			get_players ();
+			break;
+		case RVR_MSG_MOVE: /* 2 */
+			get_move ();
+			break;
+		case RVR_MSG_GAMEOVER: /*game.state = RVR_STATE_DONE; */
+			get_gameover ();
+			break;
+		case RVR_MSG_START: /*game.state = RVR_STATE_PLAYING; */
+			init_new_game ();
+			break;
+		case RVR_MSG_SYNC: /* 6 */
+			if (get_sync () < 0)
+				gui_message ("Sync error!");
+			else
+				gui_message ("Sync all right.");				
+			break;
+		default:
+			gui_message ("Got incorrect opcode!");
+			break;
+	}
 
-static gboolean handle_ggzmod(GIOChannel * channel, GIOCondition cond,
-			      gpointer data)
-{
-  GGZMod *mod = data;
-
-  return (ggzmod_dispatch(mod) >= 0);
+	return TRUE;
 }
 
-static gboolean handle_game_server(GIOChannel * channel, GIOCondition cond,
-				   gpointer data)
+static gboolean
+handle_ggzmod (GIOChannel *channel, GIOCondition cond, gpointer data)
 {
-  GGZMod *mod = data;
+	GGZMod *mod = data;
 
-  return game_handle_io(mod);
+	return (ggzmod_dispatch (mod) >= 0);
 }
 
-static void handle_ggzmod_server(GGZMod * mod, GGZModEvent e,
-				 const void *data)
+static gboolean
+handle_game_server (GIOChannel *channel, GIOCondition cond, gpointer data)
 {
-  const int *fd = data;
-  GIOChannel *channel;
+	GGZMod *mod = data;
 
-  ggzmod_set_state(mod, GGZMOD_STATE_PLAYING);
-  channel = g_io_channel_unix_new(*fd);
-  g_io_add_watch(channel, G_IO_IN, handle_game_server, mod);
+	return game_handle_io (mod);
 }
 
-/****************************************************************************
-  Callback function that's called by the library when a connection is
-  established (or lost) to the GGZ server.  The server parameter gives
-  the server (or NULL).
-****************************************************************************/
-static void ggz_connected(GGZServer * server)
+static void
+handle_ggzmod_server (GGZMod *mod, GGZModEvent e, const void *data)
 {
-  /* Nothing useful to do... */
+	const int *fd = data;
+	GIOChannel *channel;
+
+	ggzmod_set_state (mod, GGZMOD_STATE_PLAYING);
+	channel = g_io_channel_unix_new (*fd);
+	g_io_add_watch (channel, G_IO_IN, handle_game_server, mod);
 }
 
-/****************************************************************************
-  Callback function that's called by the library when we launch a game.  This
-  means we now have a connection to a gnect server so handling can be given
-  back to the regular gnect code.
-****************************************************************************/
-static void ggz_game_launched(void)
+static void
+ggz_connected (GGZServer *server)
 {
-  network_init();
-  init_new_game();
-  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), MAIN_PAGE);
+	/* Nothing useful to do... */
 }
 
-/****************************************************************************
-  Callback function that's invoked when GGZ is exited.
-****************************************************************************/
-static void ggz_closed(void)
+static void
+ggz_game_launched (void)
 {
-  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), MAIN_PAGE);
-  ggz_network_mode = FALSE;
-  init_new_game();
+	init_new_game ();
 }
 
-void network_init(void)
+void
+network_init (void)
 {
-  GGZMod *mod;
-  GIOChannel *channel;
-  int ret, ggzmodfd;
-
-  if (!ggzmod_is_ggz_mode())
-    return;
-  ggz_network_mode = TRUE;
-
-  mod = ggzmod_new(GGZMOD_GAME);
-  ggzmod_set_handler(mod, GGZMOD_EVENT_SERVER, handle_ggzmod_server);
+	GIOChannel *channel;
 
-  ret = ggzmod_connect(mod);
-  if (ret != 0) {
-    /* Error: GGZ core client error (e.g. faked GGZMODE env variable) */
-    return;
-  }
+	ggzmod = ggzmod_new (GGZMOD_GAME);
+	ggzmod_set_handler (ggzmod, GGZMOD_EVENT_SERVER, handle_ggzmod_server);
+	ggzmod_connect (ggzmod);
 
-  ggzmodfd = ggzmod_get_fd(mod);
-  channel = g_io_channel_unix_new(ggzmodfd);
-  g_io_add_watch(channel, G_IO_IN, handle_ggzmod, mod);
-
-  init_player_list(mod);
-  init_chat(mod);
+	channel = g_io_channel_unix_new (ggzmod_get_fd (ggzmod));
+	g_io_add_watch (channel, G_IO_IN, handle_ggzmod, ggzmod);
 
+	ggz_gtk_initialize (FALSE,
+			    ggz_connected, ggz_game_launched,
+			    NETWORK_ENGINE, NETWORK_VERSION);
 }
 
-void on_network_game(void)
+int
+network_quit (void)
 {
-  GtkWidget *ggzbox;
-
-
-  if (ggz_network_mode) {
-    gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), NETWORK_PAGE);
-    return;
-  }
-
-  init_new_game();
-  ggz_network_mode = TRUE;
-
-  ggz_gtk_initialize(FALSE,
-		     ggz_connected, ggz_game_launched, ggz_closed,
-		     NETWORK_ENGINE, NETWORK_VERSION, "GNOME GGZ");
-
-  ggz_embed_ensure_server("GNOME GGZ", "gnome.ggzgamingzone.org",
-     			  5688, _("Player")); 
-
-  ggzbox = ggz_gtk_create_main_area(window);
-  gtk_notebook_append_page(GTK_NOTEBOOK(notebook), ggzbox, NULL);
-  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), NETWORK_PAGE);
+	if (ggzmod_disconnect(ggzmod) < 0)
+		return -2;
+	ggzmod_free(ggzmod);
+	return 0;
 }
Index: gnome-games/iagno/ggz-network.h
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/ggz-network.h,v
retrieving revision 1.1
diff -u -r1.1 ggz-network.h
--- gnome-games/iagno/ggz-network.h	5 Sep 2006 16:36:27 -0000	1.1
+++ gnome-games/iagno/ggz-network.h	3 Oct 2006 04:55:38 -0000
@@ -16,124 +16,16 @@
  * USA
  */
 
-#define EMPTY  0
-
-/* REVERSI PROTOCOL VERSION 0.0.5
- *
- * The server handles everything, from the AI to the validity of moves
- *
- * RVR_STATE_INIT:
- *
- * First, it fetchs from the ggz_server how much seats there are, and how much are open/closed
- *
- * RVR_STATE_JOIN:
- *
- * Then, it waits until some player join . When he does, it sends:
- *
- * To Joining player:
- * 	RVR_MSG_SEAT (int)SEAT_NUM
- * To All Human players:
- * 	RVR_MSG_PLAYERS PLAYER_IDENTIFER[BLACK] PLAYER_IDENTIFIER[WHITE]
- *  where PLAYER_IDENTIFIER is:
- *  	(int)PLAYER_TYPE
- *  	if PLAYER_TYPE == GGZ_SEAT_OPEN
- *  		(str)PLAYER_NAME
- *
- * If the game was already happening, send the current game state to the new player
- *
- * 	RVR_MSG_SYNC (char)TURN BOARD_STATE
- * 	where TURN is the current turn, and:
- * 		BOARD_STATE = (char)POSITION * 64
- *
- * When all the open seats are filled, it enters playing state (state = RVR_STATE_PLAYING) and sends:
- *
- * To All Human players:
- * 	RVR_MSG_START
- *
- * RVR_STATE_PLAYING:
- *
- * If current player is AI:
- *
- * 	doMove(AI_MOVE());
- *
- * If it isn't AI, then it waits until client sends a RVR_REQ_MOVE
- *
- * When client sends a RVR_REQ_MOVE, the server must check if he is the current player and
- * if the move is valid. (The client should do it too, must the server must recheck to avoid cheating)
- * Then the server executes the move, and sends:
- * 
- * To All Human players:
- *
- *	RVR_MSG_MOVE (int)MOVE
- * 	where MOVE can be a array index (0-63) or one of the following error values:
- * 		RVR_ERROR_WRONGTURN
- * 			The player tried to move when it wasn't his turn
- * 		RVR_ERROR_INVALIDMOVE
- * 			The player tried a invalid move (Cheating sign!)
- *
- * Then the server checks if the game is over (No more valid moves) and who has won. If the game is over,
- * it sends to All Human players:
- *
- * 	RVR_MSG_GAMEOVER (int)WINNER
- * 		where WINNER can be: BLACK, WHITE, EMPTY(draw)
- *
- * If some player left while the game was happening, it sends to all Human players:
- *
- * 	RVR_MSG_PLAYERS
- *
- * And it will wait until someone returns
- *
- * The client:
- *
- * game_init():
- * - Init variables and set the turn to BLACK (first turn) and the state to init
- *
- * RVR_MSG_SEAT
- * - Store his seat on a safe variable
- *
- * RVR_MSG_PLAYERS
- * - Store (and display) the name of the players
- * - Set the state to wait
- *
- * RVR_MSG_START
- * - Set the state to playing
- *
- * RVR_MSG_SYNC
- * - Believes what the server says and updates everything
- *
- * RVR_MSG_MOVE
- * - Do the move
- *
- * RVR_MSG_GAMEOVER
- * - Display ending message
- * 
- * And sends to the server:
- *
- * RVR_REQ_MOVE
- * - Ask to move
- *
- * RVR_REQ_SYNC
- * - Ask for sync
- *
- * RVR_REQ_AGAIN
- * - Ask for playing again
- *
- * Luckily that's all, this protocol is perfect and it shouldn't be modified anymore. Or so I hope. :) */
-
-// Reversi protocol
-// The numbers aren't on order, because I used the same constants from TicTacToe - simplify testing
-
-#include "gnothello.h"
-
+/* IAGNO PROTOCOL VERSION 1 */
 #define RVR_MSG_SEAT 0
 #define RVR_MSG_PLAYERS 1
-#define RVR_MSG_SYNC 6
-#define RVR_REQ_SYNC 7
-#define RVR_REQ_AGAIN 8
-#define RVR_MSG_START 5
 #define RVR_MSG_MOVE 2
 #define RVR_MSG_GAMEOVER 3
 #define RVR_REQ_MOVE 4
+#define RVR_MSG_START 5
+#define RVR_MSG_SYNC 6
+#define RVR_REQ_SYNC 7
+#define RVR_REQ_AGAIN 8
 
 // States
 #define RVR_STATE_INIT 0
@@ -153,48 +45,17 @@
 #define RVR_ERROR_WRONGTURN -2
 #define RVR_ERROR_CANTMOVE -3
 
-// Takes cartesian coordinates and transform them into a array index
-#define CART(X,Y) ( (Y-1)*8+(X-1) )
-
-// Takes a index and transform it in cartesians coordinates
-#define X(I) ( (I%8)+1 )
-#define Y(I) ( (I/8)+1 )
-
-// See what's the value at that place (like a 10x10 board)
-#define GET(X,Y) ( (X==0 || Y==0 || X>8 || Y>8) ? EMPTY : game.board[CART(X,Y)] )
-
 // Takes a seat and transform into a player code
-#define SEAT2PLAYER(seat) ( (seat==0)?BLACK_TURN:WHITE_TURN )
+#define SEAT2PLAYER(seat) ( (seat==0)?BLACK:WHITE )
 
 // Takes a player code and transform into a seat index
-#define PLAYER2SEAT(player) ( (player==BLACK_TURN)?0:1 )
+#define PLAYER2SEAT(player) ( (player==BLACK)?0:1 )
 
 #define NETWORK_ENGINE "Iagno"
 #define NETWORK_VERSION "1"
 
-void network_init(void);
-void on_network_game(void);
-
-int fd;
+void send_my_move (int move);
 
-// Setup functions
-void game_init(void);
+void network_init (void);
 
-// Get stuff from server
-int get_seat(void);
-int get_players(void);
-int get_gameover(void);
-int get_sync(void);
-int get_move(void);
-int get_gameover(void);
-
-// Send stuff to server
-void send_my_move(int move, guint turn);
-int request_sync(void);
-
-// Game functions
-void game_make_move(int);
-void game_mark_board(int, int, int, int, int);
-int game_check_direction(int, int, int, int, int);
-int game_check_move(int, int);
-void game_update_scores(void);
+int network_quit (void);
Index: gnome-games/iagno/gnothello.c
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/gnothello.c,v
retrieving revision 1.138
diff -u -r1.138 gnothello.c
--- gnome-games/iagno/gnothello.c	1 Oct 2006 09:06:02 -0000	1.138
+++ gnome-games/iagno/gnothello.c	3 Oct 2006 04:55:38 -0000
@@ -1,8 +1,5 @@
-/* -*- mode:C; indent-tabs-mode:t; tab-width:8; c-basic-offset:8; -*- */
-
 /*
- * gnothello.c - Main GUI part of iagno
- * written by Ian Peters <itp@gnu.org>
+ * gnothello.c - callbacks and main code for iagno.
  *
  * 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
@@ -21,849 +18,573 @@
  * For more details see the file COPYING.
  */
 
-#include <config.h>
+#include "config.h"
 #include <gnome.h>
-#include <gdk/gdkkeysyms.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
+#include <glib.h>
+#include <gconf/gconf-client.h>
+#include <stdio.h>
+#include <fcntl.h>
 #include <string.h>
-#include <games-stock.h>
 
-#ifdef GGZ_CLIENT
-#include <games-dlg-chat.h>
-#include <games-dlg-players.h>
-#include "ggz-network.h"
-#include <ggz-embed.h>
-#endif
+#include "games-stock.h"
 
-#include "gnothello.h"
 #include "othello.h"
+#include "gnothello.h"
 #include "properties.h"
 
-GnomeAppBar *appbar;
-GtkWidget *window;
-GtkWidget *notebook;
-GtkWidget *drawing_area;
-GtkWidget *tile_dialog;
-GtkWidget *black_score;
-GtkWidget *white_score;
-
-GdkPixmap *buffer_pixmap = NULL;
-GdkPixmap *tiles_pixmap = NULL;
-GdkPixmap *tiles_mask = NULL;
-
-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;
-
-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 };
-
-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")},
-  {NULL}
-};
-
-GnomeUIInfo game_menu[] = {
-        GNOMEUIINFO_MENU_NEW_GAME_ITEM(new_game_cb, NULL),
-
-	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
-};
+#ifdef GGZ_CLIENT
+#include <ggzmod.h>
+#include <ggz-gtk.h>
+#include "ggz-network.h"
+extern int fd;
+#endif
 
-GnomeUIInfo help_menu[] = {
-        GNOMEUIINFO_HELP("iagno"),
-	GNOMEUIINFO_MENU_ABOUT_ITEM(about_cb, NULL),
-	GNOMEUIINFO_END
-};
+gboolean  ggz_network_mode = FALSE;
+guint8    kifu[SIZE * SIZE - 3][2];
 
-GnomeUIInfo mainmenu[] = {
-        GNOMEUIINFO_MENU_GAME_TREE(game_menu),
-        GNOMEUIINFO_MENU_SETTINGS_TREE(settings_menu),
-        GNOMEUIINFO_MENU_HELP_TREE(help_menu),
-	GNOMEUIINFO_END
-};
+extern gint8     pixmaps[SIZE][SIZE];
+extern gint8     board[SIZE][SIZE];
 
-static void undo_set_sensitive (gboolean state)
-{
-	gtk_widget_set_sensitive (game_menu[3].widget, state);
-}
+extern GtkWidget *window;
+extern GtkWidget *file_open_dialog;
+extern GtkWidget *file_save_dialog;
+extern GtkWidget *counter;
+extern GtkWidget *score[4];
+extern GtkWidget *entry;
+extern GTimer    *b_timer;
+extern GTimer    *w_timer;
+
+extern guint     black_computer_level;
+extern guint     white_computer_level;
+extern gboolean  flip_final;
+extern guint     computer_speed;
+extern guint     tile_width;
+extern guint     tile_height;
+extern gboolean  game_in_progress;
+extern gboolean  gameover;
+extern guint     flip_final_id;
+extern guint     computer_id;
+extern gboolean  flip_tiles;
+extern gboolean  play_sound;
+
+extern guint8    board0[(SIZE + 2) * (SIZE + 2)];
+extern gint      vsquares[280][2];
+extern guint     bcount;
+extern guint     wcount;
+extern guint     move_count;
+extern guint     whose_turn;
 
 void
-quit_game_cb (GtkWidget *widget, gpointer data)
+copy_board (void)
 {
-  gtk_main_quit ();
-}
+	guint i, j;
 
-void
-new_game_cb (GtkWidget *widget, gpointer data)
-{
-  init_new_game ();
+	for (i = 0; i < SIZE; i++)
+		for (j = 0; j < SIZE; j++)
+			board[i][j] = (gint8) board0[(i + 1) * (SIZE + 2) + j + 1];
 }
 
 void
-on_player_list (void)
+copy_pixmaps (void)
 {
-	#ifdef GGZ_CLIENT
-	create_or_raise_dlg_players (GTK_WINDOW (window));
-	#endif
-}
+	guint i, j;
 
-void
-on_chat_window (void)
-{
-	#ifdef GGZ_CLIENT
-	create_or_raise_dlg_chat (GTK_WINDOW (window));
-	#endif
+	for (i = 0; i < SIZE; i++)
+		for (j = 0; j < SIZE; j++)
+			pixmaps[i][j] = board[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
-}
 
 void
-on_network_leave (GObject *object, gpointer data)
+gui_status (void)
 {
-	#ifdef GGZ_CLIENT
-	ggz_embed_leave_table();
-	gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), 
-					NETWORK_PAGE);
-	#endif
+	gchar message[5];
+
+	sprintf (message, _("%.2d"), move_count - 4);
+	gtk_label_set_text (GTK_LABEL (counter), message);
+	sprintf (message, _("%.2d"), bcount);
+	gtk_label_set_text (GTK_LABEL (score[0]), message);
+	sprintf (message, _("%.2d"), wcount);
+	gtk_label_set_text (GTK_LABEL (score[1]), message);
 }
 
-void
-undo_move_cb (GtkWidget *widget, gpointer data)
+
+static void
+gui_hint (gint yx, gint score)
 {
-	gint8 which_computer, xy;
+	gchar message[10];
 
-	if ((black_computer_level && white_computer_level) || move_count == 4)
-		return;
+	message[0] = (gchar) (yx % (SIZE + 2) + 0x40);
+	message[1] = (gchar) (yx / (SIZE + 2) + 0x30);
+	message[2] = 0x20;
+	sprintf (&message[3], _("%d"), score);
 
-	if (flip_final_id) {
-		g_source_remove (flip_final_id);
-		flip_final_id = 0;
-	}
+	gui_entry (message);
+}
 
-	game_in_progress = 1;
+static void
+clear_board (void)
+{
+	guint i, j;
 
- 	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;
-	}
+	for (i = 0; i < SIZE; i++)
+		for (j = 0; j < SIZE; j++)
+			board[i][j] = BLANK;
 
-	gui_status ();
-	tiles_to_flip = 1;
-	check_computer_players ();
+	game_in_progress = FALSE;
+	move_count = 4;
+	bcount = 0;
+	wcount = 0;
 }
 
-void
-black_level_cb (GtkWidget *widget, gpointer data)
+static gboolean
+check_game_over (void)
 {
-        int tmp;
-
-        tmp = atoi ((gchar *)data);
+	if (mobility (whose_turn))
+	{
+		if (whose_turn == BLACK)
+		{
+			gui_message ("Dark's move");
+			if (game_in_progress)
+				g_timer_continue (b_timer);
+		}
+		else if (whose_turn == WHITE)
+		{
+			gui_message ("Light's move");
+			if (game_in_progress)
+				g_timer_continue (w_timer);
+		}
+		return FALSE;
+	}
 
-        gnome_config_set_int ("/iagno/Preferences/blacklevel", tmp);
-        gnome_config_sync ();
+	whose_turn = OTHER_PLAYER (whose_turn);
+	if (mobility (whose_turn))
+	{
+		if (whose_turn == BLACK)
+		{
+			gui_message ("Light must pass, Dark's move");
+			if (game_in_progress)
+				g_timer_continue (b_timer);
+		}
+		else if (whose_turn == WHITE)
+		{
+			gui_message ("Dark must pass, Light's move");
+			if (game_in_progress)
+				g_timer_continue (w_timer);
+		}
+		return FALSE;
+	}
 
-        black_computer_level = tmp;
+	if (wcount > bcount)
+		gui_message ("Light player wins!");
+	if (bcount > wcount)
+		gui_message ("Dark player wins!");
+	if (wcount == bcount)
+		gui_message ("The game was a draw.");
+
+	whose_turn = 0;
+	game_in_progress = FALSE;
+	gameover = TRUE;
+	if (flip_final)
+		flip_final_id = g_timeout_add (computer_speed, flip_final_results, NULL);
 
-        check_computer_players ();
+	return TRUE;
 }
 
-void
-white_level_cb (GtkWidget *widget, gpointer data)
+gboolean
+t_computer_move (gpointer level)
 {
-        int tmp;
+	guint yx;
 
-        tmp = atoi ((gchar *)data);
+	yx = computer_move (GPOINTER_TO_INT (level));
+	if (game_in_progress)
+		move (yx);
+	computer_id = 0;
+	return FALSE;
+}
 
-        gnome_config_set_int ("/iagno/Preferences/whitelevel", tmp);
-        gnome_config_sync ();
 
-        white_computer_level = tmp;
+static gboolean
+check_valid_move (guint who, guint yx)
+{	
+	if (!game_in_progress)
+		return FALSE;
+	if (whose_turn == WHITE && white_computer_level)
+		return FALSE;
+	if (whose_turn == BLACK && black_computer_level)
+		return FALSE;
+	if (who != whose_turn)
+		return FALSE;
+	if (yx % (SIZE + 2) < 1 || yx % (SIZE + 2) > SIZE
+		|| yx / (SIZE + 2) < 1 || yx / (SIZE + 2) > SIZE)
+		return FALSE;
+	if (board0[yx] != BLANK)
+		return FALSE;
+
+	return is_valid (who, yx);
+}
+
+gboolean
+move (guint yx)
+{
+	if (game_in_progress)
+	{
+		kifu[move_count - 4][0] = (guint8) whose_turn;
+		kifu[move_count - 4][1] = (guint8) yx;
+		kifu[move_count - 3][0] = 0;
+		if (whose_turn == BLACK)
+			g_timer_stop (b_timer);
+		else
+			g_timer_stop (w_timer);
+	}
+
+	move_board (yx);
+	gui_entry (" ");
+	gtk_entry_set_position ((GtkEntry *) entry, 0);
+	copy_board ();
+	gui_status ();
+	flip_tiles = TRUE;
+	play_sound = TRUE;
+	check_game_over ();
+	if (game_in_progress)
+		return check_computer_players ();
 
-        check_computer_players ();
+	return FALSE;
 }
 
 void
-about_cb (GtkWidget *widget, gpointer data)
+init_new_game (void)
 {
-	const gchar *authors[] = {"Ian Peters", NULL};
-
-	const gchar *documenters[] = {"Eric Baudais", NULL};
-
-	gchar *license = games_get_license (_("Iagno"));
-
+	if (flip_final_id)
+	{
+		g_source_remove (flip_final_id);
+		flip_final_id = 0;
+	}
+	if (computer_id)
+	{
+		g_source_remove (computer_id);
+		computer_id = 0;
+	}
 
-	gtk_show_about_dialog (GTK_WINDOW (window),
-			       "name", _("Iagno"),
-			       "version", VERSION,
-			       "copyright", "Copyright \xc2\xa9 1998-2006 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);
+	kifu[0][0] = 0;
+	init ();
+	copy_board ();
+	redraw_board ();
+	game_in_progress = TRUE;
+	g_timer_stop (b_timer);
+	g_timer_reset (b_timer);
+	g_timer_stop (w_timer);
+	g_timer_reset (w_timer);
+	gui_timer ();
+	timer_start ();
+	check_game_over ();
+	check_computer_players ();
 }
 
 void
-properties_cb (GtkWidget *widget, gpointer data)
+on_sync_activate (GtkMenuItem *menuitem, gpointer user_data)
 {
-	show_properties_dialog ();
+#ifdef GGZ_CLIENT
+	if (ggz_write_int (fd, RVR_REQ_SYNC) < 0)
+		gui_message ("Can't send request sync!");
+#endif
 }
 
-gint
-expose_event (GtkWidget *widget, GdkEventExpose *event)
+void
+on_again_activate (GtkMenuItem *menuitem, gpointer user_data)
 {
-	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);
-
-	return(FALSE);
+#ifdef GGZ_CLIENT
+	if (ggz_write_int (fd, RVR_REQ_AGAIN) < 0)
+		gui_message ("Can't send request again!");
+#endif
 }
 
-gint
-configure_event (GtkWidget *widget, GdkEventConfigure *event)
+void
+write_kifu (int fd)
 {
-	static int old_width = 0, old_height = 0;
-	guint i, j;
+	gchar buf[9];
+	gint8 i;
+	ssize_t err;
 
-	if (old_width == event->width && old_height == event->height) {
-		return TRUE;
-	} else {
-		old_width = event->width;
-		old_height = event->height;
-	}
-	
-	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 ();
+	i = 0;
+	buf[2] = buf[4] = 0x20;
+	buf[7] = 0x0A;
+	buf[8] = 0;
+
+	err = write (fd, _("iagno\n"), 6);
+	while (kifu[i][0] && err > 0)
+	{
+		buf[0] = (i + 1) / 10 + 0x30;
+		buf[1] = (i + 1) % 10 + 0x30;
+		buf[3] = (kifu[i][0] == BLACK) ? 0x42 : 0x57;
+		buf[5] = kifu[i][1] % 10 + 0x40;
+		buf[6] = kifu[i][1] / 10 + 0x30;
+
+		err = write (fd, buf, 8);
+		i++;
 	}
-	
-	return TRUE;
 }
 
-gint
-button_press_event (GtkWidget *widget, GdkEventButton *event)
+void
+read_kifu (int fd)
 {
-	guint x, y;
-
-	if (game_in_progress == 0)
-		return TRUE;
+	gchar buf[9];
+	gint8 i = 0;
+	ssize_t err;
 
-	if (!ggz_network_mode && (whose_turn == WHITE_TURN) && white_computer_level)
-		return TRUE;
-
-	if (!ggz_network_mode && (whose_turn == BLACK_TURN) && black_computer_level)
-		return TRUE;
-
-	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."));
-		} 
-			
+	err = read (fd, buf, 6);
+	buf[6] = 0;
+	if (!g_str_equal (buf, _("iagno\n")))
+	{
+		gui_message (_("not iagno's file"));
+		return;
 	}
-
-	return TRUE;
+	err = read (fd, buf, 8);
+	while (err > 0)
+	{
+		i = (buf[0] - 0x30) * 10 + buf[1] - 0x30 - 1;
+		kifu[i][0] = (buf[3] == 0x42) ? BLACK : WHITE;
+		kifu[i][1] = (buf[6] - 0x30) * 10 + buf[5] - 0x40;
+		err = read (fd, buf, 8);
+	}
+	kifu[i + 1][0] = 0;
 }
 
 void
-gui_draw_pixmap (gint which, gint x, gint y)
+on_open_activate (GtkMenuItem *menuitem, gpointer user_data)
 {
-	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);
+	game_in_progress = FALSE;
+	g_timer_stop (b_timer);
+	g_timer_stop (w_timer);
+	g_timer_reset (b_timer);
+	g_timer_reset (w_timer);
+	gui_timer ();
+	kifu[0][0] = 0;
+	file_open_dialog = create_file_open_dialog ();
+	gtk_widget_show (file_open_dialog);
 }
 
 void
-gui_draw_pixmap_buffer (gint which, gint x, gint y)
-{
-	gdk_draw_drawable (buffer_pixmap, gridGC[0], tiles_pixmap,
-			   (which % 8) * TILEWIDTH, (which / 8) * TILEHEIGHT,
-			   x * (TILEWIDTH + GRIDWIDTH),
-			   y * (TILEHEIGHT + GRIDWIDTH),
-			   TILEWIDTH, TILEHEIGHT);
+on_save_activate (GtkMenuItem *menuitem, gpointer user_data)
+{
+	GDate *date;
+	gchar filename[17];
+
+	date = g_date_new ();
+	g_date_set_time_t (date, time (NULL));
+	g_date_strftime (filename, 17, _("%y%m%d%H"), date);
+
+	file_save_dialog = create_file_save_dialog ();
+	gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER
+					   (file_save_dialog), filename);
+	gtk_widget_show (file_save_dialog);
+	g_date_free (date);
 }
 
+
 void
-gui_draw_grid (void)
-{
-	int i;
-        
-	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);
-	}
+on_redo_activate (GtkMenuItem *menuitem, gpointer user_data)
+{
+	if (game_in_progress)
+		return;
+	if (move_count < 4 || move_count > 63)
+		return;
 	
-	gdk_draw_drawable (drawing_area->window, gridGC[0], buffer_pixmap,
-			   0, 0, 0, 0, BOARDWIDTH, BOARDHEIGHT);
+	game_in_progress = TRUE;
+	kifu[move_count - 4][0] = 0;
+	check_game_over ();
+	check_computer_players ();
 }
 
 void
-load_pixmaps (void)
+on_hint_activate (GtkMenuItem *menuitem, gpointer user_data)
 {
-	GdkPixbuf *image;
-	GError    *error = NULL;
-	gchar      *tmp;
-	gchar      *fname;
-
-	g_return_if_fail (tile_set != NULL && tile_set [0] != '0');
-
-	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 (! 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);
-	}
+	gint best_yx;
 
-	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);
+	if (move_count < 4 || move_count > SIZE * SIZE - 1)
+		return;
+	if (!mobility (whose_turn))
+		return;
 
-	gdk_pixbuf_unref (image);
-	g_free (fname);
+	best_yx = computer_move (MAX_DEPTH);
+	gui_hint (best_yx, vsquares[0][0]);
 }
 
-gint
-flip_pixmaps (gpointer data)
+void
+on_help_activate (GtkMenuItem *menuitem, gpointer user_data)
 {
-	guint i, j;
-	guint flipped_tiles = 0;
-
-	if (! tiles_to_flip)
-		return TRUE;
-	
-	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)) {
-				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;
-
-	return TRUE;
+	gnome_help_display ("iagno.xml", NULL, NULL);
 }
 
-static void
-redraw_board (void)
+void
+on_about_activate (GtkMenuItem *menuitem, gpointer user_data)
 {
-	guint i, j;
-
-	gui_status();
+	const gchar *authors[] = {"Ian Peters", NULL};
 
-	for (i = 0; i < 8; i++)
-		for (j = 0; j < 8; j++)
-			gui_draw_pixmap_buffer (pixmaps[i][j], i, j);
+	const gchar *documenters[] = {"Eric Baudais", NULL};
 
-	gui_draw_grid ();
+	gtk_show_about_dialog (GTK_WINDOW (window),
+			       "name", _("Iagno"),
+			       "version", VERSION,
+			       "copyright", "Copyright \xc2\xa9 1998-2006 Ian Peters",
+			       "license", "GPL 2+",
+			       "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);
 }
 
-void
-clear_board (void)
+static gboolean
+check_back (void)
 {
-	guint i, j;
-
-	if (flip_final_id) {
+	if (flip_final_id)
+	{
 		g_source_remove (flip_final_id);
 		flip_final_id = 0;
 	}
-
-	if (black_computer_id) {
-		g_source_remove (black_computer_id);
-		black_computer_id = 0;
+	if (game_in_progress)
+	{
+		game_in_progress = FALSE;
+		if (whose_turn == BLACK)
+			g_timer_stop (b_timer);
+		else
+			g_timer_stop (w_timer);
 	}
-
-	if (white_computer_id) {
-		g_source_remove (white_computer_id);
-		white_computer_id = 0;
-	}
-
-	game_in_progress = 0;
-	move_count = 0;
-	for (i = 0; i < 8; i++)
-		for (j = 0; j < 8; j++)
-			board[i][j] = 0;
-
-	memcpy (pixmaps, board, sizeof (gint8) * 8 * 8);
-
-	bcount = 0;
-	wcount = 0;
-
-	redraw_board ();
+	return TRUE;
 }
 
 void
-init_new_game (void)
+on_head_button_clicked (GtkToolButton *toolbutton, gpointer user_data)
 {
-	clear_board ();
-	game_in_progress = 1;
-	move_count = 4;
-
-	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);
+	if (!check_back ())
+		return;
 
+	init ();
+	copy_board ();
+	copy_pixmaps ();
 	redraw_board ();
-
-	whose_turn = BLACK_TURN;
-	gui_status ();
-	gtk_widget_show (mainmenu[0].widget);
-	gtk_widget_show (mainmenu[1].widget);
-
-	check_computer_players ();
+	check_game_over ();
 }
 
 void
-create_window (void)
+on_back_button_clicked (GtkToolButton *toolbutton, gpointer user_data)
 {
-	GtkWidget *table;
-
-	window = gnome_app_new ("iagno", _("Iagno"));
-
-	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);
+	if (move_count <= 4)
+		return;
+	if (!check_back ())
+		return;	
 
-	gnome_appbar_set_status (GNOME_APPBAR (appbar),
-				 _("Welcome to Iagno!"));
+	back ();
+	copy_board ();
+	gui_status ();
+	flip_tiles = TRUE;
+	play_sound = TRUE;
+	check_game_over ();
 }
 
 void
-gui_status (void)
+on_forward_button_clicked (GtkToolButton *toolbutton, gpointer user_data)
 {
-	gchar message[3];
-
-	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);
-
-	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);
-	}
-
-	gtk_widget_set_sensitive (settings_menu[0].widget, !ggz_network_mode);
-
-	#ifndef GGZ_CLIENT
-	gtk_widget_set_sensitive (game_menu[1].widget, FALSE);
-	#endif
-
-	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"));
-	        }
+	guint who;
 
+	game_in_progress = FALSE;
+	who = (guint) kifu[move_count - 4][0];
+	if (!who)
+	{
+		if (!check_game_over ())
+		{
+			game_in_progress = TRUE;
+			check_computer_players ();
+		}
+		return;
 	}
-
-
+	whose_turn = who;
+	move ((guint) kifu[move_count - 4][1]);
 }
 
 void
-gui_message (gchar *message)
+on_last_button_clicked (GtkToolButton *toolbutton, gpointer user_data)
 {
-	gnome_appbar_pop (GNOME_APPBAR (appbar));
-        gnome_appbar_push (GNOME_APPBAR (appbar), message);
-}
-
-guint
-check_computer_players (void)
-{
-
-	if (ggz_network_mode) {
-		black_computer_id = 0;
-		white_computer_id = 0;
-		return TRUE;
+	game_in_progress = FALSE;
+	while (kifu[move_count - 4][0])
+	{
+		whose_turn = (guint) kifu[move_count - 4][0];
+		move_board ((guint) kifu[move_count - 4][1]);
+	}
+	copy_board ();
+	copy_pixmaps ();
+	redraw_board ();
+	if (!check_game_over ())
+	{
+		game_in_progress = TRUE;
+		check_computer_players ();
 	}
-	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;
 }
 
-void
-set_bg_color (void)
+static gboolean
+check_event_move (guint x, guint y)
 {
-	GdkImage *tmpimage;
-	GdkColor bgcolor;
-
-	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);
-
-	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);
-
-	gdk_gc_copy (gridGC [0],drawing_area->style->bg_gc[0]);
-	gdk_gc_copy (gridGC [1],drawing_area->style->bg_gc[0]);
+	guint yx;
 	
-	gdk_gc_set_background (gridGC [0],&bgcolor);
-	gdk_gc_set_foreground (gridGC [0],&bgcolor);
+	yx = y * (SIZE + 2) + x;
 	
-	/* 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);
-
-	gdk_gc_set_line_attributes (gridGC [1], 0,
-				    GDK_LINE_ON_OFF_DASH,
-				    GDK_CAP_BUTT, GDK_JOIN_MITER);
+	if (!game_in_progress)
+		return FALSE;
+	if (!check_valid_move (whose_turn, yx))
+	{
+		/* gui_message ("Invalid move."); */
+		return FALSE;
+	}
+
+	#ifdef GGZ_CLIENT
+	if (ggz_network_mode)
+		send_my_move(yx);
+	else
+	#endif
 	
-	g_object_unref (tmpimage);
+		move (yx);
+	return FALSE;
 }
 
-static int
-save_state (GnomeClient *client, gint phase, GnomeRestartStyle save_style,
-	    gint shutdown, GnomeInteractStyle interact_style,
-	    gint fast, gpointer client_data)
+gboolean
+on_drawing_area_button_press_event (GtkWidget *widget,
+				    GdkEventButton *event, gpointer user_data)
 {
-	char *argv[20];
-	int i;
-	gint xpos, ypos;
-
-	gdk_window_get_origin (window->window, &xpos, &ypos);
-
-	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);
+	guint x, y;
+ 	
+	if (event->button != 1)
+		return FALSE;
 
-	gnome_client_set_restart_command (client, i, argv);
-	gnome_client_set_clone_command (client, 0, NULL);
+	x = event->x / (tile_width + GRIDWIDTH) + 1;
+	y = event->y / (tile_height + GRIDWIDTH) + 1;
+	return check_event_move (x, y);
+}
 
-	g_free (argv[2]);
-	g_free (argv[4]);
+gboolean
+on_entry_key_press_event (GtkWidget *widget,
+					GdkEventKey *event, gpointer user_data)
+{
+	gchar *ch;
+	guint x, y;
 
-	return TRUE;
+	ch = gtk_entry_get_text (GTK_ENTRY (entry));
+	x = (guint) ((*ch++ & 0xdf) - 0x40);
+	if (!*ch)
+		return FALSE;
+	y = (guint) (*ch - 0x30);
+	if (y < 1 || y > SIZE)
+		return FALSE;
+	return check_event_move (x, y);
 }
 
 int
-main (int argc, char **argv)
-{
-	GnomeClient *client;
+main (int argc, char *argv[])
+{	
 	GnomeProgram *program;
-	GOptionContext *context;
 
 	gnome_score_init ("iagno");
 
@@ -871,53 +592,41 @@
 	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 	textdomain (GETTEXT_PACKAGE);
 
-        context = g_option_context_new ("");
-        g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
-
-	program = gnome_program_init ("iagno", VERSION,
-				      LIBGNOMEUI_MODULE,
-				      argc, argv,
-				      GNOME_PARAM_GOPTION_CONTEXT, context,
-				      GNOME_PARAM_APP_DATADIR, DATADIR, NULL);
+	program = gnome_program_init ("iagno", VERSION, LIBGNOMEUI_MODULE, argc, argv,
+			    GNOME_PARAM_APP_DATADIR, DATADIR, NULL);
 
+	gconf_init (argc, argv, NULL);
+	games_stock_init ();
 	gtk_window_set_default_icon_name ("gnome-iagno");
 
-	client= gnome_master_client ();
-
-	g_object_ref (G_OBJECT (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 ();
-	
 	load_properties ();
-
-	load_pixmaps ();
-
-	gtk_widget_show (window);
+	clear_board ();
+	window = create_window ();
+	reset_properties ();
+	apply_changes ();
+
+	set_sound ();
+	b_timer = g_timer_new ();
+	w_timer = g_timer_new ();
 
 	#ifdef GGZ_CLIENT
-	network_init ();
-	#endif
-
-	if (session_xpos >= 0 && session_ypos >= 0) {
-		gdk_window_move (window->window, session_xpos, session_ypos);
+	if (argc > 1)
+	{
+		network_init ();
+		ggz_network_mode = TRUE;
 	}
+	#endif
 
-	buffer_pixmap = gdk_pixmap_new (drawing_area->window,
-					BOARDWIDTH, BOARDHEIGHT, -1);
-
-	set_bg_color ();
-
-	init_new_game ();
+	network_gui_update ();
 
+	gui_message ("Welcome to Iagno!");
+/*	init_new_game (); */
 	gtk_main ();
 
+	#ifdef GGZ_CLIENT
+	if (ggz_network_mode && network_quit () < 0)
+		return -2;
+	#endif
 	g_object_unref (program);
-
 	return 0;
 }
-
Index: gnome-games/iagno/gnothello.h
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/gnothello.h,v
retrieving revision 1.25
diff -u -r1.25 gnothello.h
--- gnome-games/iagno/gnothello.h	5 Sep 2006 16:36:27 -0000	1.25
+++ gnome-games/iagno/gnothello.h	3 Oct 2006 04:55:38 -0000
@@ -1,6 +1,5 @@
 /*
- * gnothello.h - Header for gnothello.c
- * written by Ian Peters <itp@gnu.org>
+ * gnothello.h
  *
  * 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
@@ -19,71 +18,62 @@
  * For more details see the file COPYING.
  */
 
-#ifndef _GNOTHELLO_H_
-#define _GNOTHELLO_H_
+#define KEY_BLACK_LEVEL        "/apps/iagno/black_level"
+#define KEY_WHITE_LEVEL        "/apps/iagno/white_level"
+#define KEY_ANIMATE            "/apps/iagno/animate"
+#define KEY_QUICK_MOVES        "/apps/iagno/quick_moves"
+#define KEY_ANIMATE_STAGGER    "/apps/iagno/animate_stagger"
+#define KEY_SHOW_GRID          "/apps/iagno/show_grid"
+#define KEY_FLIP_FINAL_RESULTS "/apps/iagno/flip_final_results"
+#define KEY_TILESET            "/apps/iagno/tileset"
+#define KEY_BG_COLOR           "/apps/iagno/bg_color_name"
+#define KEY_BOARD_WIDTH        "/apps/iagno/board_width"
+#define KEY_BOARD_HEIGHT       "/apps/iagno/board_height"
+
+void copy_board (void);
+
+void copy_pixmaps (void);
 
-#define BLACK_TURN 1
-#define WHITE_TURN 31
-#define PIXMAP_FLIP_DELAY 20
-#define PIXMAP_STAGGER_DELAY 3
-#define COMPUTER_MOVE_DELAY 1000
-
-#define OTHER_PLAYER(w) (((w) == WHITE_TURN) ? BLACK_TURN : WHITE_TURN)
-
-#define TILEWIDTH   80
-#define TILEHEIGHT  80
-#define GRIDWIDTH   1
-#define BOARDWIDTH  ((TILEWIDTH+GRIDWIDTH)  * 8)
-#define BOARDHEIGHT ((TILEHEIGHT+GRIDWIDTH) * 8)
-
-#define MAIN_PAGE           	0
-#define NETWORK_PAGE           	1
-
-gboolean ggz_network_mode;
-int player_id;
-int seat;
-int seats[2];
-char names[2][17];
-
-extern GtkWidget *notebook;
-extern GtkWidget *window;
-
-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 black_level_cb (GtkWidget *widget, gpointer data);
-void white_level_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);
-void set_bg_color (void);
-void gui_draw_grid (void);
 
-#endif
+gboolean t_computer_move (gpointer level);
+
+gboolean move (guint yx);
+
+void init_new_game (void);
+
+void write_kifu (int fd);
+
+void read_kifu (int fd);
+
+void on_sync_activate (GtkMenuItem *menuitem, gpointer user_data);
+
+void on_again_activate (GtkMenuItem *menuitem, gpointer user_data);
+
+void on_open_activate (GtkMenuItem *menuitem, gpointer user_data);
+
+void on_save_activate (GtkMenuItem *menuitem, gpointer user_data);
+
+void on_redo_activate (GtkMenuItem *menuitem, gpointer user_data);
+
+void on_hint_activate (GtkMenuItem *menuitem, gpointer user_data);
+
+void on_help_activate (GtkMenuItem *menuitem, gpointer user_data);
+
+void on_about_activate (GtkMenuItem *menuitem, gpointer user_data);
+
+void on_head_button_clicked (GtkToolButton *toolbutton, gpointer user_data);
+
+void on_back_button_clicked (GtkToolButton *toolbutton, gpointer user_data);
+
+void on_forward_button_clicked (GtkToolButton *toolbutton, gpointer user_data);
+
+void on_last_button_clicked (GtkToolButton *toolbutton, gpointer user_data);
+
+gboolean
+on_drawing_area_button_press_event (GtkWidget *widget,
+				    GdkEventButton *event, gpointer user_data);
+
+gboolean
+on_entry_key_press_event (GtkWidget *widget,
+					GdkEventKey *event, gpointer user_data);
Index: gnome-games/iagno/iagno-client.dsc.in
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/iagno-client.dsc.in,v
retrieving revision 1.1
diff -u -r1.1 iagno-client.dsc.in
--- gnome-games/iagno/iagno-client.dsc.in	5 Sep 2006 16:36:27 -0000	1.1
+++ gnome-games/iagno/iagno-client.dsc.in	3 Oct 2006 04:55:38 -0000
@@ -2,7 +2,7 @@
 [ModuleInfo]
 Name = Iagno
 Author = The GNOME Project 
-CommandLine = @prefix@/bin/iagno
+CommandLine = @prefix@/bin/iagno -ggz
 Frontend = gtk
 Homepage = http://www.gnome.org/projects/gnome-games/
 ProtocolEngine = Iagno 
Index: gnome-games/iagno/othello.c
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/othello.c,v
retrieving revision 1.45
diff -u -r1.45 othello.c
--- gnome-games/iagno/othello.c	5 Sep 2006 16:36:27 -0000	1.45
+++ gnome-games/iagno/othello.c	3 Oct 2006 04:55:38 -0000
@@ -1,8 +1,5 @@
-/* -*- mode:C; indent-tabs-mode:t; tab-width:4; c-basic-offset:8; -*- */
-
 /*
- * othello.c - Othello support routines for iagno
- * written by Ian Peters <itp@gnu.org>
+ * othello.c - AI code for iagno.
  *
  * 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
@@ -21,694 +18,540 @@
  * For more details see the file COPYING.
  */
 
-#include <config.h>
 #include <gnome.h>
-#include <string.h>
-#include <games-clock.h>
 
 #include "othello.h"
-#include "gnothello.h"
 
-#define PERFECT   17
-#define VICTORY   19
-#define BEST      56
-#define MAX_DEPTH  7
-
-#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,
-                     32,62,37,67,13,16,31,61,
-                     38,68,83,86,14,15,41,51,
-                     48,58,84,85,24,25,42,52,
-                     74,75,47,57,36,63,33,35,
-                     53,66,46,64,34,43,56,65,
-                     12,17,21,71,28,78,82,87,
-                     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  };
+#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
+
+static guint8 squares[SIZE * SIZE] = {
+	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,
+	74, 75, 47, 57, 36, 63, 33, 35,
+	53, 66, 46, 64, 34, 43, 56, 65,
+	12, 17, 21, 71, 28, 78, 82, 87,
+	22, 27, 72, 77, 11, 18, 81, 88
+};
+
+static const gint heuristic[(SIZE + 2) * (SIZE + 2)] = {
+	0,   0,   0, 0, 0, 0, 0,   0,   0, 0,
+	0, 145, -23, 6, 4, 4, 6, -23, 145, 0,
+	0, -23, -65, 3, 2, 2, 3, -65, -23, 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, -23, -65, 3, 2, 2, 3, -65, -23, 0,
+	0, 145, -23, 6, 4, 4, 6, -23, 145, 0,
+	0,   0,   0, 0, 0, 0, 0,   0,   0, 0
+};
 
 static const gint dirs[] = { UL, UU, UR, LL, RR, DL, DD, DR };
 
-guint flip_final_id = 0;
-gint flip_final;
-
-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;
+/* This array can probably be a lot smaller (< 300). */
+static guint8 history[600];
+static guint  hpointer;
+static guint  vpointer;
+static guint  s_kind;
+static GRand  *rgen;
+
+guint8 board0[(SIZE + 2) * (SIZE + 2)];
+gint   vsquares[280][2];
+guint  move_count;
+guint  whose_turn;
+guint  bcount;
+guint  wcount;
 
 /* Initialization of data */
 void
-init ( void )
+init (void)
 {
-    gint i,j;
-    gint x;
-
-    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;
-                else                         board0[x] = BLANK;
-                x++;
-            }
-
-    board0[ 44 ] = WHITE_TURN;
-    board0[ 45 ] = BLACK_TURN;
-    board0[ 54 ] = BLACK_TURN;
-    board0[ 55 ] = WHITE_TURN;
+	guint i, j, ij;
 
-    hpointer = 0;
-    vpointer = 0;
-}
-
-/* Copy data from board0 to board */
-void
-board_copy ( void )
-{
-    gint i,j;
+	rgen = g_rand_new ();
 
-    for ( j = 0; j < 8; j++ )
-        for ( i = 0; i < 8; i++ )
-            board[ i ][ j ] = board0[ ( j + 1 ) * 10 + i + 1 ];
+	ij = 0;
+	for (i = 0; i < SIZE + 2; i++)
+		for (j = 0; j < SIZE + 2; j++)
+		{
+			if (i == 0 || i == SIZE + 1)
+				board0[ij] = OUTSIDE;
+			else if (j == 0 || j == SIZE + 1)
+				board0[ij] = OUTSIDE;
+			else
+				board0[ij] = BLANK;
+			ij++;
+		}
+
+	board0[44] = WHITE;
+	board0[45] = BLACK;
+	board0[54] = BLACK;
+	board0[55] = WHITE;
+
+	hpointer = 0;
+	vpointer = 0;
+	move_count = 4;
+	whose_turn = BLACK;
+	bcount = 2;
+	wcount = 2;
 }
 
 /* Check the validity of the move in a given direction. */
-static
-gint
-is_valid0 (gint xy, gint dir, gint who)
+static gboolean
+is_valid0 (guint who, guint yx, gint dir)
 {
-    gint tmp;
-    gint8 not_me;
-
-    not_me = OTHER_PLAYER (who);
+	guint tmp, not_me;
 
-    /* To be valid, the next counter should not be the current player ... */
-    tmp = xy + dir;
-    if ( board0[tmp] != not_me )
-            return FALSE;
+	not_me = OTHER_PLAYER (who);
 
-    /* ... but eventually we must find a counter that is. */
-    do { tmp += dir; } while ( board0[tmp] == not_me );
+	/* To be valid, the next counter should not be the current player ... */
+	tmp = yx + dir;
+	if (board0[tmp] != (guint8)not_me)
+		return FALSE;
+
+	/* ... but eventually we must find a counter that is. */
+	do
+	{
+		tmp += dir;
+	}
+	while (board0[tmp] == (guint8)not_me);
 
-    return board0[tmp] == who;
+	return board0[tmp] == (guint8)who;
 }
 
 /* Check if a given (empty) square can provide a valid move */
-static
-gint
-is_valid (gint xy, gint who)
-{
-    int i;
-
-    for (i=0; i<NDIRS; i++)
-            if ( is_valid0( xy, dirs[i], who ) ) return( TRUE );
-
-    return FALSE;
-}
-
-/* Check whether the supplied move is a valid one. */
-gint
-is_valid_move (guint x, guint y, guint who) {
-    gint xy;
-
-    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)
+gboolean
+is_valid (guint who, guint yx)
 {
-    gint8 tmp;
-    guint not_me;
+	guint i;
 
-    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;
-        }
+	for (i = 0; i < NDIRS; i++)
+		if (is_valid0 (who, yx, dirs[i]))
+			return (TRUE);
+
+	return FALSE;
+}
+
+static void
+move_board0 (guint yx, gint dir)
+{
+	guint tmp;
+	guint not_me;
+
+	not_me = OTHER_PLAYER (whose_turn);
+	tmp = yx + dir;
+	if (board0[tmp] != (guint8)not_me)
+		return;
+	/* Find the extent of the move in direction dir. */
+	do
+	{
+		tmp += dir;
+	}
+	while (board0[tmp] == (guint8)not_me);
+	if (board0[tmp] != (guint8)whose_turn)
+		return;
+
+	/* Now walk back to where we started flipping pieces over. */
+	tmp -= dir;
+	while (tmp != yx)
+	{
+		board0[tmp] = (guint8)whose_turn;  /* Flip pieces    */
+		history[hpointer++] = (guint8)tmp; /* Record history */
+		tmp -= dir;
+	}
 }
 
 /* reverse some pieces */
 void
-move_board (gint xy)
-{
-    gint tmp, count;
-    int i;
-
-    count = hpointer;
-
-    for (i=0; i<NDIRS; i++)
-            move_board0( xy, dirs[i] );
-
-    board0[xy] = whose_turn;
-    count = hpointer-count;
-    history[ hpointer++ ] = count;     /* make history */
-    history[ hpointer++ ] = whose_turn;
-
-    if ( whose_turn == WHITE_TURN )
-        {
-            wcount += count+1;
-            bcount -= count;
-        }
-    else
-        {
-            bcount += count+1;
-            wcount -= 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)
+move_board (guint yx)
 {
-    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();
+	guint count, i, tmp;
 
-    pixmaps[ x ][ y ] = (gint8)me;
-    gui_draw_pixmap( me, x, y );
+	count = hpointer;
 
-    gui_status();
+	for (i = 0; i < NDIRS; i++)
+		move_board0 (yx, dirs[i]);
 
-    tiles_to_flip = 1;
-    check_valid_moves();
-    check_computer_players();
-
-    return FALSE;
+	board0[yx] = (guint8)whose_turn;
+	count = hpointer - count;
+	history[hpointer++] = (guint8)count;	/* history[t1,t2,,,tn, n,who] */
+	history[hpointer++] = (guint8)whose_turn;
+	if (whose_turn == WHITE)
+	{
+		wcount += count + 1;
+		bcount -= count;
+	}
+	else
+	{
+		bcount += count + 1;
+		wcount -= count;
+	}
+	i = move_count++;		 /* increase move_count */
+	tmp = (guint)squares[i]; /* squares[0,1,2,3.,,move_count,,,62,63] */
+	squares[i] = (guint8)yx; /*        [-already puted-|-yet blank--] */
+	if (tmp != yx)			 /* sort squares */
+	{
+		while (squares[++i] != (guint8)yx);
+		squares[i] = (guint8)tmp;
+	}
+	whose_turn = OTHER_PLAYER (whose_turn);
 }
 
 /* Back to before board0 */
 void
-undo ( void )
+back (void)
 {
-    gint8 not_me, count;
-
-    whose_turn = history[ --hpointer ];     /* history[t1,t2,,,tn, n,who] */
-    count = history[ --hpointer ];
+	guint count, not_me;
 
-    if ( whose_turn == WHITE_TURN )
-        {
-            wcount -= count+1;
-            bcount += count;
-        }
-    else
-        {
-            bcount -= count+1;
-            wcount += count;
-        }
-
-    board0[ squares[ --move_count ]] = BLANK;  /* decrease move_count    */
-
-    not_me = OTHER_PLAYER (whose_turn);
-    while ( count > 0 )
-        {
-            board0[ history[ --hpointer ] ] = not_me;
-            count--;
-        }
-}
+	whose_turn = (guint)history[--hpointer];	/* history[t1,t2,,,tn, n,who] */
+	count = (guint)history[--hpointer];
 
-/* Sort vsquares by small order */
-static
-void
-sort (gint l, gint r)
-{
-    gint i, j, v, w, x;
+	if (whose_turn == WHITE)
+	{
+		wcount -= count + 1;
+		bcount += count;
+	}
+	else
+	{
+		bcount -= count + 1;
+		wcount += count;
+	}
 
-    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 );
+	board0[squares[--move_count]] = BLANK;	/* decrease move_count    */
 
-    if ( l < j ) sort( l, j );
-    if ( i < r ) sort( i, r );
+	not_me = OTHER_PLAYER (whose_turn);
+	while (count > 0)
+	{
+		board0[history[--hpointer]] = (guint8)not_me;
+		count--;
+	}
 }
 
-static
-gint
-eval_heuristic( void )
+static gint
+eval_heuristic (void)
 {
-    gint8 i, xy;
-    gint count = 0;
+	guint 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 ];
-        }
+	for (i = 0; i < move_count; i++)
+	{
+		yx = (guint)squares[i];
+		if (board0[yx] == (guint8)whose_turn)
+			count += heuristic[yx];
+		else
+			count -= heuristic[yx];
+	}
 
-    return count;
+	return count;
 }
 
-static
 gint
-mobility( void )
+mobility (guint who)
 {
-    gint8 i, xy;
-    gint count = 0;
+	guint i, yx;
+	gint count = 0;
 
-    for ( i = move_count; i < 64; i++ )
-        {
-            xy = squares[ i ];
-            if ( is_valid( xy, whose_turn ) ) count++;
-        }
+	for (i = move_count; i < SIZE * SIZE; i++)
+	{
+		yx = (guint)squares[i];
+		if (is_valid (who, yx))
+			count++;
+	}
 
-    return count;
+	return count;
 }
 
-static
-gint
-around0(gint xy)
+static gint
+around0 (guint yx)
 {
-    gint count = 0;
-    int i;
+	guint i;
+	gint count = 0;
 
-    for (i=0; i<NDIRS; i++)
-            if ( board0[ xy + dirs[i] ] == BLANK ) count--;
+	for (i = 0; i < NDIRS; i++)
+		if (board0[yx + dirs[i]] == BLANK)
+			count--;
 
-    if ( !count ) count = 2;
+	if (!count)
+		count = 2;
 
-    return count;
+	return count;
 }
 
-static
-gint
-around( void )
+static gint
+around (void)
 {
-    gint8 i, xy;
-    gint count = 0;
+	guint 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 );
-        }
+	for (i = 0; i < move_count; i++)
+	{
+		yx = (guint)squares[i];
+		if (board0[yx] == (guint8)whose_turn)
+			count += around0 (yx);
+		else
+			count -= around0 (yx);
+	}
 
-    return count;
+	return count;
 }
 
-/* Evaluate the board   */
-static
-gint
-b_evaluation( void )
+/* Best evaluation */
+static gint
+b_evaluation (void)
 {
-    gint score1, score2, score3;
-
-    score1 = mobility();
-    whose_turn = OTHER_PLAYER (whose_turn);
-    score1 -= mobility();
-    whose_turn = OTHER_PLAYER (whose_turn);
-
-    score2 = around();
-    score3 = eval_heuristic();
+	gint score1, score2, score3;
 
-    return score1 + score2 + score3;
+	score1 = mobility (whose_turn);
+	score1 -= mobility (OTHER_PLAYER (whose_turn));
+	score2 = around ();
+	score3 = eval_heuristic ();
+	return score1 * 2 + score2 + score3 / 2;
 }
 
 /* Victory evaluation */
-static
-gint
-v_evaluation( void )
+static gint
+v_evaluation (void)
 {
-    gint aa;
-
-    aa = wcount - bcount;
-    if ( whose_turn == BLACK_TURN ) aa = -aa;
+	gint aa;
 
-    if ( aa > 0 ) return  1;    /* win  */
-    if ( aa < 0 ) return -1;    /* lose */
-    return 0;                   /* draw */
+	aa = wcount - bcount;
+	if (whose_turn == BLACK)
+		aa = -aa;
+
+	if (aa > 0)
+		return 1;	/* win  */
+	if (aa < 0)
+		return -1;	/* lose */
+	return 0;		/* draw */
+}
+
+/* Perfect evaluation */
+static gint
+p_evaluation (void)
+{
+	if (whose_turn == WHITE)
+		return wcount - bcount;
+	return bcount - wcount;
+}
+
+/* Win evaluation under best search */
+static gint
+w_evaluation (void)
+{
+	gint aa;
+
+	aa = wcount - bcount;
+	if (whose_turn == BLACK)
+		aa = -aa;
+
+	if (!bcount || !wcount)
+	{
+		if (aa > 0)
+			return aa + 10000;
+		return aa - 10000;
+	}
+
+	if (aa > 0)
+		return aa + 1000;
+	if (aa < 0)
+		return aa - 1000;
+	return 0;
+}
+
+/* entry valid squares */
+static gint
+entry_valid_squares (void)
+{
+	gint i, j, yx;
+
+	j = vpointer;				
+	for (i = move_count; i < SIZE * SIZE; i++)
+	{
+		yx = (gint)squares[i];
+		if (is_valid (whose_turn, yx))
+		{
+			j++;
+			vsquares[j][1] = yx;
+			move_board (yx);
+			vsquares[j][0] = mobility (whose_turn);	/* simple evaluation */
+			back ();
+		}
+	}
+	return j;
 }
 
-static
-gint
-p_evaluation( void )
-{
-
-    if ( whose_turn == WHITE_TURN )
-            return wcount - bcount;
-
-    return bcount - wcount;
-}
-
-static
-gint
-w_evaluation( void )
+/* Sort vsquares by small order */
+static void
+sort (guint l, guint r)
 {
-    gint aa;
+	guint i, j;
+	gint v, w, x;
 
-    if ( !bcount || !wcount )
-        {
-            if ( whose_turn == WHITE_TURN && !bcount )   return 10000;
-            if ( whose_turn == BLACK_TURN && !wcount )   return 10000;
-            return -10000;
-        }
-
-    aa = wcount - bcount;
-    if ( whose_turn == BLACK_TURN ) aa = -aa;
-
-    if ( aa > 0 ) return aa + 100;
-    if ( aa < 0 ) return aa - 100;
-    return( 0 );
+	i = l;
+	j = r;
+	x = vsquares[(l + r) / 2][0];
+	do
+	{
+		while (vsquares[i][0] < x)
+			i++;
+		while (x < vsquares[j][0])
+			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);
 }
 
 /* alpha-beta search */
-static
-gint
-search(gint n, gint a, gint b)
-{
-    gint aa, bb, xy, i, j;
-
-    if ( !n )
-    {
-        switch (s_kind)
-                {
-                    case PERFECT:
-                            return( p_evaluation() );
-                    case VICTORY:
-                            return( v_evaluation() );
-                    default:
-                            return( b_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);
-
-                    switch ( s_kind )
-                        {
-                            case PERFECT:       return( p_evaluation() );
-                            case VICTORY:       return( v_evaluation() );
-                            default:            return( w_evaluation() );
-                        }
-                }
-            aa = -search( n, -b, -aa );
-            whose_turn = OTHER_PLAYER (whose_turn);
-            vsquares[ j ][ 0 ] = 0;        /* mark pass              */
-            return aa;
-        }
-
-    sort( vpointer + 1, j );
-
-    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 = bb;
-                    vsquares[ i ][ 0 ] = xy;   /* save this square       */
-                }
-            j++;
-        }
-    vpointer = i;                          /* pop vpointer           */
-    return aa;
-}
-
-static
-void
-random_select( void )
-{
-    gint xy, i, j;
-
-    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 ];
-        }
-}
-
-static
-gint
-computer_move (gint level)
-{
-    gint nn, aa, kind, best_xy;
-
-    vsquares[ 0 ][ 0 ] = -1;
-    nn = 64 - move_count;
-    if  ( nn > BEST )  random_select();
-    else
-        {
-            if ( nn <= PERFECT - level )
-                { kind = PERFECT;  aa = 127; }
-            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. */
-        {
-            s_kind = BEST;
-            vsquares[ 0 ][ 1 ] = search( MAX_DEPTH - level, -32767, 32767 );
-            best_xy = vsquares[ 0 ][ 0 ];
-        }
-
-    if ( best_xy )
-        move ( best_xy % 10 - 1, best_xy / 10 - 1, whose_turn );
-
-    return FALSE;
-}
-
-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)
+static gint
+search (guint n, gint a, gint b)
 {
-    guint white_moves = 0;
-    guint black_moves = 0;
+	guint i, j, yx;
+	gint aa, bb;
 
-    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);
-            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;
-        }
+	if (!n)					/* end ? */
+	{
+		switch (s_kind)
+		{
+			case PERFECT:
+				return p_evaluation ();
+			case VICTORY:
+				return v_evaluation ();
+			default:
+				return b_evaluation ();
+		}
+	}
+
+	aa = a;
+	j = entry_valid_squares ();
+	if (j == vpointer)			/* pass ? */
+	{
+		whose_turn = OTHER_PLAYER (whose_turn);
+		if (!mobility (whose_turn))	/* end ?  */
+		{
+			whose_turn = OTHER_PLAYER (whose_turn);
+			switch (s_kind)
+			{
+				case PERFECT:
+					return p_evaluation ();
+				case VICTORY:
+					return v_evaluation ();
+				default:
+					return w_evaluation ();
+			}
+		}
+
+		aa = -search (n, -b, -aa);
+		whose_turn = OTHER_PLAYER (whose_turn);
+		vsquares[j][1] = 0;		/* mark pass       */
+		return aa;
+	}
+
+	sort (vpointer + 1, j);		/* sort vsquares    */
+	i = vpointer;				/* save vpointer    */
+	vpointer = j + 1;			/* new vpointer     */
+
+	j = i + 1;
+	while (aa < b && j < vpointer)	/* evaluate squares */
+	{
+		yx = vsquares[j][1];
+		move_board (yx);
+		bb = -search (n - 1, -b, -aa);
+		back ();
+		if (aa < bb)
+		{
+			aa = bb;
+			vsquares[i][1] = yx;	/* save this square  */
+		}
+		j++;
+	}
+	vpointer = i;				/* pop vpointer      */
+	return aa;
+}
+
+/* for first 6 turns */
+static gint
+random_select (void)
+{
+	guint i, j;
+
+	j = entry_valid_squares ();
+	i = vpointer + 1;
+	if (j > i)
+	{
+		i = g_rand_int_range (rgen, i, j + 1); /* If the square is critical */
+		if (heuristic[vsquares[i][1]] < 0)     /* then select once more,    */  
+			i = g_rand_int_range (rgen, 1, j + 1); /* but not three times.  */
+	}
+
+	vsquares[0][1] = vsquares[i][1];
+	return 0;
+}
+
+gint
+computer_move (guint level)
+{
+	guint depth, nn, kind;
+	gint aa, best_yx;
+
+	vsquares[0][1] = -1;
+	depth = level;
+	nn = SIZE * SIZE - move_count;
+	kind = PERFECT;
+	aa = 127;
+	if (nn > BEST)
+		vsquares[0][0] = random_select ();
+	else
+	{
+		if (PERFECT - MAX_DEPTH + depth < nn && nn <= VICTORY - MAX_DEPTH + depth)
+		{
+			kind = VICTORY;
+			aa = 2;
+		}
+		if (VICTORY - MAX_DEPTH + depth < nn && nn <= BEST)
+		{
+			kind = BEST;
+			aa = 32767;
+			nn = depth;
+		}
+		s_kind = kind;
+		vsquares[0][0] = search (nn, -aa, aa);
+	}
+
+	best_yx = vsquares[0][1];
+	if (best_yx == -1)	/* If I can't win, then search the best again. */
+	{
+		s_kind = BEST;
+		vsquares[0][0] = search (depth, -32767, 32767);
+		best_yx = vsquares[0][1];
+	}
 
-    return TRUE;
+	return best_yx;
 }
Index: gnome-games/iagno/othello.h
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/othello.h,v
retrieving revision 1.9
diff -u -r1.9 othello.h
--- gnome-games/iagno/othello.h	5 Jan 2006 06:02:21 -0000	1.9
+++ gnome-games/iagno/othello.h	3 Oct 2006 04:55:38 -0000
@@ -1,6 +1,5 @@
 /*
- * othello.h - Header for othello.c
- * written by Ian Peters <itp@gnu.org>
+ * othello.h
  *
  * 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
@@ -19,20 +18,26 @@
  * For more details see the file COPYING.
  */
 
-#ifndef _OTHELLO_H_
-#define _OTHELLO_H_
+#define SIZE        8
+#define BEST       54
+#define VICTORY    20
+#define PERFECT    18
+#define MAX_DEPTH   8
+
+#define BLACK       1
+#define WHITE      31
+#define BLANK     127
+#define OUTSIDE (BLACK + WHITE)
+#define OTHER_PLAYER(who) (OUTSIDE - who)
 
-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);
 void init (void);
-void board_copy (void);
-void undo (void);
 
-#endif
+gboolean is_valid (guint who, guint yx);
+
+void move_board (guint yx);
+
+void back (void);
+
+gint mobility (guint who);
+
+gint computer_move (guint level);
Index: gnome-games/iagno/properties.c
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/properties.c,v
retrieving revision 1.34
diff -u -r1.34 properties.c
--- gnome-games/iagno/properties.c	6 Jun 2005 22:51:13 -0000	1.34
+++ gnome-games/iagno/properties.c	3 Oct 2006 04:55:38 -0000
@@ -1,7 +1,5 @@
-/* -*- mode:C; indent-tabs-mode:t; tab-width:8; c-basic-offset:8; -*- */
-
 /*
- * Properties.c - Properties and preferences part of iagno
+ * properties.c - properties dialog code for iagno.
  *
  * 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
@@ -20,689 +18,1301 @@
  * For more details see the file COPYING.
  */
 
-#include <config.h>
+#include "config.h"
 #include <gnome.h>
-#include <string.h>
+#include <glib.h>
 #include <gconf/gconf-client.h>
-#include <games-gconf.h>
-#include <games-frame.h>
-#include <games-files.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+
+#include "games-stock.h"
+#include "games-preimage.h"
 
-#include "properties.h"
-#include "gnothello.h"
 #include "othello.h"
+#include "gnothello.h"
 
-#define KEY_TILESET "/apps/iagno/tileset"
-#define KEY_BLACK_LEVEL "/apps/iagno/black_level"
-#define KEY_WHITE_LEVEL "/apps/iagno/white_level"
-#define KEY_QUICK_MOVES "/apps/iagno/quick_moves"
-#define KEY_ANIMATE "/apps/iagno/animate"
-#define KEY_ANIMATE_STAGGER "/apps/iagno/animate_stagger"
-#define KEY_SHOW_GRID "/apps/iagno/show_grid"
-#define KEY_FLIP_FINAL_RESULTS "/apps/iagno/flip_final_results"
-
-
-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;
-
-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;
+#include "properties.h"
 
-static GamesFileList * theme_file_list = NULL;
+gint8     pixmaps[SIZE][SIZE];
+gint8     board[SIZE][SIZE];
 
-static void apply_changes (void);
+GtkWidget *window;
+GtkWidget *file_open_dialog;
+GtkWidget *file_save_dialog;
+GtkWidget *counter;
+GtkWidget *score[4];
+GtkWidget *entry;
+GTimer    *b_timer;
+GTimer    *w_timer;
+
+guint     tile_width;
+guint     tile_height;
+guint     black_computer_level;
+guint     white_computer_level;
+gboolean  flip_final;
+guint     computer_speed;
+gboolean  game_in_progress;
+gboolean  play_sound = FALSE;
+gboolean  gameover = FALSE;
+gboolean  flip_tiles = FALSE;
+guint     flip_final_id = 0;
+guint     computer_id = 0;
+
+static GtkWidget *properties_dialog = NULL;
+static GtkWidget *drawing_area;
+static GtkWidget *menubar;
+static GtkWidget *toolbar;
+static GtkWidget *statusbar;
+static GdkGC     *gridGC[2] = { 0 };
+static GdkColor  bg_color[3] = {{0,0,0,0},      /* background color */
+            {0xffffffff,0xffff,0xffff,0xffff},  /* grid color */
+            {0,0,0,0}};                         /* tmp color  */
+static guint     board_width;
+static guint     board_height;
+static gboolean  animate;
+static gboolean  quick_moves;
+static gboolean  animate_stagger;
+static gboolean  grid;
+static gchar     *tile_set;
+static gchar     *bg_color_name;
+static guint     flip_speed;
+static GdkPixmap *buffer_pixmap = NULL;
+static GdkPixmap *tiles_pixmap = NULL;
+static gchar     *flip_sound;
+static gchar     *gameover_sound;
+static guint     context_id = 0;
+static guint     flip_pixmaps_id = 0;
+static guint     timer_id = 0;
+static guint     t_image_id = 0;
+
+static guint     t_computer_level[2];
+static gboolean  t_options[5];
+static gchar     *t_tile_set;
+static gchar     *t_bg_color_name;
+
+static GtkActionGroup *action_group;
+static GtkUIManager *manager;
+static GtkAction *open_action;
+static GtkAction *new_game_action;
+static GtkAction *redo_game_action;
+static GtkAction *show_hint_action;
+static GtkAction *sync_action;
+static GtkAction *again_action;
+static GtkAction *preferences_action;
+static GamesPreimage *t_image;
+
+extern guint     bcount;
+extern guint     wcount;
+extern guint     move_count;
+extern guint     whose_turn;
 
-/*
- * FIXME:
- * 	This was only a quick port to gconf.
- *	It doesn't abide by the HIG.
- */
+extern gboolean  ggz_network_mode;
 
-static gint clamp_int (gint input, gint low, gint high)
+gint
+clamp_int (gint input, gint low, gint high)
 {
-        if (input < low)
-                input = low;
-        if (input > high)
-                input = high;
+	if (input < low)
+		input = low;
+	if (input > high)
+		input = high;
 
-        return input;
+	return input;
 }
 
-void 
-load_properties (void)
+static void
+set_board_size (void)
 {
-	GConfClient *client;
-	GError      *error = NULL;
-
-	client = gconf_client_get_default ();
-	if (!games_gconf_sanity_check_string (client, KEY_TILESET)) {
-		exit(1);
-	}
-	black_computer_level = gconf_client_get_int (client, KEY_BLACK_LEVEL, &error);
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-        black_computer_level = clamp_int (black_computer_level, 0, 3);
-	
-	white_computer_level = gconf_client_get_int (client, KEY_WHITE_LEVEL, &error);
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-        white_computer_level = clamp_int (white_computer_level, 0, 3);
+	gint depth = -1;
 	
-	if (gconf_client_get_bool (client, KEY_QUICK_MOVES, &error))
-		computer_speed = COMPUTER_MOVE_DELAY / 2;
-	else
-		computer_speed = COMPUTER_MOVE_DELAY;
-
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
+	board_width = clamp_int(board_width, BOARD_MIN, BOARD_W_MAX);
+	board_height = clamp_int(board_height, BOARD_MIN, BOARD_H_MAX);
+	tile_width = (board_width - GRIDWIDTH * (SIZE - 1)) / SIZE;
+	tile_height = (board_height - GRIDWIDTH * (SIZE - 1)) / SIZE;
+	board_width = tile_width * SIZE + GRIDWIDTH * (SIZE - 1);
+	board_height = tile_height * SIZE + GRIDWIDTH * (SIZE - 1);
+	save_properties ();
+	
+	gtk_widget_set_size_request (drawing_area, board_width, board_height);
+	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);
+}
 
-	if (tile_set)
-		g_free (tile_set);
-
-	tile_set = gconf_client_get_string (client, KEY_TILESET, &error);
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-	if (tile_set == NULL)
-		tile_set = g_strdup ("classic.png");
-	
-	animate = gconf_client_get_int (client, KEY_ANIMATE, &error);
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-        animate = clamp_int (animate, 0, 2);
-
-	animate_stagger = gconf_client_get_bool (client, KEY_ANIMATE_STAGGER, &error);
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-
-	grid = gconf_client_get_bool (client, KEY_SHOW_GRID, &error);
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-
-	flip_final = gconf_client_get_bool (client, KEY_FLIP_FINAL_RESULTS, &error);
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-
-	switch (animate) {
-	case 0:
-		flip_pixmaps_id = g_timeout_add (100, flip_pixmaps, &error);
-		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;
+static void
+set_bg_color (void)
+{
+	gint i;
+	
+	gdk_color_parse (bg_color_name, &bg_color[0]);
+	gdk_colormap_alloc_color (gtk_widget_get_colormap (drawing_area),
+				&bg_color[0], FALSE, TRUE);
+	
+	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]);
 	}
+}
 
-	g_object_unref (client);
+static gboolean
+free_t_image (gpointer user_data)
+{
+	g_object_unref (t_image);
+	t_image = NULL;
+	t_image_id = 0;
+	return FALSE;
 }
 
 static void
-reset_properties (void)
+load_image (gchar *tileset)
 {
-	GConfClient *client;
-	GError      *error = NULL;
-
-	client = gconf_client_get_default ();
+	gchar *fname, *pathname;
+	GError *error = NULL;
 
-	black_computer_level =
-		gconf_client_get_int (client, KEY_BLACK_LEVEL, &error);
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-        t_black_computer_level = black_computer_level
-		= clamp_int (black_computer_level, 0, 3);
-
-	white_computer_level =
-		gconf_client_get_int (client, KEY_WHITE_LEVEL, &error);
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-        t_white_computer_level = white_computer_level
-		= clamp_int (white_computer_level, 0, 3);
-	
-	t_quick_moves = gconf_client_get_bool (client, KEY_QUICK_MOVES, &error);
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-
-	if (tile_set_tmp)
-		g_free (tile_set_tmp);
-
-	tile_set_tmp = gconf_client_get_string (client, KEY_TILESET, &error);
-	if (error) {
-		g_warning (G_STRLOC ": gconf error: %s\n", error->message);
-		g_error_free (error);
-		error = NULL;
-	}
-	if (tile_set_tmp == NULL)
-		tile_set_tmp = g_strdup("classic.png");
-	
-	t_animate         = animate;
-	t_animate_stagger = animate_stagger;
-	t_grid            = grid;
-	t_flip_final      = flip_final;
+	if (t_image)
+		return;
+	fname = g_build_filename ("iagno", tileset, NULL);
+	pathname = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_APP_PIXMAP,
+					   fname, TRUE, NULL);
+	t_image = games_preimage_new_from_file (pathname, &error);
+	g_free (fname);
+	t_image_id = g_timeout_add (3000,
+					(GSourceFunc) free_t_image, NULL);
+}
 
-	g_object_unref (client);
+static void
+load_pixmaps (void)
+{
+	GdkPixbuf *image;
+	gint depth = -1;
+	GdkGC *gc;
+	
+	load_image (tile_set);
+	if (!t_image)
+	{
+		if (tile_set)
+			g_free (tile_set);
+		tile_set = g_strdup (_("marble.svg"));
+		load_image (tile_set);
+		if (!t_image)
+		{
+			g_print (_("Could not find \'%s\' pixmap file\n"), _("iagno/marble.svg"));
+			exit (1);
+		}
+		save_properties ();
+		reset_properties ();
+	}
+
+	image = games_preimage_render (t_image,
+				tile_width * 8, tile_height * 4, NULL);
+
+	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);
+
+	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 (image);
 }
 
-static void 
-black_computer_level_select (GtkWidget *widget, gpointer data)
+static void
+gui_draw_pixmap_buffer (guint x, guint y, guint which)
 {
-	if ((GPOINTER_TO_INT(data) != t_black_computer_level) 
-	    && (GTK_TOGGLE_BUTTON (widget)->active)) {
-		t_black_computer_level = GPOINTER_TO_INT(data);
-		apply_changes ();
-	}
+	gdk_draw_drawable (buffer_pixmap, gridGC[0], tiles_pixmap,
+			    tile_width * (which % 8),    tile_height * (which / 8),
+			   (tile_width + GRIDWIDTH) * x,(tile_height + GRIDWIDTH) * y,
+			    tile_width,                  tile_height);
 }
 
-static void 
-white_computer_level_select (GtkWidget *widget, gpointer data)
+static void
+gui_draw_pixmap (guint x, guint y, guint which)
 {
-	if ((GPOINTER_TO_INT(data) != t_white_computer_level)
-	    && (GTK_TOGGLE_BUTTON (widget)->active)) {
-		t_white_computer_level = GPOINTER_TO_INT(data);
-		apply_changes ();
-	}
+	gui_draw_pixmap_buffer (x, y, which);
+	gdk_draw_drawable (drawing_area->window, gridGC[0], tiles_pixmap,
+			    tile_width * (which % 8),    tile_height * (which / 8),
+			   (tile_width + GRIDWIDTH) * x,(tile_height + GRIDWIDTH) * y,
+			    tile_width,                  tile_height);
 }
 
-static void 
-quick_moves_select (GtkWidget *widget, gpointer data)
+static void
+gui_draw_grid (guint j)
 {
-	if (GTK_TOGGLE_BUTTON (widget)->active)
-		t_quick_moves = 1;
-	else
-		t_quick_moves = 0;
-	apply_changes ();
+	guint i;
+
+	gdk_gc_set_line_attributes (gridGC[1], GRIDWIDTH, GDK_LINE_ON_OFF_DASH,
+				    GDK_CAP_BUTT, GDK_JOIN_MITER);
+		
+	for (i = tile_height; i < board_height; i += tile_height + GRIDWIDTH)
+		gdk_draw_line (buffer_pixmap, gridGC[j], 0, i, board_width, i);
+	for (i = tile_width; i < board_width; i += tile_width + GRIDWIDTH)
+		gdk_draw_line (buffer_pixmap, gridGC[j], i, 0, i, board_height);
 }
 
-static void 
-flip_final_select (GtkWidget *widget, gpointer data)
+void
+redraw_board (void)
 {
-	if (GTK_TOGGLE_BUTTON (widget)->active)
-		t_flip_final = 1;
-	else
-		t_flip_final = 0;
-	apply_changes ();	
+	guint i, j, which;
+
+	copy_pixmaps ();
+	for (i = 0; i < SIZE; i++)
+		for (j = 0; j < SIZE; j++)
+		{
+			which = 0;
+			if (pixmaps[i][j] != BLANK)
+				which = (guint) (pixmaps[i][j] - BLACK + 1);
+			gui_draw_pixmap_buffer (j, i, which);
+		}
+
+	gui_draw_grid (0);
+	if (grid)
+		gui_draw_grid (1);
+	gtk_widget_queue_draw_area (drawing_area, 0, 0, board_width, board_height);
+	gui_status ();
 }
 
 static void
-animate_stagger_select (GtkWidget *widget, gpointer data)
+refresh_board (void)
 {
-	if (GTK_TOGGLE_BUTTON (widget)->active)
-		t_animate_stagger = 1;
-	else
-		t_animate_stagger = 0;
-	apply_changes ();	
+	set_board_size ();
+	set_bg_color ();
+	load_pixmaps ();
+	redraw_board ();	
 }
 
 static void
-grid_select (GtkWidget *widget, gpointer data)
+sprint_time (gchar *message, GTimer *timer)
 {
-	if (GTK_TOGGLE_BUTTON (widget)->active)
-		t_grid = 1;
-	else
-		t_grid = 0;
-	apply_changes ();
+	gint mm, ss;
+
+	ss = (gint) g_timer_elapsed (timer, NULL);
+	mm = ss / 60;
+	ss -= mm * 60;
+	sprintf (message, _("%.2d:%.2d"), mm, ss);
 }
 
-static void
-animate_select (GtkWidget *widget, gpointer data)
+void
+gui_timer (void)
 {
-	if (GTK_TOGGLE_BUTTON (widget)->active) {
-		t_animate = GPOINTER_TO_INT(data);
-	}
-	apply_changes ();	
+	gchar message[9];
+	
+	sprint_time (message,b_timer);
+	gtk_label_set_text (GTK_LABEL (score[2]), message);
+	sprint_time (message,w_timer);
+	gtk_label_set_text (GTK_LABEL (score[3]), message);		
 }
 
-static void
-save_properties (void)
+void
+timer_start (void)
 {
-	GConfClient *client;
+	if (timer_id)
+		g_source_remove (timer_id);
+	timer_id = g_timeout_add (500, (GSourceFunc) gui_timer, NULL);
+}
 
-	client = gconf_client_get_default ();
+void
+gui_message (gchar *message)
+{
+	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);
+}
 
-	gconf_client_set_int (client, KEY_BLACK_LEVEL,
-			      black_computer_level, NULL);
-	gconf_client_set_int (client, KEY_WHITE_LEVEL,
-			      white_computer_level, NULL);
-
-	gconf_client_set_bool (client, KEY_QUICK_MOVES,
-			       t_quick_moves, NULL);
-
-	gconf_client_set_string (client, KEY_TILESET,
-				 tile_set_tmp, NULL);
-
-	gconf_client_set_int (client, KEY_ANIMATE,
-			      animate, NULL);
-
-	gconf_client_set_bool (client, KEY_ANIMATE_STAGGER,
-			       animate_stagger, NULL);
-	gconf_client_set_bool (client, KEY_SHOW_GRID,
-			       grid, NULL);
-	gconf_client_set_bool (client, KEY_FLIP_FINAL_RESULTS,
-			       flip_final, NULL);
+void
+gui_entry (gchar *message)
+{
+	gtk_entry_set_text (GTK_ENTRY (entry), message);
 }
 
 static void
-apply_changes (void)
+check_sound (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 (play_sound)
+	{
+		gnome_sound_play (flip_sound);
+		play_sound = FALSE;
+	}
+	if (gameover)
+	{
+		gnome_sound_play (gameover_sound);
+		gameover = FALSE;
 	}
-	
-	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);
+}
+
+static gboolean
+flip_pixmaps (gpointer data)
+{
+	guint i, j, which;
+
+	check_sound ();
+
+	if (!flip_tiles)
+		return TRUE;
+	flip_tiles = FALSE;
+
+	for (i = 0; i < SIZE; i++)
+		for (j = 0; j < SIZE; j++)
+		{
+			if (pixmaps[i][j] == BLANK && board[i][j] != BLANK)
+			{
+				pixmaps[i][j] = board[i][j];
+				which = clamp_int ((gint)pixmaps[i][j], BLACK, WHITE);
+				gui_draw_pixmap (j, i, which - BLACK + 1);
+				flip_tiles = TRUE;
+			}
+			else if (pixmaps[i][j] != BLANK && board[i][j] == BLANK)
+			{
+				pixmaps[i][j] = BLANK;
+				gui_draw_pixmap (j, i, 0);
+				flip_tiles = TRUE;
+			}
+			else if (pixmaps[i][j] < board[i][j] && board[i][j] != BLANK)
+			{
+				if (!animate)
+				{
+					if (pixmaps[i][j] == BLACK)
+						pixmaps[i][j] = board[i][j];
+					else
+						pixmaps[i][j]++;
+				}
 				else
-					gui_draw_pixmap_buffer (0, i, j);
-		gui_draw_grid();
+					pixmaps[i][j]++;
+
+				which = clamp_int ((gint)pixmaps[i][j], BLACK, WHITE);
+				gui_draw_pixmap (j, i, which - BLACK + 1);
+				flip_tiles = TRUE;
+			}
+			else if (pixmaps[i][j] > board[i][j] && pixmaps[i][j] != BLANK)
+			{
+				if (!animate)
+				{
+					if (pixmaps[i][j] == WHITE)
+						pixmaps[i][j] = board[i][j];
+					else
+						pixmaps[i][j]--;
+				}
+				else
+					pixmaps[i][j]--;
+
+				which = clamp_int ((gint)pixmaps[i][j], BLACK, WHITE);
+				gui_draw_pixmap (j, i, which - BLACK + 1);
+				flip_tiles = TRUE;
+			}
+		}
+
+	return TRUE;
+}
+
+gboolean
+flip_final_results (gpointer data)
+{
+	guint i;
+	gint8 adder = 0;
+
+	i = 0;
+	for (; i < bcount; i++)
+	{
+		board[i / SIZE][i % SIZE] = BLACK;
+		if (pixmaps[i / SIZE][i % SIZE] == BLANK)
+			pixmaps[i / SIZE][i % SIZE] = WHITE;
+		if (pixmaps[i / SIZE][i % SIZE] == WHITE)
+		{
+			pixmaps[i / SIZE][i % SIZE] += adder;
+			if (animate_stagger)
+				adder++;
+		}
+	}
+
+	for (; i < SIZE * SIZE - wcount; i++)
+		board[i / SIZE][i % SIZE] = BLANK;
+
+	for (; i < SIZE * SIZE; i++)
+	{
+		board[i / SIZE][i % SIZE] = WHITE;
+		if (pixmaps[i / SIZE][i % SIZE] == BLANK)
+			pixmaps[i / SIZE][i % SIZE] = BLACK;
+		if (pixmaps[i / SIZE][i % SIZE] == BLACK)
+		{
+			pixmaps[i / SIZE][i % SIZE] -= adder;
+			if (animate_stagger)
+				adder++;
+		}
 	}
-	
-	animate = t_animate;
-	
-	if (flip_pixmaps_id) {
+	flip_tiles = TRUE;
+	return FALSE;
+}
+
+void
+set_flip_pixmaps_id (void)
+{
+	if (flip_pixmaps_id)
 		g_source_remove (flip_pixmaps_id);
-		flip_pixmaps_id = 0;
-	}
+
+	if (!animate)
+		flip_pixmaps_id = g_timeout_add (100, flip_pixmaps, NULL);
+	else
+		flip_pixmaps_id = g_timeout_add (flip_speed, flip_pixmaps, NULL);
+}
+
+gboolean
+check_computer_players (void)
+{
+	guint level = 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;
+	if (computer_id)
+	{
+		g_source_remove (computer_id);
+		computer_id = 0;
+	}
+
+	if (black_computer_level && whose_turn == BLACK)
+		level = black_computer_level;
+	else if (white_computer_level && whose_turn == WHITE)
+		level = white_computer_level;
+	if (level)
+	{
+		gui_entry ("Now thinking.");
+		computer_id = g_timeout_add (computer_speed,
+					(GSourceFunc) t_computer_move, GINT_TO_POINTER (level));
 	}
-	
-	animate_stagger = t_animate_stagger;
+	return FALSE;
+}
 
-	flip_final = t_flip_final;
+void
+network_gui_update (void)
+{
+	if (ggz_network_mode)
+	{
+		black_computer_level = 0;
+		white_computer_level = 0;
+	}
+	gtk_action_set_sensitive (open_action,        !ggz_network_mode); 
+	gtk_action_set_visible   (new_game_action,    !ggz_network_mode); 
+	gtk_action_set_visible   (redo_game_action,   !ggz_network_mode); 
+	gtk_action_set_visible   (show_hint_action,   !ggz_network_mode); 
+	gtk_action_set_visible   (sync_action,         ggz_network_mode); 
+	gtk_action_set_visible   (again_action,        ggz_network_mode); 
+	gtk_action_set_sensitive (preferences_action, !ggz_network_mode); 
+	gtk_widget_set_sensitive (toolbar,            !ggz_network_mode);
+}
 
-	if (grid != t_grid) {
-			grid = t_grid;
-			gui_draw_grid ();
-	}
+static void
+on_quit_activate (GtkMenuItem *menuitem, gpointer user_data)
+{
+	gtk_main_quit ();
+}
 
-	check_computer_players ();
+static void
+on_new_game_activate (GtkMenuItem *menuitem, gpointer user_data)
+{
+	init_new_game ();
+}
 
-	save_properties ();
+static void
+on_properties_activate (GtkMenuItem *menuitem, gpointer user_data)
+{
+	if (properties_dialog)
+		return;
+	properties_dialog = create_properties_dialog ();
+	gtk_widget_show (properties_dialog);
+}
+
+static void
+on_minimum_board_activate (GtkMenuItem *menuitem, gpointer user_data)
+{
+	board_width = board_height = BOARD_MIN;
+	gtk_window_resize ((GtkWindow *)window, board_width, board_height); 
+	refresh_board ();
 }
 
 static gboolean
-close_cb (GtkWidget *widget)
+on_drawing_area_expose_event (GtkWidget *widget,
+					GdkEventExpose *event, gpointer user_data)
 {
-	gtk_widget_hide (widget);
+	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;
+}
 
-	return TRUE;
+static gboolean
+on_drawing_area_configure_event (GtkWidget *widget,
+					GdkEventConfigure *event, gpointer user_data)
+{
+	board_width = (event->width * 99) / 100;
+	board_height = (event->height * 99) / 100;
+
+	refresh_board ();
+	return FALSE;
+}
+
+const char manager_definition[] =
+	"<ui>"
+	"  <menubar name='MenuBar'>"
+	"    <menu name='GameMenu'			action='game_menu'>"
+	"      <menuitem name='New_Game'		action='new_game'/>"
+	"      <separator/>"
+	"      <menuitem name='Redo'			action='redo_game'/>"
+	"      <menuitem name='Hint'			action='show_hint'/>"
+	"      <separator/>"
+	"      <menuitem name='Sync'			action='sync'/>"
+	"      <menuitem name='Again'			action='again'/>"
+	"      <separator/>"
+	"      <menuitem name='Open'			action='open'/>"
+	"      <menuitem name='Save'			action='save'/>"
+	"      <separator/>"
+	"      <menuitem name='Quit_Game'		action='quit_game'/>"
+	"    </menu>"
+	"    <menu name='SettingsMenu'		action='settings_menu'>"
+	"      <menuitem name='Preferences'		action='preferences'/>"
+	"      <menuitem name='Minimum Board'   action='minimum_board'/>"
+	"    </menu>"
+	"    <menu name='HelpMenu'			action='help_menu'>"
+	"      <menuitem name='Contents'		action='help'/>"
+	"      <menuitem name='About'			action='about'/>"
+	"    </menu>"
+	"  </menubar>"
+	"  <toolbar  name='ToolBar'>"
+	"      <toolitem name='Head'		action='head'/>"
+	"      <toolitem name='Back'		action='back'/>"
+	"      <toolitem name='Forward'		action='forward'/>"
+	"      <toolitem name='Last'		action='last'/>"
+	"      <toolitem name='Hint'		action='hint'/>"
+	"      <toolitem name='Redo'		action='redo'/>"
+	"      <toolitem name='New'			action='new'/>"
+	"      <toolitem name='Quit'		action='quit'/>"
+	"  </toolbar>"
+	"</ui>";
+
+const GtkActionEntry entries[] = {
+	{"game_menu", NULL, N_("_Game")},
+	{"new_game", GAMES_STOCK_NEW_GAME, NULL, NULL, NULL,
+		G_CALLBACK (on_new_game_activate)},
+	{"redo_game", GAMES_STOCK_REDO_MOVE, NULL, NULL, NULL,
+		G_CALLBACK (on_redo_activate)},
+	{"show_hint", GAMES_STOCK_HINT, NULL, NULL, NULL,
+		G_CALLBACK (on_hint_activate)},
+	{"sync", NULL, N_("_Sync"), NULL, NULL,
+		G_CALLBACK (on_sync_activate)},
+	{"again", NULL, N_("Play _Again"), NULL, NULL,
+		G_CALLBACK (on_again_activate)},
+	{"open", GTK_STOCK_OPEN, NULL, NULL, NULL,
+		G_CALLBACK (on_open_activate)},
+	{"save", GTK_STOCK_SAVE, NULL, NULL, NULL,
+		G_CALLBACK (on_save_activate)},
+	{"quit_game", GTK_STOCK_QUIT, NULL, NULL, NULL,
+		G_CALLBACK (on_quit_activate)},
+	{"settings_menu", NULL, N_("_Settings")},
+	{"preferences", GTK_STOCK_PREFERENCES, NULL, NULL, NULL,
+		G_CALLBACK (on_properties_activate)},
+	{"minimum_board", GTK_STOCK_ZOOM_OUT, NULL, NULL, NULL,
+		G_CALLBACK (on_minimum_board_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)},
+	{"head", GTK_STOCK_GOTO_FIRST, NULL, "<Ctl><Shift>f" , NULL,
+		G_CALLBACK (on_head_button_clicked)},
+	{"back", GTK_STOCK_GO_BACK, NULL, "<Ctl>b", NULL,
+		G_CALLBACK (on_back_button_clicked)},
+	{"forward", GTK_STOCK_GO_FORWARD, NULL, "<Ctl>f", NULL,
+		G_CALLBACK (on_forward_button_clicked)},
+	{"last", GTK_STOCK_GOTO_LAST, NULL,"<Ctl>l" , NULL,
+		G_CALLBACK (on_last_button_clicked)},
+	{"hint", GAMES_STOCK_HINT, NULL, "<Ctl>h", NULL,
+		G_CALLBACK (on_hint_activate)},
+	{"redo", GAMES_STOCK_REDO_MOVE, NULL,"<Ctl>r" , NULL,
+		G_CALLBACK (on_redo_activate)},
+	{"new", GAMES_STOCK_NEW_GAME, NULL, NULL, NULL,
+		G_CALLBACK (on_new_game_activate)},
+	{"quit", GTK_STOCK_QUIT, NULL, NULL, NULL,
+		G_CALLBACK (on_quit_activate)},
+};
+
+static void
+set_actions (void)
+{
+	open_action        = gtk_action_group_get_action (action_group, "open");
+	new_game_action    = gtk_action_group_get_action (action_group, "new_game");
+	redo_game_action   = gtk_action_group_get_action (action_group, "redo_game");
+	show_hint_action   = gtk_action_group_get_action (action_group, "show_hint");
+	sync_action        = gtk_action_group_get_action (action_group, "sync");
+	again_action       = gtk_action_group_get_action (action_group, "again");
+	preferences_action = gtk_action_group_get_action (action_group, "preferences");
+}
+
+GtkWidget *
+create_window (void)
+{	
+	const gchar *strs[] =
+	{
+		N_("Dark:"),
+		N_("Light:"),
+		_("00"),
+		_("00:00")
+	};
+
+	GtkWidget *window;
+	GtkWidget *vbox1;
+	GtkWidget *vbox3;
+	GtkWidget *hbox;
+	GtkWidget *label;
+	GtkAccelGroup *accel_group;
+	
+	gint i,j;
+	gchar name[2] = { 0, 0 };
+	gchar *markup;
+	
+	GError *error = NULL;
+
+	accel_group = gtk_accel_group_new ();
+
+	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+#ifdef GATAXX
+	gtk_window_set_title (GTK_WINDOW (window), _("gataxx"));
+#else
+	gtk_window_set_title (GTK_WINDOW (window), _("iagno"));
+#endif
+
+	g_signal_connect ((gpointer) window, "destroy",
+				G_CALLBACK (on_quit_activate), NULL);
+
+	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, entries, G_N_ELEMENTS (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));
+	set_actions ();
+
+	vbox1 = gtk_vbox_new (FALSE, 0);
+	gtk_container_add (GTK_CONTAINER (window), vbox1);
+
+	menubar = gtk_ui_manager_get_widget (manager, "/MenuBar");
+	toolbar = gtk_ui_manager_get_widget (manager, "/ToolBar");
+	gtk_box_pack_start (GTK_BOX (vbox1), menubar, FALSE, FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox1), toolbar, FALSE, FALSE, 0);
+	gtk_toolbar_set_style (GTK_TOOLBAR (toolbar),GTK_TOOLBAR_ICONS);
+	for (i = 0; i < 8; i++)
+	{
+		gtk_tool_item_set_expand (
+			gtk_toolbar_get_nth_item ((GtkToolbar *) toolbar, i), TRUE);			
+		gtk_tool_item_set_homogeneous (
+			gtk_toolbar_get_nth_item ((GtkToolbar *) toolbar, i), FALSE);
+	}
+	
+	hbox = gtk_hbox_new (FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox1), hbox, TRUE, TRUE, 0);
+
+	label = gtk_label_new (_("  "));
+	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+	gtk_widget_set_size_request (label, 17, 17);
+
+	for (*name = 0x41; *name < 0x41 + SIZE; (*name)++)
+	{
+		label = gtk_label_new (name);
+		gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+		gtk_widget_set_size_request (label, -1, 17);
+		markup = g_markup_printf_escaped (
+			"<span foreground=\"red\">%s</span>", name);
+		gtk_label_set_markup_with_mnemonic ((GtkLabel *)label, markup);
+		g_free (markup);
+	}
+	
+	hbox = gtk_hbox_new (FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox1), hbox, TRUE, TRUE, 0);
+
+	vbox3 = gtk_vbox_new (FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (hbox), vbox3, TRUE, TRUE, 0);
+
+	for (*name = 0x31; *name < 0x31 + SIZE; (*name)++)
+	{
+		label = gtk_label_new (name);
+		gtk_box_pack_start (GTK_BOX (vbox3), label, TRUE, TRUE, 0);
+		gtk_widget_set_size_request (label, 17, -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 = gtk_drawing_area_new ();
+    /* We do our own double-buffering. */
+	gtk_widget_set_double_buffered (drawing_area, FALSE);
+	gtk_widget_set_size_request (drawing_area, board_width, board_height);
+	gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
+	gtk_widget_set_events (drawing_area, GDK_BUTTON_PRESS_MASK);
+	g_signal_connect ((gpointer) drawing_area, "button_press_event",
+				G_CALLBACK (on_drawing_area_button_press_event), NULL);
+	g_signal_connect ((gpointer) drawing_area, "expose_event",
+				G_CALLBACK (on_drawing_area_expose_event), NULL);
+	g_signal_connect ((gpointer) drawing_area, "configure_event",
+				G_CALLBACK (on_drawing_area_configure_event), NULL);
+
+	hbox = gtk_hbox_new (FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox1), hbox, FALSE, FALSE, 0);
+
+	counter = gtk_label_new (_("00"));
+	gtk_box_pack_start (GTK_BOX (hbox), counter, TRUE, TRUE, 0);
+
+	for (i = 0; i < 2; i++)
+		for (j = 0; j < 2; j++)
+		{
+			label = gtk_label_new (strs[j]);
+			gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, TRUE, 0);
+			markup = g_markup_printf_escaped (
+			"<span foreground=\"blue\">%s</span>", strs[j]);
+			gtk_label_set_markup_with_mnemonic ((GtkLabel *)label, markup);
+			g_free (markup);
+			score[i*2+j] = gtk_label_new (strs[i+2]);
+			gtk_box_pack_start (GTK_BOX (hbox), score[i*2+j], TRUE, TRUE, 0);
+		}
+
+	hbox = gtk_hbox_new (FALSE, 0);
+	gtk_box_pack_start (GTK_BOX (vbox1), hbox, TRUE, FALSE, 0);
+
+	statusbar = gtk_statusbar_new ();
+	gtk_box_pack_start (GTK_BOX (hbox), statusbar, TRUE, TRUE, 0);
+	gtk_statusbar_set_has_resize_grip (GTK_STATUSBAR (statusbar), FALSE);
+
+	entry = gtk_entry_new ();
+	gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
+	gtk_widget_set_events (entry, GDK_KEY_PRESS_MASK);
+	g_signal_connect ((gpointer) entry, "key_press_event",
+			  G_CALLBACK (on_entry_key_press_event), NULL);
+
+	gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
+
+	gtk_widget_show_all (window);
+	gtk_widget_grab_focus (entry);
+	return window;
 }
 
 void
-set_selection (GtkWidget *widget, gpointer data)
+set_sound (void)
 {
-	gchar * filename;
+	gchar *tmp;
 
-	if (tile_set_tmp)
-		g_free (tile_set_tmp);
+	tmp = g_build_filename ("iagno", "flip-piece.wav", NULL);
+	flip_sound = gnome_program_locate_file (NULL,
+						GNOME_FILE_DOMAIN_APP_SOUND, tmp, TRUE, NULL);
+	g_free (tmp);
+
+	tmp = g_build_filename ("iagno", "gameover.wav", NULL);
+	gameover_sound = gnome_program_locate_file (NULL,
+						GNOME_FILE_DOMAIN_APP_SOUND, tmp, TRUE, NULL);
+	g_free (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);
+void
+load_properties (void)
+{
+	GConfClient *client;
 
-	apply_changes ();
+	client = gconf_client_get_default ();
+
+	if (tile_set)
+		g_free (tile_set);
+	if (bg_color_name)
+		g_free (bg_color_name);
+
+	black_computer_level = clamp_int (gconf_client_get_int (client, KEY_BLACK_LEVEL, NULL), 0, MAX_DEPTH - 1);
+	white_computer_level = clamp_int (gconf_client_get_int (client, KEY_WHITE_LEVEL, NULL), 0, MAX_DEPTH - 1);
+	animate              = gconf_client_get_bool           (client, KEY_ANIMATE,     NULL);
+	quick_moves          = gconf_client_get_bool           (client, KEY_QUICK_MOVES, NULL);
+	animate_stagger      = gconf_client_get_bool           (client, KEY_ANIMATE_STAGGER, NULL);
+	grid                 = gconf_client_get_bool           (client, KEY_SHOW_GRID,   NULL);
+	flip_final           = gconf_client_get_bool           (client, KEY_FLIP_FINAL_RESULTS, NULL);
+	tile_set             = gconf_client_get_string         (client, KEY_TILESET,     NULL);
+	bg_color_name        = gconf_client_get_string         (client, KEY_BG_COLOR,    NULL);
+	board_width          = gconf_client_get_int            (client, KEY_BOARD_WIDTH, NULL);
+	board_height         = gconf_client_get_int            (client, KEY_BOARD_HEIGHT, NULL);
+
+	if (!bg_color_name)
+		bg_color_name    = g_strdup (_("#000066660000"));
+	if (!board_width || !board_height)
+		board_width = board_height = BOARD_SIZE;
+	
+	g_object_unref (client);
+}
+
+void
+save_properties (void)
+{
+	GConfClient *client;
+
+	client = gconf_client_get_default ();
+
+	gconf_client_set_int    (client, KEY_BLACK_LEVEL, black_computer_level, NULL);
+	gconf_client_set_int    (client, KEY_WHITE_LEVEL, white_computer_level, NULL);
+	gconf_client_set_bool   (client, KEY_ANIMATE,     animate,              NULL);
+	gconf_client_set_bool   (client, KEY_QUICK_MOVES, quick_moves,          NULL);
+	gconf_client_set_bool   (client, KEY_ANIMATE_STAGGER, animate_stagger,  NULL);
+	gconf_client_set_bool   (client, KEY_SHOW_GRID,   grid,                 NULL);
+	gconf_client_set_bool   (client, KEY_FLIP_FINAL_RESULTS, flip_final,    NULL);
+	gconf_client_set_string (client, KEY_TILESET,     tile_set,             NULL);
+	gconf_client_set_string (client, KEY_BG_COLOR,    bg_color_name,        NULL);
+	gconf_client_set_int    (client, KEY_BOARD_WIDTH, board_width,          NULL);
+	gconf_client_set_int    (client, KEY_BOARD_HEIGHT, board_height,        NULL);
+
+	g_object_unref (client);
+}
+
+void
+reset_properties (void)
+{
+	if (t_tile_set)
+		g_free (t_tile_set);
+	if (t_bg_color_name)
+		g_free (t_bg_color_name);
+
+	t_computer_level[0] = black_computer_level;
+	t_computer_level[1] = white_computer_level;
+	t_options[0]        = animate;
+	t_options[1]        = quick_moves;
+	t_options[2]        = animate_stagger;
+	t_options[3]        = grid;
+	t_options[4]        = flip_final;
+	t_tile_set          = g_strdup (tile_set);
+	t_bg_color_name     = g_strdup (bg_color_name);
+	gdk_color_parse (t_bg_color_name, &bg_color[2]);
+	if (drawing_area)
+		gdk_colormap_alloc_color (gtk_widget_get_colormap (drawing_area),
+				&bg_color[2], FALSE, TRUE);
 }
 
 void
-free_str (GtkWidget *widget, void *data)
+apply_changes (void)
 {
-        g_free(data);
+	if (bg_color_name)
+		g_free (bg_color_name);
+	if (tile_set)
+		g_free (tile_set);
+
+	black_computer_level = t_computer_level[0];
+	white_computer_level = t_computer_level[1];
+	animate              = t_options[0];
+	quick_moves          = t_options[1];
+	animate_stagger      = t_options[2];
+	grid                 = t_options[3];
+	flip_final           = t_options[4];
+	tile_set             = g_strdup (t_tile_set);
+	bg_color_name        = g_strdup (t_bg_color_name);
+	computer_speed       = COMPUTER_MOVE_DELAY;
+	flip_speed           = PIXMAP_FLIP_DELAY;
+	if (quick_moves)
+	{
+		computer_speed   /= 2;
+		flip_speed       /= 2;
+	}
+	set_flip_pixmaps_id ();
+
+	refresh_board ();
+	if (game_in_progress)
+		check_computer_players ();
 }
 
-static GtkWidget *
-fill_menu (void)
+static void
+on_computer_level_changed (GtkToggleButton *togglebutton, gpointer user_data)
 {
-        gchar *dname = NULL;
+	if (togglebutton->active)
+		t_computer_level[GPOINTER_TO_INT (user_data) / 8] =
+				GPOINTER_TO_INT (user_data) % 8;
+}
 
-	/* FIXME: we need to check that both dname is valid and that
-	 * games_file_list_new_images returns something. */
+static void
+on_options_toggled (GtkToggleButton *togglebutton, gpointer user_data)
+{
+	t_options [GPOINTER_TO_INT (user_data)] = togglebutton->active;
+}
 
-	dname = gnome_program_locate_file (NULL,
-					   GNOME_FILE_DOMAIN_APP_PIXMAP, 
-					   "iagno", FALSE, NULL);
+static void
+on_tile_set_box_changed (GtkComboBox *combobox, gpointer user_data)
+{
+	if (t_tile_set)
+		g_free (t_tile_set);
+	t_tile_set = gtk_combo_box_get_active_text (combobox);
+}
 
-	if (theme_file_list)
-		g_object_unref (theme_file_list);
+static void
+on_color_button_color_set (GtkColorButton *colorbutton, gpointer user_data)
+{
+	gtk_color_button_get_color (colorbutton, &bg_color[2]);
+	if (t_bg_color_name)
+		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);
+}
 
-	theme_file_list = games_file_list_new_images (dname, NULL);
-	g_free (dname);
+static void
+on_apply_button_clicked (GtkButton *button, gpointer user_data)
+{
+	apply_changes ();
+	save_properties ();
+}
 
-	games_file_list_transform_basename (theme_file_list);
+static void
+on_properties_cancel_clicked (GtkButton *button, gpointer user_data)
+{
+	reset_properties ();
+	gtk_widget_destroy (properties_dialog);
+	properties_dialog = NULL;
+}
 
-	return games_file_list_create_widget (theme_file_list, tile_set,
-					      GAMES_FILE_LIST_REMOVE_EXTENSION |
-					      GAMES_FILE_LIST_REPLACE_UNDERSCORES);
+static void
+on_ok_button_clicked (GtkButton *button, gpointer user_data)
+{
+	apply_changes ();
+	save_properties ();
+	gtk_widget_destroy (properties_dialog);
+	properties_dialog = NULL;
 }
 
-void
-show_properties_dialog (void)
+GtkWidget *
+create_properties_dialog (void)
 {
+	const gchar *strs [] = 
+	{
+		N_("Human"),            /* 0 */
+		N_("Level "),           /* 1 */
+		N_("Dark"),             /* 2 */
+		N_("Light"),            /* 3 */
+		N_("A_nimation"),       /* 4 */
+		N_("Use _Quick moves"), /* 5 */
+		N_("_Stagger flips"),   /* 6 */
+		N_("Show _Grid"),       /* 7 */
+		N_("_Flip final results"), /* 8 */
+		N_("Tile set:"),       /* 9 */
+		N_("Background color:"),/* 10 */
+		N_("Options"),          /* 11 */
+		N_("Players"),          /* 12 */
+		N_("Appearance"),       /* 13 */
+		N_("Iagno Preferences"),/* 14 */
+		N_("Gataxx Preferences"),/* 15 */
+		_("gtk-apply"),         /* 16 */
+		_("gtk-cancel"),        /* 17 */
+		_("gtk-ok"),            /* 18 */
+		_("coin.svg"),          /* 19 */
+		_("marble.svg"),        /* 20 */
+		_("sun_and_star.svg")   /* 21 */
+	};
+	
+	const GtkSignalFunc *signalfunc[3] =
+	{
+		(GtkSignalFunc *)on_apply_button_clicked,
+		(GtkSignalFunc *)on_properties_cancel_clicked,
+		(GtkSignalFunc *)on_ok_button_clicked
+	};
+	
+	GtkWidget *properties_dialog;
+	GtkWidget *dialog_vbox;
 	GtkWidget *notebook;
 	GtkWidget *hbox;
+	GtkWidget *frame;
+	GtkWidget *alignment;
+	GtkWidget *vbox;
+	GtkWidget *button;
 	GtkWidget *label;
-	GtkWidget *label2;
+	GSList    *human_group[2] = {NULL, NULL};
 	GtkWidget *table;
-	GtkWidget *button;
-	GtkWidget *frame;
-	GtkWidget *vbox, *vbox2;
-	GtkWidget *propbox = NULL;
-	GtkWidget *option_menu;
-
-	if (propbox) {
-                gtk_window_present (GTK_WINDOW (propbox));
-                return;
-	}
+	GtkWidget *tile_set_box;
+	GtkWidget *color_button;
+	GtkWidget *dialog_action_area;
+	GString   *string;
+	
+	gint n, f, v;
+	
+	properties_dialog = gtk_dialog_new ();
+#ifdef GATAXX
+	gtk_window_set_title (GTK_WINDOW (properties_dialog),strs[15]);
+#else
+	gtk_window_set_title (GTK_WINDOW (properties_dialog),strs[14]);
+#endif
+	gtk_window_set_resizable (GTK_WINDOW (properties_dialog), FALSE);
+	gtk_window_set_type_hint (GTK_WINDOW (properties_dialog),
+				  GDK_WINDOW_TYPE_HINT_DIALOG);
 
-	reset_properties ();
+	dialog_vbox = GTK_DIALOG (properties_dialog)->vbox;
 
-	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);
 	notebook = gtk_notebook_new ();
-	gtk_container_set_border_width (GTK_CONTAINER (notebook), 5);
-	gtk_container_add (GTK_CONTAINER (GTK_DIALOG (propbox)->vbox),
-                           notebook);
-
-	label = gtk_label_new (_("Players"));
-
-	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);
-        
-
-	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);
-
-
-        label = gtk_label_new (_("Appearance"));
-
-	table = gtk_table_new (1, 2, FALSE);
-	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);
-	
-        frame = games_frame_new (_("Options"));
-	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);
-	
-	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);
-	
-	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_box_pack_start (GTK_BOX (dialog_vbox), notebook, TRUE, TRUE, 0);
+
+	for (n = 0; n < 2; n++)
+	{
+		hbox = gtk_hbox_new (FALSE, 0);
+		gtk_container_add (GTK_CONTAINER (notebook), hbox);
+
+		if ( n == 0)
+		{
+			for (f = 0; f < 2; f++)
+			{
+				frame = gtk_frame_new (NULL);
+				gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
+				gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
+
+				alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
+				gtk_container_add (GTK_CONTAINER (frame), alignment);
+				gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
+
+				vbox = gtk_vbox_new (FALSE, 0);
+				gtk_container_add (GTK_CONTAINER (alignment), vbox);
+
+				for (v = 0; v < MAX_DEPTH; v++)
+				{
+					if (!v)
+						button = gtk_radio_button_new_with_mnemonic (NULL, strs[0]);
+					else
+					{
+						string = g_string_new (strs[1]);
+						g_string_append_printf (string,"%d",v);
+						button = gtk_radio_button_new_with_mnemonic (NULL, string->str);
+						g_string_free (string, TRUE);
+					}
+					gtk_box_pack_start (GTK_BOX (vbox), 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*8+v));
+				}
+
+				label = gtk_label_new (strs[f+2]);
+				gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+				gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+			}
+		}
+		else
+		{
+			for (f = 0; f < 2; f++)
+			{
+				frame = gtk_frame_new (NULL);
+				gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
+				gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_OUT);
+
+				alignment = gtk_alignment_new (0.5, 0.5, 1, 1);
+				gtk_container_add (GTK_CONTAINER (frame), alignment);
+				gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
+
+				vbox = gtk_vbox_new (FALSE, 0);
+				gtk_container_add (GTK_CONTAINER (alignment), vbox);
+				if (f == 0)
+				{
+					for (v = 0; v < 5; v++)
+					{
+						button = gtk_check_button_new_with_mnemonic (strs[v+4]);
+						gtk_box_pack_start (GTK_BOX (vbox), 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));
+					}
+				}	
+				else
+				{
+					table = gtk_table_new (2, 2, FALSE);
+					gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
+			
+					for (v = 0; v < 2; v++)
+					{
+						label = gtk_label_new (strs[v+9]);
+						gtk_table_attach (GTK_TABLE (table), label, 0, 1, v, v+1,
+							(GtkAttachOptions) (0),
+							(GtkAttachOptions) (0), 0, 0);
+						gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+					}
+			
+					tile_set_box = gtk_combo_box_new_text ();
+					gtk_table_attach (GTK_TABLE (table), tile_set_box, 1, 2, 0, 1,
+						(GtkAttachOptions) (0),
+						(GtkAttachOptions) (0), 0, 0);
+					for (v = 0; v < 3; v ++)
+					{
+						gtk_combo_box_append_text (GTK_COMBO_BOX (tile_set_box), strs[v+19]);
+						if (g_str_equal (t_tile_set, strs[v+19]))
+							gtk_combo_box_set_active (GTK_COMBO_BOX (tile_set_box), v);
+					}
+					g_signal_connect ((gpointer) tile_set_box, "changed",
+						G_CALLBACK (on_tile_set_box_changed), NULL);
+
+					color_button = gtk_color_button_new ();
+					gtk_table_attach (GTK_TABLE (table), color_button, 1, 2, 1, 2,
+						(GtkAttachOptions) (0),
+						(GtkAttachOptions) (0), 0, 0);
+					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);
+				}
+				label = gtk_label_new (strs[11]);
+				gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+				gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+			}
+		}
+		label = gtk_label_new (strs[n+12]);
+		gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook),
+		gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), n),label);
+	}
+
+	dialog_action_area = GTK_DIALOG (properties_dialog)->action_area;
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area),
+				GTK_BUTTONBOX_END);
+
+	for (n = 0; n < 3; n++)
+	{
+		button = gtk_button_new_from_stock (strs[n+16]);
+		gtk_dialog_add_action_widget (GTK_DIALOG (properties_dialog),
+				      	button, GTK_RESPONSE_APPLY);
+		GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+		g_signal_connect ((gpointer) button, "clicked",
+					G_CALLBACK (signalfunc[n]), NULL);
+	};
+
+	gtk_widget_show_all (properties_dialog);
+	return properties_dialog;
+}
+
+
+static void
+on_save_clicked (GtkButton *button, gpointer user_data)
+{
+	gchar *filename;
+	int fd;
+
+	filename =
+		gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_save_dialog));
+
+	fd = creat (filename, 0644);
+	if (fd)
+	{
+		write_kifu (fd);
+		close (fd);
+	}
+	gtk_widget_destroy (file_save_dialog);
+	g_free (filename);
+}
+
+static void
+on_open_clicked (GtkButton *button, gpointer user_data)
+{
+	gchar *filename;
+	int fd;
+
+	filename =
+		gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (file_open_dialog));
+	fd = open (filename, 0, 0644);
+	if (fd)
+	{
+		read_kifu (fd);
+		close (fd);
+	}
+	gtk_widget_destroy (file_open_dialog);
+	g_free (filename);
+	on_head_button_clicked (NULL, NULL);
+}
 
-	gtk_widget_show_all (propbox);
+GtkWidget *
+create_file_save_dialog (void)
+{
+	GtkWidget *file_save_dialog;
+	GtkWidget *dialog_vbox;
+	GtkWidget *dialog_action_area;
+	GtkWidget *save_cancel;
+	GtkWidget *save;
+
+	file_save_dialog =
+		gtk_file_chooser_dialog_new ("", (GtkWindow *)window,
+				GTK_FILE_CHOOSER_ACTION_SAVE, NULL);
+	gtk_window_set_type_hint (GTK_WINDOW (file_save_dialog),
+				GDK_WINDOW_TYPE_HINT_DIALOG);
+	g_signal_connect ((gpointer) file_save_dialog, "destroy",
+				G_CALLBACK (gtk_widget_destroy), NULL);
+
+	dialog_vbox = GTK_DIALOG (file_save_dialog)->vbox;
+
+	dialog_action_area = GTK_DIALOG (file_save_dialog)->action_area;
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area),
+				GTK_BUTTONBOX_END);
+
+	save_cancel = gtk_button_new_from_stock ("gtk-cancel");
+	gtk_dialog_add_action_widget (GTK_DIALOG (file_save_dialog),
+				save_cancel, GTK_RESPONSE_CANCEL);
+	GTK_WIDGET_SET_FLAGS (save_cancel, GTK_CAN_DEFAULT);
+	g_signal_connect_swapped ((gpointer) save_cancel, "clicked",
+				G_CALLBACK (gtk_widget_destroy), (gpointer) file_save_dialog);
+
+	save = gtk_button_new_from_stock ("gtk-save");
+	gtk_dialog_add_action_widget (GTK_DIALOG (file_save_dialog), save,
+				GTK_RESPONSE_OK);
+	GTK_WIDGET_SET_FLAGS (save, GTK_CAN_DEFAULT);
+	g_signal_connect ((gpointer) save, "clicked",
+				G_CALLBACK (on_save_clicked), NULL);
+
+	gtk_widget_show_all (file_save_dialog);
+	gtk_widget_grab_default (save);
+	return file_save_dialog;
+}
+
+GtkWidget *
+create_file_open_dialog (void)
+{
+	GtkWidget *file_open_dialog;
+	GtkWidget *dialog_vbox;
+	GtkWidget *dialog_action_area;
+	GtkWidget *open_cancel;
+	GtkWidget *open;
+
+	file_open_dialog =
+		gtk_file_chooser_dialog_new ("", (GtkWindow *)window,
+				GTK_FILE_CHOOSER_ACTION_OPEN, NULL);
+	gtk_window_set_type_hint (GTK_WINDOW (file_open_dialog),
+				GDK_WINDOW_TYPE_HINT_DIALOG);
+	g_signal_connect ((gpointer) file_open_dialog, "destroy",
+				G_CALLBACK (gtk_widget_destroy), NULL);
+
+	dialog_vbox = GTK_DIALOG (file_open_dialog)->vbox;
+
+	dialog_action_area = GTK_DIALOG (file_open_dialog)->action_area;
+	gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area),
+				GTK_BUTTONBOX_END);
+
+	open_cancel = gtk_button_new_from_stock ("gtk-cancel");
+	gtk_dialog_add_action_widget (GTK_DIALOG (file_open_dialog),
+				      open_cancel, GTK_RESPONSE_CANCEL);
+	GTK_WIDGET_SET_FLAGS (open_cancel, GTK_CAN_DEFAULT);
+	g_signal_connect_swapped ((gpointer) open_cancel, "clicked",
+				G_CALLBACK (gtk_widget_destroy), (gpointer) file_open_dialog);
+
+	open = gtk_button_new_from_stock ("gtk-open");
+	gtk_dialog_add_action_widget (GTK_DIALOG (file_open_dialog), open,
+				GTK_RESPONSE_OK);
+	GTK_WIDGET_SET_FLAGS (open, GTK_CAN_DEFAULT);
+	g_signal_connect ((gpointer) open, "clicked",
+				G_CALLBACK (on_open_clicked), NULL);
+
+	gtk_widget_show_all (file_open_dialog);
+	gtk_widget_grab_default (open);
+	return file_open_dialog;
 }
Index: gnome-games/iagno/properties.h
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/properties.h,v
retrieving revision 1.2
diff -u -r1.2 properties.h
--- gnome-games/iagno/properties.h	18 Jun 2003 15:54:41 -0000	1.2
+++ gnome-games/iagno/properties.h	3 Oct 2006 04:55:38 -0000
@@ -1,7 +1,67 @@
-#ifndef _PROPERTIES_H_
-#define _PROPERTIES_H_
+/*
+ * properties.h
+ *
+ * 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.
+ */
+
+#define BOARD_SIZE    519
+#define BOARD_MIN     279
+#define BOARD_W_MAX  1214
+#define BOARD_H_MAX   799
+#define GRIDWIDTH       1
+
+#define PIXMAP_FLIP_DELAY      30
+#define PIXMAP_STAGGER_DELAY    3
+#define COMPUTER_MOVE_DELAY  1000
+
+gint clamp_int (gint input, gint low, gint high);
+
+void redraw_board (void);
+
+void gui_timer (void);
+
+void timer_start (void);
+
+void gui_message (gchar *message);
+
+void gui_entry (gchar *message);
+
+gboolean flip_final_results (gpointer data);
+
+void set_flip_pixmaps_id (void);
+
+gboolean check_computer_players (void);
+
+void network_gui_update (void);
+
+GtkWidget *create_window (void);
+
+void set_sound (void);
 
 void load_properties (void);
-void show_properties_dialog (void);
 
-#endif
+void save_properties (void);
+
+void reset_properties (void);
+
+void apply_changes (void);
+
+GtkWidget* create_properties_dialog (void);
+
+GtkWidget* create_file_save_dialog (void);
+
+GtkWidget* create_file_open_dialog (void);
Index: gnome-games/iagno/server.c
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/server.c,v
retrieving revision 1.1
diff -u -r1.1 server.c
--- gnome-games/iagno/server.c	5 Sep 2006 16:36:27 -0000	1.1
+++ gnome-games/iagno/server.c	3 Oct 2006 04:55:38 -0000
@@ -1,5 +1,5 @@
 /*
- * File: main.c
+ * File: server.c
  * Author: Ismael Orenstein
  * Project: GGZ Reversi game module
  * Date: 09/17/2000
@@ -26,590 +26,497 @@
 #include "config.h"
 #include <gnome.h>
 #include <ggzdmod.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <time.h>
-#include <unistd.h>
 
+#include <assert.h>
+
+#include "othello.h"
 #include "server.h"
 
 // Global game variables
 struct rvr_game_t rvr_game;
 
+extern guint8 board0[100];
+extern guint move_count;
+extern guint whose_turn;
+extern guint bcount;
+extern guint wcount;
 
-// Initializes everything
-void game_init(GGZdMod * ggzdmod)
-{
-  int i;
-  rvr_game.ggz = ggzdmod;
-  rvr_game.black = 2;
-  rvr_game.white = 2;
-  rvr_game.state = RVR_STATE_INIT;
-  rvr_game.turn = EMPTY;
-  for (i = 0; i < 64; i++) {
-    rvr_game.board[i] = EMPTY;
-  }
-  // Initial positions
-  rvr_game.board[CART(4, 4)] = WHITE;
-  rvr_game.board[CART(5, 5)] = WHITE;
-  rvr_game.board[CART(5, 4)] = BLACK;
-  rvr_game.board[CART(4, 5)] = BLACK;
-  // Inits random number generator
-  srand(time(0));
-}
-
-// Handle server messages
-void game_handle_ggz_state(GGZdMod * ggz, GGZdModEvent event,
-			   const void *data)
-{
-  GGZdModState new_state = ggzdmod_get_state(ggz);
-  const GGZdModState *old_state_ptr = data;
-  const GGZdModState old_state = *old_state_ptr;
-
-  // Check if it's the right time to launch the game and if ggz could do taht
-  if (old_state == GGZDMOD_STATE_CREATED) {
-    /*assert(rvr_game.state == RVR_STATE_INIT); */
-    return;
-  }
-
-  if (new_state == GGZDMOD_STATE_PLAYING) {
-    // Game already going on?
-    if (rvr_game.turn == EMPTY)
-      rvr_game.turn = BLACK;
-
-    // No! Let's start the game!
-    game_start();
-    game_play();
-  }
-
-  if (new_state == GGZDMOD_STATE_WAITING) {
-    // That's great! Update the state
-    // Now waiting for people to join
-    rvr_game.state = RVR_STATE_WAIT;
-    ggzdmod_log(rvr_game.ggz, "Waiting for players");
-  }
-}
-
-
-static int seats_full(void)
-{
-  /* This calculation is a bit inefficient, but that's OK */
-  return ggzdmod_count_seats(rvr_game.ggz, GGZ_SEAT_OPEN) == 0
-      && ggzdmod_count_seats(rvr_game.ggz, GGZ_SEAT_RESERVED) == 0
-      && ggzdmod_count_seats(rvr_game.ggz, GGZ_SEAT_ABANDONED) == 0;
-}
-
-
-static int seats_empty(void)
-{
-  /* This calculation is a bit inefficient, but that's OK */
-  return ggzdmod_count_seats(rvr_game.ggz, GGZ_SEAT_PLAYER) == 0
-      && ggzdmod_count_spectators(rvr_game.ggz) == 0;
-}
-
-
-void game_handle_ggz_seat(GGZdMod * ggz, GGZdModEvent event,
-			  const void *data)
-{
-  const GGZSeat *old_seat = data;
-  GGZSeat new_seat = ggzdmod_get_seat(ggz, old_seat->num);
-  GGZdModState new_state;
-
-  /* Check the state. */
-  if (seats_full())
-    new_state = GGZDMOD_STATE_PLAYING;
-  else if (seats_empty())
-    new_state = GGZDMOD_STATE_DONE;
-  else
-    new_state = GGZDMOD_STATE_WAITING;
-
-  // That's great!! Do stuff
-
-  if (new_seat.type == GGZ_SEAT_PLAYER)
-    game_send_seat(new_seat.num);
-  game_send_players();
-
-  if (new_state == GGZDMOD_STATE_PLAYING && rvr_game.turn != EMPTY)
-    game_send_sync(new_seat.num);
-
-  ggzdmod_set_state(ggz, new_state);
-}
-
-
-int game_send_seat(int seat)
-{
-  int fd = ggzdmod_get_seat(rvr_game.ggz, seat).fd;
-
-  ggzdmod_log(rvr_game.ggz, "Sending player %d's his seat number\n", seat);
-
-  if (ggz_write_int(fd, RVR_MSG_SEAT) < 0 || ggz_write_int(fd, seat) < 0) {
-    ggzdmod_log(rvr_game.ggz, "Couldn't send seat!\n");
-    return -1;
-  }
-
-  return 0;
-}
-
-int game_send_players(void)
-{
-  int i, j, fd;
-
-  for (j = 0; j < ggzdmod_get_num_seats(rvr_game.ggz); j++) {
-    if ((fd = ggzdmod_get_seat(rvr_game.ggz, j).fd) == -1) {
-      ggzdmod_log(rvr_game.ggz, "Bot seat\n");
-      continue;
-    }
-    ggzdmod_log(rvr_game.ggz, "Sending player list to player %d", j);
-
-    if (ggz_write_int(fd, RVR_MSG_PLAYERS) < 0) {
-      ggzdmod_log(rvr_game.ggz, "Can't send player list!\n");
-      return -1;
-    }
-
-    for (i = 0; i < ggzdmod_get_num_seats(rvr_game.ggz); i++) {
-      if (ggz_write_int(fd, ggzdmod_get_seat(rvr_game.ggz, i).type) < 0)
-	return -1;
-      if (ggzdmod_get_seat(rvr_game.ggz, i).type != GGZ_SEAT_OPEN &&
-	  ggz_write_string(fd, ggzdmod_get_seat(rvr_game.ggz, i).name) < 0) {
-	ggzdmod_log(rvr_game.ggz, "Can't send player name!\n");
-	return -1;
-      }
-    }
-  }
-
-  return 0;
-}
-
-int game_send_sync(int seat)
-{
-  int i, fd = ggzdmod_get_seat(rvr_game.ggz, seat).fd;
-
-  ggzdmod_log(rvr_game.ggz, "Handling sync for player %d", seat);
-
-  // Send SYNC message and current turn
-
-  if (ggz_write_int(fd, RVR_MSG_SYNC) < 0
-      || ggz_write_char(fd, rvr_game.turn) < 0)
-    return -1;
-
-  // Send current board state
-
-  for (i = 0; i < 64; i++) {
-    if (ggz_write_char(fd, rvr_game.board[i]) < 0)
-      return -1;
-  }
-
-  // That's fine
-
-  return 0;
-
-}
-
-int game_start(void)
-{
-
-  int i, fd;
-
-  // Start game variables
-  rvr_game.state = RVR_STATE_PLAYING;
-
-  // Sends out start message
-  for (i = 0; i < ggzdmod_get_num_seats(rvr_game.ggz); i++) {
-    fd = ggzdmod_get_seat(rvr_game.ggz, i).fd;
-    // Don't send anything if the player is a computer!
-    if (fd == -1)
-      continue;
-    if (ggz_write_int(fd, RVR_MSG_START) < 0)
-      return -1;
-  }
-
-  ggzdmod_log(rvr_game.ggz, "Game has started!\n");
-
-  return 0;
-}
-
-/* return -1 on error, 1 on gameover */
-void game_handle_player(GGZdMod * ggz, GGZdModEvent event, const void *data)
-{
-  const int *seat_ptr = data;
-  const int seat = *seat_ptr;
-  int op, move;
-  int fd = ggzdmod_get_seat(ggz, seat).fd;
-
-  if (ggz_read_int(fd, &op) < 0)
-    return;
-
-  switch (op) {
-
-  case RVR_REQ_MOVE:
-    game_handle_move(seat, &move);
-    break;
-
-  case RVR_REQ_SYNC:
-    game_send_sync(seat);
-    break;
-
-  case RVR_REQ_AGAIN:
-    game_play_again(seat);
-    break;
-
-  default:
-    ggzdmod_log(rvr_game.ggz, "ERROR: unknown player opcode %d.", op);
-    break;
-  }
-}
-
-int game_handle_move(int seat, int *move)
-{
-  int fd = ggzdmod_get_seat(rvr_game.ggz, seat).fd, status;
-
-  // Get the move from the message
-  if (ggz_read_int(fd, move) < 0)
-    return -1;
+static int
+game_make_move (int player, int move);
 
-  ggzdmod_log(rvr_game.ggz, "Handling move %d,%dfor player %d\n", X(*move),
-	      Y(*move), seat);
-
-  // Check if it's his turn
-  if (SEAT2PLAYER(seat) != rvr_game.turn) {
-    status = RVR_ERROR_WRONGTURN;
-  } else {
-    // Check if it's valid (status return a negative value if error, the move on sucess)
-    status = game_check_move(SEAT2PLAYER(seat), *move);
-  }
-
-  // Make move if it's valid (also sends it to everyone);
-  game_make_move(SEAT2PLAYER(seat), status);
-
-  return status;
-
-}
-
-void game_play(void)
-{
-  int move;
-  int seat = PLAYER2SEAT(rvr_game.turn);
-
-  // Is the AI?
-  if (ggzdmod_get_seat(rvr_game.ggz, seat).type == GGZ_SEAT_BOT) {
-    // Yes! Wait for a second
-    sleep(1);
-    move = game_bot_move(rvr_game.turn);
-    game_make_move(rvr_game.turn, move);
-  }
-  // It's not! Wait until the player sends the message...
-
-  return;
-}
-
-int game_bot_move(int player)
-{
-  int i;
-
-  // Returns a random move between 0 and 63
-  i = (int) (64.0 * rand() / (RAND_MAX + 1.0));
-  if (game_check_move(player, i) >= 0)
-    return i;
-  else
-    return game_bot_move(player);
-}
-
-int game_check_move(int player, int move)
-{
-
-  int x = X(move), y = Y(move), status = 0;
-
-  // Check if it's right time
-  if (rvr_game.state != RVR_STATE_PLAYING)
-    return RVR_ERROR_WRONGTURN;
-
-  // Check if out of bounds
-  if (move < 0 || move > 63)
-    return RVR_ERROR_INVALIDMOVE;
-
-  // Check if duplicated
-  if (rvr_game.board[move] != EMPTY)
-    return RVR_ERROR_INVALIDMOVE;
-
-  /* CHECK IF THE MOVE IS VALID */
-
-  // Check if it's valid up
-  status += game_check_direction(player, 0, -1, x, y);
-  status += game_check_direction(player, 1, -1, x, y);
-  status += game_check_direction(player, 1, 0, x, y);
-  status += game_check_direction(player, 1, 1, x, y);
-  status += game_check_direction(player, 0, 1, x, y);
-  status += game_check_direction(player, -1, 1, x, y);
-  status += game_check_direction(player, -1, 0, x, y);
-  status += game_check_direction(player, -1, -1, x, y);
-
-  if (status > 0)
-    return move;
-  else
-    return RVR_ERROR_INVALIDMOVE;
-
-}
-
-int game_check_direction(int player, int vx, int vy, int x, int y)
-{
-  int i, j;
-  for (i = x + vx, j = y + vy; GET(i, j) == -player; i += vx, j += vy) {
-    if (GET(i + vx, j + vy) == player)
-      return 1;
-  }
-  return 0;
-}
-
-int game_make_move(int player, int move)
-{
-  int x = X(move), y = Y(move);
-  int status = 0;
-  int a, fd;
-
-  // Make the move
-  if (move >= 0) {
-    rvr_game.board[move] = player;
-
-    // Now goes through all directions, marking the board
-
-    status += game_mark_board(player, 0, -1, x, y);
-    status += game_mark_board(player, 1, -1, x, y);
-    status += game_mark_board(player, 1, 0, x, y);
-    status += game_mark_board(player, 1, 1, x, y);
-    status += game_mark_board(player, 0, 1, x, y);
-    status += game_mark_board(player, -1, 1, x, y);
-    status += game_mark_board(player, -1, 0, x, y);
-    status += game_mark_board(player, -1, -1, x, y);
-
-
-    // Change turn
-    rvr_game.turn *= -1;
-
-    game_update_scores();
-
-  } else
-    status = -1;
-
-  for (a = 0; a < ggzdmod_get_num_seats(rvr_game.ggz); a++) {
-    fd = ggzdmod_get_seat(rvr_game.ggz, a).fd;
-    if (fd == -1)
-      continue;
-    if (status > 0) {
-      if (ggz_write_int(fd, RVR_MSG_MOVE) < 0 || ggz_write_int(fd, move) < 0)
-	ggzdmod_log(rvr_game.ggz, "Couldn't send message to player\n");
-    } else {
-      if (ggz_write_int(fd, RVR_MSG_MOVE) < 0
-	  || ggz_write_int(fd, RVR_ERROR_INVALIDMOVE) < 0)
-	ggzdmod_log(rvr_game.ggz, "Couldn't send error message to player\n");
-    }
-    player *= -1;
-  }
-
-  // Check if game is over
-  if (status >= 0 && !game_check_over()) {
-
-    // AI play
-    game_play();
-
-  }
-
-  // If couldn`t make the move, sends sync to the player
-  if (status < 0)
-    game_send_sync(PLAYER2SEAT(player));
-
-  return status;
-
-}
-
-int game_check_over(void)
-{
-  int i, status = 0;
-
-  // Check if the current player can play
-  for (i = 0; i < 64; i++) {
-    if (game_check_move(rvr_game.turn, i) > 0) {
-      status++;
-      break;
-    }
-  }
-
-  // If he can play, the game is not over
-  if (status > 0)
-    return 0;
-
-  // He can't! Check if the opponent can
-  status = 0;
-
-  for (i = 0; i < 64; i++) {
-    if (game_check_move(-rvr_game.turn, i) > 0) {
-      status++;
-      break;
-    }
-  }
-
-  // If he can, then skip the players move.
-  // If he can't, end the game
-
-  if (status > 0)
-    game_skip_move();
-  else {
-    game_gameover();
-    return 1;
-  }
-
-  return 0;
-}
-
-
-
-
-
-int game_mark_board(int player, int vx, int vy, int x, int y)
-{
-  int i, j;
-  if (!game_check_direction(player, vx, vy, x, y))
-    return 0;
-  for (i = x + vx, j = y + vy; GET(i, j) == -player; i += vx, j += vy) {
-    rvr_game.board[CART(i, j)] *= -1;
-  }
-  return 1;
-}
-
-void game_skip_move(void)
-{
-  int seat;
-
-  for (seat = 0; seat < ggzdmod_get_num_seats(rvr_game.ggz); seat++) {
-    int fd = ggzdmod_get_seat(rvr_game.ggz, seat).fd;
-    if (fd != -1) {
-      if (ggz_write_int(fd, RVR_MSG_MOVE) < 0 ||
-	  ggz_write_int(fd, RVR_ERROR_CANTMOVE) < 0)
-	ggzdmod_log(rvr_game.ggz, "Can't skip move");
-    }
-  }
-
-  rvr_game.turn *= -1;
-
-  return;
-
-}
-
-void game_gameover(void)
-{
-  int seat, fd, winner;
-  GGZGameResult results[2];
-
-  // Ends everything
-  rvr_game.turn = EMPTY;
-  rvr_game.state = RVR_STATE_DONE;
-
-  if (rvr_game.black > rvr_game.white) {
-    results[PLAYER2SEAT(BLACK)] = GGZ_GAME_WIN;
-    results[PLAYER2SEAT(WHITE)] = GGZ_GAME_LOSS;
-    winner = BLACK;
-  } else if (rvr_game.white > rvr_game.black) {
-    results[PLAYER2SEAT(WHITE)] = GGZ_GAME_WIN;
-    results[PLAYER2SEAT(BLACK)] = GGZ_GAME_LOSS;
-    winner = WHITE;
-  } else {
-    winner = EMPTY;
-    results[0] = results[1] = GGZ_GAME_TIE;
-  }
-
-  /* Report game to GGZ */
-  ggzdmod_report_game(rvr_game.ggz, NULL, results, NULL);
-
-  // Send message 
-  for (seat = 0; seat < ggzdmod_get_num_seats(rvr_game.ggz); seat++) {
-    fd = ggzdmod_get_seat(rvr_game.ggz, seat).fd;
-    if (fd == -1)
-      continue;
-    if (ggz_write_int(fd, RVR_MSG_GAMEOVER) < 0
-	|| ggz_write_int(fd, winner) < 0)
-      ggzdmod_log(rvr_game.ggz, "Can't send gameover message");
-  }
-
-  // What to do now?
-  // Puts human players score = 0
-  // When they send a REQ_AGAIN message, put it = 1
-  // When everyone equal = 1, then starts it all again
-  ggzdmod_log(rvr_game.ggz,
-	      "Game is over. Waiting to see if we should play again\n");
-  rvr_game.white =
-      (ggzdmod_get_seat(rvr_game.ggz, PLAYER2SEAT(WHITE)).type ==
-       GGZ_SEAT_BOT);
-  rvr_game.black =
-      (ggzdmod_get_seat(rvr_game.ggz, PLAYER2SEAT(BLACK)).type ==
-       GGZ_SEAT_BOT);
-
-  return;
-
-}
-
-int game_play_again(int seat)
+// Initializes everything
+static void
+game_init (GGZdMod * ggzdmod)
 {
-  ggzdmod_log(rvr_game.ggz, "%d wants to play again! He is a good fellow.\n",
-	      seat);
-  // If game is not finished, forget about it
-  if (rvr_game.state != RVR_STATE_DONE) {
-    ggzdmod_log(rvr_game.ggz, "The game wasn`t over yet! Are you crazy?\n");
-    return RVR_SERVER_ERROR;
-  }
-
-  if (SEAT2PLAYER(seat) == WHITE)
-    rvr_game.white = 1;
-  else if (SEAT2PLAYER(seat) == BLACK)
-    rvr_game.black = 1;
-
-  if (rvr_game.white && rvr_game.black) {
-    // Starts is again
-    game_init(rvr_game.ggz);
-    game_start();
-    rvr_game.turn = BLACK;
-    game_play();
-  }
+	init ();
+	rvr_game.ggz = ggzdmod;
+	rvr_game.kifu[0][0] = EMPTY;
+	rvr_game.black = EMPTY;
+	rvr_game.white = EMPTY;
+	rvr_game.state = RVR_STATE_INIT;
+	rvr_game.turn = EMPTY;
+}
+
+static int
+game_send_sync (int seat)
+{
+	int fd = ggzdmod_get_seat (rvr_game.ggz, seat).fd;
+	int i;
+	
+	ggzdmod_log (rvr_game.ggz, "Handling sync for player %d", seat);
+
+	// Send SYNC message and move_count
+	if (ggz_write_int (fd, RVR_MSG_SYNC) < 0 
+		|| ggz_write_int (fd, (move_count - 4)) < 0 )
+		return -1;
+
+	// Send kifu
+	for (i = 0; i < (move_count - 4); i++)
+	{
+		if (ggz_write_int (fd, (int)rvr_game.kifu[i][0] ) < 0
+			|| ggz_write_int (fd, (int)rvr_game.kifu[i][1]) < 0)
+			return -1;
+	}
+	// Send current turn
+	if (ggz_write_int (fd, rvr_game.turn) < 0)
+		return -1;
+
+	// That's fine
+	return 0;
+}
+
+static int
+game_skip_move (void)
+{
+	int seat, fd;
+
+	for (seat = 0; seat < ggzdmod_get_num_seats (rvr_game.ggz); seat++)
+	{
+		fd = ggzdmod_get_seat (rvr_game.ggz, seat).fd;
+		if (fd != -1)
+		{
+			if (ggz_write_int (fd, RVR_MSG_MOVE) < 0 ||
+			    ggz_write_int (fd, RVR_ERROR_CANTMOVE) < 0)
+				ggzdmod_log (rvr_game.ggz, "Can't skip move");
+		}
+	}
+	whose_turn = OTHER_PLAYER (whose_turn);
+	rvr_game.turn = whose_turn;
+	return FALSE;
+}
+
+static int
+game_check_over (void)
+{
+	int seat, fd, winner;
+	GGZGameResult results[2];
+
+	if (mobility (whose_turn))
+		return FALSE;
+	if (mobility (OTHER_PLAYER (whose_turn)))
+		return game_skip_move ();
+
+	// Ends everything
+	rvr_game.turn = EMPTY;
+	rvr_game.state = RVR_STATE_DONE;
+
+	if (bcount > wcount)
+	{
+		results[PLAYER2SEAT (BLACK)] = GGZ_GAME_WIN;
+		results[PLAYER2SEAT (WHITE)] = GGZ_GAME_LOSS;
+		winner = BLACK;
+	}
+	else if (wcount > bcount)
+	{
+		results[PLAYER2SEAT (WHITE)] = GGZ_GAME_WIN;
+		results[PLAYER2SEAT (BLACK)] = GGZ_GAME_LOSS;
+		winner = WHITE;
+	}
+	else
+	{
+		winner = EMPTY;
+		results[0] = results[1] = GGZ_GAME_TIE;
+	}
+
+	/* Report game to GGZ */
+	ggzdmod_report_game (rvr_game.ggz, NULL, results, NULL);
+
+	// Send message 
+	for (seat = 0; seat < ggzdmod_get_num_seats (rvr_game.ggz); seat++)
+	{
+		fd = ggzdmod_get_seat (rvr_game.ggz, seat).fd;
+		if (fd == -1)
+			continue;
+		if (ggz_write_int (fd, RVR_MSG_GAMEOVER) < 0
+		    || ggz_write_int (fd, winner) < 0)
+			ggzdmod_log (rvr_game.ggz, "Can't send gameover message");
+	}
+
+	// What to do now?
+	// Puts human players score = 0
+	// When they send a REQ_AGAIN message, put it = 1
+	// When everyone equal = 1, then starts it all again
+	ggzdmod_log (rvr_game.ggz,
+			"Game is over. Waiting to see if we should play again\n");
+	rvr_game.white = (ggzdmod_get_seat (rvr_game.ggz,
+				PLAYER2SEAT (WHITE)).type == GGZ_SEAT_BOT);
+	rvr_game.black = (ggzdmod_get_seat (rvr_game.ggz, 
+				PLAYER2SEAT (BLACK)).type == GGZ_SEAT_BOT);
+	return TRUE;
+}
+
+static int
+game_bot_move (int level)
+{
+	return computer_move (level);
+}
+
+static void
+game_play (void)
+{
+	int move;
+	int seat = PLAYER2SEAT (rvr_game.turn);
+
+	// Is the AI?
+	if (ggzdmod_get_seat (rvr_game.ggz, seat).type == GGZ_SEAT_BOT)
+	{
+		// Yes! Wait for a second
+		sleep (1);
+		move = game_bot_move (COMPUTER_LEVEL);
+		game_make_move ((int)rvr_game.turn, move);
+	}
+
+	// It's not! Wait until the player sends the message...
+	return;
+}
+
+static int
+game_check_move (int player, int move)
+{
+	// Check if it's right time
+	if (rvr_game.state != RVR_STATE_PLAYING)
+		return RVR_ERROR_WRONGTURN;
+
+	// Check if out of bounds
+	if (move / 10 < 1 || move / 10 > 8 || move % 10 < 1 || move % 10 > 8)
+		return RVR_ERROR_INVALIDMOVE;
+
+	// Check if duplicated
+	if (board0[move] != BLANK)
+		return RVR_ERROR_INVALIDMOVE;
+
+	if (!is_valid (player, move))
+		return RVR_ERROR_INVALIDMOVE;
+	else
+		return move;
+}
+
+static int
+game_make_move (int player, int move)
+{
+	int fd, seat, status = 1;
+
+	if (game_check_move (player, move) > 0)
+	 {
+		rvr_game.kifu[move_count - 4][0] = (guint8) whose_turn;
+		rvr_game.kifu[move_count - 4][1] = (guint8) move;
+		rvr_game.kifu[move_count - 3][0] = 0;
+		rvr_game.kifu[move_count - 3][1] = 0;
+		move_board (move);
+		rvr_game.turn = whose_turn;
+	 }
+	else
+		status = -1;
+
+	for (seat = 0; seat < ggzdmod_get_num_seats (rvr_game.ggz); seat++)
+	 {
+		fd = ggzdmod_get_seat (rvr_game.ggz, seat).fd;
+		if (fd == -1)
+			continue;
+		if (status > 0)
+		 {
+			if (ggz_write_int (fd, RVR_MSG_MOVE) < 0
+			    || ggz_write_int (fd, move) < 0)
+				ggzdmod_log (rvr_game.ggz,
+					     "Couldn't send message to player\n");
+		 }
+		else
+		 {
+			if (ggz_write_int (fd, RVR_MSG_MOVE) < 0
+			    || ggz_write_int (fd, RVR_ERROR_INVALIDMOVE) < 0)
+				ggzdmod_log (rvr_game.ggz,
+					     "Couldn't send error message to player\n");
+		 }
+	 }
+
+	// Check if game is over
+	if (status > 0 && !game_check_over ())
+		// AI play
+		game_play ();
+
+	// If couldn`t make the move, sends sync to the player
+	if (status < 0)
+		game_send_sync (PLAYER2SEAT (player));
+
+	return status;
+}
+
+static int
+game_start (void)
+{
+	int seat, fd;
+
+	// Start game variables
+	rvr_game.state = RVR_STATE_PLAYING;
+
+	// Sends out start message
+	for (seat = 0; seat < ggzdmod_get_num_seats (rvr_game.ggz); seat++)
+	{
+		fd = ggzdmod_get_seat (rvr_game.ggz, seat).fd;
+		// Don't send anything if the player is a computer!
+		if (fd == -1)
+			continue;
+		if (ggz_write_int (fd, RVR_MSG_START) < 0)
+			return -1;
+	}
+
+	ggzdmod_log (rvr_game.ggz, "Game has started!\n");
+	return 0;
+}
+
+static int
+game_play_again (int seat)
+{
+	ggzdmod_log (rvr_game.ggz, "%d wants to play again!\n", seat);
+
+	// If game is not finished, forget about it
+	if (rvr_game.state != RVR_STATE_DONE)
+	{
+		ggzdmod_log (rvr_game.ggz, "The game wasn`t over yet!\n");
+		return RVR_SERVER_ERROR;
+	}
+
+	if (SEAT2PLAYER (seat) == WHITE)
+		rvr_game.white = 1;
+	else if (SEAT2PLAYER (seat) == BLACK)
+		rvr_game.black = 1;
+
+	if (rvr_game.black * rvr_game.white)
+	{
+		// Starts is again
+		game_init (rvr_game.ggz);
+		game_start ();
+		rvr_game.turn = BLACK;
+		game_play ();
+	}
+
+	return RVR_SERVER_OK;
+}
+
+/* return full: TRUE, other: FALSE */
+static gboolean
+seats_full (void)
+{
+	/* This calculation is a bit inefficient, but that's OK */
+	return ggzdmod_count_seats (rvr_game.ggz, GGZ_SEAT_OPEN) == 0
+		&& ggzdmod_count_seats (rvr_game.ggz, GGZ_SEAT_RESERVED) == 0
+		&& ggzdmod_count_seats (rvr_game.ggz, GGZ_SEAT_ABANDONED) == 0;
+}
+
+/* return empty: TRUE, other: FALSE */
+static gboolean
+seats_empty (void)
+{
+	/* This calculation is a bit inefficient, but that's OK */
+	return ggzdmod_count_seats (rvr_game.ggz, GGZ_SEAT_PLAYER) == 0
+		&& ggzdmod_count_spectators (rvr_game.ggz) == 0;
+}
+
+/* return -1: error, 0: ok. */
+static int
+game_send_seat (int seat)
+{
+	int fd = ggzdmod_get_seat (rvr_game.ggz, seat).fd;
+
+	ggzdmod_log (rvr_game.ggz, "Sending player %d's his seat number\n", seat);
+
+	if (ggz_write_int (fd, RVR_MSG_SEAT) < 0 || ggz_write_int (fd, seat) < 0)
+	{
+		ggzdmod_log (rvr_game.ggz, "Couldn't send seat!\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/* return -1: error, 0: ok. */
+static int
+game_send_players (void)
+{
+	int i, j, fd;
+
+	for (j = 0; j < ggzdmod_get_num_seats (rvr_game.ggz); j++)
+	{
+		if ((fd = ggzdmod_get_seat (rvr_game.ggz, j).fd) == -1)
+		{
+			ggzdmod_log (rvr_game.ggz, "Bot seat\n");
+			continue;
+		}
+		ggzdmod_log (rvr_game.ggz, "Sending player list to player %d", j);
+
+		if (ggz_write_int (fd, RVR_MSG_PLAYERS) < 0)
+		{
+			ggzdmod_log (rvr_game.ggz, "Can't send player list!\n");
+			return -1;
+		}
+
+		for (i = 0; i < ggzdmod_get_num_seats (rvr_game.ggz); i++)
+		{
+			if (ggz_write_int (fd, ggzdmod_get_seat (rvr_game.ggz, i).type) < 0)
+				return -1;
+			if (ggzdmod_get_seat (rvr_game.ggz, i).type != GGZ_SEAT_OPEN &&
+				ggz_write_string (fd, ggzdmod_get_seat (rvr_game.ggz, i).name) < 0)
+			{
+				ggzdmod_log (rvr_game.ggz, "Can't send player name!\n");
+				return -1;
+			}
+		}
+	}
 
-
-  return RVR_SERVER_OK;
-
-}
-
-void game_update_scores(void)
-{
-  int i;
-  rvr_game.white = 0;
-  rvr_game.black = 0;
-  for (i = 0; i < 64; i++) {
-    if (rvr_game.board[i] == WHITE)
-      rvr_game.white++;
-    if (rvr_game.board[i] == BLACK)
-      rvr_game.black++;
-  }
+	return 0;
 }
 
-
-int main(void)
+// Handle server messages
+static void
+game_handle_ggz_state (GGZdMod *ggz, GGZdModEvent event, const void *data)
 {
-  GGZdMod *ggz = ggzdmod_new(GGZDMOD_GAME);
-
-  /* game_init is called at the start of _each_ game, so we must do
-     ggz stuff here. */
-  ggzdmod_set_handler(ggz, GGZDMOD_EVENT_STATE, &game_handle_ggz_state);
-  ggzdmod_set_handler(ggz, GGZDMOD_EVENT_JOIN, &game_handle_ggz_seat);
-  ggzdmod_set_handler(ggz, GGZDMOD_EVENT_LEAVE, &game_handle_ggz_seat);
-  ggzdmod_set_handler(ggz, GGZDMOD_EVENT_SEAT, &game_handle_ggz_seat);
-  ggzdmod_set_handler(ggz, GGZDMOD_EVENT_PLAYER_DATA, &game_handle_player);
-
-  game_init(ggz);
-
-  /* Connect to GGZ server; main loop */
-  if (ggzdmod_connect(ggz) < 0)
-    return -1;
-  (void) ggzdmod_loop(ggz);
-  (void) ggzdmod_disconnect(ggz);
-  ggzdmod_free(ggz);
+	GGZdModState new_state = ggzdmod_get_state (ggz);
+	const GGZdModState *old_state_ptr = data;
+	const GGZdModState old_state = *old_state_ptr;
+
+	// Check if it's the right time to launch the game and if ggz could do taht
+	if (old_state == GGZDMOD_STATE_CREATED)
+		assert(rvr_game.state == RVR_STATE_INIT);
+
+	if (new_state == GGZDMOD_STATE_PLAYING)
+	{
+		// Game already going on?
+		if (!rvr_game.turn)
+			rvr_game.turn = BLACK;
+
+		// No! Let's start the game!
+		game_start ();
+		game_play ();
+	}
+	if (new_state == GGZDMOD_STATE_WAITING)
+	{
+		// That's great! Update the state
+		// Now waiting for people to join
+		rvr_game.state = RVR_STATE_WAIT;
+		ggzdmod_log (rvr_game.ggz, "Waiting for players");
+	}
+}
+
+static void
+game_handle_ggz_seat (GGZdMod *ggz, GGZdModEvent event, const void *data)
+{
+	const GGZSeat *old_seat = data;
+	GGZSeat new_seat = ggzdmod_get_seat (ggz, old_seat->num);
+	GGZdModState new_state;
+
+	/* Check the state. */
+	if (seats_full ())
+		new_state = GGZDMOD_STATE_PLAYING;
+	else if (seats_empty ())
+		new_state = GGZDMOD_STATE_DONE;
+	else
+		new_state = GGZDMOD_STATE_WAITING;
+
+	// That's great!! Do stuff
+	if (new_seat.type == GGZ_SEAT_PLAYER)
+		game_send_seat (new_seat.num);
+	game_send_players ();
+
+	if (new_state == GGZDMOD_STATE_PLAYING && rvr_game.turn != EMPTY)
+		game_send_sync (new_seat.num);
+
+	ggzdmod_set_state (ggz, new_state);
+}
+
+static int
+game_handle_move(int seat, int *move)
+{
+	int fd = ggzdmod_get_seat(rvr_game.ggz, seat).fd, status;
+
+	// Get the move from the message
+	if (ggz_read_int(fd, move) < 0)
+		return -1;
+
+	ggzdmod_log(rvr_game.ggz, "Handling move %d, for player %d\n", *move, seat);
+
+	// Check if it's his turn
+	if (SEAT2PLAYER(seat) != rvr_game.turn)
+		status = RVR_ERROR_WRONGTURN;
+	else
+		// Check if it's valid (status return a negative value if error, the move on sucess)
+		status = game_check_move(SEAT2PLAYER(seat), *move);
+
+	// Make move if it's valid (also sends it to everyone);
+	game_make_move(SEAT2PLAYER(seat), status);
+
+	return status;
+
+}
+
+static void
+game_handle_player (GGZdMod * ggz, GGZdModEvent event, const void *data)
+{
+	const int *seat_ptr = data;
+	const int seat = *seat_ptr;
+	int op, move;
+	int fd = ggzdmod_get_seat (ggz, seat).fd;
+
+	if (ggz_read_int (fd, &op) < 0)
+		return;
+
+	switch (op)
+	{
+		case RVR_REQ_MOVE:
+			game_handle_move (seat, &move);
+			break;
+		case RVR_REQ_SYNC:
+			game_send_sync (seat);
+			break;
+		case RVR_REQ_AGAIN:
+			game_play_again (seat);
+			break;
+		default:
+			ggzdmod_log (rvr_game.ggz, "ERROR: unknown player opcode %d.", op);
+			break;
+	}
+}
+
+int
+main (void)
+{
+	GGZdMod *ggz = ggzdmod_new (GGZDMOD_GAME);
+
+	/* game_init is called at the start of _each_ game, so we must do
+	 * ggz stuff here. */
+	ggzdmod_set_handler (ggz, GGZDMOD_EVENT_STATE, &game_handle_ggz_state);
+	ggzdmod_set_handler (ggz, GGZDMOD_EVENT_JOIN,  &game_handle_ggz_seat);
+	ggzdmod_set_handler (ggz, GGZDMOD_EVENT_LEAVE, &game_handle_ggz_seat);
+	ggzdmod_set_handler (ggz, GGZDMOD_EVENT_SEAT,  &game_handle_ggz_seat);
+	ggzdmod_set_handler (ggz, GGZDMOD_EVENT_PLAYER_DATA, &game_handle_player);
+
+	game_init (ggz);
+
+	/* Connect to GGZ server; main loop */
+	if (ggzdmod_connect (ggz) < 0)
+		return -1;
+	(void) ggzdmod_loop (ggz);
+	(void) ggzdmod_disconnect (ggz);
+	ggzdmod_free (ggz);
 
-  return 0;
+	return 0;
 }
Index: gnome-games/iagno/server.h
===================================================================
RCS file: /cvs/gnome/gnome-games/iagno/server.h,v
retrieving revision 1.1
diff -u -r1.1 server.h
--- gnome-games/iagno/server.h	5 Sep 2006 16:36:27 -0000	1.1
+++ gnome-games/iagno/server.h	3 Oct 2006 04:55:38 -0000
@@ -1,5 +1,5 @@
 /*
- * File: game.h
+ * File: server.h
  * Author: Ismael Orenstein
  * Project: GGZ Reversi game module
  * Date: 09/17/2000
@@ -23,121 +23,17 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
  */
 
-#define BLACK -1
-#define WHITE +1
-#define EMPTY  0
+/* IAGNO PROTOCOL VERSION 1 */
 
-/* REVERSI PROTOCOL VERSION 0.0.5
- *
- * The server handles everything, from the AI to the validity of moves
- *
- * RVR_STATE_INIT:
- *
- * First, it fetchs from the ggz_server how much seats there are, and how much are open/closed
- *
- * RVR_STATE_JOIN:
- *
- * Then, it waits until some player join . When he does, it sends:
- *
- * To Joining player:
- * 	RVR_MSG_SEAT (int)SEAT_NUM
- * To All Human players:
- * 	RVR_MSG_PLAYERS PLAYER_IDENTIFER[BLACK] PLAYER_IDENTIFIER[WHITE]
- *  where PLAYER_IDENTIFIER is:
- *  	(int)PLAYER_TYPE
- *  	if PLAYER_TYPE == GGZ_SEAT_OPEN
- *  		(str)PLAYER_NAME
- *
- * If the game was already happening, send the current game state to the new player
- *
- * 	RVR_MSG_SYNC (char)TURN BOARD_STATE
- * 	where TURN is the current turn, and:
- * 		BOARD_STATE = (char)POSITION * 64
- *
- * When all the open seats are filled, it enters playing state (state = RVR_STATE_PLAYING) and sends:
- *
- * To All Human players:
- * 	RVR_MSG_START
- *
- * RVR_STATE_PLAYING:
- *
- * If current player is AI:
- *
- * 	doMove(AI_MOVE());
- *
- * If it isn't AI, then it waits until client sends a RVR_REQ_MOVE
- *
- * When client sends a RVR_REQ_MOVE, the server must check if he is the current player and
- * if the move is valid. (The client should do it too, must the server must recheck to avoid cheating)
- * Then the server executes the move, and sends:
- * 
- * To All Human players:
- *
- *	RVR_MSG_MOVE (int)MOVE
- * 	where MOVE can be a array index (0-63) or one of the following error values:
- * 		RVR_ERROR_WRONGTURN
- * 			The player tried to move when it wasn't his turn
- * 		RVR_ERROR_INVALIDMOVE
- * 			The player tried a invalid move (Cheating sign!)
- * 		RVR_ERROR_CANTMOVE
- * 			The player can't move (no possible move)
- *
- * Then the server checks if the game is over (No more valid moves) and who has won. If the game is over,
- * it sends to All Human players:
- *
- * 	RVR_MSG_GAMEOVER (int)WINNER
- * 		where WINNER can be: BLACK, WHITE, EMPTY(draw)
- *
- * If some player left while the game was happening, it sends to all Human players:
- *
- * 	RVR_MSG_PLAYERS
- *
- * And it will wait until someone returns
- *
- * Any time, the server can receive a RVR_REQ_SYNC message from the client.
- *  If this is the case, it sents a RVR_MSG_SYNC to this player.
- *
- * The client (more information should be avaiable on the client's game.h file):
- * 
- * The client waits until a RVR_MSG_SEAT is sent to him, indicating what is his seat.
- * Then it waits until a RVR_MSG_PLAYERS, with the type/name of all the players
- * Then it waits until a RVR_MSG_START is sent.
- *
- * If a RVR_MSG_SYNC message is sent to him, it replaces the current game state with the one sent.
- * 
- * Then he enters playing mode.
- *
- * If it is his turn, The user selects a valid square and the client sends:
- * 	RVR_REQ_MOVE (int)MOVE
- * Then it waits until the server sends:
- * 	RVR_MSG_MOVE (int)MOVE
- * If move >= 0, do the move. Else, tell the player what was the error.
- * 
- * If it isn't his turn, it waits until the server sents a
- * 	RVR_MSG_MOVE (int)MOVE
- * If move >= 0, do the move. Else, tell (if necessary) what was the error.
- * 
- * After the move is done, change to the other turn.	
- *
- * If anyone has left the table, it will receive a RVR_MSG_PLAYERS from the server. Then it enters waiting mode again.
- *
- * When the game is over, it sends a RVR_MSG_GAMEOVER (int)winner to the players, and enters DONE state. If it receives enough RVR_REQ_AGAIN msgs, it sends a RVR_MSG_START to the players.
- *
- * Luckily that's all, this protocol is perfect and it shouldn't be modified anymore. Or so I hope. :) */
-
-#include "ggzdmod.h"
-
-// Reversi protocol
-// The numbers aren't on order, because I used the same constants from TicTacToe - simplify testing
 #define RVR_MSG_SEAT 0
 #define RVR_MSG_PLAYERS 1
-#define RVR_MSG_SYNC 6
-#define RVR_REQ_SYNC 7
-#define RVR_REQ_AGAIN 8
-#define RVR_MSG_START 5
 #define RVR_MSG_MOVE 2
 #define RVR_MSG_GAMEOVER 3
 #define RVR_REQ_MOVE 4
+#define RVR_MSG_START 5
+#define RVR_MSG_SYNC 6
+#define RVR_REQ_SYNC 7
+#define RVR_REQ_AGAIN 8
 
 // States
 #define RVR_STATE_INIT 0
@@ -157,77 +53,25 @@
 #define RVR_ERROR_WRONGTURN -2
 #define RVR_ERROR_CANTMOVE -3
 
-// Takes cartesian coordinates and transform them into a array index
-#define CART(X,Y) ( (Y-1)*8+(X-1) )
-
-// Takes a index and transform it in cartesians coordinates
-#define X(I) ( (I%8)+1 )
-#define Y(I) ( (I/8)+1 )
-
-// See what's the value at that place (like a 10x10 board)
-#define GET(X,Y) ( (X==0 || Y==0 || X>8 || Y>8) ? EMPTY : rvr_game.board[CART(X,Y)] )
-
 // Takes a seat and transform into a player code
 #define SEAT2PLAYER(seat) ( (seat==0)?BLACK:WHITE )
 
 // Takes a player code and transform into a seat index
 #define PLAYER2SEAT(player) ( (player==BLACK)?0:1 )
 
+#define COMPUTER_LEVEL 4
+#define EMPTY 0
 
 struct rvr_game_t {
   /* GGZ data */
   GGZdMod *ggz;
-  // Board
-  char board[64];
+  // Kifu
+  guint8 kifu[61][2];
   // Score
   int black;
   int white;
-  // State
-  char state;
   // Turn
-  char turn;
+  int turn;
+  // State
+  int state;
 };
-
-// Intializes game variables
-void game_init(GGZdMod * ggzdmod);
-// Handle server messages
-void game_handle_ggz_state(GGZdMod * ggz,
-			   GGZdModEvent event, const void *data);
-void game_handle_ggz_seat(GGZdMod * ggz,
-			  GGZdModEvent event, const void *data);
-// Handle player messages
-void game_handle_player(GGZdMod * ggz, GGZdModEvent event, const void *data);
-// Handle player move
-int game_handle_move(int, int *);
-
-// Send to the player what is his seat
-int game_send_seat(int);
-// Send to everyone who is playing
-int game_send_players(void);
-// Send game state to player
-int game_send_sync(int);
-// Sends the start message and start the game
-int game_start(void);
-
-// Play the game (if it is the AI)
-void game_play(void);
-// AI move
-int game_bot_move(int);
-// Check if move is valid (return a error code or the move)
-int game_check_move(int, int);
-// Check if a move is valid in this direction (return true or false)
-int game_check_direction(int, int, int, int, int);
-// Make the move, mark the board, increases the score and sends out the msg
-int game_make_move(int, int);
-// Mark the board at this direction (and increases the score)
-int game_mark_board(int, int, int, int, int);
-// Check if game is over
-int game_check_over(void);
-// Skip current player move
-void game_skip_move(void);
-// Game is over! Send gameover message and stop everything
-void game_gameover(void);
-// Play again?
-int game_play_again(int);
-// Update scores
-void game_update_scores(void);
Index: gnome-games/m4/ggz.m4
===================================================================
RCS file: /cvs/gnome/gnome-games/m4/ggz.m4,v
retrieving revision 1.1
diff -u -r1.1 ggz.m4
--- gnome-games/m4/ggz.m4	5 Sep 2006 16:36:28 -0000	1.1
+++ gnome-games/m4/ggz.m4	3 Oct 2006 04:55:44 -0000
@@ -1027,7 +1027,7 @@
   if test "$try_ggz" = "yes"; then
     # For now, version 0.0.14 is required.  This could be an additional
     # parameter.
-    AC_GGZ_VERSION([0], [0], [14], [], [try_ggz=no])
+    AC_GGZ_VERSION([0], [0], [13], [], [try_ggz=no])
   fi
 
   ggz_server="no"
