#!/bin/bash # # sliders : http://wingtk.sourceforge.net/ishan/sliders.html # http://www.hc11.demon.nl/15puzzle/15puzzen.htm # # Created by alain COURIVAUD, august 2008 # #----------------------------------------------------------- # Pipe filename must be unique for your application PIPE="/tmp/gtk.bash.\$$" # Find GTK-server configfile first if [[ -f gtk-server.cfg ]]; then CFG=gtk-server.cfg elif [[ -f /etc/gtk-server.cfg ]]; then CFG=/etc/gtk-server.cfg elif [[ -f /usr/local/etc/gtk-server.cfg ]]; then CFG=/usr/local/etc/gtk-server.cfg else echo "No GTK-server configfile found! Please install GTK-server..." exit 1 fi # Now create global functionnames from GTK API if [[ ! -f $HOME/.gtk4bash || $CFG -nt $HOME/.gtk4bash ]]; then echo "#!/bin/bash" > $HOME/.gtk4bash echo "gtk-server -fifo=$PIPE &" >> $HOME/.gtk4bash echo "while [ ! -p $PIPE ]; do continue; done" >> $HOME/.gtk4bash while read LINE do if [[ $LINE = *FUNCTION_NAME* ]]; then LINE=${LINE#*= } printf "\nfunction ${LINE%%,*}\n" >> $HOME/.gtk4bash printf "{\n/bin/echo ${LINE%%,*} \$@ > $PIPE" >> $HOME/.gtk4bash printf "\nread GTK < $PIPE\n}\n" >> $HOME/.gtk4bash fi done < $CFG fi # Declare global variables declare GTK NULL="NULL" unset CFG PIPE LINE # Include the generated file to use embedded GTK functions . ${HOME}/.gtk4bash #---------------------------------------------------------- Global inits # GTK-server must go after an error in the script trap 'echo "gtk_server_exit" > $PIPE' ERR # Define SIGUSR1 in GTK-server configfile to catch exit of GTK-server trap 'exit' SIGUSR1 # Assignment function function define() { $2 $3 $4 $5 $6 $7 $8 $9; eval $1="$GTK"; } # Save my directory MYDIR=${0%/*} gtk_init $NULL $NULL # Window define WIN gtk_window_new 0 #gtk_window_set_default_size $WIN 300 300 #why can't i use it for the WIN size ? gtk_widget_set_size_request $WIN 200 200 gtk_window_set_title $WIN "TAQUIN" gtk_window_set_position $WIN 1 gtk_window_set_resizable $WIN 0 #Vbox define VBOX gtk_vbox_new 0 0 gtk_container_add $WIN $VBOX gtk_widget_show $VBOX # Accec_group define GRP gtk_accel_group_new gtk_window_add_accel_group $WIN $GRP # Menubar define BAR gtk_menu_bar_new define FILE gtk_menu_item_new_with_mnemonic "_File" define HELP gtk_menu_item_new_with_mnemonic "_Help" define FILEMENU gtk_menu_new define HELPMENU gtk_menu_new gtk_menu_item_set_submenu $FILE $FILEMENU gtk_menu_item_set_submenu $HELP $HELPMENU # File menu content define NEW gtk_image_menu_item_new_from_stock "gtk-new" $GRP define QUIT gtk_image_menu_item_new_from_stock "gtk-quit" $GRP # Help menu content define ABOUT gtk_image_menu_item_new_from_stock "gtk-about" $GRP #define ABOUT gtk_menu_item_new_with_mnemonic "_About" $GRP #FUNCTION_NAME = gtk_widget_add_accelerator, NONE, NONE, 6, WIDGET, STRING, WIDGET, LONG, LONG, LONG gtk_widget_add_accelerator $ABOUT "activate" $GRP 97 1 1 #separator define SEPARATOR_FILE gtk_separator_menu_item_new gtk_widget_set_sensitive $SEPARATOR_FILE 0 gtk_box_pack_start $VBOX $BAR 0 0 1 gtk_container_add $BAR $FILE gtk_container_add $FILEMENU $NEW gtk_container_add $FILEMENU $SEPARATOR_FILE gtk_container_add $FILEMENU $QUIT gtk_container_add $BAR $HELP gtk_container_add $HELPMENU $ABOUT gtk_server_connect $QUIT "activate" "al1_gtk_quit" gtk_server_connect $NEW "activate" "al1_gtk_new" gtk_server_connect $ABOUT "activate" "al1_gtk_about" #alignement define ALIGNEMENT gtk_alignment_new 0.5 0.5 1 1 gtk_box_pack_start $VBOX $ALIGNEMENT 1 1 0 gtk_alignment_set_padding $ALIGNEMENT 20 20 40 40 #table define TAB gtk_table_new 4 4 1 #gtk_box_pack_start $VBOX $TAB 1 1 1 gtk_container_add $ALIGNEMENT $TAB gtk_widget_show $TAB #buttons for x in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 do temp=$x define BTN[$x] gtk_button_new_with_label "$((x + 1))" gtk_object_set_data ${BTN[$x]} "current_pos" "$x" unset temp done c=0 for x in 0 1 2 3 do for y in 0 1 2 3 do if ! [[ ($x -eq 3 && $y -eq 3) ]] then gtk_table_attach_defaults $TAB ${BTN[$c]} $y $((y + 1)) $x $((x + 1)) gtk_widget_show ${BTN[$c]} ((c = c + 1)) fi done done # Status bar define STATUSBAR gtk_statusbar_new gtk_statusbar_set_has_resize_grip $STATUSBAR 0 gtk_box_pack_start $VBOX $STATUSBAR 0 0 1 gtk_statusbar_push $STATUSBAR 0 "'Welcome to TAQUIN...'" gtk_widget_show $STATUSBAR # Show all widgets gtk_widget_show_all $WIN #---------------------------------------------------------- Init variables VACANT_POS=15 MOVE_NO=1 #---------------------------------------------------------- Functions function has_player_won { gagne="OUI" for x in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 do # set -x echo "x : " $x define POS gtk_object_get_data ${BTN[$x]} "current_pos" echo "pos : " $POS if ! [[ $x -eq $POS ]] then gagne="NON" fi set +x done } function is_legal { # set -x ((vacant_x_pos = VACANT_POS % 4)) ((vacant_y_pos = VACANT_POS / 4)) ((current_x_pos = CURRENT_POS % 4)) ((current_y_pos = CURRENT_POS / 4)) ((diffa = vacant_x_pos - current_x_pos)) ((diffb = vacant_y_pos - current_y_pos)) # val abs d'un entier : x=${x#-} a=${diffa#-} b=${diffb#-} if [[ ( (($a -eq 1 && $b -eq 0) || ($a -eq 0 && $b -eq 1)) && !($a -eq 1 && $b -eq 1) ) ]] then libre="OUI" gtk_statusbar_push $STATUSBAR 0 "'Move N° : $MOVE_NO'" else libre="NON" gtk_statusbar_push $STATUSBAR 0 "'Illegal move !'" fi set +x } function move { define CURRENT_POS gtk_object_get_data ${BTN[$1]} "current_pos" is_legal if [[ $libre = "OUI" ]] then ((x_pos = VACANT_POS % 4)) ((y_pos = VACANT_POS / 4)) gtk_container_remove $TAB ${BTN[$1]} define BTN[$1] gtk_button_new_with_label "$(($1 + 1))" gtk_table_attach_defaults $TAB ${BTN[$1]} $x_pos $((x_pos + 1)) $y_pos $((y_pos + 1)) gtk_widget_show ${BTN[$1]} gtk_object_set_data ${BTN[$1]} "current_pos" "$VACANT_POS" VACANT_POS=$CURRENT_POS ((MOVE_NO = MOVE_NO + 1)) has_player_won if [[ $gagne = "OUI" ]] then gtk_widget_hide $TAB define IMAGE gtk_image_new gtk_image_set_from_file $IMAGE "coupe1.jpeg" gtk_object_ref $TAB gtk_container_remove $ALIGNEMENT $TAB gtk_container_add $ALIGNEMENT $IMAGE gtk_widget_show $IMAGE gtk_statusbar_push $STATUSBAR 0 "'Win ! in $((MOVE_NO - 1)) move(s)'" fi fi } function swap_buttons { define P_POS gtk_object_get_data ${BTN[$1]} "current_pos" define Q_POS gtk_object_get_data ${BTN[$2]} "current_pos" ((p_x_pos = $P_POS % 4)) ((p_y_pos = $P_POS / 4)) ((q_x_pos = $Q_POS % 4)) ((q_y_pos = $Q_POS / 4)) gtk_object_ref ${BTN[$1]} gtk_object_ref ${BTN[$2]} gtk_container_remove $TAB ${BTN[$1]} gtk_container_remove $TAB ${BTN[$2]} gtk_table_attach_defaults $TAB ${BTN[$1]} $q_x_pos $((q_x_pos + 1)) $q_y_pos $((q_y_pos + 1)) gtk_table_attach_defaults $TAB ${BTN[$2]} $p_x_pos $((p_x_pos + 1)) $p_y_pos $((p_y_pos + 1)) gtk_object_set_data ${BTN[$1]} "current_pos" "$Q_POS" gtk_object_set_data ${BTN[$2]} "current_pos" "$P_POS" } function on_new_activate { MOVE_NO=1 if [[ $IMAGE ]] then gtk_object_ref $IMAGE gtk_container_remove $ALIGNEMENT $IMAGE gtk_container_add $ALIGNEMENT $TAB gtk_widget_show $TAB #gtk_container_remove $VBOX $STATUSBAR #gtk_box_pack_start $VBOX $TAB 1 1 1 #gtk_widget_show $TAB #define STATUSBAR gtk_statusbar_new #gtk_box_pack_start $VBOX $STATUSBAR 1 1 1 #gtk_statusbar_push $STATUSBAR 0 "'Welcome to TAQUIN...'" #gtk_widget_show $STATUSBAR fi for x in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 do rand=$(($RANDOM%15)) if ! [[ $x -eq $rand ]] then swap_buttons $x $rand fi done } function on_about_activate { gtk_server_version define DIALOG gtk_message_dialog_new $WIN 0 0 2 "'\t\t TAQUIN \r\rBASH ${BASH_VERSION#* } with GTK-server $GTK.\r\r\tVisit http://www.gtk-server.org/ for more info!'" gtk_window_set_title $DIALOG "'About this program'" gtk_widget_show $DIALOG gtk_dialog_run $DIALOG gtk_widget_destroy $DIALOG } #---------------------------------------------------------- Mainloop until [[ $EVENT = $WIN || $EVENT = "al1_gtk_quit" ]] do define EVENT gtk_server_callback "wait" case $EVENT in "al1_gtk_new") on_new_activate;; "al1_gtk_about") on_about_activate;; ${BTN[0]}) move 0;; ${BTN[1]}) move 1;; ${BTN[2]}) move 2;; ${BTN[3]}) move 3;; ${BTN[4]}) move 4;; ${BTN[5]}) move 5;; ${BTN[6]}) move 6;; ${BTN[7]}) move 7;; ${BTN[8]}) move 8;; ${BTN[9]}) move 9;; ${BTN[10]}) move 10;; ${BTN[11]}) move 11;; ${BTN[12]}) move 12;; ${BTN[13]}) move 13;; ${BTN[14]}) move 14;; ${BTN[15]}) move 15;; esac done # Exit GTK gtk_server_exit