Я прошу прощения за неопределенный вопрос, я полностью потерян и не знаю, что пошло не так в данный момент.
Недавно я пытался изучить bash-скриптинг и решил написать тиктактое с минимаксной и альфа-бета-обрезкой.Я написал сценарий очень питоническим способом, так как в целом я все еще плохо знаком с UNIX.Когда я попытался запустить функцию минимакса, я не получил никаких ошибок, но он ничего не выводил и не выходил нормально (пришлось CTRL C).
если текущая доска выиграна, функция может сказать, что она выиграна, и вернуть то, что мне нужно.Но когда он не выигран, он не может перейти на следующий уровень.
#!/bin/bash
declare -a board=( A1 " o" " x" " o" " o" " x" C1 C2 C3 )
shopt -s extglob
#draws the grid
draw(){
grid="| "${board[0]}" | ${board[1]} | ${board[2]} |
----------------
| ${board[3]} | ${board[4]} | ${board[5]} |
----------------
| ${board[6]} | ${board[7]} | ${board[8]} |"
echo "$grid"
}
#test if board has a winning combination for either player
wintest(){
local testboard=("$@")
for p in " o" " x"
do
#test for vertical win
for i in $(seq 0 2)
do
if [ "$p" == "${testboard[$i]}" -a "$p" == "${testboard[$(($i+3))]}" -a "$p" == "${testboard[$(($i+6))]}" ]; then
echo 1
fi
done
#test for horizontal win
for i in 0 3 6
do
if [ "$p" == "${testboard[$i]}" -a "$p" == "${testboard[$i+1]}" -a "$p" == "${testboard[$i+2]}" ]; then
echo 1
fi
done
#diagonal win
if [ "$p" == "${testboard[0]}" -a "$p" == "${testboard[4]}" -a "$p" == "${testboard[8]}" ]; then
echo 1
fi
if [ "$p" == "${testboard[2]}" -a "$p" == "${testboard[4]}" -a "$p" == "${testboard[6]}" ]; then
echo 1
fi
done
}
#minimax function. parameters: player depth alpha beta board
minimax(){
if [ $1 -eq 1 ]; then
local player="1"
local p=" o"
elif [ $1 -eq 2 ]; then
local player="2"
local p=" x"
fi
local depth=$2
local alpha=$3
local beta=$4
shift 4
#create array amove containing available moves
local boardc=("$@")
local amove=("${boardc[@]/+(" x"|" o")}")
for i in "${!amove[@]}"; do
if [[ -z "${amove[$i]}" ]]; then
unset amove[$i]
fi
done
#determine if anybody has won in the current board
#$player=1 is the maximing player. wintest is called on the start of the turn,
#if a winning combination exist, it belongs to the previous player
local winstat=$(wintest "${boardc[@]}")
if [ -n "$winstat" ]; then
if [ "${player}" == 2 ]; then
echo "$depth"
else
echo "-$depth"
fi
else
if [ "${player}" == 1 ]; then
local bestval=-1000
for i in "${amove[@]}"
do
local boardcm="${boardc[@]}"
boardcm=("${boardcm[@]/"$i"/"$p"}")
local value="$( minimax 2 $(( $depth+1 )) $alpha $beta "${boardcm[@]}" )"
bestval=$(( "$bestval" > "$value" ? $bestval : "$value" ))
alpha=$(( "$bestval" > "$alpha" ? "$bestval" : "$alpha" ))
if [ "$beta" -le "$alpha" ]
then
break
fi
done
echo "$bestval"
elif [ "${player}" == 2 ]; then
local bestval=1000
for i in "${amove[@]}"
do
local boardcm="${boardc[@]}"
boardcm=("${boardcm[@]/"$i"/"$p"}")
local value="$( minimax 1 $(( $depth+1 )) $alpha $beta "${boardcm[@]}" )"
bestval=$(( "$bestval" < "$value" ? "$bestval" : "$value" ))
beta=$(( "$bestval" < "$beta" ? "$bestval" : "$beta" ))
if [ "$beta" -le "$alpha" ]; then
break
fi
done
echo "$bestval"
fi
fi
}
Теоретически, функция минимакса должна возвращать единственное значение, которое является самым высоким (или самым низким в зависимости от игрока) значением, которое может быть гарантировано в текущем состоянии доски.Функция работает до той части, где происходит рекурсия.
Прошу прощения за то, что не могу более подробно ответить на мой вопрос, я действительно понятия не имею, почему функция не работает