Bash MineSweeper from Heise.de

Aus AirSpaceWatch & More
Version vom 6. Januar 2021, 13:20 Uhr von Raz0rsedge (Diskussion | Beiträge)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen
  1 #!/bin/bash
  2 
  3 declare -a mine
  4 if [ -z "$1" ] ; then w=10 ; else w=${1} ; shift ;fi
  5 if [ -z "$1" ] ; then h=10 ; else h=${1} ; shift ;fi
  6 if [ -z "$1" ] ; then n=10 ; else n=${1} ; shift ;fi
  7 
  8 function getfield() {
  9   if [ "${1}" -lt 0 \
 10        -o "${1}" -ge "${w}" \
 11        -o "${2}" -lt 0 \
 12        -o "${2}" -ge "${h}" \
 13      ]; then
 14     echo "-"
 15   else
 16     echo "${mine[$((${2}*${w}+${1}))]}"
 17   fi
 18 }
 19 
 20 function minecount() {
 21   local x y e=""
 22   local IFS=$'\n'
 23   for ((x=${1}-1; ${x}<=${1}+1; x++)) do
 24     for ((y=${2}-1; ${y}<=${2}+1; y++)) do
 25       e+=$(getfield ${x} ${y})$'\n'
 26     done
 27   done
 28   grep -c "*" <<< ${e}
 29 }
 30 
 31 function fieldcount() {
 32   local IFS=$'\n'
 33   tr ' ' '\012' <<< ${mine[*]} | grep -c "\\${1}"
 34 }
 35 
 36 function showmatrix () {
 37   local i x y e
 38   # Drucke X-Achse
 39   #b=$(seq -s "         " 1 $(((${w}-1)/10))); echo -n -e "\e[42m             ${b}"
 40   echo -e -n "\e[42m   "
 41   for i in $(seq 0 $((${w}-1))) ; do
 42     echo -n $(($i/10))
 43     echo -n "|"
 44   done
 45   echo
 46   echo -n "   "
 47   for i in $(seq 0 $((${w}-1))) ; do
 48     if [ $i -ge 10 ] ; then
 49       echo -n $(($i%10))
 50       echo -n "|"
 51     else
 52       echo -n $i
 53       echo -n "|"
 54     fi
 55   done
 56   echo -e "\e[49m" # grün aus
 57   for ((y=0; ${y}<${h}; y++)) do
 58     printf "\e[42m%02d\e[49m " ${y} 
 59     for ((x=0; ${x}<${w}; x++)) do
 60       e="${mine[$((${y}*${w}+${x}))]}"
 61       echo -e -n "${e/${1}/${2}}"
 62       echo -n "|"
 63     done
 64     echo 
 65   done
 66 }
 67 
 68 function searchmine() {
 69   local x y m
 70   case "${mine[$((${2}*${w}+${1}))]}" in
 71     '.')
 72           m=$(minecount ${1} ${2})
 73           mine[$((${2}*${w}+${1}))]=${m}
 74           if [ ${m} -eq 0 ] ; then
 75           for ((x=${1}-1; ${x}<=${1}+1; x++)) do
 76             for ((y=${2}-1; ${y}<=${2}+1; y++)) do
 77               if [ "${mine[$((${y}*${w}+${x}))]}" == "." ] && [ ${x} -ne ${1} -o ${y} -ne ${2} ] && \
 78           [ ${x} -ge 0 -a ${x} -lt ${w} -a ${y} -ge 0 -a ${y} -lt ${h} ]; then
 79          searchmine ${x} ${y}
 80               fi
 81             done
 82           done
 83           fi
 84           ;;
 85     '*')
 86           clear
 87           echo "Boom!"
 88           mine[((${2}*${w}+${1}))]="\e[41mX\e[49m"
 89           showmatrix
 90           exit
 91   esac
 92  
 93 }
 94 
 95 function searchall() {
 96   local i
 97   for ((i=0;
 98       ${i}<${w}*${h};
 99       i++)) do
100       if [[ "${mine[i]}" =~ [*.] ]]; then
101         searchmine $(((${i})%${w})) $(((${i}-(${i})%${w})/${h}))
102       fi
103   done
104 }
105 
106 for ((i=0;
107       ${i}<${w}*${h};
108       i++)) do
109   mine[${i}]="."
110 done
111 
112 for i in $(shuf -i 0-$((${w}*${h}-1)) -n ${n}); do
113   mine[$i]="*"
114 done
115 
116 while true; do
117   clear
118   if [ $(fieldcount '.') == 0 ]; then
119     echo "Geschafft!"
120     showmatrix
121     break
122   else
123     echo "Noch $(fieldcount '.') Feld(er) und $(($(fieldcount '*')-$(fieldcount '\\e'))) Minen"
124   fi
125   showmatrix "\*" "."
126   echo "Enter x y or"
127   echo "Enter s for search all unmarked Fields"
128   echo "Enter x y m (m for mark/unmark a mine)"
129   echo -n "x y?"
130   read x y z
131 
132   if [ "${z}" == "m" ] ; then # Markieren einer Mine
133     if grep -q '\\e\[41' <<<${mine[$((${y}*${w}+${x}))]} ; then
134       mine[$((${y}*${w}+${x}))]=${mine[$((${y}*${w}+${x}))]:6:1}
135     elif [[ "${mine[$((${y}*${w}+${x}))]}" =~ [*.] ]] ; then
136       mine[$((${y}*${w}+${x}))]="\e[41m${mine[$((${y}*${w}+${x}))]}\e[49m"
137     fi
138   elif [ "${x}" == "s" ] ; then # open all unmarked fields
139     searchall
140   else
141     if [ "${x}" -ge 0 \
142          -a "${y}" -ge 0 \
143          -a "${y}" -lt "${h}" \
144          -a "${x}" -lt "${w}" \
145        ]; then
146    searchmine ${x} ${y} 
147     fi
148   fi
149 done