#!/bin/bash
map=( {01..15} )
gx=0 gy=0
total_step=0
input(){
echo -ne "\033[?25l"
local aKey=(0 0 0 0)
local cESC=`echo -ne "\033"`
local index
while ! check
do
read -s -n 1 key
aKey=( "${aKey[@]:1}" "$key")
if [[ $key${aKey[2]} == $cESC$cESC ]] ; then break
elif [ "${aKey[@]:1:2}$key" = "${cESC} [A" -a $gy != 3 ] ; then # up
(( ++gy ))
swap $(( gx + gy*4 )) $(( gx + gy*4 - 4 ))
elif [ "${aKey[@]:1:2}$key" = "${cESC} [B" -a $gy != 0 ] ; then # down
(( --gy ))
swap $(( gx + gy*4 )) $(( gx + gy*4 + 4 ))
elif [ "${aKey[@]:1:2}$key" = "${cESC} [C" -a $gx != 0 ] ; then # right
(( --gx ))
swap $(( gx + gy*4 )) $(( gx + gy*4 + 1 ))
elif [ "${aKey[@]:1:2}$key" = "${cESC} [D" -a $gx != 3 ] ; then # left
(( ++gx ))
swap $(( gx + gy*4 )) $(( gx + gy*4 - 1 ))
else continue
fi
draw
(( total_step++ ))
done
echo -ne "\033[?25h"
}
draw(){
tput cup 0 0
printf "%2s %2s %2s %2s\n%2s %2s %2s %2s\n%2s %2s %2s %2s\n%2s %2s %2s %2s\n" "${map[@]}"
}
check(){
local i j
for (( i=1,j=2; j<16; i++,j++ ))
do
(( 1${map[$i]} > 1${map[$j]} )) && return 1
done
return 0
}
swap(){
local tmp=${map[$1]}
map[$1]=${map[$2]}
map[$2]=$tmp
}
random(){
map=( ' ' $(printf "%s\n" "${map[@]}" | sort -R))
}
clear
random
draw
input
echo finish. Total step is $total_step
IyEvYmluL2Jhc2gKbWFwPSggezAxLi4xNX0gKQpneD0wIGd5PTAKdG90YWxfc3RlcD0wCmlucHV0KCl7CiAgZWNobyAtbmUgIlwwMzNbPzI1bCIKICBsb2NhbCBhS2V5PSgwIDAgMCAwKQogIGxvY2FsIGNFU0M9YGVjaG8gLW5lICJcMDMzImAKICBsb2NhbCBpbmRleAogIHdoaWxlICEgY2hlY2sKICBkbwogICAgcmVhZCAtcyAtbiAxIGtleQogICAgYUtleT0oICIke2FLZXlbQF06MX0iICIka2V5IikKICAgIGlmIFtbICRrZXkke2FLZXlbMl19ID09ICRjRVNDJGNFU0MgXV0gOyB0aGVuIGJyZWFrCiAgICBlbGlmIFsgIiR7YUtleVtAXToxOjJ9JGtleSIgPSAiJHtjRVNDfSBbQSIgLWEgJGd5ICE9IDMgXSA7IHRoZW4gIyB1cAogICAgICAoKCArK2d5ICkpICAgICAgICAgCiAgICAgIHN3YXAgJCgoIGd4ICsgZ3kqNCApKSAkKCggZ3ggKyBneSo0IC0gNCApKQogICAgZWxpZiBbICIke2FLZXlbQF06MToyfSRrZXkiID0gIiR7Y0VTQ30gW0IiIC1hICRneSAhPSAwIF0gOyB0aGVuICMgZG93bgogICAgICAoKCAtLWd5ICkpCiAgICAgIHN3YXAgJCgoIGd4ICsgZ3kqNCApKSAkKCggZ3ggKyBneSo0ICsgNCApKQogICAgZWxpZiBbICIke2FLZXlbQF06MToyfSRrZXkiID0gIiR7Y0VTQ30gW0MiIC1hICRneCAhPSAwIF0gOyB0aGVuICMgcmlnaHQKICAgICAgKCggLS1neCApKQogICAgICBzd2FwICQoKCBneCArIGd5KjQgKSkgJCgoIGd4ICsgZ3kqNCArIDEgKSkKICAgIGVsaWYgWyAiJHthS2V5W0BdOjE6Mn0ka2V5IiA9ICIke2NFU0N9IFtEIiAtYSAkZ3ggIT0gMyBdIDsgdGhlbiAjIGxlZnQKICAgICAgKCggKytneCApKQogICAgICBzd2FwICQoKCBneCArIGd5KjQgKSkgJCgoIGd4ICsgZ3kqNCAtIDEgKSkKICAgIGVsc2UgY29udGludWUKICAgIGZpCiAgICBkcmF3CiAgICAoKCB0b3RhbF9zdGVwKysgKSkKICBkb25lCiAgZWNobyAtbmUgIlwwMzNbPzI1aCIKfQpkcmF3KCl7CiAgIHRwdXQgY3VwIDAgMAogICBwcmludGYgIiUycyAlMnMgJTJzICUyc1xuJTJzICUycyAlMnMgJTJzXG4lMnMgJTJzICUycyAlMnNcbiUycyAlMnMgJTJzICUyc1xuIiAiJHttYXBbQF19Igp9CmNoZWNrKCl7CiAgbG9jYWwgaSBqCiAgZm9yICgoIGk9MSxqPTI7IGo8MTY7IGkrKyxqKysgKSkKICBkbwogICAgICgoIDEke21hcFskaV19ID4gMSR7bWFwWyRqXX0gKSkgJiYgcmV0dXJuIDEKICBkb25lCiAgcmV0dXJuIDAKfQpzd2FwKCl7CiAgIGxvY2FsIHRtcD0ke21hcFskMV19CiAgIG1hcFskMV09JHttYXBbJDJdfQogICBtYXBbJDJdPSR0bXAKfQpyYW5kb20oKXsKICAgbWFwPSggJyAnICQocHJpbnRmICIlc1xuIiAiJHttYXBbQF19IiB8IHNvcnQgLVIpKQp9CmNsZWFyCnJhbmRvbQpkcmF3CmlucHV0CmVjaG8gZmluaXNoLiBUb3RhbCBzdGVwIGlzICR0b3RhbF9zdGVwCgo=