#!/usr/bin/env bash set -u set -e # File locations path="$HOME/dev/bash/robocode/svm" settings="$path/.settings.battle" results="$path/.results.data" training="$path/training.data" testing="$path/testing.data" # scaling="$path/scaling.data" # Battle parameters rounds=1000 width=500 height=500 robot1="sample.SpinBot" robot2="sample.VelociRobot" # Run battle without GUI, following the settings file, and returning the lines containing winners battle() { echo $(robocode -nodisplay -battle "$settings" | tail -2); } # Make sure files are right cd $path rm -f "$results"; touch "$results" # Repeat the battle desired number of times for i in `seq 1 $rounds`; 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 robocode.battleField.width=$width robocode.battleField.height=$height robocode.battle.numRounds=1 robocode.battle.gunCoolingRate=0.1 robocode.battle.rules.inactivityTime=450 robocode.battle.selectedRobots=$robot1,$robot2 robocode.battle.initialPositions=($(($width/2)),$(($height/2)),0),($x,$y,$alpha)" > "$settings" # If the robots are of the same name if [ "$robot1" == "$robot2" ] ; then # Their order number is in the bracket after the name winner=$(battle | awk 'NR==1 {print substr($3,2,1)}') else # Otherwise we need to match the actual names winner=$(battle | awk 'NR==1F {print $2}') if [ "$winner" == "$robot1" ] ; then winner=1 else winner=2 fi fi # Inform user about the winner of current round and append the results to the file echo "Round $i winner: $winner" # echo "$winner 1:$x 2:$y" >> "$results" echo "$winner 1:$x 2:$y 3:$alpha" >> "$results" done # 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