char salt[256];
} Puzzle;
+/* The player data struct type - for the player app */
+typedef struct {
+ Puzzle puzzle;
+ char filename[65535];
+ bool is_loaded;
+ char char_ans[MAX_PUZZLE_SIZE][MAX_PUZZLE_SIZE];
+ int cur_row;
+ int cur_col;
+} MainPlayerData;
+
+
/* get a number from the user */
int get_num ()
{
/* freeze the grid - make editing impossible because it finalizes the
across and down words in the grid */
void freeze_puzzle (Puzzle *p)
-{
+{
int word_num = 1;
bool across_word_start, down_word_start;
for (int i = 0; i < p->grid_size; i ++)
across_word_start = false;
down_word_start = false;
/* if it is a blank cell - cover it with a block */
- if (p->chars[i][j] == ' ')
+ if (p->chars[i][j] == ' ' || p->chars[i][j] == '#')
p->chars[i][j] = '#';
/* it is not a blank cell - check all possibilities */
else
printf ("\u2550");
printf ("\u2557");
reset_color (); printf ("\n");
+ set_color (fg, bg, NORMAL);
printf ("\u2551");
set_color (fg, bg, BOLD);
printf ("%-*s", padding, title);
reset_color (); printf ("\n");
}
+/* reset the player data, from the new file */
+void reset_player_data (MainPlayerData *app_data, const char *filename)
+{
+ app_data->puzzle = load_puzzle (filename);
+
+ app_data->is_loaded = app_data->puzzle.grid_frozen;
+ app_data->cur_col = -1;
+ app_data->cur_row = -1;
+ strcpy (app_data->filename, filename);
+ /* reset the answer keys */
+ for (int i = 0; i < app_data->puzzle.grid_size; i ++)
+ for (int j = 0; j < app_data->puzzle.grid_size; j ++)
+ app_data->char_ans[i][j] = ' ';
+
+}
+
+/* in the player app, move the current selection index left or right */
+void move_current_col (MainPlayerData *app_data, enum DIRECTION dir)
+{
+ int r = app_data->cur_row;
+ int c = app_data->cur_col;
+ if (dir == DIR_FORWARD)
+ {
+ c ++;
+ while (c < app_data->puzzle.grid_size)
+ {
+ if (app_data->puzzle.chars[r][c] == '#')
+ c ++;
+ else
+ break;
+ }
+ if (c < app_data->puzzle.grid_size)
+ app_data->cur_col = c;
+ }
+ else
+ {
+ c --;
+ while (c >= 0)
+ {
+ if (app_data->puzzle.chars[r][c] == '#')
+ c --;
+ else
+ break;
+ }
+ if (c >= 0)
+ app_data->cur_col = c;
+ }
+}
+
+/* in the player app move the current selection index up or down */
+void move_current_row (MainPlayerData *app_data, enum DIRECTION dir)
+{
+ int r = app_data->cur_row;
+ int c = app_data->cur_col;
+ if (dir == DIR_FORWARD)
+ {
+ r ++;
+ while (r < app_data->puzzle.grid_size)
+ {
+ if (app_data->puzzle.chars[r][c] == '#')
+ r ++;
+ else
+ break;
+ }
+ if (r < app_data->puzzle.grid_size)
+ app_data->cur_row = r;
+ }
+ else
+ {
+ r --;
+ while (r >= 0)
+ {
+ if (app_data->puzzle.chars[r][c] == '#')
+ r --;
+ else
+ break;
+ }
+ if (r >= 0)
+ app_data->cur_row = r;
+ }
+}
+
#endif
GtkListStore *across_store;
GtkListStore *down_store;
-struct MainAppData {
- Puzzle puzzle;
- char filename[65535];
- bool is_loaded;
- int cur_row;
- int cur_col;
-} app_data;
+MainPlayerData app_data;
-/* update the clue items */
+/* update the clue items store */
void update_clue_items ()
{
gtk_list_store_clear (across_store);
}
}
-/* move the current selection index left or right */
-void move_current_col (enum DIRECTION dir)
+/* slot for handling mouse button event for puzzle drawing area */
+gboolean on_puzzle_area_button_press_event (GtkWidget *widget,
+ GdkEventButton *event, gpointer data)
{
- int r = app_data.cur_row;
- int c = app_data.cur_col;
- if (dir == DIR_FORWARD)
+ if (event->type == GDK_BUTTON_PRESS && event->button == 1)
{
- c ++;
- while (c < app_data.puzzle.grid_size)
- {
- if (app_data.puzzle.chars[r][c] == '#')
- c ++;
- else
- break;
- }
- if (c < app_data.puzzle.grid_size)
- app_data.cur_col = c;
- }
- else
- {
- c --;
- while (c >= 0)
+ int col = (event->x - 5) / GRID_PIXELS;
+ int row = (event->y - 5) / GRID_PIXELS;
+
+ if (app_data.puzzle.chars[row][col] != '#')
{
- if (app_data.puzzle.chars[r][c] == '#')
- c --;
- else
- break;
+ if (row < app_data.puzzle.grid_size &&
+ col < app_data.puzzle.grid_size)
+ {
+ app_data.cur_row = row;
+ app_data.cur_col = col;
+ }
}
- if (c >= 0)
- app_data.cur_col = c;
}
-}
+
+ gtk_widget_queue_draw_area (widget, 0, 0,
+ app_data.puzzle.grid_size*GRID_PIXELS+10,
+ app_data.puzzle.grid_size*GRID_PIXELS+10);
+
-/* move the current selection index up or down */
-void move_current_row (enum DIRECTION dir)
-{
- int r = app_data.cur_row;
- int c = app_data.cur_col;
- if (dir == DIR_FORWARD)
- {
- r ++;
- while (r < app_data.puzzle.grid_size)
- {
- if (app_data.puzzle.chars[r][c] == '#')
- r ++;
- else
- break;
- }
- if (r < app_data.puzzle.grid_size)
- app_data.cur_row = r;
- }
- else
- {
- r --;
- while (r >= 0)
- {
- if (app_data.puzzle.chars[r][c] == '#')
- r --;
- else
- break;
- }
- if (r >= 0)
- app_data.cur_row = r;
- }
+
+ return FALSE;
}
-
/* slot for handling key press event for puzzle drawing area */
gboolean on_puzzle_area_key_press_event (GtkWidget *widget,
GdkEventKey *event, gpointer data)
{
switch (event->keyval)
{
- case GDK_KEY_Down : move_current_row (DIR_FORWARD);
- gtk_widget_queue_draw_area (widget,
- 0, 0,
- app_data.puzzle.grid_size*GRID_PIXELS+10,
- app_data.puzzle.grid_size*GRID_PIXELS+10);
+ case GDK_KEY_Down : move_current_row (&app_data, DIR_FORWARD);
+ break;
+ case GDK_KEY_Up : move_current_row (&app_data, DIR_BACK);
+ break;
+ case GDK_KEY_Right: move_current_col (&app_data, DIR_FORWARD);
+ break;
+ case GDK_KEY_Left : move_current_col (&app_data, DIR_BACK);
+ break;
+ case GDK_KEY_Delete:
+ case GDK_KEY_space:
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = ' ';
+ break;
+ case GDK_KEY_a :
+ case GDK_KEY_A :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'A';
+ break;
+ case GDK_KEY_b :
+ case GDK_KEY_B :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'B';
break;
- case GDK_KEY_Up : move_current_row (DIR_BACK);
- gtk_widget_queue_draw_area (widget,
- 0, 0,
- app_data.puzzle.grid_size*GRID_PIXELS+10,
- app_data.puzzle.grid_size*GRID_PIXELS+10);
+ case GDK_KEY_c :
+ case GDK_KEY_C :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'C';
break;
- case GDK_KEY_Right: move_current_col (DIR_FORWARD);
- gtk_widget_queue_draw_area (widget,
- 0, 0,
- app_data.puzzle.grid_size*GRID_PIXELS+10,
- app_data.puzzle.grid_size*GRID_PIXELS+10);
+ case GDK_KEY_d :
+ case GDK_KEY_D :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'D';
break;
- case GDK_KEY_Left : move_current_col (DIR_BACK);
- gtk_widget_queue_draw_area (widget,
- 0, 0,
- app_data.puzzle.grid_size*GRID_PIXELS+10,
- app_data.puzzle.grid_size*GRID_PIXELS+10);
+ case GDK_KEY_e :
+ case GDK_KEY_E :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'E';
+ break;
+ case GDK_KEY_f :
+ case GDK_KEY_F :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'F';
+ break;
+ case GDK_KEY_g :
+ case GDK_KEY_G :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'G';
+ break;
+ case GDK_KEY_h :
+ case GDK_KEY_H :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'H';
+ break;
+ case GDK_KEY_i :
+ case GDK_KEY_I :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'I';
+ break;
+ case GDK_KEY_j :
+ case GDK_KEY_J :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'J';
+ break;
+ case GDK_KEY_k :
+ case GDK_KEY_K :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'K';
+ break;
+ case GDK_KEY_l :
+ case GDK_KEY_L :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'L';
+ break;
+ case GDK_KEY_m :
+ case GDK_KEY_M :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'M';
+ break;
+ case GDK_KEY_n :
+ case GDK_KEY_N :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'N';
+ break;
+ case GDK_KEY_o :
+ case GDK_KEY_O :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'O';
+ break;
+ case GDK_KEY_p :
+ case GDK_KEY_P :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'P';
+ break;
+ case GDK_KEY_q :
+ case GDK_KEY_Q :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'Q';
+ break;
+ case GDK_KEY_r :
+ case GDK_KEY_R :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'R';
+ break;
+ case GDK_KEY_s :
+ case GDK_KEY_S :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'S';
+ break;
+ case GDK_KEY_t :
+ case GDK_KEY_T :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'T';
+ break;
+ case GDK_KEY_u :
+ case GDK_KEY_U :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'U';
+ break;
+ case GDK_KEY_v :
+ case GDK_KEY_V :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'V';
+ break;
+ case GDK_KEY_w :
+ case GDK_KEY_W :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'W';
+ break;
+ case GDK_KEY_x :
+ case GDK_KEY_X :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'X';
+ break;
+ case GDK_KEY_y :
+ case GDK_KEY_Y :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'Y';
+ break;
+ case GDK_KEY_z :
+ case GDK_KEY_Z :
+ app_data.char_ans[app_data.cur_row][app_data.cur_col] = 'Z';
+ break;
+ default : return FALSE;
+
}
}
+ gtk_widget_queue_draw_area (widget, 0, 0,
+ app_data.puzzle.grid_size*GRID_PIXELS+10,
+ app_data.puzzle.grid_size*GRID_PIXELS+10);
+
return FALSE;
}
cairo_show_text (cr, (const char*)cnum);
}
+ /* draw the answer if it is there */
+ gdk_cairo_set_source_rgba (cr, &colorfore);
+ cairo_select_font_face (cr, "sans serif",
+ CAIRO_FONT_SLANT_NORMAL,
+ CAIRO_FONT_WEIGHT_BOLD);
+
+ cairo_set_font_size (cr, 16);
+ cairo_move_to (cr, j*GRID_PIXELS+GRID_PIXELS/2,
+ i*GRID_PIXELS+GRID_PIXELS-10);
+ char ctxt[3];
+ sprintf (ctxt, "%c", app_data.char_ans[i][j]);
+ cairo_show_text (cr, (const char*) ctxt);
}
}
{
char *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(dialog));
- app_data.puzzle = load_puzzle (filename);
- app_data.is_loaded = true;
- strcpy (app_data.filename, filename);
+ MainPlayerData temp;
+ reset_player_data (&temp, filename);
+
/* if the grid is not frozen then the game cannot be played */
- if (app_data.puzzle.grid_frozen == false)
+ if (temp.is_loaded == false)
{
GtkWidget *errordlg ;
errordlg = gtk_message_dialog_new (GTK_WINDOW(window),
UNFROZEN_GRID_PLAYER);
gtk_dialog_run (GTK_DIALOG(errordlg));
gtk_widget_destroy (errordlg);
- app_data.is_loaded = false;
- app_data.cur_col = -1;
- app_data.cur_row = -1;
}
else
{
+ app_data = temp;
gtk_widget_queue_draw_area (GTK_WIDGET (area), 0, 0,
app_data.puzzle.grid_size*30+10,
app_data.puzzle.grid_size*30+10);
- update_clue_items ();
+
}
+ update_clue_items ();
g_free (filename);
}
if (window != NULL)
{
- gtk_window_set_default_icon (icon);
+ gtk_window_set_default_icon (icon);
+
+ GtkWidget *draw_area = GTK_WIDGET (
+ gtk_builder_get_object(builder, "puzzle_area"));
+
+ /* make drawing area respond to mouse event */
+ gtk_widget_set_events(draw_area,
+ gtk_widget_get_events(draw_area)
+ | GDK_BUTTON_PRESS_MASK);
gtk_builder_connect_signals (builder, NULL);
g_object_unref (builder);