[swell-foop/arnaudb/save-on-exit] Save game on exit.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [swell-foop/arnaudb/save-on-exit] Save game on exit.
- Date: Mon, 11 May 2020 17:36:39 +0000 (UTC)
commit 16b326df2b74d6b984bda22a1f05494cb5384220
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Sun May 10 22:22:45 2020 +0200
Save game on exit.
data/org.gnome.swell-foop.gschema.xml | 17 +++++++
src/game.vala | 88 ++++++++++++++++++++++++++++++++++-
src/window.vala | 32 ++++++++-----
3 files changed, 124 insertions(+), 13 deletions(-)
---
diff --git a/data/org.gnome.swell-foop.gschema.xml b/data/org.gnome.swell-foop.gschema.xml
index 3c1d735..e63b093 100644
--- a/data/org.gnome.swell-foop.gschema.xml
+++ b/data/org.gnome.swell-foop.gschema.xml
@@ -7,29 +7,46 @@
<schema id="org.gnome.swell-foop" path="/org/gnome/swell-foop/" gettext-domain="swell-foop">
<key name="theme" type="s">
<default>'shapesandcolors'</default>
+ <!-- Translators: summary of a settings key, see 'dconf-editor /org/gnome/swell-foop/theme' -->
<summary>The theme to use</summary>
+ <!-- Translators: description of a settings key, see 'dconf-editor /org/gnome/swell-foop/theme' -->
<description>The title of the tile theme to use.</description>
</key>
<key name="size" enum="org.gnome.swell-foop.Sizes">
<default>'small'</default>
+ <!-- Translators: summary of a settings key, see 'dconf-editor /org/gnome/swell-foop/size' -->
<summary>Board size</summary>
+ <!-- Translators: description of a settings key, see 'dconf-editor /org/gnome/swell-foop/size' -->
<description>The size of the game board.</description>
</key>
<key name="colors" type="i">
<default>3</default>
<range min="2" max="4"/>
+ <!-- Translators: summary of a settings key, see 'dconf-editor /org/gnome/swell-foop/colors' -->
<summary>Board color count</summary>
+ <!-- Translators: description of a settings key, see 'dconf-editor /org/gnome/swell-foop/colors' -->
<description>The number of colors of tiles to use in the game.</description>
</key>
<key name="first-run" type="b">
<default>true</default>
+ <!-- Translators: summary of a settings key, see 'dconf-editor /org/gnome/swell-foop/first-run' -->
<summary>Is this the first run</summary>
+ <!-- Translators: description of a settings key, see 'dconf-editor /org/gnome/swell-foop/first-run' -->
<description>Setting to decide whether to show first-run hint dialog or not.</description>
</key>
<key name="zealous" type="b">
<default>true</default>
+ <!-- Translators: summary of a settings key, see 'dconf-editor /org/gnome/swell-foop/zealous' -->
<summary>Zealous animation</summary>
+ <!-- Translators: description of a settings key, see 'dconf-editor /org/gnome/swell-foop/zealous' -->
<description>Use more flashy, but slower, animations.</description>
</key>
+ <key name="saved-game" type="m(yqaay)">
+ <default>nothing</default>
+ <!-- Translators: summary of a settings key, see 'dconf-editor /org/gnome/swell-foop/saved-game' -->
+ <summary>Saved game</summary>
+ <!-- Translators: description of a settings key, see 'dconf-editor /org/gnome/swell-foop/saved-game';
"nothing" is a keyword: you might want to translate « “nothing” (your translation) » for example -->
+ <description>Has value “nothing” if there is no saved game. Else, the values are: the number of
colors, the score, and a copy of the board, where “0” means “empty”.</description>
+ </key>
</schema>
</schemalist>
diff --git a/src/game.vala b/src/game.vala
index 8dea8a1..50a8be7 100644
--- a/src/game.vala
+++ b/src/game.vala
@@ -78,7 +78,7 @@ private class Game : Object
public int color_num
{
internal get { return _color_num; }
- protected construct
+ protected construct set // TODO should be doable to make construct only again
{
if (value < 2 || value > 4)
_color_num = 3;
@@ -96,10 +96,15 @@ private class Game : Object
internal signal void started ();
/* Constructor */
- internal Game (int rows, int columns, int color_num)
+ internal Game (int rows, int columns, int color_num, Variant? variant = null)
{
Object (rows: rows, columns: columns, color_num: color_num);
+ if (variant == null || !load_saved_game ((!) variant))
+ create_new_game ();
+ }
+ private inline void create_new_game ()
+ {
/* A 2D array holds all tiles */
tiles = new Tile [rows, columns];
@@ -295,4 +300,83 @@ private class Game : Object
score += increment;
update_score (increment);
}
+
+ /*\
+ * * loading and saving
+ \*/
+
+ private inline bool load_saved_game (Variant variant)
+ {
+ if (variant.get_type_string () != "m(yqaay)")
+ return false; // assert_not_reached() ?
+
+ Variant? child = variant.get_maybe ();
+ if (child == null)
+ return false;
+
+ VariantIter iter = new VariantIter ((!) child);
+ uint8 color_num;
+ uint16 score;
+ iter.next ("y", out color_num);
+ iter.next ("q", out score);
+ Variant tmp_variant = iter.next_value ();
+
+ if (color_num < 2 || color_num > 4)
+ return false;
+
+ // all the following way to extract values feels horrible, but there is a bug when trying to do it
properly (05/2020)
+ Variant tmp_variant_2 = tmp_variant.get_child_value (0);
+ uint rows = (uint) tmp_variant.n_children ();
+ uint columns = (uint) tmp_variant_2.n_children ();
+ if (rows != this.rows
+ || columns != this.columns)
+ return false;
+
+ this.color_num = color_num;
+ this.score = score;
+ update_score (score);
+ tiles = new Tile [rows, columns];
+ for (uint8 i = 0; i < rows; i++)
+ {
+ tmp_variant_2 = tmp_variant.get_child_value (i);
+ for (uint8 j = 0; j < columns; j++)
+ {
+ Variant tmp_variant_3 = tmp_variant_2.get_child_value (j);
+ uint8 color = tmp_variant_3.get_byte ();
+ if (color == 0)
+ {
+ tiles [rows - i - 1, j] = new Tile (j, (int) (rows - i - 1), 0);
+ tiles [rows - i - 1, j].closed = true;
+ }
+ else
+ tiles [rows - i - 1, j] = new Tile (j, (int) (rows - i - 1), color - 1);
+ }
+ }
+ is_started = true;
+ return true;
+ }
+
+ internal Variant get_saved_game ()
+ {
+ if (!is_started || has_completed ())
+ return new Variant ("m(yqaay)", null);
+
+ VariantBuilder builder = new VariantBuilder (new VariantType ("(yqaay)"));
+ builder.add ("y", (uint8) color_num);
+ builder.add ("q", (uint16) score);
+ builder.open (new VariantType ("aay"));
+ VariantType ay_type = new VariantType ("ay");
+ for (uint8 i = (uint8) rows; i > 0; i--)
+ {
+ builder.open (ay_type);
+ for (uint8 j = 0; j < columns; j++)
+ if (tiles [i - 1, j] == null || ((!) tiles [i - 1, j]).closed)
+ builder.add ("y", 0);
+ else
+ builder.add ("y", tiles [i - 1, j].color + 1);
+ builder.close ();
+ }
+ builder.close ();
+ return new Variant.maybe (null, builder.end ());
+ }
}
diff --git a/src/window.vala b/src/window.vala
index 4fa6997..9775412 100644
--- a/src/window.vala
+++ b/src/window.vala
@@ -127,8 +127,12 @@ private class SwellFoopWindow : ApplicationWindow
stage = (Clutter.Stage) clutter_embed.get_stage ();
stage.background_color = Clutter.Color.from_string ("#000000"); /* background color is black */
- /* Create an instance of game with initial values for row, column and color */
- game = new Game (get_board_size ().rows, get_board_size ().columns, settings.get_int ("colors"));
+ /* Create an instance of game, either with a saved game, or with initial values for row, column and
color */
+ Size size = get_board_size ();
+ game = new Game (size.rows, size.columns, settings.get_int ("colors"), settings.get_value
("saved-game"));
+ update_score_cb (game.score);
+ if (game.score != 0)
+ game_in_progress = true;
/* Game score change will be sent to the main window and show in the score label */
game.update_score.connect (update_score_cb);
@@ -222,8 +226,9 @@ private class SwellFoopWindow : ApplicationWindow
internal void new_game ()
{
- game = new Game (get_board_size ().rows,
- get_board_size ().columns,
+ Size size = get_board_size ();
+ game = new Game (size.rows,
+ size.columns,
settings.get_int ("colors"));
game.update_score.connect (update_score_cb);
game.complete.connect (complete_cb);
@@ -240,13 +245,19 @@ private class SwellFoopWindow : ApplicationWindow
update_score_cb (0);
}
- private bool being_destroyed = false;
protected override void destroy ()
{
- /* Record the score if the game isn't over. */
- being_destroyed = true;
- if (game != null && !game.has_completed () && game.score > 0)
- add_score ();
+ settings.delay ();
+ settings.set_value ("saved-game", game.get_saved_game ());
+ settings.set_int ("colors", game.color_num);
+ for (uint8 i = 0; i < sizes.length; i++)
+ if (game.rows == sizes [i].rows && game.columns == sizes [i].columns)
+ {
+ settings.set_string ("size", sizes [i].id);
+ break;
+ }
+ settings.apply ();
+
base.destroy ();
}
@@ -481,8 +492,7 @@ private class SwellFoopWindow : ApplicationWindow
{
warning ("Failed to add score: %s", e.message);
}
- if (!being_destroyed)
- scores_context.run_dialog ();
+ scores_context.run_dialog ();
});
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]