[Xfce4-commits] <xfce4-panel:master> Add hidden game.
Nick Schermer
noreply at xfce.org
Tue Mar 23 21:40:01 CET 2010
Updating branch refs/heads/master
to dbda8ee64f602a415ed1d8df6322de08dcbdb344 (commit)
from 6268b05c44ffffa1dd3f2366b7e7af9972b79fe8 (commit)
commit dbda8ee64f602a415ed1d8df6322de08dcbdb344
Author: Nick Schermer <nick at xfce.org>
Date: Tue Mar 23 20:38:25 2010 +0100
Add hidden game.
panel/Makefile.am | 2 +
panel/panel-dialogs.c | 27 ++-
panel/panel-tic-tac-toe.c | 658 +++++++++++++++++++++++++++++++++++++++++++++
panel/panel-tic-tac-toe.h | 43 +++
po/POTFILES.in | 1 +
5 files changed, 729 insertions(+), 2 deletions(-)
diff --git a/panel/Makefile.am b/panel/Makefile.am
index 5183c32..906217a 100644
--- a/panel/Makefile.am
+++ b/panel/Makefile.am
@@ -47,6 +47,8 @@ xfce4_panel_SOURCES = \
panel-plugin-external-46.h \
panel-preferences-dialog.c \
panel-preferences-dialog.h \
+ panel-tic-tac-toe.c \
+ panel-tic-tac-toe.h \
panel-window.c \
panel-window.h
diff --git a/panel/panel-dialogs.c b/panel/panel-dialogs.c
index b18603d..32f017f 100644
--- a/panel/panel-dialogs.c
+++ b/panel/panel-dialogs.c
@@ -33,6 +33,28 @@
#include <panel/panel-dialogs.h>
#include <panel/panel-application.h>
+#include <panel/panel-tic-tac-toe.h>
+
+
+
+static void
+panel_dialogs_show_about_email_hook (GtkAboutDialog *dialog,
+ const gchar *uri,
+ gpointer data)
+{
+ if (g_strcmp0 ("tictactoe at xfce.org", uri) == 0)
+ {
+ /* gtk needs to finish some stuff before the dialog can be closed */
+ exo_gtk_object_destroy_later (GTK_OBJECT (dialog));
+
+ /* open tic-tac-toe */
+ panel_tic_tac_toe_show ();
+ }
+ else
+ {
+ exo_gtk_url_about_dialog_hook (dialog, uri, data);
+ }
+}
@@ -43,12 +65,12 @@ panel_dialogs_show_about (void)
{
"Jasper Huijsmans <jasper at xfce.org>",
"Nick Schermer <nick at xfce.org>",
+ "Tic-tac-toe <tictactoe at xfce.org>",
NULL
};
+ gtk_about_dialog_set_email_hook (panel_dialogs_show_about_email_hook, NULL, NULL);
#if !GTK_CHECK_VERSION (2, 18, 0)
- /* set exo hooks for urls and email */
- gtk_about_dialog_set_email_hook (exo_gtk_url_about_dialog_hook, NULL, NULL);
gtk_about_dialog_set_url_hook (exo_gtk_url_about_dialog_hook, NULL, NULL);
#endif
@@ -64,6 +86,7 @@ panel_dialogs_show_about (void)
"website", "http://www.xfce.org/",
"logo-icon-name", PACKAGE_NAME,
NULL);
+
}
diff --git a/panel/panel-tic-tac-toe.c b/panel/panel-tic-tac-toe.c
new file mode 100644
index 0000000..77d8493
--- /dev/null
+++ b/panel/panel-tic-tac-toe.c
@@ -0,0 +1,658 @@
+/*
+ * Copyright (C) 2010 Nick Schermer <nick at xfce.org>
+ *
+ * The game code has been taken (with adjustments) from the javascript
+ * game of Stephen Ostermiller: http://ostermiller.org/calc/tictactoe.html.
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <libxfce4ui/libxfce4ui.h>
+#include <libxfce4util/libxfce4util.h>
+
+#include <common/panel-private.h>
+#include <panel/panel-tic-tac-toe.h>
+
+
+
+static void panel_tic_tac_toe_response (GtkDialog *dialog,
+ gint response_id);
+static void panel_tic_tac_toe_move (PanelTicTacToe *dialog);
+static void panel_tic_tac_toe_button_clicked (GtkWidget *button,
+ PanelTicTacToe *dialog);
+static void panel_tic_tac_toe_new_game (PanelTicTacToe *dialog);
+
+
+
+#define cells_to_hex(c1,c2,c3,c4,c5,c6,c7,c8,c9) (c1 << 0 | c2 << 1 | c3 << 2 | \
+ c4 << 3 | c5 << 4 | c6 << 5 | \
+ c7 << 6 | c8 << 7 | c9 << 8)
+#define cells_to_hex2(c1,c2,c3,c4,c5,c6,c7,c8,c9) (c1 << 0 | c2 << 2 | c3 << 4 | \
+ c4 << 6 | c5 << 8 | c6 << 10 | \
+ c7 << 12 | c8 << 14 | c9 << 16)
+#define winner_hex(winner,state) ((((winner) - 1) << 18) | (state))
+
+
+
+struct _PanelTicTacToeClass
+{
+ XfceTitledDialogClass __parent__;
+};
+
+struct _PanelTicTacToe
+{
+ XfceTitledDialog __parent__;
+
+ GtkWidget *buttons[9];
+ GtkWidget *labels[9];
+ GtkWidget *level;
+};
+
+enum
+{
+ LEVEL_NOVICE,
+ LEVEL_INTERMEDIATE,
+ LEVEL_EXPERIENCED,
+ LEVEL_EXPERT
+};
+
+enum
+{
+ ONE = 1,
+ PLAYER_O = 2,
+ PLAYER_X = 3,
+ TIE = 4
+};
+
+
+
+G_DEFINE_TYPE (PanelTicTacToe, panel_tic_tac_toe, XFCE_TYPE_TITLED_DIALOG)
+
+
+
+static void
+panel_tic_tac_toe_class_init (PanelTicTacToeClass *klass)
+{
+ GtkDialogClass *gtkdialog_class;
+
+ gtkdialog_class = GTK_DIALOG_CLASS (klass);
+ gtkdialog_class->response = panel_tic_tac_toe_response;
+}
+
+
+
+static void
+panel_tic_tac_toe_init (PanelTicTacToe *dialog)
+{
+ GtkWidget *button;
+ GtkWidget *table;
+ GtkWidget *separator;
+ guint i;
+ GtkWidget *label;
+ guint row, col;
+ GtkWidget *align;
+ GtkWidget *vbox;
+ GtkWidget *combo;
+ GtkWidget *hbox;
+
+ gtk_window_set_title (GTK_WINDOW (dialog), "Tic-tac-toe");
+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), "applications-games");
+ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+
+ button = xfce_gtk_button_new_mixed (GTK_STOCK_NEW, _("_New Game"));
+ gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, GTK_RESPONSE_ACCEPT);
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), vbox, TRUE, TRUE, 0);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
+
+ hbox = gtk_hbox_new (FALSE, 12);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+ label = gtk_label_new_with_mnemonic (_("_Level:"));
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+ dialog->level = combo = gtk_combo_box_new_text ();
+ gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Novice"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Intermidiate"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Experienced"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Expert"));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), LEVEL_EXPERIENCED);
+
+ align = gtk_alignment_new (0.5, 0.5, 0.0, 0.0);
+ gtk_box_pack_start (GTK_BOX (vbox), align, TRUE, TRUE, 0);
+
+ table = gtk_table_new (5, 5, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 1);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ gtk_container_add (GTK_CONTAINER (align), table);
+
+ separator = gtk_hseparator_new ();
+ gtk_table_attach (GTK_TABLE (table), separator, 0, 5, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
+ separator = gtk_hseparator_new ();
+ gtk_table_attach (GTK_TABLE (table), separator, 0, 5, 3, 4, GTK_FILL, GTK_FILL, 0, 0);
+ separator = gtk_vseparator_new ();
+ gtk_table_attach (GTK_TABLE (table), separator, 1, 2, 0, 5, GTK_FILL, GTK_FILL, 0, 0);
+ separator = gtk_vseparator_new ();
+ gtk_table_attach (GTK_TABLE (table), separator, 3, 4, 0, 5, GTK_FILL, GTK_FILL, 0, 0);
+
+ for (i = 0; i < 9; i++)
+ {
+ button = dialog->buttons[i] = gtk_button_new ();
+ gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+ gtk_widget_set_size_request (button, 70, 70);
+ gtk_widget_set_can_focus (button, FALSE);
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (panel_tic_tac_toe_button_clicked), dialog);
+
+ label = dialog->labels[i] = gtk_label_new ("");
+ gtk_container_add (GTK_CONTAINER (button), label);
+
+ row = (i / 3) * 2;
+ col = (i % 3) * 2;
+
+ gtk_table_attach (GTK_TABLE (table), button,
+ col, col + 1,
+ row, row + 1,
+ GTK_EXPAND | GTK_FILL,
+ GTK_EXPAND | GTK_FILL,
+ 0, 0);
+ }
+
+ /* set label attributes */
+ panel_tic_tac_toe_new_game (dialog);
+}
+
+
+
+static void
+panel_tic_tac_toe_response (GtkDialog *gtk_dialog,
+ gint response_id)
+{
+ panel_return_if_fail (PANEL_IS_TIC_TAC_TOE (gtk_dialog));
+
+ if (response_id == GTK_RESPONSE_ACCEPT)
+ {
+ /* new game */
+ panel_tic_tac_toe_new_game (PANEL_TIC_TAC_TOE (gtk_dialog));
+ }
+ else
+ {
+ gtk_widget_destroy (GTK_WIDGET (gtk_dialog));
+ }
+}
+
+
+
+static gint
+panel_tic_tac_toe_has_winner (gint state)
+{
+ guint i;
+ gint player_x, player_o, tie;
+ gint matches[] =
+ {
+ /* horizontal */
+ cells_to_hex2 (ONE, ONE, ONE, 0, 0, 0, 0, 0, 0),
+ cells_to_hex2 (0, 0, 0, ONE, ONE, ONE, 0, 0, 0),
+ cells_to_hex2 (0, 0, 0, 0, 0, 0, ONE, ONE, ONE),
+
+ /* vertical */
+ cells_to_hex2 (ONE, 0, 0, ONE, 0, 0, ONE, 0, 0),
+ cells_to_hex2 (0, ONE, 0, 0, ONE, 0, 0, ONE, 0),
+ cells_to_hex2 (0, 0, ONE, 0, 0, ONE, 0, 0, ONE),
+
+ /* diagonal */
+ cells_to_hex2 (ONE, 0, 0, 0, ONE, 0, 0, 0, ONE),
+ cells_to_hex2 (0, 0, ONE, 0, ONE, 0, ONE, 0, 0),
+ };
+
+ for (i = 0; i < G_N_ELEMENTS (matches); i++)
+ {
+ /* x wins */
+ player_x = matches[i] * PLAYER_X;
+ if ((state & player_x) == player_x)
+ return winner_hex (PLAYER_X, player_x);
+
+ /* o wins */
+ player_o = matches[i] * PLAYER_O;
+ if ((state & player_x) == player_o)
+ return winner_hex (PLAYER_O, player_o);
+ }
+
+ /* tie */
+ tie = cells_to_hex2 (PLAYER_O, PLAYER_O, PLAYER_O,
+ PLAYER_O, PLAYER_O, PLAYER_O,
+ PLAYER_O, PLAYER_O, PLAYER_O);
+ if ((state & tie) == tie)
+ return winner_hex (TIE, 0);
+
+ /* no winner or tie */
+ return 0;
+}
+
+
+
+static gint
+panel_tic_tac_toe_best_opening (gint state,
+ gint possible_initial_moves)
+{
+ gint mask;
+
+ /* no moves yet, return the valid initial moves */
+ if (state == 0)
+ return possible_initial_moves;
+
+ mask = state & cells_to_hex2 (PLAYER_O, PLAYER_O, PLAYER_O,
+ PLAYER_O, PLAYER_O, PLAYER_O,
+ PLAYER_O, PLAYER_O, PLAYER_O);
+
+ /* user took the center, pick a corner */
+ if (mask == cells_to_hex2 (0, 0, 0, 0, PLAYER_O, 0, 0, 0, 0))
+ return cells_to_hex (ONE, 0, ONE, 0, 0, 0, ONE, 0, ONE);
+
+ /* user took a corner, pick the center */
+ if (mask == cells_to_hex2 (PLAYER_O, 0, 0, 0, 0, 0, 0, 0, 0)
+ || mask == cells_to_hex2 (0, 0, PLAYER_O, 0, 0, 0, 0, 0, 0)
+ || mask == cells_to_hex2 (0, 0, 0, 0, 0, 0, PLAYER_O, 0, 0)
+ || mask == cells_to_hex2 (0, 0, 0, 0, 0, 0, 0, 0, PLAYER_O))
+ return cells_to_hex (0, 0, 0, 0, ONE, 0, 0, 0, 0);
+
+ /* user took an edge, pick something in the same diagonal */
+ if (mask == cells_to_hex2 (0, PLAYER_O, 0, 0, 0, 0, 0, 0, 0))
+ return cells_to_hex (ONE, 0, ONE, 0, ONE, 0, 0, ONE, 0);
+ if (mask == cells_to_hex2 (0, 0, 0, PLAYER_O, 0, 0, 0, 0, 0))
+ return cells_to_hex (ONE, 0, 0, 0, ONE, ONE, ONE, 0, 0);
+ if (mask == cells_to_hex2 (0, 0, 0, 0, 0, PLAYER_O, 0, 0, 0))
+ return cells_to_hex (0, 0, ONE, ONE, ONE, 0, 0, 0, ONE);
+ if (mask == cells_to_hex2 (0, 0, 0, 0, 0, 0, 0, PLAYER_O, 0))
+ return cells_to_hex (0, ONE, 0, 0, ONE, 0, ONE, 0, ONE);
+
+ /* no best opening move possible */
+ return 0;
+}
+
+
+
+static gint
+panel_tic_tac_toe_get_random_move (gint moves)
+{
+ gint i;
+ gint n_moves;
+ gint seed;
+
+ /* count number of moves in the state */
+ for (i = 0, n_moves = 0; i < 9; i++)
+ if ((moves & (1 << i)) != 0)
+ n_moves++;
+
+ if (n_moves > 0)
+ {
+ /* return one random move from the state */
+ seed = g_random_int_range (0, n_moves);
+ for (i = 0, n_moves = 0; i < 9; i++)
+ {
+ if ((moves & (1 << i)) != 0
+ && n_moves++ == seed)
+ return i;
+ }
+
+ panel_assert_not_reached ();
+ }
+
+ /* no move possible */
+ return -1;
+}
+
+
+
+static gint
+panel_tic_tac_toe_get_legal_moves (gint state)
+{
+ gint i, moves = 0;
+
+ for (i = 0; i < 9; i++)
+ if ((state & (1 << (i * 2 + 1))) == 0)
+ moves |= 1 << i;
+
+ return moves;
+}
+
+
+
+static gint
+panel_tic_tac_toe_get_winner_move (gint state,
+ gint player)
+{
+ gint i;
+
+ for (i = 0; i < 9; i++)
+ if ((state & (1 << (i * 2 + 1))) == 0)
+ if (panel_tic_tac_toe_has_winner (state | (player << (i * 2))) != 0)
+ return 1 << i;
+
+ return 0;
+}
+
+
+
+static gint
+panel_tic_tac_toe_get_move_rate (gint state,
+ gint move,
+ gint move_for,
+ gint next_turn,
+ gint limit,
+ gint depth)
+{
+ gint new_state;
+ gint winner;
+ gint rate;
+ gint legal_moves, i;
+ gint value;
+
+ new_state = state | (next_turn << (move * 2));
+
+ /* check if this new state has a winner or tie */
+ winner = panel_tic_tac_toe_has_winner (new_state);
+ if (winner == winner_hex (TIE, 0))
+ return 0;
+ if (winner != 0)
+ {
+ if (move_for == next_turn)
+ return 10 - depth;
+ else
+ return depth - 10;
+ }
+
+ rate = move_for == next_turn ? 999 : -999;
+ if (depth == limit)
+ return rate;
+
+ legal_moves = panel_tic_tac_toe_get_legal_moves (new_state);
+ for (i = 0; i < 9; i++)
+ {
+ if ((legal_moves & (1 << i)) != 0)
+ {
+ value = panel_tic_tac_toe_get_move_rate (new_state, i, move_for,
+ next_turn == PLAYER_O ? PLAYER_X : PLAYER_O,
+ 10 - ABS (rate), depth + 1);
+ if (ABS (value) != 999)
+ {
+ if ((move_for == next_turn && value < rate)
+ || (move_for != next_turn && value > rate))
+ rate = value;
+ }
+ }
+ }
+
+ return rate;
+}
+
+
+
+static gint
+panel_tic_tac_toe_get_move (gint state,
+ gint player,
+ gint level)
+{
+ gint winner;
+ gint moves, legal_moves;
+ gint first_moves;
+ gint rate, value;
+ gint i;
+ gint move = -1;
+
+ winner = panel_tic_tac_toe_has_winner (state);
+ if (winner == 0)
+ {
+ legal_moves = panel_tic_tac_toe_get_legal_moves (state);
+
+ switch (level)
+ {
+ case LEVEL_EXPERT:
+ /* just take a random position on the first move */
+ first_moves = cells_to_hex (ONE, ONE, ONE, ONE, ONE, ONE, ONE, ONE, ONE);
+ moves = panel_tic_tac_toe_best_opening (state, first_moves);
+ if (moves != 0)
+ break;
+
+ /* find the moves with the best rate */
+ rate = -999;
+ for (i = 0; i < 9; i++)
+ {
+ if ((legal_moves & (1 << i)) == 0)
+ continue;
+
+ value = panel_tic_tac_toe_get_move_rate (state, i, player, player, 15, 1);
+ if (value > rate)
+ {
+ /* found a better game, reset moves */
+ rate = value;
+ moves = 0;
+ }
+
+ /* add the moves with the current rating */
+ if (rate == value)
+ moves |= (1 << i);
+
+ }
+ break;
+
+ case LEVEL_EXPERIENCED:
+ /* take a corner on the first move */
+ first_moves = cells_to_hex (ONE, 0, ONE, 0, 0, 0, ONE, 0, ONE);
+ moves = panel_tic_tac_toe_best_opening (state, first_moves);
+ if (moves != 0)
+ break;
+
+ case LEVEL_INTERMEDIATE:
+ /* try to find a winning move */
+ moves = panel_tic_tac_toe_get_winner_move (state, PLAYER_X);
+ if (moves != 0)
+ break;
+
+ /* try to find a blocking move */
+ moves = panel_tic_tac_toe_get_winner_move (state, PLAYER_O);
+ if (moves != 0)
+ break;
+
+ case LEVEL_NOVICE:
+ moves = legal_moves;
+ break;
+ }
+
+ move = panel_tic_tac_toe_get_random_move (moves);
+ }
+
+ return move;
+}
+
+
+
+static gint
+panel_tic_tac_toe_get_state (PanelTicTacToe *dialog)
+{
+ gint state = 0;
+ gint i;
+ const gchar *text;
+ gint value;
+
+ panel_return_val_if_fail (PANEL_IS_TIC_TAC_TOE (dialog), 0);
+
+ for (i = 0; i < 9; i++)
+ {
+ text = gtk_label_get_text (GTK_LABEL (dialog->labels[i]));
+
+ if (text != NULL && *text == 'X')
+ value = PLAYER_X;
+ else if (text != NULL && *text == 'O')
+ value = PLAYER_O;
+ else
+ continue;
+
+ state |= value << (i * 2);
+ }
+
+ return state;
+}
+
+
+
+static void
+panel_tic_tac_toe_move (PanelTicTacToe *dialog)
+{
+ gint move;
+ gint state;
+ gint level;
+
+ panel_return_if_fail (PANEL_IS_TIC_TAC_TOE (dialog));
+
+ state = panel_tic_tac_toe_get_state (dialog);
+ level = gtk_combo_box_get_active (GTK_COMBO_BOX (dialog->level));
+ move = panel_tic_tac_toe_get_move (state, PLAYER_X, level);
+ if (move != -1)
+ {
+ gtk_widget_set_sensitive (dialog->buttons[move], FALSE);
+ gtk_label_set_text (GTK_LABEL (dialog->labels[move]), "X");
+ }
+
+
+}
+
+
+
+static void
+panel_tic_tac_toe_highlight_winner (PanelTicTacToe *dialog,
+ gint winner)
+{
+ PangoAttribute *attr;
+ PangoAttrList *attrs;
+ gint i;
+ gint tie;
+
+ panel_return_if_fail (PANEL_IS_TIC_TAC_TOE (dialog));
+
+ tie = winner_hex (TIE, 0);
+ if ((winner & tie) == winner_hex (PLAYER_X, 0))
+ {
+ attr = pango_attr_foreground_new (0xffff, 0, 0);
+ }
+ else if ((winner & tie) == winner_hex (PLAYER_O, 0))
+ {
+ attr = pango_attr_foreground_new (0, 0, 0xffff);
+ }
+ else
+ {
+ /* grey out all the cells */
+ attr = pango_attr_foreground_new (0xcccc, 0xcccc, 0xcccc);
+ winner |= cells_to_hex2 (PLAYER_O, PLAYER_O, PLAYER_O,
+ PLAYER_O, PLAYER_O, PLAYER_O,
+ PLAYER_O, PLAYER_O, PLAYER_O);
+ }
+
+ for (i = 0; i < 9; i++)
+ {
+ gtk_widget_set_sensitive (dialog->buttons[i], FALSE);
+
+ if ((winner & (1 << (i * 2 + 1))) != 0)
+ {
+ attrs = gtk_label_get_attributes (GTK_LABEL (dialog->labels[i]));
+ pango_attr_list_insert (attrs, pango_attribute_copy (attr));
+ gtk_label_set_attributes (GTK_LABEL (dialog->labels[i]), attrs);
+ }
+ }
+
+ pango_attribute_destroy (attr);
+}
+
+
+
+static void
+panel_tic_tac_toe_button_clicked (GtkWidget *button,
+ PanelTicTacToe *dialog)
+{
+ GtkWidget *label;
+ gint state;
+ gint winner;
+
+ panel_return_if_fail (PANEL_IS_TIC_TAC_TOE (dialog));
+
+ label = gtk_bin_get_child (GTK_BIN (button));
+ gtk_widget_set_sensitive (button, FALSE);
+ gtk_label_set_text (GTK_LABEL (label), "O");
+
+ panel_tic_tac_toe_move (dialog);
+
+ state = panel_tic_tac_toe_get_state (dialog);
+ winner = panel_tic_tac_toe_has_winner (state);
+ if (winner != 0)
+ panel_tic_tac_toe_highlight_winner (dialog, winner);
+}
+
+
+
+static void
+panel_tic_tac_toe_new_game (PanelTicTacToe *dialog)
+{
+ PangoAttrList *attrs, *attrs_dup;
+ PangoAttribute *attr;
+ gint i;
+
+ attrs = pango_attr_list_new ();
+ attr = pango_attr_weight_new (PANGO_WEIGHT_BOLD);
+ pango_attr_list_insert (attrs, attr);
+ attr = pango_attr_size_new (36 * PANGO_SCALE);
+ pango_attr_list_insert (attrs, attr);
+ attr = pango_attr_foreground_new (0, 0, 0);
+ pango_attr_list_insert (attrs, attr);
+
+ for (i = 0; i < 9; i++)
+ {
+ gtk_label_set_text (GTK_LABEL (dialog->labels[i]), "");
+ gtk_widget_set_sensitive (dialog->buttons[i], TRUE);
+
+ attrs_dup = pango_attr_list_copy (attrs);
+ gtk_label_set_attributes (GTK_LABEL (dialog->labels[i]), attrs_dup);
+ pango_attr_list_unref (attrs_dup);
+ }
+
+ pango_attr_list_unref (attrs);
+
+ /* 50/50 the panel will start the game */
+ if (g_random_int_range (0, 2) == 0)
+ panel_tic_tac_toe_move (dialog);
+}
+
+
+
+void
+panel_tic_tac_toe_show (void)
+{
+ GtkWidget *dialog;
+
+ dialog = g_object_new (PANEL_TYPE_TIC_TAC_TOE, NULL);
+ gtk_widget_show_all (dialog);
+}
diff --git a/panel/panel-tic-tac-toe.h b/panel/panel-tic-tac-toe.h
new file mode 100644
index 0000000..b648e01
--- /dev/null
+++ b/panel/panel-tic-tac-toe.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __PANEL_TIC_TAC_TOE_H__
+#define __PANEL_TIC_TAC_TOE_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _PanelTicTacToeClass PanelTicTacToeClass;
+typedef struct _PanelTicTacToe PanelTicTacToe;
+
+#define PANEL_TYPE_TIC_TAC_TOE (panel_tic_tac_toe_get_type ())
+#define PANEL_TIC_TAC_TOE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_TIC_TAC_TOE, PanelTicTacToe))
+#define PANEL_TIC_TAC_TOE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_TIC_TAC_TOE, PanelTicTacToeClass))
+#define PANEL_IS_TIC_TAC_TOE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_TIC_TAC_TOE))
+#define PANEL_IS_TIC_TAC_TOE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_TIC_TAC_TOE))
+#define PANEL_TIC_TAC_TOE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANEL_TYPE_TIC_TAC_TOE, PanelTicTacToeClass))
+
+GType panel_tic_tac_toe_get_type (void) G_GNUC_CONST;
+
+void panel_tic_tac_toe_show (void);
+
+G_END_DECLS
+
+#endif /* !__PANEL_TIC_TAC_TOE_H__ */
+
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 14c6d26..10029ee 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -24,6 +24,7 @@ panel/panel-plugin-external.c
panel/panel-plugin-external-46.c
panel/panel-preferences-dialog.c
panel/panel-preferences-dialog.glade
+panel/panel-tic-tac-toe.c
panel/panel-window.c
wrapper/main.c
More information about the Xfce4-commits
mailing list