Commit da3931dc authored by Arnaud B.'s avatar Arnaud B. 😎

Use uint8.

parent c10e3c41
...@@ -27,7 +27,7 @@ private class FourInARow : Gtk.Application ...@@ -27,7 +27,7 @@ private class FourInARow : Gtk.Application
/* Translators: application name, as used in the window manager, the window title, the about dialog... */ /* Translators: application name, as used in the window manager, the window title, the about dialog... */
private const string PROGRAM_NAME = _("Four-in-a-row"); private const string PROGRAM_NAME = _("Four-in-a-row");
private const int SIZE_VSTR = 53; private const uint8 SIZE_VSTR = 53;
private const int SPEED_BLINK = 150; private const int SPEED_BLINK = 150;
private const int SPEED_MOVE = 35; private const int SPEED_MOVE = 35;
private const int SPEED_DROP = 20; private const int SPEED_DROP = 20;
...@@ -50,13 +50,13 @@ private class FourInARow : Gtk.Application ...@@ -50,13 +50,13 @@ private class FourInARow : Gtk.Application
private PlayerID last_first_player = PlayerID.NOBODY; private PlayerID last_first_player = PlayerID.NOBODY;
private Board game_board = new Board (); private Board game_board = new Board ();
private bool one_player_game; private bool one_player_game;
private int ai_level; private uint8 ai_level;
/** /**
* score: * score:
* *
* The scores for the current instance (Player 1, Player 2, Draw) * The scores for the current instance (Player 1, Player 2, Draw)
*/ */
private int [] score = { 0, 0, 0 }; private uint [] score = { 0, 0, 0 };
private bool reset_score = true; private bool reset_score = true;
private uint playgame_timeout = 0; private uint playgame_timeout = 0;
...@@ -69,19 +69,19 @@ private class FourInARow : Gtk.Application ...@@ -69,19 +69,19 @@ private class FourInARow : Gtk.Application
private MenuButton history_button_2; private MenuButton history_button_2;
// game state // game state
private char vstr [53]; private char vstr [/* SIZE_VSTR */ 53];
private int moves; private uint8 moves;
private int column; private uint8 column;
private int column_moveto; private uint8 column_moveto;
private int row; private uint8 row;
private int row_dropto; private uint8 row_dropto;
// animation // animation
private static AnimID anim = AnimID.NONE; private static AnimID anim = AnimID.NONE;
private int [,] blink_lines = {{}}; private uint8 [,] blink_lines = {{}};
private uint8 blink_line = 0; // index of currenly blinking line in blink_lines private uint8 blink_line = 0; // index of currenly blinking line in blink_lines
private int blink_t = 0; private Tile blink_t = Tile.PLAYER1; // garbage
private int blink_n = 0; private uint8 blink_n = 0;
private bool blink_on = false; private bool blink_on = false;
private uint timeout = 0; private uint timeout = 0;
...@@ -90,7 +90,7 @@ private class FourInARow : Gtk.Application ...@@ -90,7 +90,7 @@ private class FourInARow : Gtk.Application
[CCode (notify = false)] internal int keypress_right { private get; internal set; } [CCode (notify = false)] internal int keypress_right { private get; internal set; }
[CCode (notify = false)] internal int keypress_left { private get; internal set; } [CCode (notify = false)] internal int keypress_left { private get; internal set; }
[CCode (notify = false)] internal bool sound_on { private get; internal set; } [CCode (notify = false)] internal bool sound_on { private get; internal set; }
[CCode (notify = false)] private int theme_id { private get; private set; } private uint8 theme_id;
private const GLib.ActionEntry app_entries [] = // see also add_actions() private const GLib.ActionEntry app_entries [] = // see also add_actions()
{ {
...@@ -195,10 +195,10 @@ private class FourInARow : Gtk.Application ...@@ -195,10 +195,10 @@ private class FourInARow : Gtk.Application
settings.bind ("theme-id", scorebox, "theme-id", SettingsBindFlags.GET | SettingsBindFlags.NO_SENSITIVITY); settings.bind ("theme-id", scorebox, "theme-id", SettingsBindFlags.GET | SettingsBindFlags.NO_SENSITIVITY);
settings.changed ["theme-id"].connect (() => { settings.changed ["theme-id"].connect (() => {
scorebox.update (score, one_player_game); scorebox.update (score, one_player_game);
theme_id = settings.get_int ("theme-id"); theme_id = (uint8) settings.get_int ("theme-id");
prompt_player (); prompt_player ();
}); });
theme_id = settings.get_int ("theme-id"); theme_id = (uint8) settings.get_int ("theme-id");
add_actions (); add_actions ();
...@@ -313,7 +313,7 @@ private class FourInARow : Gtk.Application ...@@ -313,7 +313,7 @@ private class FourInARow : Gtk.Application
{ {
player = settings.get_string ("first-player") == "computer" ? PlayerID.PLAYER2 : PlayerID.PLAYER1; player = settings.get_string ("first-player") == "computer" ? PlayerID.PLAYER2 : PlayerID.PLAYER1;
settings.set_string ("first-player", player == PlayerID.PLAYER1 ? "computer" : "human"); settings.set_string ("first-player", player == PlayerID.PLAYER1 ? "computer" : "human");
ai_level = settings.get_int ("opponent"); ai_level = (uint8) settings.get_int ("opponent");
} }
else else
{ {
...@@ -344,19 +344,25 @@ private class FourInARow : Gtk.Application ...@@ -344,19 +344,25 @@ private class FourInARow : Gtk.Application
{ {
vstr [0] = vlevel [ai_level]; vstr [0] = vlevel [ai_level];
playgame_timeout = Timeout.add (COMPUTER_INITIAL_DELAY, () => { playgame_timeout = Timeout.add (COMPUTER_INITIAL_DELAY, () => {
process_move (playgame ((string) vstr) - 1); int c = playgame ((string) vstr) - 1;
if (c > 6)
assert_not_reached ();
if (c < 0)
return Source.REMOVE;
process_move ((uint8) c);
playgame_timeout = 0; playgame_timeout = 0;
return Source.REMOVE; return Source.REMOVE;
}); });
} }
} }
private void blink_winner (int n) /* blink the winner's line(s) n times */ private void blink_winner (uint8 n) /* blink the winner's line(s) n times */
// requires (n < 128)
{ {
if (winner == NOBODY) if (winner == NOBODY)
return; return;
blink_t = winner; blink_t = (Tile) winner; // FIXME converting a PlayerID in Tile, bad
if (game_board.is_line_at ((Tile) winner, row, column, out blink_lines)) if (game_board.is_line_at ((Tile) winner, row, column, out blink_lines))
{ {
...@@ -371,32 +377,31 @@ private class FourInARow : Gtk.Application ...@@ -371,32 +377,31 @@ private class FourInARow : Gtk.Application
} }
} }
private inline void draw_line (int r1, int c1, int r2, int c2, int tile) private inline void draw_line (uint8 _r1, uint8 _c1, uint8 _r2, uint8 _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; bool done = false;
int d_row; int8 d_row;
int d_col; int8 d_col;
if (r1 < r2) int8 r1 = (int8) _r1;
d_row = 1; int8 c1 = (int8) _c1;
else if (r1 > r2) int8 r2 = (int8) _r2;
d_row = -1; int8 c2 = (int8) _c2;
else
d_row = 0;
if (c1 < c2) if (r1 < r2) d_row = 1;
d_col = 1; else if (r1 > r2) d_row = -1;
else if (c1 > c2) else d_row = 0;
d_col = -1;
else if (c1 < c2) d_col = 1;
d_col = 0; else if (c1 > c2) d_col = -1;
else d_col = 0;
do do
{ {
done = (r1 == r2 && c1 == c2); done = (r1 == r2 && c1 == c2);
game_board[r1, c1] = (Tile) tile; game_board [r1, c1] = (Tile) tile;
game_board_view.draw_tile (r1, c1); game_board_view.draw_tile (r1, c1);
if (r1 != r2) if (r1 != r2)
r1 += d_row; r1 += d_row;
...@@ -413,7 +418,7 @@ private class FourInARow : Gtk.Application ...@@ -413,7 +418,7 @@ private class FourInARow : Gtk.Application
window.allow_hint (human && !gameover); window.allow_hint (human && !gameover);
if (one_player_game) if (one_player_game)
window.allow_undo ((human && moves >1) || (!human && gameover)); window.allow_undo ((human && moves > 1) || (!human && gameover));
else else
window.allow_undo (moves > 0); window.allow_undo (moves > 0);
...@@ -469,7 +474,7 @@ private class FourInARow : Gtk.Application ...@@ -469,7 +474,7 @@ private class FourInARow : Gtk.Application
prompt_player (); prompt_player ();
} }
private void process_move3 (int c) private void process_move3 (uint8 c)
{ {
play_sound (SoundID.DROP); play_sound (SoundID.DROP);
...@@ -493,10 +498,12 @@ private class FourInARow : Gtk.Application ...@@ -493,10 +498,12 @@ private class FourInARow : Gtk.Application
{ {
playgame_timeout = Timeout.add (COMPUTER_MOVE_DELAY, () => { playgame_timeout = Timeout.add (COMPUTER_MOVE_DELAY, () => {
vstr [0] = vlevel [ai_level]; vstr [0] = vlevel [ai_level];
c = playgame ((string) vstr) - 1; int col = playgame ((string) vstr) - 1;
if (c < 0) if (col < 0)
gameover = true; gameover = true;
var nm = new NextMove (c, this); else if (col > 6)
assert_not_reached ();
var nm = new NextMove ((uint8) col, this);
Timeout.add (SPEED_DROP, nm.exec); Timeout.add (SPEED_DROP, nm.exec);
playgame_timeout = 0; playgame_timeout = 0;
return Source.REMOVE; return Source.REMOVE;
...@@ -532,10 +539,10 @@ private class FourInARow : Gtk.Application ...@@ -532,10 +539,10 @@ private class FourInARow : Gtk.Application
return true; return true;
} }
private void process_move2 (int c) private void process_move2 (uint8 c)
{ {
int r = game_board.first_empty_row (c); uint8 r = game_board.first_empty_row (c);
if (r > 0) if (r != 0)
{ {
row = 0; row = 0;
row_dropto = r; row_dropto = r;
...@@ -547,7 +554,7 @@ private class FourInARow : Gtk.Application ...@@ -547,7 +554,7 @@ private class FourInARow : Gtk.Application
play_sound (SoundID.COLUMN_FULL); play_sound (SoundID.COLUMN_FULL);
} }
private void process_move (int c) private void process_move (uint8 c)
{ {
if (timeout != 0) if (timeout != 0)
{ {
...@@ -574,7 +581,7 @@ private class FourInARow : Gtk.Application ...@@ -574,7 +581,7 @@ private class FourInARow : Gtk.Application
game_board_view.draw_tile (row, column); game_board_view.draw_tile (row, column);
} }
private inline void move (int c) private inline void move (uint8 c)
{ {
game_board [0, column] = Tile.CLEAR; game_board [0, column] = Tile.CLEAR;
game_board_view.draw_tile (0, column); game_board_view.draw_tile (0, column);
...@@ -585,7 +592,7 @@ private class FourInARow : Gtk.Application ...@@ -585,7 +592,7 @@ private class FourInARow : Gtk.Application
game_board_view.draw_tile (0, c); game_board_view.draw_tile (0, c);
} }
private void move_cursor (int c) private void move_cursor (uint8 c)
{ {
move (c); move (c);
column = column_moveto = c; column = column_moveto = c;
...@@ -599,10 +606,10 @@ private class FourInARow : Gtk.Application ...@@ -599,10 +606,10 @@ private class FourInARow : Gtk.Application
private class NextMove private class NextMove
{ {
int c; private uint8 c;
FourInARow application; private FourInARow application;
internal NextMove (int c, FourInARow application) internal NextMove (uint8 c, FourInARow application)
{ {
this.c = c; this.c = c;
this.application = application; this.application = application;
...@@ -628,7 +635,7 @@ private class FourInARow : Gtk.Application ...@@ -628,7 +635,7 @@ private class FourInARow : Gtk.Application
{ {
game_board.clear (); game_board.clear ();
for (var i = 0; i < SIZE_VSTR; i++) for (uint8 i = 0; i < SIZE_VSTR; i++)
vstr [i] = '\0'; vstr [i] = '\0';
vstr [0] = vlevel [/* weak */ 1]; vstr [0] = vlevel [/* weak */ 1];
...@@ -636,13 +643,13 @@ private class FourInARow : Gtk.Application ...@@ -636,13 +643,13 @@ private class FourInARow : Gtk.Application
moves = 0; moves = 0;
} }
private inline void blink_tile (int row, int col, int t, int n) private inline void blink_tile (uint8 row, uint8 col, Tile tile, uint8 n)
{ {
if (timeout != 0) if (timeout != 0)
return; return;
blink_lines = {{ row, col, row, col }}; blink_lines = {{ row, col, row, col }};
blink_line = 0; blink_line = 0;
blink_t = t; blink_t = tile;
blink_n = n; blink_n = n;
blink_on = false; blink_on = false;
anim = AnimID.BLINK; anim = AnimID.BLINK;
...@@ -652,10 +659,11 @@ private class FourInARow : Gtk.Application ...@@ -652,10 +659,11 @@ private class FourInARow : Gtk.Application
private class Animate private class Animate
{ {
private int c; private uint8 c;
private FourInARow application; private FourInARow application;
private int blink_n_times; private uint8 blink_n_times;
internal Animate (int c, FourInARow application, int blink_n_times = 0)
internal Animate (uint8 c, FourInARow application, uint8 blink_n_times = 0)
{ {
this.c = c; this.c = c;
this.application = application; this.application = application;
...@@ -708,7 +716,7 @@ private class FourInARow : Gtk.Application ...@@ -708,7 +716,7 @@ private class FourInARow : Gtk.Application
/* col 2 */ application.blink_lines [application.blink_line, 3], /* col 2 */ application.blink_lines [application.blink_line, 3],
/* tile */ application.blink_on ? application.blink_t : Tile.CLEAR); /* tile */ application.blink_on ? application.blink_t : Tile.CLEAR);
application.blink_n--; application.blink_n--;
if (application.blink_n <= 0 && application.blink_on) if (application.blink_n == 0 && application.blink_on)
{ {
if (application.blink_line >= application.blink_lines.length [0] - 1) if (application.blink_line >= application.blink_lines.length [0] - 1)
{ {
...@@ -743,7 +751,7 @@ private class FourInARow : Gtk.Application ...@@ -743,7 +751,7 @@ private class FourInARow : Gtk.Application
private inline void on_game_hint () private inline void on_game_hint ()
{ {
string s; string s;
int c; uint8 c;
if (timeout != 0) if (timeout != 0)
return; return;
...@@ -757,7 +765,10 @@ private class FourInARow : Gtk.Application ...@@ -757,7 +765,10 @@ private class FourInARow : Gtk.Application
set_status_message (_("I’m Thinking…")); set_status_message (_("I’m Thinking…"));
vstr [0] = vlevel [/* strong */ 3]; vstr [0] = vlevel [/* strong */ 3];
c = playgame ((string) vstr) - 1; int _c = playgame ((string) vstr) - 1;
if (_c < 0 || _c > 6)
assert_not_reached ();
c = (uint8) _c;
column_moveto = c; column_moveto = c;
while (timeout != 0) while (timeout != 0)
...@@ -783,8 +794,8 @@ private class FourInARow : Gtk.Application ...@@ -783,8 +794,8 @@ private class FourInARow : Gtk.Application
if (timeout != 0) if (timeout != 0)
return; return;
int c = vstr [moves] - '0' - 1; uint8 c = vstr [moves] - '0' - 1;
int r = game_board.first_empty_row (c) + 1; uint8 r = game_board.first_empty_row (c) + 1;
vstr [moves] = '0'; vstr [moves] = '0';
vstr [moves + 1] = '\0'; vstr [moves + 1] = '\0';
moves--; moves--;
...@@ -897,7 +908,7 @@ private class FourInARow : Gtk.Application ...@@ -897,7 +908,7 @@ private class FourInARow : Gtk.Application
if (key == "Left" || event.keyval == keypress_left) if (key == "Left" || event.keyval == keypress_left)
{ {
if (column <= 0) if (column == 0)
return false; return false;
column_moveto--; column_moveto--;
move_cursor (column_moveto); move_cursor (column_moveto);
...@@ -912,12 +923,12 @@ private class FourInARow : Gtk.Application ...@@ -912,12 +923,12 @@ private class FourInARow : Gtk.Application
else if (key == "space" || key == "Return" || key == "KP_Enter" || key == "Down" || event.keyval == keypress_drop) else if (key == "space" || key == "Return" || key == "KP_Enter" || key == "Down" || event.keyval == keypress_drop)
process_move (column); process_move (column);
else if (key == "1" || key == "2" || key == "3" || key == "4" || key == "5" || key == "6" || key == "7") else if (key == "1" || key == "2" || key == "3" || key == "4" || key == "5" || key == "6" || key == "7")
process_move (int.parse (key) - 1); process_move ((uint8) int.parse (key) - 1);
return true; return true;
} }
private inline bool column_clicked_cb (int column) private inline bool column_clicked_cb (uint8 column)
{ {
if (gameover && timeout == 0) if (gameover && timeout == 0)
blink_winner (2); blink_winner (2);
...@@ -1093,12 +1104,14 @@ private class FourInARow : Gtk.Application ...@@ -1093,12 +1104,14 @@ private class FourInARow : Gtk.Application
} }
} }
// WARNING PlayerID and Tile should be synced
private enum PlayerID { private enum PlayerID {
PLAYER1 = 0, PLAYER1 = 0,
PLAYER2, PLAYER2,
NOBODY; NOBODY;
} }
// WARNING PlayerID and Tile should be synced
private enum Tile { private enum Tile {
PLAYER1 = 0, PLAYER1 = 0,
PLAYER2, PLAYER2,
......
...@@ -273,7 +273,7 @@ private class GameBoardView : Gtk.DrawingArea ...@@ -273,7 +273,7 @@ private class GameBoardView : Gtk.DrawingArea
* *
* Which column was clicked on * Which column was clicked on
*/ */
internal signal bool column_clicked (int column); internal signal bool column_clicked (uint8 column);
protected override bool button_press_event (Gdk.EventButton e) protected override bool button_press_event (Gdk.EventButton e)
{ {
...@@ -284,18 +284,22 @@ private class GameBoardView : Gtk.DrawingArea ...@@ -284,18 +284,22 @@ private class GameBoardView : Gtk.DrawingArea
assert_not_reached (); assert_not_reached ();
((!) window).get_device_position (e.device, out x, out y, null); ((!) window).get_device_position (e.device, out x, out y, null);
int col; uint8 col;
if (get_column (x, y, out col)) if (get_column (x, y, out col))
return column_clicked (col); return column_clicked (col);
else else
return false; return false;
} }
private inline bool get_column (int x, int y, out int col) private inline bool get_column (int x, int y, out uint8 col)
{ {
col = (x - board_x) / tile_size; int _col = (x - board_x) / tile_size;
if (x < board_x || y < board_y || col < 0 || col > 6) if (x < board_x || y < board_y || _col < 0 || _col > 6)
{
col = 0;
return false; return false;
}
col = (uint8) _col;
int row = (y - board_y) / tile_size; int row = (y - board_y) / tile_size;
if (row < 0 || row > 6) if (row < 0 || row > 6)
......
...@@ -18,45 +18,50 @@ ...@@ -18,45 +18,50 @@
with GNOME Four-in-a-row. If not, see <https://www.gnu.org/licenses/>. with GNOME Four-in-a-row. If not, see <https://www.gnu.org/licenses/>.
*/ */
private class Board : Object { private class Board : Object
private static Tile[,] gboard; {
private const int BOARD_SIZE = 7; private static Tile [,] gboard;
private const uint8 BOARD_SIZE = 7;
internal Board() {
gboard = new Tile[BOARD_SIZE, BOARD_SIZE]; internal Board ()
{
gboard = new Tile [BOARD_SIZE, BOARD_SIZE];
} }
internal new void @set(int x, int y, Tile tile) { internal new void @set (uint8 x, uint8 y, Tile tile)
gboard[x, y] = tile; {
gboard [x, y] = tile;
} }
internal new Tile @get(int x, int y) { internal new Tile @get (uint8 x, uint8 y)
return gboard[x, y]; {
return gboard [x, y];
} }
internal void clear() { internal void clear ()
for (int r = 0; r < BOARD_SIZE; r++) { {
for (int c = 0; c < BOARD_SIZE; c++) { for (uint8 row = 0; row < BOARD_SIZE; row++)
gboard[r, c] = Tile.CLEAR; for (uint8 col = 0; col < BOARD_SIZE; col++)
} gboard [row, col] = Tile.CLEAR;
}
} }
internal int first_empty_row(int c) { internal uint8 first_empty_row (uint8 col)
int r = 1; {
uint8 row = 1;
while (r < BOARD_SIZE && gboard[r, c] == Tile.CLEAR) while (row < BOARD_SIZE && gboard [row, col] == Tile.CLEAR)
r++; row++;
return r - 1; return row - 1;
} }
/*\ /*\
* * check if there is a line passing by a given point * * check if there is a line passing by a given point
\*/ \*/
internal bool is_line_at(Tile tile, int row, int col, out int [,] lines = null) { internal bool is_line_at (Tile tile, uint8 row, uint8 col, out uint8 [,] lines = null)
{
uint8 n_lines = 0; uint8 n_lines = 0;
int [,] lines_tmp = new int [4, 4]; uint8 [,] lines_tmp = new uint8 [4, 4];
if (is_hline_at (tile, row, col, out lines_tmp [0, 0], if (is_hline_at (tile, row, col, out lines_tmp [0, 0],
out lines_tmp [0, 1], out lines_tmp [0, 1],
...@@ -79,84 +84,86 @@ private class Board : Object { ...@@ -79,84 +84,86 @@ private class Board : Object {
out lines_tmp [n_lines, 3])) out lines_tmp [n_lines, 3]))
n_lines++; n_lines++;
lines = new int [n_lines, 4]; lines = new uint8 [n_lines, 4];
for (int x = 0; x < n_lines; x++) for (uint8 x = 0; x < n_lines; x++)
for (int y = 0; y < 4; y++) for (uint8 y = 0; y < 4; y++)
lines [x, y] = lines_tmp [x, y]; lines [x, y] = lines_tmp [x, y];
return n_lines != 0; return n_lines != 0;
} }
private inline bool is_hline_at(Tile p, int r, int c, private inline bool is_hline_at (Tile tile, uint8 row, uint8 col,
out int r1, out int c1, out uint8 row_1, out uint8 col_1,
out int r2, out int c2) { out uint8 row_2, out uint8 col_2)
r1 = r; {
r2 = r; row_1 = row;
c1 = c;