Commit e201b0e2 authored by Arnaud Bonatti's avatar Arnaud Bonatti

Help playing 16-puzzle.

How to play the 16-puzzle is not
exactly obvious. Notify the user
by an hopefully helpful message,
if it looks like he is searching
how to play (bad click or keys).
parent 20a4fe60
......@@ -491,7 +491,7 @@ private class BaseWindow : AdaptativeWindow, AdaptativeWidget
* * notifications
\*/
protected void show_notification (string notification)
internal void show_notification (string notification)
{
main_view.show_notification (notification);
}
......
......@@ -128,12 +128,6 @@ private class GameWindow : BaseWindow, AdaptativeWidget
* * Some public calls
\*/
internal void cannot_move ()
{
/* Translators: notification, as a subtitle of the headerbar; on the 15-Puzzle game, if the user clicks a tile that cannot move */
show_notification (_("You can’t move this tile!"));
}
internal void move (uint moves_count)
{
headerbar.set_moves_count (ref moves_count);
......
......@@ -56,8 +56,14 @@ public class Game : Object
/* signals */
public signal void complete ();
public signal void move (bool x_axis, int number, int x_gap, int y_gap, uint moves_count, bool disable_animation);
public signal void empty_tile ();
public signal void cannot_move (int x, int y);
public signal void bad_click (BadClick reason, bool keyboard_call);
public enum BadClick {
EMPTY_TILE,
NOT_MOVING,
IS_OUTSIDE,
USE_ARROWS;
}
/*\
* * Creation / exporting
......@@ -131,31 +137,43 @@ public class Game : Object
* * Game code
\*/
public void request_move (int x, int y)
public void request_move (int x, int y, bool keyboard_call)
{
if (game_type == GameType.FIFTEEN)
fifteen_move (x, y, /* undoing */ false);
else
sixteen_move (x, y, /* undoing */ false);
}
private void fifteen_move (int x, int y, bool undoing = false, bool restarting = false)
requires (!restarting || undoing)
{
if (x < 0 || x >= size || y < 0 || y >= size)
{
bad_click (BadClick.IS_OUTSIDE, keyboard_call);
return;
}
if (x == x_gap && y == y_gap)
{
empty_tile ();
bad_click (BadClick.EMPTY_TILE, keyboard_call);
return;
}
if (x != x_gap && y != y_gap)
{
cannot_move (x, y);
bad_click (BadClick.NOT_MOVING, keyboard_call);
return;
}
fifteen_move (x, y, /* undoing */ false);
}
else
{
// TODO real touch support
if (x >= 0 && x < size && y >= 0 && y < size)
{
bad_click (BadClick.USE_ARROWS, keyboard_call);
return;
}
sixteen_move (x, y, /* undoing */ false);
}
}
private void fifteen_move (int x, int y, bool undoing = false, bool restarting = false)
requires (!restarting || undoing)
requires ((x >= 0) && (x < size) && (y >= 0) && (y < size))
{
/* we do the move before notifying */
bool was_complete = check_complete ();
......@@ -193,11 +211,8 @@ public class Game : Object
private void sixteen_move (int x, int y, bool undoing = false, bool restarting = false)
requires (!restarting || undoing)
requires ((x < 0) || (x >= size) || (y < 0) || (y >= size))
{
/* TODO touch */
if (x >= 0 && x < size && y >= 0 && y < size)
return;
var move_x_axis = false;
if (x < 0 || x >= size)
{
......
......@@ -249,6 +249,7 @@ private class Taquin : Gtk.Application, BaseApplication
game = new Game (type, size);
view.game = (!) game;
window.move (0);
move_done = false;
string filename = "";
var dirlist = theme_dirlist.copy ();
......@@ -263,7 +264,7 @@ private class Taquin : Gtk.Application, BaseApplication
view.realize (); // TODO does that help?
((!) game).complete.connect (game_complete_cb);
((!) game).cannot_move.connect (window.cannot_move);
((!) game).bad_click.connect (bad_click_cb);
((!) game).move.connect (move_cb);
}
......@@ -276,6 +277,7 @@ private class Taquin : Gtk.Application, BaseApplication
{
((!) game).restart ();
play_sound ("sliding-n");
move_done = false;
}
private void undo_cb ()
......@@ -293,6 +295,7 @@ private class Taquin : Gtk.Application, BaseApplication
{
window.move (moves_count);
play_sound ("sliding-1"); // TODO sliding-n??
move_done = true;
}
private void game_complete_cb ()
......@@ -301,6 +304,37 @@ private class Taquin : Gtk.Application, BaseApplication
play_sound ("gameover");
}
private bool move_done = false;
private void bad_click_cb (Game.BadClick reason, bool keyboard_call)
{
switch (reason)
{
case Game.BadClick.NOT_MOVING:
/* Translators: in-window notification; on the 15-Puzzle game, if the user clicks a tile that cannot move */
window.show_notification (_("You can’t move this tile!"));
return;
case Game.BadClick.USE_ARROWS:
if (move_done) // do nothing if a move has already been done, a bad click or key press happens; reset on next game
return;
if (keyboard_call)
/* Translators: in-window notification; on the 16-Puzzle game, help for keyboard use, displayed if the user uses an unmeaningful keyboard key */
window.show_notification (_("Use Shift and an arrow to move tiles!"));
else
/* Translators: in-window notification; on the 16-Puzzle game, if the user clicks on a tile of the board (the game is played using mouse with arrows around the board) */
window.show_notification (_("Click on the arrows to move tiles!"));
return;
case Game.BadClick.IS_OUTSIDE: // TODO something?
case Game.BadClick.EMPTY_TILE: // TODO something?
default:
return;
}
}
/*\
* * Options of the start-screen
\*/
......
......@@ -482,7 +482,8 @@ public class TaquinView : Gtk.DrawingArea
{
draw_lights = false;
game.request_move ((int) (event.x - x_offset - grid_border_main + tile_size) / tile_size - 1,
(int) (event.y - y_offset - grid_border_main + tile_size) / tile_size - 1);
(int) (event.y - y_offset - grid_border_main + tile_size) / tile_size - 1,
/* keyboard */ false);
}
return true;
}
......@@ -496,16 +497,16 @@ public class TaquinView : Gtk.DrawingArea
if (game.game_type == GameType.SIXTEEN && ((event.state & ModifierType.SHIFT_MASK) > 0 || (event.state & ModifierType.CONTROL_MASK) > 0))
{
switch (k_name) {
case "Left": game.request_move (- 1, y_arrow); break;
case "Right": game.request_move (game.size, y_arrow); break;
case "Up": game.request_move (x_arrow, - 1); break;
case "Down": game.request_move (x_arrow, game.size); break;
case "Left": game.request_move (- 1, y_arrow, /* keyboard */ true); break;
case "Right": game.request_move (game.size, y_arrow, /* keyboard */ true); break;
case "Up": game.request_move (x_arrow, - 1, /* keyboard */ true); break;
case "Down": game.request_move (x_arrow, game.size, /* keyboard */ true); break;
default: return false;
}
}
if (k_name == "space" || k_name == "KP_Enter" || k_name == "Return") // TODO even if game.game_type == GameType.SIXTEEN ??
{
game.request_move (x_arrow, y_arrow);
game.request_move (x_arrow, y_arrow, /* keyboard */ true);
return true;
}
switch (k_name) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment