[four-in-a-row: 5/72] finished translation (still need to fix game)
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [four-in-a-row: 5/72] finished translation (still need to fix game)
- Date: Sun, 16 Dec 2018 20:57:11 +0000 (UTC)
commit 5c8e719edc5e0ad1697881a331162271398e764f
Author: Jacob Humphrey <jacob ryan humphrey gmail com>
Date: Fri Nov 16 04:35:03 2018 -0600
finished translation (still need to fix game)
build/config.h | 51 --
build/src/ai.c | 1918 ----------------------------------------------
build/src/ai.h | 64 --
src/Makefile.am | 49 +-
src/ai.vala | 2 +-
src/games-controls.c | 374 ---------
src/games-controls.h | 45 --
src/games-controls2.vala | 186 +++++
src/gfx.c | 153 ----
src/gfx.h | 13 -
src/gfx.vala | 260 +++++++
src/gfx2.vala | 174 -----
src/main.c | 725 ------------------
src/main.h | 75 --
src/main2.vala | 890 ++++++++++++++++++---
src/prefs.c | 640 ----------------
src/prefs.h | 17 -
src/prefs.vala | 10 +-
src/rules.h | 24 -
src/temp.vapi | 105 +--
src/theme.c | 13 -
src/theme.h | 27 -
src/theme.vala | 27 +-
23 files changed, 1271 insertions(+), 4571 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 480e4d8..d255254 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,22 +2,13 @@ bin_PROGRAMS = four-in-a-row
check_PROGRAMS = ai-test
-four_in_a_row_SOURCES = main.h \
- main.c \
- gfx.h \
- gfx.c \
- prefs.h \
- theme.h \
- games-controls.c \
- games-controls.h \
- games-controls2.vala \
- rules.h \
- $(ai_C) \
- main2.vala \
- $(ai_HEADER)\
- prefs.vala \
- gfx2.vala \
- theme.vala
+four_in_a_row_SOURCES = \
+ games-controls2.vala \
+ ai.vala \
+ main2.vala \
+ prefs.vala \
+ gfx.vala \
+ theme.vala
four_in_a_row_CPPFLAGS = \
-I$(top_srcdir)
@@ -27,26 +18,18 @@ four_in_a_row_CFLAGS = \
-DSOUND_DIRECTORY=\"$(datadir)/four-in-a-row/sounds\" \
-DLOCALEDIR=\"$(datadir)/locale\" \
-DICON_THEME_DIRECTORY="\"$(datadir)/icons\"" \
+ -DGETTEXT_PACKAGE=$GETTEXT_PACKAGE \
$(FOUR_IN_A_ROW_CFLAGS)
four_in_a_row_LDADD = \
$(FOUR_IN_A_ROW_LIBS)
-four_in_a_row_VALAFLAGS = --pkg gtk+-3.0 \
- --vapidir . \
- --pkg temp
-
-ai_VALA = ai.vala
-
-ai_HEADER = ai.h
-
-ai_C = $(ai_VALA:.vala=.c)
-
-$(ai_HEADER): $(ai_VALA)
- $(V_VALAC) $(VALAC) -C --basedir=$(srcdir) --directory=$(builddir) --header=ai.h \
- --pkg glib-2.0 --pkg gio-2.0 --pkg posix --use-header $(VALAFLAGS) $^
-
-$(ai_C) : $(ai_HEADER)
+four_in_a_row_VALAFLAGS = \
+ --pkg gtk+-3.0 \
+ --pkg libcanberra-gtk \
+ --pkg libcanberra \
+ --vapidir . \
+ --pkg temp
ai_test_SOURCES = \
ai.vala \
@@ -61,10 +44,6 @@ ai_test_LDADD = \
check-local: $(check_PROGRAMS)
$(GTESTER) --keep-going --verbose $(check_PROGRAMS)
-BUILT_SOURCES = \
- $(ai_C) \
- $(ai_HEADER)
-
EXTRA_DIST = $(BUILT_SOURCES)
MAINTAINERCLEANFILES = \
diff --git a/src/ai.vala b/src/ai.vala
index d1ec09e..cbe9a72 100644
--- a/src/ai.vala
+++ b/src/ai.vala
@@ -29,7 +29,7 @@ const int BOARD_COLUMNS = 7;
enum Player { NONE, HUMAN, AI; }
enum Difficulty { EASY, MEDIUM, HARD; }
-int playgame (string moves_until_now)
+public int playgame (string moves_until_now)
{
var t = new DecisionTree ();
return t.playgame (moves_until_now);
diff --git a/src/games-controls2.vala b/src/games-controls2.vala
index e69de29..2371fd5 100644
--- a/src/games-controls2.vala
+++ b/src/games-controls2.vala
@@ -0,0 +1,186 @@
+using Gtk;
+
+const string jjjj = Config.GETTEXT_PACKAGE;
+
+enum Columns {
+ CONFKEY_COLUMN = 0,
+ LABEL_COLUMN,
+ KEYCODE_COLUMN,
+ KEYMODS_COLUMN,
+ DEFAULT_KEYCODE_COLUMN,
+ DEFAULT_KEYMODS_COLUMN,
+ N_COLUMNS
+}
+
+public class GamesControlsList: Gtk.ScrolledWindow {
+ Gtk.TreeModel model;
+ Gtk.ListStore store;
+ Gtk.TreeView view;
+
+ GLib.Settings settings;
+ ulong notify_handler_id;
+
+ public GamesControlsList(GLib.Settings settings) {
+ Gtk.CellRenderer label_renderer;
+ CellRendererAccel key_renderer;
+ Gtk.TreeViewColumn column;
+
+ this.hscrollbar_policy = Gtk.PolicyType.NEVER;
+ this.vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
+ this.shadow_type = Gtk.ShadowType.IN;
+ this.settings = settings;
+ notify_handler_id = settings.changed
+ .connect(settings_changed_cb);
+
+ store = new Gtk.ListStore(Columns.N_COLUMNS,
+ Type.STRING,
+ Type.STRING,
+ Type.UINT,
+ Type.UINT,
+ Type.UINT,
+ Type.UINT);
+
+ model = store;
+ view = new Gtk.TreeView.with_model(model);
+
+ view.headers_visible = false;
+ view.enable_search = false;
+
+ label_renderer = new Gtk.CellRendererText();
+ column = new Gtk.TreeViewColumn.with_attributes("Control", label_renderer,
+ "text", Columns.LABEL_COLUMN);
+
+ view.append_column(column);
+
+ key_renderer = new Gtk.CellRendererAccel();
+
+ key_renderer.editable = true;
+ key_renderer.accel_mode = Gtk.CellRendererAccelMode.OTHER;
+
+ key_renderer.accel_edited.connect(this.accel_edited_cb);
+ key_renderer.accel_cleared.connect(this.accel_cleared_cb);
+
+ column = new TreeViewColumn.with_attributes("Key", key_renderer,
+ "accel-key", Columns.KEYCODE_COLUMN,
+ "accel-mods", Columns.KEYMODS_COLUMN);
+
+ view.append_column(column);
+ this.add(view);
+ }
+
+ void accel_cleared_cb (string path_string)
+ {
+ TreePath path;
+ TreeIter iter;
+ string conf_key = null;
+ int default_keyval = 0; //set to 0 to make valac happy
+
+ path = new TreePath.from_string (path_string);
+ if (path == null)
+ return;
+
+ if (!model.get_iter (out iter, path)) {
+ return;
+ }
+
+ model.get(iter,
+ Columns.CONFKEY_COLUMN, conf_key,
+ Columns.DEFAULT_KEYCODE_COLUMN, default_keyval);
+
+ if(conf_key == null)
+ return;
+
+ /* Note: the model is updated in the conf notification callback */
+ /* FIXME: what to do with the modifiers? */
+ settings.set_int(conf_key, default_keyval);
+ }
+
+ void accel_edited_cb (string path_string, uint keyval,
+ Gdk.ModifierType mask, uint hardware_keycode)
+ {
+ TreePath path;
+ TreeIter iter;
+ string conf_key = null;
+ bool valid;
+ bool unused_key = true;
+
+
+ path = new TreePath.from_string (path_string);
+ if (path == null)
+ return;
+
+ if (!model.get_iter (out iter, path)) {
+ return;
+ }
+
+ model.get (iter, Columns.CONFKEY_COLUMN, conf_key);
+ if (conf_key == null)
+ return;
+
+ valid = model.get_iter_first (out iter);
+ while (valid) {
+ string actual_conf_key = null;
+
+ model.get (iter, Columns.CONFKEY_COLUMN, actual_conf_key);
+
+ if (settings.get_int (actual_conf_key) == keyval){
+ unused_key = false;
+
+ if (conf_key == actual_conf_key) {
+ var dialog = new MessageDialog.with_markup (window,
+ DialogFlags.DESTROY_WITH_PARENT,
+ MessageType.WARNING,
+ ButtonsType.OK,
+ "<span weight=\"bold\" size=\"larger\">%s</span>",
+ _("This key is already in use."));
+
+ dialog.run();
+ }
+ break;
+ }
+
+ valid = store.iter_next (ref iter);
+ }
+
+ /* Note: the model is updated in the conf notification callback */
+ /* FIXME: what to do with the modifiers? */
+ if (unused_key)
+ settings.set_int (conf_key, (int)keyval);
+ }
+
+ void add_control (string conf_key, string? label,
+ uint default_keyval) {
+ Gtk.TreeIter iter;
+ uint keyval;
+
+ if (label == null)
+ label = _("Unknown Command");
+
+ keyval = settings.get_int(conf_key);
+
+ store.insert_with_values(out iter, -1,
+ Columns.CONFKEY_COLUMN, conf_key,
+ Columns.LABEL_COLUMN, label,
+ Columns.KEYCODE_COLUMN, keyval,
+ Columns.KEYMODS_COLUMN, 0,
+ Columns.DEFAULT_KEYCODE_COLUMN, default_keyval,
+ Columns.DEFAULT_KEYMODS_COLUMN, 0
+ );
+
+ }
+
+ void add_controls (string first_gconf_key, ...) {
+ var args = va_list();
+ string? key;
+ string label;
+ uint keyval;
+
+ key = first_gconf_key;
+ while (key != null) {
+ label = args.arg();
+ keyval = args.arg();
+ this.add_control (key, label, keyval);
+ key = args.arg();
+ }
+ }
+}
diff --git a/src/gfx.vala b/src/gfx.vala
new file mode 100644
index 0000000..5296774
--- /dev/null
+++ b/src/gfx.vala
@@ -0,0 +1,260 @@
+//using GETTTEXT_PACKAGE_CONTENT;
+const string GETTEXT_PACKAGE2 = Config.GETTEXT_PACKAGE;
+Gtk.Widget drawarea;
+//extern Theme theme[];
+int[,] gboard;
+int boardsize = 0;
+int tilesize = 0;
+int offset[6];
+
+namespace Gfx{
+ /* unscaled pixbufs */
+ Gdk.Pixbuf pb_tileset_raw;
+ Gdk.Pixbuf pb_bground_raw;
+
+ /* scaled pixbufs */
+ Gdk.Pixbuf pb_tileset;
+ Gdk.Pixbuf pb_bground;
+
+ public int get_column (int xpos) {
+ /* Derive column from pixel position */
+ int c = xpos / tilesize;
+ if (c > 6)
+ c = 6;
+ if (c < 0)
+ c = 0;
+
+ return c;
+ }
+
+ public void draw_tile (int r, int c) {
+ drawarea.queue_draw_area(c*tilesize, r*tilesize, tilesize, tilesize);
+ }
+
+ public void draw_all () {
+ drawarea.queue_draw_area(0, 0, boardsize, boardsize);
+ }
+
+ bool change_theme () {
+ if (!Gfx.load_pixmaps ())
+ return false;
+
+ Gfx.refresh_pixmaps ();
+ draw_all ();
+ return true;
+ }
+
+ void resize (Gtk.Widget w) {
+ int width, height;
+
+ width = w.get_allocated_width ();
+ height = w.get_allocated_height ();
+
+ boardsize = int.min (width, height);
+ tilesize = boardsize / 7;
+
+ offset[Tile.PLAYER1] = 0;
+ offset[Tile.PLAYER2] = tilesize;
+ offset[Tile.CLEAR] = tilesize * 2;
+ offset[Tile.CLEAR_CURSOR] = tilesize * 3;
+ offset[Tile.PLAYER1_CURSOR] = tilesize * 4;
+ offset[Tile.PLAYER2_CURSOR] = tilesize * 5;
+
+ Gfx.refresh_pixmaps ();
+ draw_all ();
+ }
+
+ void expose (Cairo.Context cr) {
+ int r, c;
+
+ /* draw the background */
+ cr.save();
+ Gdk.cairo_set_source_pixbuf(cr, pb_bground, 0, 0);
+ cr.rectangle(0, 0, boardsize, boardsize);
+ cr.paint();
+ cr.restore();
+
+ for (r = 0; r < 7; r++) {
+ for (c = 0; c < 7; c++) {
+ Gfx.paint_tile (cr, r, c);
+ }
+ }
+
+ draw_grid (cr);
+ }
+
+ void draw_grid (Cairo.Context cr) {
+ const double dashes[] = { 4.0, 4.0 };
+ int i;
+ Gdk.RGBA color = Gdk.RGBA();
+
+ color.parse(theme[p.theme_id].grid_color);
+ Gdk.cairo_set_source_rgba (cr, color);
+ cr.set_operator (Cairo.Operator.SOURCE);
+ cr.set_line_width (1);
+ cr.set_line_cap (Cairo.LineCap.BUTT);
+ cr.set_line_join (Cairo.LineJoin.MITER);
+ cr.set_dash (dashes, 0);
+
+ /* draw the grid on the background pixmap */
+ for (i = 1; i < 7; i++) {
+ cr.move_to (i * tilesize + 0.5, 0);
+ cr.line_to (i * tilesize + 0.5, boardsize);
+ cr.move_to (0, i * tilesize + 0.5);
+ cr.line_to (boardsize, i * tilesize + 0.5);
+ }
+ cr.stroke();
+
+ /* Draw separator line at the top */
+ cr.set_dash(null, 0);
+ cr.move_to(0, tilesize+0.5);
+ cr.line_to(boardsize, tilesize +0.5);
+
+ cr.stroke();
+ }
+
+ void load_error (string fname) {
+ Gtk.MessageDialog dialog;
+
+ dialog = new Gtk.MessageDialog(window, Gtk.DialogFlags.MODAL,
+ Gtk.MessageType.WARNING, Gtk.ButtonsType.CLOSE,
+ dgettext(Config.GETTEXT_PACKAGE, "Unable to load image:\n%s"), fname);
+
+ dialog.run();
+ dialog.destroy();
+ }
+
+ void paint_tile (Cairo.Context cr, int r, int c) {
+ int x = c * tilesize;
+ int y = r * tilesize;
+ int tile = gboard[r,c];
+ int os = 0;
+
+ if (tile == Tile.CLEAR && r != 0)
+ return;
+
+ switch (tile) {
+ case Tile.PLAYER1:
+ if (r == 0)
+ os = offset[Tile.PLAYER1_CURSOR];
+ else
+ os = offset[Tile.PLAYER1];
+ break;
+ case Tile.PLAYER2:
+ if (r == 0)
+ os = offset[Tile.PLAYER2_CURSOR];
+ else
+ os = offset[Tile.PLAYER2];
+ break;
+ case Tile.CLEAR:
+ if (r == 0)
+ os = offset[Tile.CLEAR_CURSOR];
+ else
+ os = offset[Tile.CLEAR];
+ break;
+ }
+
+
+ cr.save();
+ //gdk_cairo_set_source_pixbuf (cr, pb_tileset, x - os, y);
+ cr.rectangle (x, y, tilesize, tilesize);
+
+ cr.clip();
+ cr.paint();
+ cr.restore();
+ }
+
+ void refresh_pixmaps () {
+ /* scale the pixbufs */
+ pb_tileset = pb_tileset_raw.scale_simple (tilesize * 6, tilesize, Gdk.InterpType.BILINEAR);
+ pb_bground = pb_bground_raw.scale_simple (boardsize, boardsize, Gdk.InterpType.BILINEAR);
+ }
+
+
+
+bool load_pixmaps ()
+{
+ string fname;
+ Gdk.Pixbuf pb_tileset_tmp;
+ Gdk.Pixbuf pb_bground_tmp = null;
+
+ /* Try the theme pixmaps, fallback to the default and then give up */
+ while (true) {
+ fname = Path.build_filename (Config.DATA_DIRECTORY, theme[p.theme_id].fname_tileset, null);
+ try {
+ pb_tileset_tmp = new Gdk.Pixbuf.from_file (fname);
+ } catch (Error e) {
+ if (p.theme_id != 0) {
+ p.theme_id = 0;
+ continue;
+ } else {
+ Gfx.load_error (fname);
+ return false;
+ }
+ }
+ break;
+ }
+
+ pb_tileset_raw = pb_tileset_tmp;
+
+ if (theme[p.theme_id].fname_bground != null) {
+ fname = Path.build_filename (Config.DATA_DIRECTORY, theme[p.theme_id].fname_bground, null);
+ try {
+ pb_bground_tmp = new Gdk.Pixbuf.from_file (fname);
+ } catch (Error e) {
+ Gfx.load_error (fname);
+ return false;
+ }
+ }
+
+ /* If a separate background image wasn't supplied,
+ * derive the background image from the tile set
+ */
+ if (pb_bground_tmp != null) {
+ pb_bground_raw = pb_bground_tmp;
+ } else {
+ int tilesize_raw;
+ int i, j;
+
+ tilesize_raw = pb_tileset_raw.get_height();
+
+ pb_bground_raw = new Gdk.Pixbuf (Gdk.Colorspace.RGB, true, 8,
+ tilesize_raw * 7, tilesize_raw * 7);
+ for (i = 0; i < 7; i++) {
+ pb_tileset_raw.copy_area (tilesize_raw * 3, 0,
+ tilesize_raw, tilesize_raw,
+ pb_bground_raw, i * tilesize_raw, 0);
+ for (j = 1; j < 7; j++) {
+ pb_tileset_raw.copy_area (
+ tilesize_raw * 2, 0,
+ tilesize_raw, tilesize_raw,
+ pb_bground_raw,
+ i * tilesize_raw, j * tilesize_raw);
+ }
+ }
+ }
+
+ return true;
+}
+
+ void free ()
+ {
+ if (pb_tileset_raw != null) {
+ pb_tileset_raw.unref();
+ pb_tileset_raw = null;
+ }
+ if (pb_bground_raw != null) {
+ pb_bground_raw.unref();
+ pb_bground_raw = null;
+ }
+ if (pb_tileset != null) {
+ pb_tileset.unref();
+ pb_tileset = null;
+ }
+ if (pb_bground != null) {
+ pb_bground.unref();
+ pb_bground = null;
+ }
+ }
+
+}
diff --git a/src/main2.vala b/src/main2.vala
index 154dff5..a82e123 100644
--- a/src/main2.vala
+++ b/src/main2.vala
@@ -1,9 +1,61 @@
+using Config;
using Intl;
using Gtk;
//using temp;
-const string jfasolfdas = Config.GETTEXT_PACKAGE;
-extern int main2(int argc, char** argv);
+public enum AnimID {
+ NONE,
+ MOVE,
+ DROP,
+ BLINK,
+ HINT
+}
+
+public enum PlayerID {
+ PLAYER1,
+ PLAYER2,
+ NOBODY
+}
+
+public enum Level {
+ HUMAN,
+ WEAK,
+ MEDIUM,
+ STRONG
+}
+
+public enum Tile {
+ PLAYER1,
+ PLAYER2,
+ CLEAR,
+ CLEAR_CURSOR,
+ PLAYER1_CURSOR,
+ PLAYER2_CURSOR,
+}
+
+public enum Move {
+ LEFT,
+ RIGHT,
+ DROP
+}
+
+public enum SoundID{
+ DROP,
+ I_WIN,
+ YOU_WIN,
+ PLAYER_WIN,
+ DRAWN_GAME,
+ COLUMN_FULL
+}
+
+SimpleAction hint_action;
+SimpleAction undo_action;
+SimpleAction new_game_action;
+
+//const string jfasolfdas = Config.GETTEXT_PACKAGE;
+const string APPNAME_LONG = N_("Four-in-a-row");
+const int SIZE_VSTR = 53;
+
Gtk.Application? application;
Window window;
Gtk.Dialog? scorebox = null;
@@ -16,10 +68,9 @@ PlayerID winner;
PlayerID who_starts;
int score[3];
AnimID anim;
-char vstr[SIZE_VSTR];
-extern char vlevel[];
+char vstr[53];
+const char vlevel[] = {'0','a','b','c','\0'};
int moves;
-extern const int SIZE_VSTR;
const int SPEED_BLINK = 150;
const int SPEED_MOVE = 35;
const int SPEED_DROP = 20;
@@ -27,7 +78,10 @@ int column;
int column_moveto;
int row;
int row_dropto;
-extern Gtk.HeaderBar headerbar;
+Gtk.HeaderBar headerbar;
+
+const int DEFAULT_WIDTH = 495;
+const int DEFAULT_HEIGHT = 435;
int blink_r1 = 0;
int blink_c1 = 0;
@@ -38,151 +92,194 @@ int blink_n = 0;
bool blink_on = false;
uint timeout = 0;
-void on_game_new(SimpleAction a, Variant v) {
- stop_anim ();
- game_reset ();
+void on_game_new(SimpleAction a, Variant? v) {
+ stop_anim ();
+ game_reset ();
}
void draw_line (int r1, int c1, int r2, int c2, int tile)
{
- /* draw a line of 'tile' from r1,c1 to r2,c2 */
+ /* draw a line of 'tile' from r1,c1 to r2,c2 */
+
+ bool done = false;
+ int d_row = 0;
+ int d_col = 0;
+
+ if (r1 < r2)
+ d_row = 1;
+ else if (r1 > r2)
+ d_row = -1;
+
+ if (c1 < c2)
+ d_col = 1;
+ else if (c1 > c2)
+ d_col = -1;
+
+ do {
+ done = (r1 == r2 && c1 == c2);
+ gboard[r1, c1] = tile;
+ Gfx.draw_tile (r1, c1);
+ if (r1 != r2)
+ r1 += d_row;
+ if (c1 != c2)
+ c1 += d_col;
+ } while (!done);
+}
- bool done = false;
- int d_row = 0;
- int d_col = 0;
+public int main(string[] argv) {
+ gboard = new int[7,7];
+ setlocale();
- if (r1 < r2)
- d_row = 1;
- else if (r1 > r2)
- d_row = -1;
+ application = new Gtk.Application("org.gnome.four-in-a-row", 0);
- if (c1 < c2)
- d_col = 1;
- else if (c1 > c2)
- d_col = -1;
+ bindtextdomain(Config.GETTEXT_PACKAGE, Config.LOCALEDIR);
+ bind_textdomain_codeset(Config.GETTEXT_PACKAGE, "UTF-8");
+ textdomain(Config.GETTEXT_PACKAGE);
- do {
- done = (r1 == r2 && c1 == c2);
- gboard[r1, c1] = tile;
- Gfx.draw_tile (r1, c1);
- if (r1 != r2)
- r1 += d_row;
- if (c1 != c2)
- c1 += d_col;
- } while (!done);
-}
+ application.startup.connect(create_app);
+ application.activate.connect(activate);
-public int main(string[] argv) {
- setlocale();
+ var context = new OptionContext();
+ context.add_group(get_option_group(true));
+ try {
+ context.parse(ref argv);
+ } catch (Error error) {
+ print("%s", error.message);
+ return 1;
+ }
+
+ settings = new GLib.Settings("org.gnome.four-in-a-row");
- var application = new Gtk.Application("org.gnome.four-in-a-row", 0);
+ Environment.set_application_name(_(Config.APPNAME_LONG));
- return main2(argv.length, argv);
+ prefs_init();
+ game_init();
+
+ if (!Gfx.load_pixmaps())
+ return 1;
+
+ var app_retval = application.run(argv);
+
+ //game_free();
+
+ return app_retval;
}
public void activate() {
- if (!window.is_visible()) {
- window.show_all();
- gfx_refresh_pixmaps();
- Gfx.draw_all ();
- scorebox_update (); /* update visible player descriptions */
- prompt_player ();
- game_reset ();
- }
+ if (!window.is_visible()) {
+ window.show_all();
+ Gfx.refresh_pixmaps();
+ Gfx.draw_all ();
+ scorebox_update (); /* update visible player descriptions */
+ prompt_player ();
+ game_reset ();
+ }
+}
+
+class NextMove {
+ int c;
+
+ public NextMove(int c) {
+ this.c = c;
+ }
+
+ public bool exec() {
+ return next_move(c);
+ }
}
-public int next_move(int c) {
- process_move(c);
- return 0;
+public bool next_move(int c) {
+ process_move(c);
+ return false;
}
public void game_process_move(int c) {
- process_move(c);
+ process_move(c);
}
public void game_free() {
- gfx_free();
+ Gfx.free();
}
public void game_init ()
{
- //Random.set_seed ((uint) Linux.timegm(null));
+ //Random.set_seed ((uint) Linux.timegm(null));
- anim = AnimID.NONE;
- gameover = true;
- player_active = false;
- player = PlayerID.PLAYER1;
- winner = PlayerID.NOBODY;
- score[PlayerID.PLAYER1] = 0;
- score[PlayerID.PLAYER2] = 0;
- score[PlayerID.NOBODY] = 0;
+ anim = AnimID.NONE;
+ gameover = true;
+ player_active = false;
+ player = PlayerID.PLAYER1;
+ winner = PlayerID.NOBODY;
+ score[PlayerID.PLAYER1] = 0;
+ score[PlayerID.PLAYER2] = 0;
+ score[PlayerID.NOBODY] = 0;
- who_starts = PlayerID.PLAYER2; /* This gets reversed immediately. */
+ who_starts = PlayerID.PLAYER2; /* This gets reversed immediately. */
- clear_board ();
+ clear_board ();
}
void clear_board () {
- int r, c, i;
+ int r, c, i;
- for (r = 0; r < 7; r++) {
- for (c = 0; c < 7; c++) {
- gboard[r, c] = Tile.CLEAR;
- }
- }
+ for (r = 0; r < 7; r++) {
+ for (c = 0; c < 7; c++) {
+ gboard[r, c] = Tile.CLEAR;
+ }
+ }
- for (i = 0; i < SIZE_VSTR; i++)
- vstr[i] = '\0';
+ for (i = 0; i < SIZE_VSTR; i++)
+ vstr[i] = '\0';
- vstr[0] = vlevel[Level.WEAK];
- vstr[1] = '0';
- moves = 0;
+ vstr[0] = vlevel[Level.WEAK];
+ vstr[1] = '0';
+ moves = 0;
}
static int first_empty_row (int c) {
- int r = 1;
+ int r = 1;
- while (r < 7 && gboard[r, c] == Tile.CLEAR)
- r++;
- return r - 1;
+ while (r < 7 && gboard[r, c] == Tile.CLEAR)
+ r++;
+ return r - 1;
}
static int get_n_human_players () {
- if (p.level[PlayerID.PLAYER1] != Level.HUMAN && p.level[PlayerID.PLAYER2] != Level.HUMAN)
- return 0;
- if (p.level[PlayerID.PLAYER1] != Level.HUMAN || p.level[PlayerID.PLAYER2] != Level.HUMAN)
- return 1;
- return 2;
+ if (p.level[PlayerID.PLAYER1] != Level.HUMAN && p.level[PlayerID.PLAYER2] != Level.HUMAN)
+ return 0;
+ if (p.level[PlayerID.PLAYER1] != Level.HUMAN || p.level[PlayerID.PLAYER2] != Level.HUMAN)
+ return 1;
+ return 2;
}
static bool is_player_human ()
{
- return player == PLAYER1 ? p.level[PlayerID.PLAYER1] == Level.HUMAN
- : p.level[PlayerID.PLAYER2] == Level.HUMAN;
+ return player == PLAYER1 ? p.level[PlayerID.PLAYER1] == Level.HUMAN
+ : p.level[PlayerID.PLAYER2] == Level.HUMAN;
}
static void drop_marble (int r, int c)
{
- int tile;
- tile = player == PlayerID.PLAYER1 ? Tile.PLAYER1 : Tile.PLAYER2;
+ int tile;
+ tile = player == PlayerID.PLAYER1 ? Tile.PLAYER1 : Tile.PLAYER2;
- gboard[r, c] = tile;
- Gfx.draw_tile (r, c);
+ gboard[r, c] = tile;
+ Gfx.draw_tile (r, c);
- column = column_moveto = c;
- row = row_dropto = r;
+ column = column_moveto = c;
+ row = row_dropto = r;
}
void drop () {
- int tile;
- tile = player == PLAYER1 ? Tile.PLAYER1 : Tile.PLAYER2;
+ int tile;
+ tile = player == PLAYER1 ? Tile.PLAYER1 : Tile.PLAYER2;
- gboard[row, column] = Tile.CLEAR;
- Gfx.draw_tile (row, column);
+ gboard[row, column] = Tile.CLEAR;
+ Gfx.draw_tile (row, column);
- row++;
- gboard[row, column] = tile;
- Gfx.draw_tile (row, column);
+ row++;
+ gboard[row, column] = tile;
+ Gfx.draw_tile (row, column);
}
void move (int c) {
@@ -210,7 +307,7 @@ void swap_player ()
}
-void set_status_message (string message)
+void set_status_message (string? message)
{
headerbar.set_title(message);
}
@@ -226,7 +323,8 @@ static void blink_tile (int r, int c, int t, int n) {
blink_n = n;
blink_on = false;
anim = AnimID.BLINK;
- timeout = Timeout.add (SPEED_BLINK, on_animate);
+ var anim = new Animate(0);
+ timeout = Timeout.add (SPEED_BLINK, anim.exec);
}
void stop_anim ()
@@ -249,7 +347,7 @@ bool on_drawarea_draw (Gtk.Widget w, Cairo.Context cr) {
}
void
-on_game_undo (SimpleAction action, Variant parameter)
+on_game_undo (SimpleAction action, Variant? parameter)
{
int r, c;
@@ -288,18 +386,18 @@ on_game_undo (SimpleAction action, Variant parameter)
}
}
}
-void on_game_scores (SimpleAction action, Variant parameter)
+void on_game_scores (SimpleAction action, Variant? parameter)
{
Gtk.Grid grid, grid2;
Gtk.Widget icon;
if (scorebox != null) {
- scorebox.present();
- return;
+ scorebox.present();
+ return;
}
scorebox = new Gtk.Dialog.with_buttons(_("Scores"), window,
- Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.USE_HEADER_BAR);
+ Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.USE_HEADER_BAR);
scorebox.set_resizable(false);
scorebox.set_border_width(5);
@@ -352,13 +450,13 @@ void on_game_scores (SimpleAction action, Variant parameter)
//scorebox.response.connect(on_dialog_close);
- scorebox.show_all();
+ scorebox.show_all();
- scorebox_update ();
+ scorebox_update ();
}
void
-on_game_exit (SimpleAction action, Variant parameter)
+on_game_exit (SimpleAction action, Variant? parameter)
{
stop_anim ();
application.quit();
@@ -374,7 +472,8 @@ process_move2 (int c)
row = 0;
row_dropto = r;
anim = AnimID.DROP;
- timeout = Timeout.add(SPEED_DROP, on_animate, c);
+ var temp = new Animate(c);
+ timeout = Timeout.add(SPEED_DROP, temp.exec);
//timeout = g_timeout_add (SPEED_DROP, (GSourceFunc) on_animate, GINT_TO_POINTER (c));
} else {
play_sound (SoundID.COLUMN_FULL);
@@ -413,12 +512,12 @@ bool is_dline1_at (PlayerID p, int r, int c, int * r1, int * c1, int * r2, int *
bool is_line_at (PlayerID p, int r, int c)
{
- int r1, r2, c1, c2;
+ int r1, r2, c1, c2;
- return is_hline_at (p, r, c, &r1, &c1, &r2, &c2) ||
- is_vline_at (p, r, c, &r1, &c1, &r2, &c2) ||
- is_dline1_at (p, r, c, &r1, &c1, &r2, &c2) ||
- is_dline2_at (p, r, c, &r1, &c1, &r2, &c2);
+ return is_hline_at (p, r, c, &r1, &c1, &r2, &c2) ||
+ is_vline_at (p, r, c, &r1, &c1, &r2, &c2) ||
+ is_dline1_at (p, r, c, &r1, &c1, &r2, &c2) ||
+ is_dline2_at (p, r, c, &r1, &c1, &r2, &c2);
}
bool is_dline2_at (PlayerID p, int r, int c, int * r1, int * c1, int * r2, int * c2) {
@@ -453,22 +552,567 @@ bool is_hline_at (PlayerID p, int r, int c, int * r1, int * c1, int * r2, int *
void scorebox_reset ()
{
- score[PlayerID.PLAYER1] = 0;
- score[PlayerID.PLAYER2] = 0;
- score[PlayerID.NOBODY] = 0;
- scorebox_update ();
+ score[PlayerID.PLAYER1] = 0;
+ score[PlayerID.PLAYER2] = 0;
+ score[PlayerID.NOBODY] = 0;
+ scorebox_update ();
}
void process_move (int c)
{
- if (timeout != 0) {
- //Timeout.add(SPEED_DROP, next_move, c.to_pointer());
- //g_timeout_add (SPEED_DROP, (GSourceFunc) next_move, GINT_TO_POINTER (c));
- return;
- }
+ if (timeout != 0) {
+ //Timeout.add(SPEED_DROP, next_move, c.to_pointer());
+ //g_timeout_add (SPEED_DROP, (GSourceFunc) next_move, GINT_TO_POINTER (c));
+ return;
+ }
+
+ column_moveto = c;
+ anim = AnimID.MOVE;
+ //Timeout.add(SPEED_DROP, on_animate, c.to_pointer());
+ //timeout = g_timeout_add (SPEED_MOVE, (GSourceFunc) on_animate, GINT_TO_POINTER (c));
+}
+
+void on_help_about (SimpleAction action, Variant? parameter)
+{
+ const string authors[] = {"Tim Musson <trmusson ihug co nz>",
+ "David Neary <bolsh gimp org>",
+ "Nikhar Agrawal <nikharagrawal2006 gmail com>"
+ };
+
+ const string artists[] = { "Alan Horkan",
+ "Anatol Drlicek",
+ "Based on the Faenza icon theme by Matthieu James"
+ };
+
+ const string documenters[] = {"Timothy Musson"};
+
+ Gtk.show_about_dialog(window,
+ name: _(Config.APPNAME_LONG),
+ version: Config.VERSION,
+ copyright: "Copyright © 1999–2008 Tim Musson and David Neary\nCopyright © 2014 Michael
Catanzaro",
+ license_type: Gtk.License.GPL_2_0,
+ comments: _("Connect four in a row to win"),
+ authors: authors,
+ documenters: documenters,
+ artists: artists,
+ translator_credits: _("translator-credits"),
+ logo_icon_name: "four-in-a-row",
+ website: "https://wiki.gnome.org/Apps/Four-in-a-row"
+ );
+}
+
+void check_game_state ()
+{
+ if (is_line_at (player, row, column)) {
+ gameover = true;
+ winner = player;
+ switch (get_n_human_players ()) {
+ case 1:
+ play_sound (is_player_human () ? SoundID.YOU_WIN : SoundID.I_WIN);
+ break;
+ case 0:
+ case 2:
+ play_sound (SoundID.PLAYER_WIN);
+ break;
+ }
+ blink_winner (6);
+ } else if (moves == 42) {
+ gameover = true;
+ winner = NOBODY;
+ play_sound (SoundID.DRAWN_GAME);
+ }
+}
+
+void
+on_help_contents (SimpleAction action, Variant? parameter)
+{
+ try {
+ Gtk.show_uri (window.get_screen(),
+ "help:four-in-a-row",
+ Gtk.get_current_event_time ());
+ } catch(Error error) {
+ warning ("Failed to show help: %s", error.message);
+ }
+}
+
+void process_move3 (int c)
+{
+ play_sound (SoundID.DROP);
+
+ vstr[++moves] = '1' + (char)c;
+ vstr[moves + 1] = '0';
+
+ check_game_state ();
+
+ if (gameover) {
+ score[winner]++;
+ scorebox_update ();
+ prompt_player ();
+ } else {
+ swap_player ();
+ if (!is_player_human ()) {
+ vstr[0] = player == PlayerID.PLAYER1 ? vlevel[p.level[PlayerID.PLAYER1]]
+ : vlevel[p.level[PlayerID.PLAYER2]];
+ c = playgame ((string)vstr) - 1;
+ if (c < 0)
+ gameover = true;
+ var nm = new NextMove(c);
+ Timeout.add(SPEED_DROP, nm.exec);
+ }
+ }
+}
+
+void game_reset ()
+{
+ stop_anim ();
+
+ undo_action.set_enabled(false);
+ hint_action.set_enabled(false);
+
+ who_starts = (who_starts == PlayerID.PLAYER1)
+ ? PlayerID.PLAYER2 : PlayerID.PLAYER1;
+ player = who_starts;
+
+ gameover = true;
+ player_active = false;
+ winner = NOBODY;
+ column = 3;
+ column_moveto = 3;
+ row = 0;
+ row_dropto = 0;
+
+ clear_board ();
+ set_status_message (null);
+ Gfx.draw_all ();
+
+ move_cursor (column);
+ gameover = false;
+ prompt_player ();
+ if (!is_player_human ()) {
+ vstr[0] = player == PLAYER1 ? vlevel[p.level[PlayerID.PLAYER1]]
+ : vlevel[p.level[PlayerID.PLAYER2]];
+ game_process_move (playgame ((string)vstr) - 1);
+ }
+}
+
+void
+play_sound (SoundID id)
+{
+ string name;
+
+ if (!p.do_sound)
+ return;
+
+ switch (id) {
+ case SoundID.DROP:
+ name = "slide";
+ break;
+ case SoundID.I_WIN:
+ name = "reverse";
+ break;
+ case SoundID.YOU_WIN:
+ name = "bonus";
+ break;
+ case SoundID.PLAYER_WIN:
+ name = "bonus";
+ break;
+ case SoundID.DRAWN_GAME:
+ name = "reverse";
+ break;
+ case SoundID.COLUMN_FULL:
+ name = "bad";
+ break;
+ default:
+ return;
+ }
+
+
+ string filename, path;
+
+ filename = name + ".ogg";
+ path = Path.build_filename (Config.SOUND_DIRECTORY, filename);
+
+ CanberraGtk.context_get().play(
+ id,
+ Canberra.PROP_MEDIA_NAME, name,
+ Canberra.PROP_MEDIA_FILENAME, path);
+
+}
+
+class Animate {
+ int c;
+ public Animate(int c) {
+ this.c = c;
+ }
+
+ public bool exec() {
+ return on_animate(c);
+ }
+}
+
+bool on_animate (int c = 0)
+{
+ if (anim == AnimID.NONE)
+ return false;
+
+ switch (anim) {
+ case AnimID.NONE:
+ break;
+ case AnimID.HINT:
+ case AnimID.MOVE:
+ if (column < column_moveto) {
+ move (column + 1);
+ } else if (column > column_moveto) {
+ move (column - 1);
+ } else {
+ timeout = 0;
+ if (anim == AnimID.MOVE) {
+ anim = AnimID.NONE;
+ process_move2 (c);
+ } else {
+ anim = AnimID.NONE;
+ }
+ return false;
+ }
+ break;
+ case AnimID.DROP:
+ if (row < row_dropto) {
+ drop ();
+ } else {
+ anim = AnimID.NONE;
+ timeout = 0;
+ process_move3 (c);
+ return false;
+ }
+ break;
+ case AnimID.BLINK:
+ draw_line (blink_r1, blink_c1, blink_r2, blink_c2, blink_on ? blink_t
+ : Tile.CLEAR);
+ blink_n--;
+ if (blink_n <= 0 && blink_on) {
+ anim = AnimID.NONE;
+ timeout = 0;
+ return false;
+ }
+ blink_on = !blink_on;
+ break;
+ }
+ return true;
+}
+
+bool on_key_press (Widget w, Gdk.EventKey e)
+{
+ if ((player_active) || timeout != 0 ||
+ (e.keyval != p.keypress[Move.LEFT] &&
+ e.keyval != p.keypress[Move.RIGHT] &&
+ e.keyval != p.keypress[Move.DROP])) {
+ return false;
+ }
+
+ if (gameover) {
+ blink_winner (2);
+ return true;
+ }
+
+ if (e.keyval == p.keypress[Move.LEFT] && column != 0) {
+ column_moveto--;
+ move_cursor (column_moveto);
+ } else if (e.keyval == p.keypress[Move.RIGHT] && column < 6) {
+ column_moveto++;
+ move_cursor (column_moveto);
+ } else if (e.keyval == p.keypress[Move.DROP]) {
+ game_process_move (column);
+ }
+ return true;
+}
+
+void
+blink_winner (int n)
+{
+ /* blink the winner's line(s) n times */
+
+ if (winner == NOBODY)
+ return;
+
+ blink_t = winner;
+ if (is_hline_at (winner, row, column, &blink_r1, &blink_c1, &blink_r2, &blink_c2)) {
+ anim = AnimID.BLINK;
+ blink_on = false;
+ blink_n = n;
+ var temp = new Animate(0);
+ timeout = Timeout.add (SPEED_BLINK, temp.exec);
+ while (timeout!=0)
+ Gtk.main_iteration();
+ }
+
+ if (is_vline_at (winner, row, column, &blink_r1, &blink_c1, &blink_r2, &blink_c2)) {
+ anim = AnimID.BLINK;
+ blink_on = false;
+ blink_n = n;
+ var temp = new Animate(0);
+ timeout = Timeout.add (SPEED_BLINK, temp.exec);
+ while (timeout!=0)
+ Gtk.main_iteration();
+ }
+
+ if (is_dline1_at (winner, row, column, &blink_r1, &blink_c1, &blink_r2, &blink_c2)) {
+ anim = AnimID.BLINK;
+ blink_on = false;
+ blink_n = n;
+ var temp = new Animate(0);
+ timeout = Timeout.add (SPEED_BLINK, temp.exec);
+ while (timeout!=0)
+ Gtk.main_iteration();
+ }
+
+ if (is_dline2_at (winner, row, column, &blink_r1, &blink_c1, &blink_r2, &blink_c2)) {
+ anim = AnimID.BLINK;
+ blink_on = false;
+ blink_n = n;
+ var temp = new Animate(0);
+ timeout = Timeout.add (SPEED_BLINK, temp.exec);
+ while (timeout!=0)
+ Gtk.main_iteration();
+ }
+}
+
+bool on_button_press (Gtk.Widget w, Gdk.EventButton e)
+{
+ int x, y;
+ if (player_active) {
+ return false;
+ }
+
+ if (gameover && timeout == 0) {
+ blink_winner (2);
+ } else if (is_player_human () && timeout == 0) {
+ w.get_window().get_device_position (e.device, out x, out y, null);
+ game_process_move (Gfx.get_column (x));
+ }
+
+ return true;
+}
+
+void
+scorebox_update ()
+{
+ string s;
+
+ if (scorebox == null)
+ return;
+
+ if (get_n_human_players () == 1) {
+ if (p.level[PlayerID.PLAYER1] == Level.HUMAN) {
+ label_score[PlayerID.PLAYER1].set_text(_("You:"));
+ label_score[PlayerID.PLAYER2].set_text(_("Me:"));
+ } else {
+ label_score[PlayerID.PLAYER2].set_text(_("You:"));
+ label_score[PlayerID.PLAYER1].set_text(_("Me:"));
+ }
+ } else {
+ label_name[PlayerID.PLAYER1].set_text(theme_get_player(PlayerID.PLAYER1));
+ label_name[PlayerID.PLAYER2].set_text(theme_get_player(PlayerID.PLAYER2));
+ }
+
+ label_score[PlayerID.PLAYER1].set_text((string)score[PlayerID.PLAYER1]);
+ label_score[PlayerID.PLAYER2].set_text((string)score[PlayerID.PLAYER2]);
+ label_score[PlayerID.NOBODY].set_text((string)score[PlayerID.NOBODY]);
+
+}
+
+void on_settings_preferences (SimpleAction action, Variant? parameter)
+{
+ prefsbox_open ();
+}
+
+void
+on_game_hint (SimpleAction action, Variant? parameter)
+{
+ string s;
+ int c;
+
+ if (timeout != 0)
+ return;
+ if (gameover)
+ return;
+
+ hint_action.set_enabled(false);
+ undo_action.set_enabled(false);
+
+ set_status_message (_("I’m Thinking…"));
+
+ vstr[0] = vlevel[Level.STRONG];
+ c = playgame ((string)vstr) - 1;
+
+ column_moveto = c;
+ while (timeout != 0)
+ Gtk.main_iteration ();
+ anim = AnimID.HINT;
+ var temp = new Animate(0);
+ timeout = Timeout.add (SPEED_MOVE, temp.exec);
+
+ blink_tile (0, c, gboard[0, c], 6);
- column_moveto = c;
- anim = AnimID.MOVE;
- //Timeout.add(SPEED_DROP, on_animate, c.to_pointer());
- //timeout = g_timeout_add (SPEED_MOVE, (GSourceFunc) on_animate, GINT_TO_POINTER (c));
+ s = _("Hint: Column ")+ (c + 1).to_string();
+ set_status_message (s);
+ g_free (s);
+
+ if (moves <= 0 || (moves == 1 && is_player_human ()))
+ undo_action.set_enabled(false);
+ else
+ undo_action.set_enabled(true);
+}
+
+const GLib.ActionEntry app_entries[] = {
+ {"new-game", on_game_new, null, null, null},
+ {"undo-move", on_game_undo, null, null, null},
+ {"hint", on_game_hint, null, null, null},
+ {"scores", on_game_scores, null, null, null},
+ {"quit", on_game_exit, null, null, null},
+ {"preferences", on_settings_preferences, null, null, null},
+ {"help", on_help_contents, null, null, null},
+ {"about", on_help_about, null, null, null}
+};
+
+void
+create_app (GLib.Application app)
+{
+ Gtk.AspectFrame frame;
+ GLib.Menu app_menu, section;
+
+ Gtk.Builder builder;
+ Gtk.CssProvider css_provider;
+ //Error *error = NULL;
+
+ Gtk.Window.set_default_icon_name("four-in-a-row");
+
+ css_provider = new Gtk.CssProvider ();
+ try {
+ css_provider.load_from_data("GtkButtonBox{-GtkButtonBox-child-internal-pad-x:0;}\0");
+ } catch (Error error){
+ stderr.printf("Could not load UI: %s\n", error.message);
+ return;
+ }
+ StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), css_provider,
STYLE_PROVIDER_PRIORITY_APPLICATION);
+
+
+ builder = new Builder.from_file (Config.DATA_DIRECTORY + "/four-in-a-row.ui");
+
+ window = (Window) builder.get_object ("fiar-window");
+ window.application = application;
+ window.set_default_size(DEFAULT_WIDTH, DEFAULT_HEIGHT); // TODO save size & state
+
+ headerbar = (HeaderBar) builder.get_object ("headerbar");
+
+ application.add_action_entries(app_entries, application);
+ application.add_accelerator("<Primary>n", "app.new-game", null);
+ application.add_accelerator("<Primary>h", "app.hint", null);
+ application.add_accelerator("<Primary>z", "app.undo-move", null);
+ application.add_accelerator("<Primary>q", "app.quit", null);
+ application.add_accelerator("F1", "app.contents", null);
+
+ app_menu = new GLib.Menu();
+ section = new GLib.Menu();
+ app_menu.append_section(null, section);
+ section.append(_("_Scores"), "app.scores");
+ section.append(_("_Preferences"), "app.preferences");
+ section = new GLib.Menu();
+ app_menu.append_section(null, section);
+ section.append(_("_Help"), "app.help");
+ section.append(_("_About"), "app.about");
+ section.append(_("_Quit"), "app.quit");
+
+ new_game_action = (GLib.SimpleAction) application.lookup_action("new-game");
+ undo_action = (GLib.SimpleAction) application.lookup_action("undo-move");
+ hint_action = (GLib.SimpleAction) application.lookup_action("hint");
+
+ application.app_menu = app_menu;
+
+ frame = (Gtk.AspectFrame) builder.get_object("frame");
+
+ drawarea = new DrawingArea();
+ /* set a min size to avoid pathological behavior of gtk when scaling down */
+ drawarea.set_size_request (350, 350);
+ drawarea.halign = Align.FILL;
+ drawarea.valign = Align.FILL;
+ frame.add(drawarea);
+
+ drawarea.events = Gdk.EventMask.EXPOSURE_MASK | Gdk.EventMask.BUTTON_PRESS_MASK |
Gdk.EventMask.BUTTON_RELEASE_MASK;
+ drawarea.configure_event.connect(on_drawarea_resize);
+ drawarea.draw.connect(on_drawarea_draw);
+ drawarea.button_press_event.connect(on_button_press);
+ drawarea.key_press_event.connect(on_key_press);
+
+ hint_action.set_enabled(false);
+ undo_action.set_enabled(false);
+}
+
+void on_dialog_close (Gtk.Widget w, int response_id)
+{
+ w.hide();
+}
+
+void
+prompt_player ()
+{
+ int players = get_n_human_players ();
+ bool human = is_player_human ();
+ string who;
+ string str;
+
+ hint_action.set_enabled(human && !gameover);
+
+ switch (players) {
+ case 0:
+ undo_action.set_enabled(false);
+ break;
+ case 1:
+ undo_action.set_enabled((human && moves >1) || (!human && gameover));
+ break;
+ case 2:
+ undo_action.set_enabled(moves > 0);
+ break;
+ }
+
+ if (gameover && winner == PlayerID.NOBODY) {
+ if (score[PlayerID.NOBODY] == 0)
+ set_status_message (null);
+ else
+ set_status_message (_("It’s a draw!"));
+ return;
+ }
+
+ switch (players) {
+ case 1:
+ if (human) {
+ if (gameover)
+ set_status_message (_("You win!"));
+ else
+ set_status_message (_("Your Turn"));
+ } else {
+ if (gameover)
+ set_status_message (_("I win!"));
+ else
+ set_status_message (_("I’m Thinking…"));
+ }
+ break;
+ case 2:
+ case 0:
+
+ if (gameover) {
+ who = player == PLAYER1 ? theme_get_player_win (PlayerID.PLAYER1)
+ : theme_get_player_win (PlayerID.PLAYER2);
+ str = _(who);
+ } else if (player_active) {
+ set_status_message (_("Your Turn"));
+ return;
+ } else {
+ who = player == PLAYER1 ? theme_get_player_turn (PlayerID.PLAYER1)
+ : theme_get_player_turn (PlayerID.PLAYER2);
+ str = _(who);
+ }
+
+ set_status_message (str);
+ break;
+ }
}
diff --git a/src/prefs.vala b/src/prefs.vala
index dd5f96d..5a279aa 100644
--- a/src/prefs.vala
+++ b/src/prefs.vala
@@ -1,6 +1,14 @@
//public const int DEFAULT_THEME_ID = 0;
//extern int n_themes;
-extern Settings settings;
+
+struct Prefs {
+ bool do_sound;
+ int theme_id;
+ Level level[2];
+ int keypress[3];
+}
+
+Settings settings;
Gtk.Dialog? prefsbox = null;
Gtk.ComboBox combobox;
Gtk.ComboBoxText combobox_theme;
diff --git a/src/temp.vapi b/src/temp.vapi
index df7c71a..a30478b 100644
--- a/src/temp.vapi
+++ b/src/temp.vapi
@@ -1,97 +1,20 @@
-[CCode (cname = "Prefs", cheader_filename="prefs.h")]
-struct Prefs {
- bool do_sound;
- int theme_id;
- Level level[2];
- int keypress[3];
-}
-
-[CCode (cname = "Theme", cheader_filename="theme.h")]
-struct Theme {
- public string title;
- public string fname_tileset;
- public string fname_bground;
- public string grid_color;
- public string player1;
- public string player2;
- public string player1_win;
- public string player2_win;
- public string player1_turn;
- public string player2_turn;
-}
-
-[CCode (cname = "AnimID", cprefix = "ANIM_", cheader_filename="main.h")]
-public enum AnimID {
- NONE,
- MOVE,
- DROP,
- BLINK,
- HINT
-}
-
-[CCode (cname = "PlayerID", cprefix = "", cheader_filename="main.h")]
-public enum PlayerID {
- PLAYER1,
- PLAYER2,
- NOBODY
-}
-
-
-[CCode (cname = "LevelID", cprefix = "LEVEL_", cheader_filename="main.h")]
-public enum Level {
- HUMAN,
- WEAK,
- MEDIUM,
- STRONG
-}
+[CCode (cprefix = "", cheader_filename = "config.h")]
+namespace Config {
+ [CCode (cname = "GETTEXT_PACKAGE")]
+ public const string GETTEXT_PACKAGE;
+ [CCode (cname = "DATA_DIRECTORY")]
+ public const string DATA_DIRECTORY;
-[CCode (cname = "int", cprefix="TILE_", has_type_id = false, cheader_filename="main.h")]
-public enum Tile {
- PLAYER1,
- PLAYER2,
- CLEAR,
- CLEAR_CURSOR,
- PLAYER1_CURSOR,
- PLAYER2_CURSOR,
-}
+ [CCode (cname = "APPNAME_LONG")]
+ public const string APPNAME_LONG;
-[CCode (cname = "MoveID", cprefix = "MOVE_", cheader_filename="main.h")]
-public enum Move {
- LEFT,
- RIGHT,
- DROP
-}
+ [CCode (cname = "VERSION")]
+ public const string VERSION;
-[CCode (cname = "SoundID", cprefix = "SOUND_", cheader_filename="main.h")]
-public enum SoundID{
- DROP,
- I_WIN,
- YOU_WIN,
- PLAYER_WIN,
- DRAWN_GAME,
- COLUMN_FULL
-}
-
-void game_reset ();
-//void process_move(int c);
-void gfx_refresh_pixmaps();
-bool gfx_load_pixmaps();
-void gfx_paint_tile(Cairo.Context cr, int r, int c);
-//void gfx_draw_grid(Cairo.Context c);
-//static void gfx_draw_all ();
-void gfx_free ();
-void scorebox_update (); /* update visible player descriptions */
-void prompt_player ();
-void on_dialog_close(int response_id);
-bool on_animate();
-//static void settings_changed_cb (string key);
-void play_sound(SoundID id);
+ [CCode (cname = "SOUND_DIRECTORY")]
+ public const string SOUND_DIRECTORY;
-[CCode (cprefix = "", cheader_filename = "config.h")]
-namespace Config {
- [CCode (cname = "GETTEXT_PACKAGE")]
- public const string GETTEXT_PACKAGE;
+ [CCode (cname = "LOCALEDIR")]
+ public const string LOCALEDIR;
}
-//[CCode(cname="GETTEXT_PACKAGE", cheader_filename="config.h,glib/gi18n-lib.h")]
-//extern const string GETTEXT_PACKAGE;
diff --git a/src/theme.vala b/src/theme.vala
index 4193f74..38588f6 100644
--- a/src/theme.vala
+++ b/src/theme.vala
@@ -1,20 +1,33 @@
+struct Theme {
+ public string title;
+ public string fname_tileset;
+ public string fname_bground;
+ public string grid_color;
+ public string player1;
+ public string player2;
+ public string player1_win;
+ public string player2_win;
+ public string player1_turn;
+ public string player2_turn;
+}
+
//extern Theme theme[];
const string random_shit = Config.GETTEXT_PACKAGE;
string theme_get_title (int id) {
- return theme[id].title;
+ return theme[id].title;
}
string theme_get_player_turn (PlayerID who) {
- if (who == PlayerID.PLAYER1)
- return theme[p.theme_id].player1_turn;
- return theme[p.theme_id].player2_turn;
+ if (who == PlayerID.PLAYER1)
+ return theme[p.theme_id].player1_turn;
+ return theme[p.theme_id].player2_turn;
}
string theme_get_player_win (PlayerID who) {
- if (who == PlayerID.PLAYER1)
- return theme[p.theme_id].player1_win;
- return theme[p.theme_id].player2_win;
+ if (who == PlayerID.PLAYER1)
+ return theme[p.theme_id].player1_win;
+ return theme[p.theme_id].player2_win;
}
string theme_get_player (PlayerID who) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]