I am trying to make a little Tic Tac Toe. I tried to make the diagonal winning line, but it did not work. If I tried the normal winning line, it worked, but, only in the first 3 fields. I made a check_winner() function, where I detect all winning fields. I do not know, why it is not detecting the winning fields.
This is my Code:
#!/usr/bin/bash
player_1="X"
player_2="O"
turn=1
game_on=true
moves=( - - - - - - - - - )
welcome_message() {
clear
echo "========================"
echo "=== LETS PLAY A GAME ==="
echo "========================"
sleep 3
}
print_board () {
clear
echo " ${moves[0]} | ${moves[1]} | ${moves[2]} "
echo "-----------"
echo " ${moves[3]} | ${moves[4]} | ${moves[5]} "
echo "-----------"
echo " ${moves[6]} | ${moves[7]} | ${moves[8]} "
echo "============="
}
player_pick(){
if [ $(($turn % 2)) == 0 ]
then
echo "Player 1 pick a square: "
play=$player_2
else
play=$player_1
echo "Player 2 pick a sqaure: "
fi
read square
space=${moves[(square -1)]}
if [[ ${moves[(square-1)]} == "-" ]] && [[ $square = [0-9] ]] || [[ $space = [0-9] ]]
then
moves[(square -1)]=$play
((turn =1))
else
player_pick
echo "Not a valid square."
fi
space=${moves[(square-1)]}
}
check_match() {
if [[ ${moves[0]} == ${moves[1]} ]]&&
[[ ${moves[1]} == ${moves[2]} ]]; then
game_on=false
fi
if [ $game_on == false ]; then
if [ ${moves[$1]} == 'x' ];then
echo "Player one wins!"
return
else
echo "player two wins!"
return
fi
fi
}
check_winner(){
if [ $game_on == false ]; then return; fi
check_match 0 1 2
if [ $game_on == false ]; then return; fi
check_match 3 4 5
if [ $game_on == false ]; then return; fi
check_match 6 7 8
if [ $game_on == false ]; then return; fi
check_match 0 4 8
if [ $game_on == false ]; then return; fi
check_match 2 4 6
if [ $game_on == false ]; then return; fi
check_match 0 3 6
if [ $game_on == false ]; then return; fi
check_match 1 4 7
if [ $game_on == false ]; then return; fi
check_match 2 5 8
if [ $game_on == false ]; then return; fi
if [ $turn -gt 9 ]; then
$game_on=false
echo "Its a draw!"
fi
}
welcome_message
print_board
while $game_on
do
player_pick
print_board
check_winner
done
CodePudding user response:
Here is my modified version:
#!/bin/bash
player_1="X"
player_2="O"
turn=1
moves=( - - - - - - - - - )
welcome_message() {
clear
echo "========================"
echo "=== LETS PLAY A GAME ==="
echo "========================"
sleep 3
}
print_board () {
clear
echo " ${moves[0]} | ${moves[1]} | ${moves[2]} "
echo "-----------"
echo " ${moves[3]} | ${moves[4]} | ${moves[5]} "
echo "-----------"
echo " ${moves[6]} | ${moves[7]} | ${moves[8]} "
echo "============="
}
player_pick(){
if [[ $(( turn % 2 )) == 0 ]]
then
echo "Player 1 pick a square: "
play=$player_2
else
play=$player_1
echo "Player 2 pick a square: "
fi
read -r square
if [[ ${moves[(square-1)]} == "-" ]] &&
[[ $square == [1-9] ]]
then
moves[(square -1)]=$play
(( turn = 1 ))
else
echo "Not a valid square."
player_pick
fi
}
check_match() {
index1=$1
index2=$2
index3=$3
if [[ ${moves[$index1]} == "${moves[$index2]}" ]] &&
[[ ${moves[$index1]} == "${moves[$index3]}" ]] &&
[[ ${moves[$index1]} != "-" ]]
then
if [[ ${moves[$index1]} == 'X' ]]
then
echo "Player one wins!"
exit
else
echo "player two wins!"
exit
fi
fi
}
check_winner(){
if [[ $turn -gt 9 ]]
then
echo "Its a draw!"
exit
fi
check_match 0 1 2
check_match 3 4 5
check_match 6 7 8
check_match 0 4 8
check_match 2 4 6
check_match 0 3 6
check_match 1 4 7
check_match 2 5 8
}
welcome_message
print_board
while true
do
player_pick
print_board
check_winner
done
Modifications:
- removed the
game_on
variable completely, thewhile
is now ontrue
. - in
player_pick()
, I removed thespace
variable, not required. - in
check_match()
, created 3 new variables (index1, index2, index3) to contain the values received in argument. Just to make it clearer later, but they are just$1
,$2
,$3
. - in
check_match()
, replaced the hard coded indexes by the new variables. You had[0]
,[1]
and[2]
all the time. You only verified the first horizontal row all the time. - in
check_match()
, theif [[ ${moves[$index1]} == 'X' ]] ...
, you had== 'x'
. Capitals matter in bash. - in
check_winner()
, remove all theif
statements.check_match()
now exits when a player wins. Smaller code, easier to read. - in
player_pick()
, "Not a valid square." is now printed beforeplayer_pick()
is called recursively.