shellchecked

master
Peter Babič 9 years ago
parent 9bfa5598f5
commit d33f18e6c0
  1. 144
      robocode-svm

@ -1,114 +1,115 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -u set -u
# set -x #set -x
# File locations # File locations
datadir="data" dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
datadir="$dir/data"
results="$datadir/battle.data" results="$datadir/battle.data"
settings="$datadir/settings.last.battle" settings="$datadir/settings.last.battle"
training="$datadir/training.scale.data" training="$datadir/training.scale.data"
testing="$datadir/testing.scale.data" testing="$datadir/testing.scale.data"
# Battle parameters # Battle parameters
rounds=1000 rounds=6
width=500 width=500
height=500 height=500
robot1="sample.Corners" robot1="sample.Corners"
robot2="sample.Fire" robot2="sample.Fire"
# Delete the battle data so the will get freshly generated
flush_battle_data() {
rm -f "$datadir/*"
touch "$results"
}
# Help function
show_help() {
echo "USAGE: robocode-svm OPTIONS"
echo " -v, --visualize Shows visual run of the battle"
echo " -x The x coordinate of the second robot, used with -v"
echo " -y The y coordinate of the second robot, used with -v"
echo " -a, --accuracy Only show the accuracy of the SVM prediction"
echo " -c, --clean Clean run (deletes everything inside data folder)"
echo " -h, --help Show this help"
}
# Run battle without GUI, following the settings file, and returning the lines containing winners
run_battle() {
robocode -nodisplay -battle "$settings" | tail -2;
}
# Prepare the data directory # Prepare the data directory
mkdir -p "$datadir/"; mkdir -p "$datadir/";
# Iterate over arguments
while :; do while :; do
case $1 in # If there are any
# Regenerate data files if [ $# -gt 0 ] ; then
-c|--clean) case $1 in
flush_battle_data # Regenerate data files
-c|--clean)
rm -rf "$datadir"
;; ;;
# Call a "show_help" function to display a synopsis, then exit. # Call a "show_help" function to display a synopsis, then exit.
-h|-\?|--help) -h|-\?|--help)
show_help echo "Generate the data required for SVM classification."
echo "USAGE: robocode-svm [OPTION] [COORDINATES]"
echo " -v, --visualize Shows visual run of the battle"
echo " -x The x coordinate of the second robot, used with -v"
echo " -y The y coordinate of the second robot, used with -v"
echo " -a, --accuracy Only show the accuracy of the SVM prediction"
echo " -c, --clean Regenerate the battle data (may take a very long time)"
echo " -h, --help Show this help"
exit exit
;; ;;
# Just accuracy
# Unrecognized parameter #-a|--accuracy)
-?*) #show_accuracy
#exit
#;;
# Unrecognized parameter
-?*)
printf 'WARNING: Unknown option (ignored): %s\n' "$1" >&2 printf 'WARNING: Unknown option (ignored): %s\n' "$1" >&2
;; ;;
# Default case: If no more options then break out of the loop. # Default case: If no more options then break out of the loop.
*) *)
break break
esac esac
# "command" reduces the chance of fatal errors in many shells. # "command" reduces the chance of fatal errors in many shells.
command shift command shift
else
break
fi
done done
# Generate the battle data (run 1000 battles) for a SVM classification
# Repeat the battle desired number of times # If the data file has required amount if data
for i in $(seq 1 $rounds); lines=$(wc -l < "$results")
do if [[ "$lines" -eq "$rounds" ]] ; then
# Generate input parameters echo "Data are already generated."
number=$RANDOM; let "number %= $width"; x=$number else
number=$RANDOM; let "number %= $height"; y=$number # Repeat the battle desired number of times (till the battle data file does not contain $rounds entries
number=$RANDOM; let "number %= 360"; alpha=$number echo "Generating the data for SVM predition. Depending on the machine, this may take very long time."
delta=$((rounds - lines))
# Write current settings to a file; first robot starts in the middle, with fixed gun angle; for ((i = 1; i <= "$delta"; i++)) ; do
# the other one start at random known position, with random known gun angle # Generate input parameters
echo "#Battle Properties number=$RANDOM; let "number %= $width"; x=$number
robocode.battleField.width=$width number=$RANDOM; let "number %= $height"; y=$number
robocode.battleField.height=$height number=$RANDOM; let "number %= 360"; alpha=$number
robocode.battle.numRounds=1
robocode.battle.gunCoolingRate=0.07 # Write current settings to a file; first robot starts in the middle, with fixed gun angle;
robocode.battle.rules.inactivityTime=450 # the other one start at random known position, with random known gun angle
robocode.battle.selectedRobots=$robot1,$robot2 {
robocode.battle.initialPositions=($((width/2)),$((height/2)),0),($x,$y,$alpha)" > "$settings" echo "#Battle Properties"
echo "robocode.battleField.width=$width"
# If the robots are of the same name echo "robocode.battleField.height=$height"
if [ "$robot1" == "$robot2" ] ; then echo "robocode.battle.numRounds=1"
# Their order number is in the bracket after the name echo "robocode.battle.gunCoolingRate=0.07"
winner=$(run_battle | awk 'NR==1 {print substr($3,2,1)}') echo "robocode.battle.rules.inactivityTime=450"
else echo "robocode.battle.selectedRobots=$robot1,$robot2"
# Otherwise we need to match the actual names echo "robocode.battle.initialPositions=($((width/2)),$((height/2)),0),($x,$y,$alpha)"
winner=$(run_battle | awk 'NR==1F {print $2}') } > "$settings"
# Run battle without GUI, following the settings file, and returning the lines containing winners
winner=$(robocode -nodisplay -battle "$settings" | tail -2| awk 'NR==1F {print $2}')
if [ "$winner" == "$robot1" ] ; then if [ "$winner" == "$robot1" ] ; then
winner=1 winner=1
else else
winner=2 winner=2
fi fi
fi
# Inform user about the winner of current round and append the results to the file # Append the result of the battle to the battle data file
echo "Round $i winner: $winner" echo "$winner 1:$x 2:$y 3:$alpha" >> "$results"
# echo "$winner 1:$x 2:$y" >> "$results" # Print a dot to infrom user tht something is happening
echo "$winner 1:$x 2:$y 3:$alpha" >> "$results" printf "."
done done
printf "\nData generation successful.\n"
fi
# Calculate and print the acuuracy of classification, given the test sample
# Calculate the lines needed to split the data to 90% and 10% # Calculate the lines needed to split the data to 90% and 10%
tr=$(bc <<< "scale=0; $rounds * 0.9 / 1"); tr=$(bc <<< "scale=0; $rounds * 0.9 / 1");
te=$(bc <<< "scale=0; ($rounds - $tr) / 1"); te=$(bc <<< "scale=0; ($rounds - $tr) / 1");
@ -117,3 +118,4 @@ te=$(bc <<< "scale=0; ($rounds - $tr) / 1");
# misuse tee for 'process substituion' and send its stdout do /dev/null # misuse tee for 'process substituion' and send its stdout do /dev/null
svm-scale -l 0 -u 1 "$results" | tee >(head -n "$tr" > "$training") >(tail -n "$te" > "$testing") > /dev/null svm-scale -l 0 -u 1 "$results" | tee >(head -n "$tr" > "$training") >(tail -n "$te" > "$testing") > /dev/null

Loading…
Cancel
Save