username=cogiz
#!/bin/bash
shuffle() #@ USAGE: shuffle
{ #@ TODO: add options for multiple or partial decks
Deck=$(
printf "%s\n" {2,3,4,5,6,7,8,9,T,J,Q,K,A}{H,S,D,C} |
awk '## Seed the random number generator
BEGIN { srand() }
## Put a random number in front of each line
{ printf "%.0f\t%s\n", rand() * 99999, $0 }
' |
sort -n | ## Sort the lines numerically
cut -f2 ## Remove the random numbers
)
}
_deal() #@ USAGE: _deal [N] -- where N is no. of cards; defaults to 1
{ #@ RESULT: stored in $_DEAL
local num=${1:-1}
set -- $Deck
_DEAL=${@:1:$num}
shift "$num"
cards_remaining=$#
Deck=$*
}
deal() #@ USAGE: deal [N]
{ #@ RESULT: cards printed one to a line
_deal "$@"
printf "%s " $_DEAL
}
################################################
shuffle
declare -a PH
deal 8 > /home/cogiz/playerhand.txt # (7D 3H 4D 9H KC 2H 7C 9S)
deal 8 > /home/cogiz/computerhand.txt
deal 1 > /home/cogiz/activecard.txt # (9C)
mapfile -t PH < /home/cogiz/playerhand.txt
X=$(</home/cogiz/activecard.txt)
A=( "${X[@]::1}" ) # 9
B=( "${X[@]:1}" ) # C
C=8 # 8
for e in ${PH[@]}; do
if [[ $e =~ $A|$B|8 ]]; then
printf "$e " >> /home/cogiz/choices.txt
else
printf "0 " >> /home/cogiz/choices.txt
fi
done
The above script is a rewrite of a terminal game of crazy 8's in Bash that I have been working on. The problem I am having is that the output file (choices.txt) is not showing me all of the results that it should. when the above script was run, the output in the choices.txt file was ( 0 0 0 9H 0 0 0 9S ).
It should have been ( 0 0 0 9H KC 0 7C 9S ).
Each time I run this script ( ./crazy.sh ) it gives me a different answer but always an incomplete one.
Can anyone explain to me why this is happening? I have been racking my brain for days trying to figure this out. Why does it show some valid card choices but not all? What am I missing?
Thank you in advance for any and all suggestions and advice.
Running your final for loop with the variables (not arrays!) set to the values indicated, I get 0 0 0 9H KC 0 7C 9S , so the logics seem to be OK. The inconsistent behaviour might be caused by some creative use of variables, arrays, separators, and assignments.
The way you assign them, A and B will be arrays with one single element only. Scrutinizer already proposed an alternative use. mapfile will ( man bash ) "Read lines from the standard input into the indexed array variable array", so again array PH has just one element as the input file has all cards in one line separated by spaces.
While the logics should work nevertheless, I can't assess the ramifications of using arrays vs. variables. Wouldn't it be worthwhile to try simple variables?
Well, talking of complexity: your entire script looks somewhat overcomplicated to me. Although I like subroutines and functions for repeating tasks, jumping to and fro between them just for the sake of it might overdo it. Consider the following - it should do exactly what you need (if I read the script correctly):
set -- $(shuf -e {2,3,4,5,6,7,8,9,T,J,Q,K,A}{H,S,D,C})
PH=$(echo ${@:1:8} | tee /home/cogiz/playerhand.txt); shift 8
DU=$(echo ${@:1:8} | tee /home/cogiz/computerhand.txt); shift 8
XX=$(echo ${@:1:1} | tee /home/cogiz/activecard.txt); shift 1
for e in $PH
do if [[ $e =~ ${XX%?}|${XX#?}|8 ]]
then printf "$e "
else printf "0 "
fi
done
0 0 0 KS 8S 0 0 0
echo
echo $PH, $DU, $XX
5H QC QH KS 8S 9C 9D 3H, 6H 7S 7H 4H QS JH AD JS, AS