You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
4.3 KiB
138 lines
4.3 KiB
#!/usr/bin/env bash
|
|
|
|
#set -x
|
|
|
|
# File locations
|
|
dir=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
|
|
datadir="$dir/data"
|
|
results="$datadir/battle.data"
|
|
settings="$datadir/settings.last.battle"
|
|
training="$datadir/training.scale.data"
|
|
testing="$datadir/testing.scale.data"
|
|
model="$datadir/model.data"
|
|
output="$datadir/output.data"
|
|
|
|
# Battle parameters
|
|
rounds=1000
|
|
width=500
|
|
height=500
|
|
robot1="sample.Corners"
|
|
robot2="sample.Fire"
|
|
|
|
# Requires a function because of two points where it is called
|
|
show_help() {
|
|
echo "Generate the data required for SVM classification and show the accuracy"
|
|
echo "of the generated SVM model. If coordinates are supported, one visual battle"
|
|
printf "is shown to support the prediction.\n\n"
|
|
echo "USAGE: robocode-svm ACTION [COORDINATES]"
|
|
echo " battle 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 " accuracy Show the accuracy of the SVM model"
|
|
echo " clean Regenerate the battle data (may take a very long time)"
|
|
echo " help Show this help"
|
|
}
|
|
|
|
# Generate the missing amount of data from running battles
|
|
generate_data() {
|
|
# Prepare the data directory
|
|
mkdir -p "$datadir/"
|
|
touch "$results"
|
|
|
|
# If the data file has required amount if data
|
|
lines=$(wc -l < "$results")
|
|
if [ "$lines" -lt "$rounds" ] ; then
|
|
# Repeat the battle desired number of times (till the battle data file does not contain $rounds entries
|
|
echo "Generating the data for SVM predition. Depending on the machine, this may take very long time."
|
|
delta=$((rounds - lines))
|
|
for ((i = 1; i <= "$delta"; i++)) ; do
|
|
# Generate input parameters
|
|
number=$RANDOM; let "number %= $width"; x=$number
|
|
number=$RANDOM; let "number %= $height"; y=$number
|
|
number=$RANDOM; let "number %= 360"; alpha=$number
|
|
|
|
# Write current settings to a file; first robot starts in the middle, with fixed gun angle;
|
|
# the other one start at random known position, with random known gun angle
|
|
{
|
|
echo "#Battle Properties"
|
|
echo "robocode.battleField.width=$width"
|
|
echo "robocode.battleField.height=$height"
|
|
echo "robocode.battle.numRounds=1"
|
|
echo "robocode.battle.gunCoolingRate=0.07"
|
|
echo "robocode.battle.rules.inactivityTime=450"
|
|
echo "robocode.battle.selectedRobots=$robot1,$robot2"
|
|
echo "robocode.battle.initialPositions=($((width/2)),$((height/2)),0),($x,$y,$alpha)"
|
|
} > "$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
|
|
winner=1
|
|
else
|
|
winner=2
|
|
fi
|
|
|
|
# Append the result of the battle to the battle data file
|
|
echo "$winner 1:$x 2:$y 3:$alpha" >> "$results"
|
|
# Print a dot to infrom user tht something is happening
|
|
printf "."
|
|
done
|
|
printf "\nData generation has been successful.\n\n"
|
|
else
|
|
if [ "$1" == "verbose" ] ; then
|
|
echo "Data have already been generated. Show accuracy or run the battle."
|
|
fi
|
|
fi
|
|
|
|
}
|
|
|
|
# Recalculate and display the accuracy of the SVM
|
|
show_accuracy() {
|
|
# Check if the data have been generated, if not, generate first
|
|
generate_data quiet
|
|
|
|
# Calculate the lines needed to split the data to 90% and 10%
|
|
tr=$(bc <<< "scale=0; $rounds * 0.9 / 1");
|
|
te=$(bc <<< "scale=0; ($rounds - $tr) / 1");
|
|
|
|
# Scale the results to interval <0, 1> and split them to training set and testing set;
|
|
# 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
|
|
# Train the SVM with the training data
|
|
svm-train -c 10 -g 2 "$training" "$model"
|
|
# Check the accuracy of the testing data against the SVM model made of training data
|
|
svm-predict "$testing" "$model" "$output" | grep "Accuracy"
|
|
}
|
|
|
|
|
|
# Iterate over arguments
|
|
while :; do
|
|
case $1 in
|
|
generate)
|
|
generate_data verbose
|
|
exit
|
|
;;
|
|
accuracy)
|
|
show_accuracy
|
|
exit
|
|
;;
|
|
clean)
|
|
rm -rf "$datadir"
|
|
echo "All the SVM data have been deleted."
|
|
exit
|
|
;;
|
|
help|-h|-\?|--help)
|
|
show_help
|
|
exit
|
|
;;
|
|
*)
|
|
echo "Type help for list of supported commands."
|
|
exit
|
|
esac
|
|
# "command" reduces the chance of fatal errors in many shells.
|
|
command shift
|
|
done
|
|
|
|
|
|
|
|
|
|
|