diff options
Diffstat (limited to 'backyard/java')
3 files changed, 135 insertions, 22 deletions
diff --git a/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/Contestant.java b/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/Contestant.java index 13333d2..77fab8e 100644 --- a/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/Contestant.java +++ b/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/Contestant.java @@ -1,29 +1,76 @@  package nl.camilstaps.botleagues; +/** + * A contestant is a process, a unique identifier and has a score. + *  + * @author Camil Staps <info@camilstaps.nl> + */  public class Contestant implements Comparable<Contestant> { +	/** The process we're running this on */  	private final Process process; +	/** A unique identifier (can be set in the constructor */ +	private final int uid; +	/** The score */  	private int score = 0; +	/** +	 * Create a new contestant with default uid -1 +	 *  +	 * @param p the process to link this contestant to +	 */  	public Contestant(Process p) {  		process = p; +		this.uid = -1;  	} +	/** +	 * Create a new contestant with a custom uid +	 *  +	 * @param p the process to link this contestant to +	 * @param uid the uid +	 */ +	public Contestant(Process p, int uid) { +		process = p; +		this.uid = uid; +	} +	 +	/** +	 * Set a new score +	 * @param new_score +	 */  	public void setScore(int new_score) {  		score = new_score;  	} +	/** +	 * Get the current score +	 * @return +	 */  	public int getScore() {  		return score;  	} +	/** +	 * Get the process +	 * @return +	 */  	public Process getProcess() {  		return process;  	}  	@Override +	/** +	 * We compare contestants based on their score. +	 * Like this, we can make a ranking. +	 */  	public int compareTo(Contestant arg0) {  		return ((Integer) getScore()).compareTo(arg0.getScore());  	} +	@Override +	public String toString() { +		return "Contestant " + uid + " (" + score + "): " + process.toString(); +	} +	  } diff --git a/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java b/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java index 73fa1da..77eea76 100644 --- a/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java +++ b/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java @@ -1,8 +1,10 @@  package nl.camilstaps.botleagues; +import java.io.File;  import java.io.IOException;  import java.util.ArrayList;  import java.util.Collections; +import java.util.List;  /**   * The idea is to let this be a generic class that can be used for any game.  @@ -16,15 +18,48 @@ import java.util.Collections;   */  public abstract class GameController { -	ArrayList<Contestant> contestants; +	/** The contestants in this game */ +	List<Contestant> contestants = new ArrayList<>(); -	protected void addContestant(String contestant) throws IOException { +	/** +	 * Add a new contestant +	 *  +	 * Internally, this will create a system call from directory `directory`: +	 *     java `contestant` +	 *      +	 * So, an example call would be: +	 *   `directory` = /home/user/my-bot +	 *   `contestant` = com.example.mybot.MyBot +	 *  +	 * @param directory The directory to work from +	 * @param contestant The Java path to start up +	 * @throws IOException +	 */ +	protected void addContestant(File directory, String contestant) throws IOException { +		System.err.println("Adding " + contestant + " from " + directory.getAbsolutePath());  		ProcessBuilder pb = new ProcessBuilder("java", contestant); -		contestants.add(new Contestant(pb.start())); +		pb.directory(directory); +		contestants.add(new Contestant(pb.start(), contestants.size()));  	} +	/** +	 * Rank the contestants by ascending score +	 */  	protected void rank() {  		Collections.sort(contestants);  	} +	/** +	 * Get the winner of the game (the one with the highest score) +	 *  +	 * NB: the contestants will be sorted after this. +	 * @see rank +	 *  +	 * @return the winner of the game +	 */ +	public Contestant getWinner() { +		rank(); +		return contestants.get(contestants.size() - 1); +	} +	  } diff --git a/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java b/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java index 4dd5410..e7c222d 100644 --- a/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java +++ b/backyard/java/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java @@ -1,10 +1,8 @@ -/** - *  - */  package nl.camilstaps.botleagues;  import java.io.BufferedReader;  import java.io.BufferedWriter; +import java.io.File;  import java.io.IOException;  import java.io.InputStreamReader;  import java.io.OutputStreamWriter; @@ -13,24 +11,41 @@ import java.util.Random;  /**   * The idea is to let this be an example of a game controller.   * Initially, we can do all the work here. Ideally, later, we'll split that up in an abstract part (in GameController) and an extension. + *  + * @author Camil Staps <info@camilstaps.nl>   */  public class MyGame extends GameController { -	 -	private int[] scores; +	/** +	 * Start the game. In the command line arguments should be descriptions of the bots, as described in @see MyGame()  +	 *  +	 * @param args command line arguments +	 */  	public static void main(String[] args) {  		@SuppressWarnings("unused")  		MyGame game = new MyGame(args);  	} +	/** +	 * Start a new game, and do some rounds. Print the winner. +	 *  +	 * @param bots descriptions of the bots (array of strings). For example: +	 *  +	 *     		/home/user/my-bot/com.example.mybot.MyBot +	 *      +	 * 		Internally, this will cd to /home/user/my-bot and then execute +	 *   +	 *     		java com.example.mybot.MyBot +	 *      +	 * 		Arbitrarily many bots can be added +	 */  	public MyGame(String[] bots) {  		try {  			for (String bot : bots) { -				addContestant(bot); +				int i = bot.lastIndexOf("/"); +				addContestant(new File(bot.substring(0, i + 1)), bot.substring(i + 1));  			} -			scores = new int[bots.length]; -			  			for (int i = 0; i < 10; i++) {  				doRound();  			} @@ -40,35 +55,51 @@ public class MyGame extends GameController {  		}  	} +	/** +	 * Do a round. +	 *  +	 * Take a number n in mind and let all the contestants guess. The contestants that are the closest to n get a point.  +	 */  	public void doRound() {  		Random rand = new Random();  		int n = rand.nextInt(100) + 1; +		System.err.println("Contestants have to guess " + n); +		  		try { +			// Let each contestant guess +			// That means: send "Guess" over stdin to the contestant, and read a number from stdout  			int[] guesses = new int[contestants.size()];  			int i = 0;  			for (Contestant contestant : contestants) {  				Process process = contestant.getProcess(); +				System.err.print("Asking contestant " + i + "...");  				BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));  				BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); -				writer.write("Guess"); +				writer.write("Guess\n"); +				writer.flush();  				int answer = Integer.parseInt(reader.readLine());  				guesses[i++] = Math.abs(n - answer); +				System.err.println("he says " + answer + ", that's " + guesses[i - 1] + " difference.");  			} -			 +			// Give every contestant that was the closest a point +			int lowest = guesses[0]; +			for (i = 0; i < guesses.length; i++) { +				if (guesses[i] < lowest) { +					lowest = guesses[i]; +				} +			} +			for (i = 0; i < guesses.length; i++) { +				if (guesses[i] == lowest) { +					System.err.println("Point for contestant " + i); +					contestants.get(i).setScore(contestants.get(i).getScore() + 1); +				} +			}  		} catch (IOException e) { +			// This shouldn't happen.  		}  	} -	public void incrementScore(int i) { -		scores[i]++; -	} -	 -	public Contestant getWinner() { -		rank(); -		return contestants.get(0); -	} -	  }  | 
