[lightsoff/wip/gtkview] Moved board logic to gtk board view
- From: Robert Roth <robertroth src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [lightsoff/wip/gtkview] Moved board logic to gtk board view
- Date: Sat, 14 Jul 2018 21:37:26 +0000 (UTC)
commit a601e1f41d9d1266c5855c071bac66dec5ebce83
Author: Robert Roth <robert roth off gmail com>
Date: Sun Jul 15 00:37:03 2018 +0300
Moved board logic to gtk board view
src/board-view-gtk.vala | 162 ++++++++++++++++++++++++++++++++++++++++++++++++
src/game-view-gtk.vala | 142 +++++++++++-------------------------------
src/meson.build | 1 +
3 files changed, 199 insertions(+), 106 deletions(-)
---
diff --git a/src/board-view-gtk.vala b/src/board-view-gtk.vala
new file mode 100644
index 0000000..8fa1989
--- /dev/null
+++ b/src/board-view-gtk.vala
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2018 Robert Roth
+ *
+ * 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. See http://www.gnu.org/copyleft/gpl.html the full text of the
+ * license.
+ */
+
+public class BoardViewGtk : Gtk.Grid
+{
+ private new const int size = 5;
+ private PuzzleGenerator puzzle_generator;
+ private Gtk.ToggleButton[,] lights;
+
+ public bool playable = true;
+
+ private int _moves = 0;
+ public int moves
+ {
+ get { return _moves;}
+ }
+
+ public signal void game_won ();
+ public signal void light_toggled ();
+
+ public BoardViewGtk ()
+ {
+ get_style_context ().add_class ("grid");
+ row_homogeneous = true;
+ column_homogeneous = true;
+ border_width = 4;
+ row_spacing = 2;
+ column_spacing = 2;
+
+ set_size_request (size * 72, size * 72);
+
+ puzzle_generator = new PuzzleGenerator (size);
+ lights = new Gtk.ToggleButton [size, size];
+ for (var x = 0; x < size; x++)
+ for (var y = 0; y < size; y++)
+ {
+ lights[x, y] = new Gtk.ToggleButton ();
+ lights[x, y].show ();
+ lights[x, y].toggled.connect (light_toggled_cb);
+ attach (lights[x, y], x, y, 1, 1);
+ }
+
+ _moves = 0;
+ }
+
+ public void slide_in (int direction, int sign, Clutter.Timeline timeline)
+ {
+ }
+
+ public void slide_out (int direction, int sign, Clutter.Timeline timeline)
+ {
+ }
+
+ public void swap_in (float direction, Clutter.Timeline timeline)
+ {
+ }
+
+ public void swap_out (float direction, Clutter.Timeline timeline)
+ {
+ }
+
+ private void find_light (Gtk.ToggleButton light, out int x, out int y)
+ {
+ x = y = 0;
+ for (x = 0; x < size; x++)
+ for (y = 0; y < size; y++)
+ if (lights[x, y] == light)
+ return;
+ }
+
+ private bool is_completed ()
+ {
+ var cleared = true;
+ for (var x = 0; x < size; x++)
+ for (var y = 0; y < size; y++)
+ if (lights[x, y].active)
+ cleared = false;
+
+ return cleared;
+ }
+
+ public void light_toggled_cb (Gtk.ToggleButton source)
+ {
+ int xl, yl;
+ find_light (source, out xl, out yl);
+
+ toggle_light (xl, yl, true);
+ _moves += 1;
+ light_toggled ();
+ if (is_completed ()) {
+ game_won ();
+ }
+ }
+ // Pseudorandomly generates and sets the state of each light based on
+ // a level number; hopefully this is stable between machines, but that
+ // depends on GLib's PRNG stability. Also, provides some semblance of
+ // symmetry for some levels.
+
+ // Toggle a light and those in each cardinal direction around it.
+ private void toggle_light (int x, int y, bool clicked = false)
+ {
+ for (var xi = 0; xi < size; xi++)
+ for (var yi = 0; yi < size; yi++)
+ lights[xi, yi].toggled.disconnect (light_toggled_cb);
+
+ if (x>= size || y >= size || x < 0 || y < 0 )
+ return;
+ if ((int) x + 1 < size)
+ lights[(int) x + 1, (int) y].set_active (!lights[(int) x + 1, (int) y].get_active ());
+ if ((int) x - 1 >= 0)
+ lights[(int) x - 1, (int) y].set_active (!lights[(int) x - 1, (int) y].get_active ());
+ if ((int) y + 1 < size)
+ lights[(int) x, (int) y + 1].set_active (!lights[(int) x, (int) y + 1].get_active ());
+ if ((int) y - 1 >= 0)
+ lights[(int) x, (int) y - 1].set_active (!lights[(int) x, (int) y - 1].get_active ());
+
+ if (!clicked)
+ lights[(int) x, (int) y].set_active (!lights[(int) x, (int) y ].get_active ());
+
+ for (var xi = 0; xi < size; xi++)
+ for (var yi = 0; yi < size; yi++)
+ lights[xi, yi].toggled.connect (light_toggled_cb);
+ }
+
+ public void load_level (int level)
+ {
+ _moves = 0;
+ light_toggled ();
+ /* We *must* not have level < 1, as the following assumes a nonzero, nonnegative number */
+ if (level < 1)
+ level = 1;
+
+ for (var xi = 0; xi < size; xi++)
+ for (var yi = 0; yi < size; yi++)
+ lights[xi, yi].toggled.disconnect (light_toggled_cb);
+
+ /* Clear level */
+ for (var x = 0; x < size; x++)
+ for (var y = 0; y < size; y++)
+ lights[x, y].active = false;
+
+ /* Use the same pseudo-random levels */
+ Random.set_seed (level);
+
+ /* Levels require more and more clicks to make */
+ var solution_length = (int) Math.floor (2 * Math.log (level) + 1);
+
+ /* Do the moves the player needs to */
+ var sol = puzzle_generator.minimal_solution (solution_length);
+ for (var x = 0; x < size; x++)
+ for (var y = 0; y < size; y++)
+ if (sol[x, y])
+ toggle_light (x, y);
+ }
+}
diff --git a/src/game-view-gtk.vala b/src/game-view-gtk.vala
index 5e83597..b6bce8e 100644
--- a/src/game-view-gtk.vala
+++ b/src/game-view-gtk.vala
@@ -1,15 +1,17 @@
-public class GtkGameView : Gtk.Grid, GameView {
+public class GtkGameView : Gtk.Frame, GameView {
- private Gtk.ToggleButton[,] lights;
- private new const int SIZE = 5;
- private PuzzleGenerator puzzle_generator;
+ private BoardViewGtk board_view;
+ private BoardViewGtk? new_board_view = null;
private int current_level;
- private int moves;
public void swap_board (int direction)
{
current_level += direction;
- load_level (current_level);
+ new_board_view = create_board_view (current_level);
+ remove (board_view);
+ add (new_board_view);
+ board_view = new_board_view;
+ level_changed (current_level);
}
public void hide_cursor ()
{
@@ -23,125 +25,53 @@ public class GtkGameView : Gtk.Grid, GameView {
public void reset_game ()
{
current_level = 1;
- load_level (current_level);
+ new_board_view = create_board_view (current_level);
+ remove (board_view);
+ add (new_board_view);
+ board_view = new_board_view;
+
+ level_changed (current_level);
}
public GtkGameView (int level)
{
- get_style_context ().add_class ("grid");
- puzzle_generator = new PuzzleGenerator (SIZE);
/* Clear level */
current_level = level;
- lights = new Gtk.ToggleButton [SIZE, SIZE];
- for (var x = 0; x < SIZE; x++)
- for (var y = 0; y < SIZE; y++)
- {
- lights[x, y] = new Gtk.ToggleButton ();
- lights[x, y].show ();
- lights[x, y].toggled.connect (light_toggled_cb);
- attach (lights[x, y], x, y, 1, 1);
- }
- set_size_request (SIZE * 72, SIZE * 72);
- row_homogeneous = true;
- column_homogeneous = true;
- load_level (current_level);
- border_width = 4;
- row_spacing = 2;
- column_spacing = 2;
- }
+ board_view = create_board_view (current_level);
+ board_view.playable = true;
+ add (board_view);
- private void find_light (Gtk.ToggleButton light, out int x, out int y)
- {
- x = y = 0;
- for (x = 0; x < SIZE; x++)
- for (y = 0; y < SIZE; y++)
- if (lights[x, y] == light)
- return;
}
- private bool is_completed ()
+ private BoardViewGtk create_board_view (int level)
{
- var cleared = true;
- for (var x = 0; x < SIZE; x++)
- for (var y = 0; y < SIZE; y++)
- if (lights[x, y].active)
- cleared = false;
-
- return cleared;
+ var view = new BoardViewGtk ();
+ view.load_level (level);
+ view.game_won.connect (game_won_cb);
+ view.light_toggled.connect (light_toggled_cb);
+ view.playable = false;
+ view.show_all ();
+ return view;
}
- public void light_toggled_cb (Gtk.ToggleButton source)
+ private void light_toggled_cb ()
{
- int xl, yl;
- find_light (source, out xl, out yl);
-
- toggle_light (xl, yl, true);
- moves_changed (++moves);
- if (is_completed ()) {
- load_level (++current_level);
- }
+ moves_changed (board_view.moves);
}
- // Pseudorandomly generates and sets the state of each light based on
- // a level number; hopefully this is stable between machines, but that
- // depends on GLib's PRNG stability. Also, provides some semblance of
- // symmetry for some levels.
- // Toggle a light and those in each cardinal direction around it.
- private void toggle_light (int x, int y, bool clicked = false)
+// The player won the game; create a new board, update the level count,
+ // and transition between the two boards in a random direction.
+ private void game_won_cb ()
{
- for (var xi = 0; xi < SIZE; xi++)
- for (var yi = 0; yi < SIZE; yi++)
- lights[xi, yi].toggled.disconnect (light_toggled_cb);
-
- if (x>= SIZE || y >= SIZE || x < 0 || y < 0 )
- return;
- if ((int) x + 1 < SIZE)
- lights[(int) x + 1, (int) y].set_active (!lights[(int) x + 1, (int) y].get_active ());
- if ((int) x - 1 >= 0)
- lights[(int) x - 1, (int) y].set_active (!lights[(int) x - 1, (int) y].get_active ());
- if ((int) y + 1 < SIZE)
- lights[(int) x, (int) y + 1].set_active (!lights[(int) x, (int) y + 1].get_active ());
- if ((int) y - 1 >= 0)
- lights[(int) x, (int) y - 1].set_active (!lights[(int) x, (int) y - 1].get_active ());
+ current_level++;
- if (!clicked)
- lights[(int) x, (int) y].set_active (!lights[(int) x, (int) y ].get_active ());
+ new_board_view = create_board_view (current_level);
+ remove (board_view);
+ add (new_board_view);
+ board_view = new_board_view;
- for (var xi = 0; xi < SIZE; xi++)
- for (var yi = 0; yi < SIZE; yi++)
- lights[xi, yi].toggled.connect (light_toggled_cb);
+ level_changed (current_level);
}
- public void load_level (int level)
- {
- moves = 0;
- moves_changed (moves);
- level_changed (level);
- /* We *must* not have level < 1, as the following assumes a nonzero, nonnegative number */
- if (level < 1)
- level = 1;
-
- for (var xi = 0; xi < SIZE; xi++)
- for (var yi = 0; yi < SIZE; yi++)
- lights[xi, yi].toggled.disconnect (light_toggled_cb);
-
- /* Clear level */
- for (var x = 0; x < SIZE; x++)
- for (var y = 0; y < SIZE; y++)
- lights[x, y].active = false;
-
- /* Use the same pseudo-random levels */
- Random.set_seed (level);
-
- /* Levels require more and more clicks to make */
- var solution_length = (int) Math.floor (2 * Math.log (level) + 1);
-
- /* Do the moves the player needs to */
- var sol = puzzle_generator.minimal_solution (solution_length);
- for (var x = 0; x < SIZE; x++)
- for (var y = 0; y < SIZE; y++)
- if (sol[x, y])
- toggle_light (x, y);
- }
}
diff --git a/src/meson.build b/src/meson.build
index 1fb5533..6e69dd8 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,5 +1,6 @@
lightsoff_vala_sources = [
'board-view-clutter.vala',
+ 'board-view-gtk.vala',
'lightsoff.vala',
'lightsoff-window.vala',
'puzzle-generator.vala',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]