[gnome-2048] Add --size command-line option.



commit 412eadb4d8ec6e39b28b5e7002c3efe6b7d5f0de
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Mon Oct 28 17:57:42 2019 +0100

    Add --size command-line option.

 data/gnome-2048.6       |  3 +++
 src/application.vala    | 60 +++++++++++++++++++++++++++++++++++++++++++++++--
 src/game-headerbar.vala |  2 +-
 src/game-window.vala    | 26 ++++++++++++++++-----
 src/grid.vala           |  6 ++---
 5 files changed, 86 insertions(+), 11 deletions(-)
---
diff --git a/data/gnome-2048.6 b/data/gnome-2048.6
index 560ae1a..bd461a1 100644
--- a/data/gnome-2048.6
+++ b/data/gnome-2048.6
@@ -30,6 +30,9 @@ Use your keyboard’s arrow keys or gestures to slide all tiles in the desired d
 Gnome 2048 only adds tiles of value 2, as opposed to the original 2048 game. Also, it allows you to play on 
grids of various size.
 .SH OPTIONS
 .TP
+.B \-s, \-\-size=<size>
+Changes the size of the grid. Size must be between 2 and 9, or in the form 2x3.
+.TP
 .B \-v, \-\-version
 Prints the program version and exits.
 .P
diff --git a/src/application.vala b/src/application.vala
index d509f54..b91c1ab 100644
--- a/src/application.vala
+++ b/src/application.vala
@@ -25,11 +25,20 @@ private class TwentyFortyEight : Gtk.Application
     private GameWindow _window;
 
     private static bool show_version;
+    private static string? size = null;
+    private uint8 cols = 0;
+    private uint8 rows = 0;
 
     private const OptionEntry [] option_entries =
     {
         /* Translators: command-line option description, see 'gnome-2048 --help' */
-        { "version", 'v', OptionFlags.NONE, OptionArg.NONE, ref show_version, N_("Print release version and 
exit"), null },
+        { "size", 's',      OptionFlags.NONE, OptionArg.STRING, ref size,           N_("Start new game of 
given size"),
+
+        /* Translators: in the command-line options description, text to indicate the user should specify a 
size, see 'gnome-2048 --help' */
+                                                                                    N_("SIZE") },
+
+        /* Translators: command-line option description, see 'gnome-2048 --help' */
+        { "version", 'v',   OptionFlags.NONE, OptionArg.NONE,   ref show_version,   N_("Print release 
version and exit"), null },
         {}
     };
 
@@ -94,9 +103,56 @@ private class TwentyFortyEight : Gtk.Application
             return Posix.EXIT_SUCCESS;
         }
 
+        if (size != null && !parse_size ((!) size, out cols, out rows))
+        {
+            /* Translators: command-line error message, displayed for an incorrect game size request; try 
'gnome-2048 -s 0' */
+            stderr.printf ("%s\n", _("Failed to parse size. Size must be between 2 and 9, or in the form 
2x3."));
+            return Posix.EXIT_FAILURE;
+        }
+
         /* Activate */
         return -1;
     }
+    private static bool parse_size (string size, out uint8 cols, out uint8 rows)
+    {
+        cols = 0;   // garbage
+        rows = 0;   // garbage
+
+        /* size is either a digit, either of the for MxN */
+        string [] tokens = size.split ("x");
+        if (tokens.length == 0 || tokens.length > 2)
+            return false;
+
+        /* parse the first token in any case */
+        uint64 test;
+        if (!uint64.try_parse (tokens [0], out test))
+            return false;
+        if (test <= 0 || test > 9)
+            return false;
+        cols = (uint8) test;
+
+        /* test for forbidden "1" size and return */
+        if (tokens.length == 1)
+        {
+            if (cols < 2)
+                return false;
+            rows = cols;
+            return true;
+        }
+
+        /* parse the second token, if any */
+        if (!uint64.try_parse (tokens [1], out test))
+            return false;
+        if (test <= 0 || test > 9)
+            return false;
+        rows = (uint8) test;
+
+        /* test for forbidden sizes, and return */
+        if (Grid.is_disallowed_grid_size (ref cols, ref rows))
+            return false;
+
+        return true;
+    }
 
     protected override void startup ()
     {
@@ -104,7 +160,7 @@ private class TwentyFortyEight : Gtk.Application
 
         add_action_entries (action_entries, this);
 
-        _window = new GameWindow (this);
+        _window = new GameWindow (this, cols, rows);
 
         set_accels_for_action ("ui.toggle-new-game",    {        "<Primary>n"       });
         set_accels_for_action ("ui.new-game",           { "<Shift><Primary>n"       });
diff --git a/src/game-headerbar.vala b/src/game-headerbar.vala
index 6c3542c..04d30b4 100644
--- a/src/game-headerbar.vala
+++ b/src/game-headerbar.vala
@@ -134,7 +134,7 @@ private class GameHeaderBar : HeaderBar
     * * new-game menu
     \*/
 
-    internal void _update_new_game_menu (int rows, int cols)
+    internal void _update_new_game_menu (uint8 rows, uint8 cols)
     {
         GLib.Menu menu = new GLib.Menu ();
 
diff --git a/src/game-window.vala b/src/game-window.vala
index b8a6c5c..711215c 100644
--- a/src/game-window.vala
+++ b/src/game-window.vala
@@ -33,6 +33,9 @@ private class GameWindow : ApplicationWindow
 
     private Game _game;
 
+    public uint8 cli_cols { private get; protected construct; default = 0; }
+    public uint8 cli_rows { private get; protected construct; default = 0; }
+
     construct
     {
         _settings = new GLib.Settings ("org.gnome.TwentyFortyEight");
@@ -47,11 +50,13 @@ private class GameWindow : ApplicationWindow
         notify ["has-toplevel-focus"].connect (() => _embed.grab_focus ());
     }
 
-    internal GameWindow (TwentyFortyEight application)
+    internal GameWindow (TwentyFortyEight application, uint8 cols, uint8 rows)
     {
-        Object (application: application, visible: true);
+        Object (application: application, visible: true, cli_cols: cols, cli_rows: rows);
 
-        if (!_game.restore_game (ref _settings))
+        if (cols != 0 && rows != 0)
+            new_game_cb ();
+        else if (!_game.restore_game (ref _settings))
             new_game_cb ();
 
         // should be done after game creation, so that you cannot move before
@@ -73,6 +78,15 @@ private class GameWindow : ApplicationWindow
 
     private void _init_game ()
     {
+        if (cli_cols != 0 && cli_rows != 0)
+        {
+            _settings.delay ();
+            _settings.set_int ("cols", cli_cols);
+            _settings.set_int ("rows", cli_rows);
+            _settings.apply ();
+            GLib.Settings.sync ();
+        }
+
         _game = new Game (ref _settings);
         _game.notify ["score"].connect (_header_bar.set_score);
         _game.finished.connect ((show_scores) => {
@@ -99,7 +113,8 @@ private class GameWindow : ApplicationWindow
                 {
                     case "cols":
                     case "rows":
-                        _header_bar._update_new_game_menu (_settings.get_int ("rows"), _settings.get_int 
("cols"));
+                        _header_bar._update_new_game_menu ((uint8) _settings.get_int ("rows"),   // schema 
ranges rows
+                                                           (uint8) _settings.get_int ("cols")); // and cols 
from 1 to 9
                         return;
                     case "allow-undo":
                         _header_bar._update_hamburger_menu (_settings.get_boolean ("allow-undo"));
@@ -111,7 +126,8 @@ private class GameWindow : ApplicationWindow
                         return;
                 }
             });
-        _header_bar._update_new_game_menu (_settings.get_int ("rows"), _settings.get_int ("cols"));
+        _header_bar._update_new_game_menu ((uint8) _settings.get_int ("rows"),   // schema ranges rows
+                                           (uint8) _settings.get_int ("cols")); // and cols from 1 to 9
         _header_bar._update_hamburger_menu (_settings.get_boolean ("allow-undo"));
         _game.load_settings (ref _settings);
 
diff --git a/src/grid.vala b/src/grid.vala
index 2b43789..8c1220c 100644
--- a/src/grid.vala
+++ b/src/grid.vala
@@ -479,7 +479,7 @@ private class Grid : Object
         return _grid [row, col];
     }
 
-    internal static bool is_disallowed_grid_size (ref int rows, ref int cols)
+    internal static bool is_disallowed_grid_size (ref uint8 rows, ref uint8 cols)
         requires (rows >= 1)
         requires (rows <= 9)
         requires (cols >= 1)
@@ -562,13 +562,13 @@ private class Grid : Object
             return false;
         if ((number_64 == 0) || (number_64 > 9))
             return false;
-        int rows = (int) number_64;
+        uint8 rows = (uint8) number_64;
         // cols
         if (!uint64.try_parse (tokens [1], out number_64))
             return false;
         if ((number_64 == 0) || (number_64 > 9))
             return false;
-        int cols = (int) number_64;
+        uint8 cols = (uint8) number_64;
 
         if (is_disallowed_grid_size (ref rows, ref cols))
             return false;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]