Created
January 20, 2021 18:15
-
-
Save knuxify/1ff38f417f57ce7b409f37e31f2a818f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
trap exit INT | |
######################## | |
# # | |
# ARRAY-LESS TICTACTOE # | |
# # | |
######################## | |
# Beware: this thing is a monstrosity. | |
# Chances are, your eyes are going to burn as you read this, | |
# and you will ping me saying "What the hell is this crap?? | |
# I could make something way better in pure bash with full | |
# busybox compatibility in 1 minute!!!" | |
# Just trust me on this one, it doesn't wipe your computer. | |
tmpdir="/tmp/tictactoe" | |
[[ ! -e "$tmpdir" ]] && mkdir -p "$tmpdir" | |
clean_up() { | |
[[ "$tmpdir" ]] && rm -rf "$tmpdir/$password" | |
clear | |
exit 0 | |
} | |
checkwin(){ | |
for p in $player $oplayer; do | |
if [[ "$map" =~ $p\ $p\ $p\ [0-9]\ [0-9]\ [0-9]\ [0-9]\ [0-9]\ [0-9] ]]; then echo "$p" > "$gamedir/winner"; | |
elif [[ "$map" =~ [0-9]\ [0-9]\ [0-9]\ $p\ $p\ $p\ [0-9]\ [0-9]\ [0-9] ]]; then echo "$p" > "$gamedir/winner"; | |
elif [[ "$map" =~ [0-9]\ [0-9]\ [0-9]\ [0-9]\ [0-9]\ [0-9]\ $p\ $p\ $p ]]; then echo "$p" > "$gamedir/winner"; | |
elif [[ "$map" =~ $p\ [0-9]\ [0-9]\ $p\ [0-9]\ [0-9]\ $p\ [0-9]\ [0-9] ]]; then echo "$p" > "$gamedir/winner"; | |
elif [[ "$map" =~ [0-9]\ $p\ [0-9]\ [0-9]\ $p\ [0-9]\ [0-9]\ $p\ [0-9] ]]; then echo "$p" > "$gamedir/winner"; | |
elif [[ "$map" =~ [0-9]\ [0-9]\ $p\ [0-9]\ [0-9]\ $p\ [0-9]\ [0-9]\ $p ]]; then echo "$p" > "$gamedir/winner"; | |
elif [[ "$map" =~ $p\ [0-9]\ [0-9]\ [0-9]\ $p\ [0-9]\ [0-9]\ [0-9]\ $p ]]; then echo "$p" > "$gamedir/winner"; | |
elif [[ "$map" =~ [0-9]\ [0-9]\ $p\ [0-9]\ $p\ [0-9]\ $p\ [0-9]\ [0-9] ]]; then echo "$p" > "$gamedir/winner"; | |
fi | |
done | |
[[ "$map" != *"0"* ]] && [[ "$(cat $gamedir/winner)" == "0" ]] && echo "3" > "$gamedir/winner" | |
if [[ "$(cat $gamedir/winner)" != "0" ]]; then return 0; else return 1; fi | |
} | |
tttgame() { | |
case $player in | |
1) oplayer=2; mark="O";; | |
2) oplayer=1; mark="X";; | |
*) echo "Broken player number" && exit 1;; | |
esac | |
if [[ "$player" == "1" ]]; then | |
echo "Waiting for another player to join..." | |
until [[ "$(cat $gamedir/players)" == "2" ]]; do | |
sleep 0.5s | |
done | |
fi | |
map="$(cat $gamedir/map)" | |
until [[ "$(cat $gamedir/winner)" != "0" ]]; do | |
echo "Waiting for player $oplayer..." | |
until [[ "$(cat $gamedir/turn)" == "$player" ]]; do | |
checkwin && break="1" && break | |
[[ ! -e "$gamedir" ]] && clear && echo "The other player has disconnected." && exit 1 | |
sleep 0.5s | |
done | |
[[ break = "1" ]] && break | |
map="$(cat $gamedir/map)" | |
clear | |
unset blockid checkid block available availableraw | |
for mapblock in $map; do | |
# 0 - Empty space | |
# 1 - Player 1's space | |
# 2 - Player 2's space | |
let blockid++ | |
case $blockid in | |
1) echo " a b c"; printf "1 ";; | |
4) printf "2 ";; | |
7) printf "3 ";; | |
esac | |
printf "|" | |
case $mapblock in | |
0) printf " "; availableraw="$availableraw 1";; | |
1) printf "O"; availableraw="$availableraw 0";; | |
2) printf "X"; availableraw="$availableraw 0";; | |
esac | |
if [[ "$blockid" == "3" ]] || [[ "$blockid" == "6" ]] || [[ "$blockid" == "9" ]]; then | |
printf "|\n" | |
fi | |
done | |
availableraw=$(echo "$availableraw" | sed -e 's/^[ \t]*//') | |
for tocheck in $availableraw; do | |
let checkid++ | |
if [[ "$tocheck" != "0" ]]; then | |
case $checkid in | |
1) available="$available 1a";; | |
2) available="$available 1b";; | |
3) available="$available 1c";; | |
4) available="$available 2a";; | |
5) available="$available 2b";; | |
6) available="$available 2c";; | |
7) available="$available 3a";; | |
8) available="$available 3b";; | |
9) available="$available 3c";; | |
esac | |
fi | |
done | |
available=$(echo "$available" | sed -e 's/^[ \t]*//') | |
checkwin && break | |
echo "You are player $player. Your blocks are marked with $mark." | |
until [[ "$block" ]] && [[ "$available" == *"$block"* ]]; do | |
read -p "Where do you want to place your block? (Available options: $available) > " -re block | |
[[ ! -e "$gamedir" ]] && clear && echo "The other player has disconnected." && exit 1 | |
[[ "$available" != *"$block"* ]] && echo "Invalid block." | |
done | |
[[ ! -e "$gamedir" ]] && clear && echo "The other player has disconnected." && exit 1 | |
case $block in | |
1a) echo "$map" | awk -v r="$player" '{$1=r}1' > "$gamedir/map";; | |
1b) echo "$map" | awk -v r="$player" '{$2=r}1' > "$gamedir/map";; | |
1c) echo "$map" | awk -v r="$player" '{$3=r}1' > "$gamedir/map";; | |
2a) echo "$map" | awk -v r="$player" '{$4=r}1' > "$gamedir/map";; | |
2b) echo "$map" | awk -v r="$player" '{$5=r}1' > "$gamedir/map";; | |
2c) echo "$map" | awk -v r="$player" '{$6=r}1' > "$gamedir/map";; | |
3a) echo "$map" | awk -v r="$player" '{$7=r}1' > "$gamedir/map";; | |
3b) echo "$map" | awk -v r="$player" '{$8=r}1' > "$gamedir/map";; | |
3c) echo "$map" | awk -v r="$player" '{$9=r}1' > "$gamedir/map";; | |
*) echo "Wrong block"; exit 1;; | |
esac | |
clear | |
echo "$oplayer" > "$gamedir/turn" | |
checkwin && break | |
done | |
echo "The winner is:" | |
gamewinner="$(cat $gamedir/winner)" | |
sleep 1s | |
case $gamewinner in | |
1) echo "Player 1!";; | |
2) echo "Player 2!";; | |
3) echo "Nobody, it's a match!";; | |
esac | |
sleep 2s | |
clean_up &>/dev/null | |
exit 0 | |
} | |
clear | |
echo "=== TIC TAC TOE ===" | |
echo "Type in your password (a nonexistent password will start a new game):" | |
read -re password | |
[[ -z "$password" ]] && echo "Password empty!" && exit 1 | |
trap clean_up INT | |
if [[ -d "$tmpdir/$password" ]]; then | |
if [[ "$(cat $tmpdir/$password/players)" = "2" ]]; then | |
echo "Game $password full!" | |
exit 1 | |
else | |
echo -e "Joining $password..." | |
player=2 | |
gamedir="$tmpdir/$password" | |
echo "2" > "$gamedir/players" | |
tttgame | |
fi | |
else | |
echo -e "Creating new game." | |
mkdir "$tmpdir/$password" | |
player=1 | |
gamedir="$tmpdir/$password" | |
echo "1" > "$gamedir/turn" | |
echo "0 0 0 0 0 0 0 0 0" > "$gamedir/map" | |
echo "1" > "$gamedir/players" | |
echo "0" > "$gamedir/winner" | |
tttgame | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment