איקס עיגול ב Bash? מה השתגעתם?!
13/06/2016
פוסט זה כולל טיפ קצר על כלי עבודה בסביבת Linux. בשביל ללמוד יותר על עבודה בסביבת Linux ו Unix אני ממליץ לכם לבדוק את קורס Linux שיש לנו כאן באתר. הקורס כולל מעל 50 שיעורי וידאו והמון תרגול מעשי ומתאים גם למתחילים.
מערכים ב Bash תמיד בלבלו אותי ולאחרונה הגעתי במקרה לקרוא סקירה יחסית מקיפה עליהם. ובשביל שדברים לא יישארו ברמת התיאוריה חשבתי לנסות ליישם עם משחק איקס עיגול.
המגבלה היתה להשתמש בפונקציות builtins של bash בלבד. יצא פחות מ-70 שורות עם זיהוי מנצח או תיקו.
1. קוד המשחק
תחילה הקוד ולאחר מכן מספר הערות:
#!/bin/bash
board=("." "." "." "." "." "." "." "." ".")
player=X
WINNERS=(
'P..P..P..'
'.P..P..P.'
'..P..P..P'
'PPP......'
'...PPP...'
'......PPP'
'P...P...P'
'..P.P.P..'
)
function join { local IFS="$1"; shift; echo "$*"; }
check_winner() {
for pat in ${WINNERS[@]}
do
input=$(join "" ${board[@]})
re=${pat//P/$1}
if [[ $input =~ $re ]]
then
echo "$1 Won"
exit 0
fi
done
}
play() {
(( idx = ($1 * 3) + $2))
[[ ${board[$idx]} == "." ]] || return
board[$idx]=$player
check_winner $player
[[ $player == O ]] && player="X" || player="O"
}
print_board() {
for (( i=0; i<3; i++ ))
do
for (( j=0; j<3; j++ ))
do
(( idx = ($i * 3) + $j ))
echo -n ${board[$idx]} " "
done
echo
done
}
printf "%s > " $player
while read row col
do
play $row $col
print_board
[[ ${board[@]} == *.* ]] || break
printf "%s > " $player
done
echo "Tie..."
זיהוי מנצח נעשה עם ביטוי רגולרי במקום לולאות. קצת יותר עבודה למחשב וקצת פחות עבודה למתכנת (אבל אנחנו ב bash אז ממילא ביצועים זה לא הצד החזק כאן).
אין בדיקות קלט או טיפול בקלט לא תקין.
מוזמנים לשחק לייב באמצעות הפעלת הקובץ game.sh במכונה הבאה: