Bash MineSweeper from Heise.de: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
(Die Seite wurde neu angelegt: „<syntaxhighlight lang="bash" line='none'> heise </syntaxhighlight>“) |
|||
Zeile 1: | Zeile 1: | ||
<syntaxhighlight lang="bash" line='none'> | <syntaxhighlight lang="bash" line='none'> | ||
− | + | #!/bin/bash | |
+ | |||
+ | declare -a mine | ||
+ | if [ -z "$1" ] ; then w=10 ; else w=${1} ; shift ;fi | ||
+ | if [ -z "$1" ] ; then h=10 ; else h=${1} ; shift ;fi | ||
+ | if [ -z "$1" ] ; then n=10 ; else n=${1} ; shift ;fi | ||
+ | |||
+ | function getfield() { | ||
+ | if [ "${1}" -lt 0 \ | ||
+ | -o "${1}" -ge "${w}" \ | ||
+ | -o "${2}" -lt 0 \ | ||
+ | -o "${2}" -ge "${h}" \ | ||
+ | ]; then | ||
+ | echo "-" | ||
+ | else | ||
+ | echo "${mine[$((${2}*${w}+${1}))]}" | ||
+ | fi | ||
+ | } | ||
+ | |||
+ | function minecount() { | ||
+ | local x y e="" | ||
+ | local IFS=$'\n' | ||
+ | for ((x=${1}-1; ${x}<=${1}+1; x++)) do | ||
+ | for ((y=${2}-1; ${y}<=${2}+1; y++)) do | ||
+ | e+=$(getfield ${x} ${y})$'\n' | ||
+ | done | ||
+ | done | ||
+ | grep -c "*" <<< ${e} | ||
+ | } | ||
+ | |||
+ | function fieldcount() { | ||
+ | local IFS=$'\n' | ||
+ | tr ' ' '\012' <<< ${mine[*]} | grep -c "\\${1}" | ||
+ | } | ||
+ | |||
+ | function showmatrix () { | ||
+ | local i x y e | ||
+ | # Drucke X-Achse | ||
+ | #b=$(seq -s " " 1 $(((${w}-1)/10))); echo -n -e "\e[42m ${b}" | ||
+ | echo -e -n "\e[42m " | ||
+ | for i in $(seq 0 $((${w}-1))) ; do | ||
+ | echo -n $(($i/10)) | ||
+ | echo -n "|" | ||
+ | done | ||
+ | echo | ||
+ | echo -n " " | ||
+ | for i in $(seq 0 $((${w}-1))) ; do | ||
+ | if [ $i -ge 10 ] ; then | ||
+ | echo -n $(($i%10)) | ||
+ | echo -n "|" | ||
+ | else | ||
+ | echo -n $i | ||
+ | echo -n "|" | ||
+ | fi | ||
+ | done | ||
+ | echo -e "\e[49m" # grün aus | ||
+ | for ((y=0; ${y}<${h}; y++)) do | ||
+ | printf "\e[42m%02d\e[49m " ${y} | ||
+ | for ((x=0; ${x}<${w}; x++)) do | ||
+ | e="${mine[$((${y}*${w}+${x}))]}" | ||
+ | echo -e -n "${e/${1}/${2}}" | ||
+ | echo -n "|" | ||
+ | done | ||
+ | echo | ||
+ | done | ||
+ | } | ||
+ | |||
+ | function searchmine() { | ||
+ | local x y m | ||
+ | case "${mine[$((${2}*${w}+${1}))]}" in | ||
+ | '.') | ||
+ | m=$(minecount ${1} ${2}) | ||
+ | mine[$((${2}*${w}+${1}))]=${m} | ||
+ | if [ ${m} -eq 0 ] ; then | ||
+ | for ((x=${1}-1; ${x}<=${1}+1; x++)) do | ||
+ | for ((y=${2}-1; ${y}<=${2}+1; y++)) do | ||
+ | if [ "${mine[$((${y}*${w}+${x}))]}" == "." ] && [ ${x} -ne ${1} -o ${y} -ne ${2} ] && \ | ||
+ | [ ${x} -ge 0 -a ${x} -lt ${w} -a ${y} -ge 0 -a ${y} -lt ${h} ]; then | ||
+ | searchmine ${x} ${y} | ||
+ | fi | ||
+ | done | ||
+ | done | ||
+ | fi | ||
+ | ;; | ||
+ | '*') | ||
+ | clear | ||
+ | echo "Boom!" | ||
+ | mine[((${2}*${w}+${1}))]="\e[41mX\e[49m" | ||
+ | showmatrix | ||
+ | exit | ||
+ | esac | ||
+ | |||
+ | } | ||
+ | |||
+ | function searchall() { | ||
+ | local i | ||
+ | for ((i=0; | ||
+ | ${i}<${w}*${h}; | ||
+ | i++)) do | ||
+ | if [[ "${mine[i]}" =~ [*.] ]]; then | ||
+ | searchmine $(((${i})%${w})) $(((${i}-(${i})%${w})/${h})) | ||
+ | fi | ||
+ | done | ||
+ | } | ||
+ | |||
+ | for ((i=0; | ||
+ | ${i}<${w}*${h}; | ||
+ | i++)) do | ||
+ | mine[${i}]="." | ||
+ | done | ||
+ | |||
+ | for i in $(shuf -i 0-$((${w}*${h}-1)) -n ${n}); do | ||
+ | mine[$i]="*" | ||
+ | done | ||
+ | |||
+ | while true; do | ||
+ | clear | ||
+ | if [ $(fieldcount '.') == 0 ]; then | ||
+ | echo "Geschafft!" | ||
+ | showmatrix | ||
+ | break | ||
+ | else | ||
+ | echo "Noch $(fieldcount '.') Feld(er) und $(($(fieldcount '*')-$(fieldcount '\\e'))) Minen" | ||
+ | fi | ||
+ | showmatrix "\*" "." | ||
+ | echo "Enter x y or" | ||
+ | echo "Enter s for search all unmarked Fields" | ||
+ | echo "Enter x y m (m for mark/unmark a mine)" | ||
+ | echo -n "x y?" | ||
+ | read x y z | ||
+ | |||
+ | if [ "${z}" == "m" ] ; then # Markieren einer Mine | ||
+ | if grep -q '\\e\[41' <<<${mine[$((${y}*${w}+${x}))]} ; then | ||
+ | mine[$((${y}*${w}+${x}))]=${mine[$((${y}*${w}+${x}))]:6:1} | ||
+ | elif [[ "${mine[$((${y}*${w}+${x}))]}" =~ [*.] ]] ; then | ||
+ | mine[$((${y}*${w}+${x}))]="\e[41m${mine[$((${y}*${w}+${x}))]}\e[49m" | ||
+ | fi | ||
+ | elif [ "${x}" == "s" ] ; then # open all unmarked fields | ||
+ | searchall | ||
+ | else | ||
+ | if [ "${x}" -ge 0 \ | ||
+ | -a "${y}" -ge 0 \ | ||
+ | -a "${y}" -lt "${h}" \ | ||
+ | -a "${x}" -lt "${w}" \ | ||
+ | ]; then | ||
+ | searchmine ${x} ${y} | ||
+ | fi | ||
+ | fi | ||
+ | done | ||
</syntaxhighlight> | </syntaxhighlight> |
Aktuelle Version vom 6. Januar 2021, 13:20 Uhr
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