(Apologies in advance if my english is bad)
So, I have started studying bash, and want to make a Connect 4 game in it. However, I got stuck a bit. I have 7 arrays named column0 to column6, and I want to reference them later on.
I read in another post a few days ago, that i can use nameref to do so, but I think I'm doing something wrong, as the function runs, but doesn't do anything (doesn't check for winner). Here is a snippet form the code
declare -n nr="column$j"
for ((j=0 ; j < 6; j )); do
if [ "${nr[0]}" = $k ] && [ "${nr[1]}" = $k ] && [ "${nr[2]}" = $k ] && [ "${nr[3]}" = $k ]; then
(this is part of the function that will check for a winner, in case 4 characters in a row match. 'k' is just a color variable, it can be $k='Y' or $k='R')
Could someone point out what I'm doing wrong here? Or am I just dumb and Bash can't work with such solutions? Thank you in advance for any help.
CodePudding user response:
Given your specifications I tried to reproduce a minimal example.
You can try to do something like this:
#!/usr/bin/env bash
k="Y"
nr_0=("R" "R" "Y" "Y")
nr_1=("R" "Y" "Y" "Y")
nr_2=("Y" "R" "Y" "Y")
nr_3=("Y" "Y" "R" "Y")
nr_4=("Y" "Y" "Y" "R")
nr_5=("Y" "Y" "Y" "Y") # the winner
nr_6=("Y" "R" "Y" "Y")
for j in {0..6}; do
tmp_array_name="nr_$j[@]"
tmp_array=("${!tmp_array_name}")
if [ "${tmp_array[0]}" == "$k" ] && [ "${tmp_array[1]}" == "$k" ] && [ "${tmp_array[2]}" == "$k" ] && [ "${tmp_array[3]}" == "$k" ]; then
echo "The winner is $tmp_array_name - ${tmp_array[*]}"
fi
done
With this output:
The winner is nr_5[@] - Y Y Y Y
CodePudding user response:
You need the nameref declare assignment to be within your loop or it gets assigned an empty string:
for ((j=0 ; j < 6; j )); do
declare -n nr="column$j"
if [ "${nr[0]}" = $k ] && [ "${nr[1]}" = $k ] && [ "${nr[2]}" = $k ] && [ "${nr[3]}" = $k ]; then
Another option to nameref which is as risky as the dynamic naming ${!dyn_name_var}
, is to use Bash's associative arrays:
declare -A grid=()
for ((column=0 ; j < 6; column )); do
if [ "${grid[$column,0]}" == "$k" ] &&
[ "${grid[$column,1]}" == "$k" ] &&
[ "${grid[$column,2]}" == "$k" ] &&
[ "${grid[$column,3]}" == "$k" ]
then
: ...
fi
: ...
done
This will use an associative arrays of key formed by column,line.
Example of the first two lines of the grid
associative array as declared statically.
declare -A grid=(
[0,0]="o" [0,1]="x" [0,2]=" ", [0,3]="o"
[1,0]=" " [1,1]="o" [1,2]="x", [1,3]="o"
)