From 131d8948cf419c4ad69a141c079deb51c8856e4e Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Mon, 16 Feb 2015 23:48:05 +0100 Subject: Added PHP API framework --- trunk/GameController/.gitignore | 73 ++++++++++++++++++++++ .../nl/camilstaps/botleagues/GameController.java | 16 +++++ .../src/nl/camilstaps/botleagues/MyGame.java | 12 ++++ 3 files changed, 101 insertions(+) create mode 100644 trunk/GameController/.gitignore create mode 100644 trunk/GameController/src/nl/camilstaps/botleagues/GameController.java create mode 100644 trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java diff --git a/trunk/GameController/.gitignore b/trunk/GameController/.gitignore new file mode 100644 index 0000000..b630aee --- /dev/null +++ b/trunk/GameController/.gitignore @@ -0,0 +1,73 @@ +# Source: http://www.bmchild.com/2012/06/git-ignore-for-java-eclipse-project.html + +# Directories # +/build/ +/bin/ +target/ + +# OS Files # +.DS_Store + +*.class + +# Package Files # +*.jar +*.war +*.ear +*.db + +###################### +# Windows +###################### + +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + +###################### +# OSX +###################### + +.DS_Store +.svn + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + + +###################### +# Eclipse +###################### + +*.pydevproject +.project +.metadata +bin/** +tmp/** +tmp/**/* +*.tmp +*.bak +*.swp +*~.nib +local.properties +.classpath +.settings/ +.loadpath +/src/main/resources/rebel.xml +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# CDT-specific +.cproject + +# PDT-specific +.buildpath diff --git a/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java b/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java new file mode 100644 index 0000000..0ad9d2c --- /dev/null +++ b/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java @@ -0,0 +1,16 @@ +/** + * + */ +package nl.camilstaps.botleagues; + +/** + * The idea is to let this be a generic class that can be used for any game. + * It should take care of functions like: + * + * * Starting up bots + * * Sending data to bots + * * Receiving data from bots + */ +public abstract class GameController { + +} diff --git a/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java new file mode 100644 index 0000000..ecce818 --- /dev/null +++ b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java @@ -0,0 +1,12 @@ +/** + * + */ +package nl.camilstaps.botleagues; + +/** + * 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. + */ +public class MyGame extends GameController { + +} -- cgit v1.2.3 From 1905ce89fbbcc9a68ae3700514e6291860cceefe Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Tue, 17 Feb 2015 20:57:20 +0100 Subject: Updated gamecontroller example --- .../nl/camilstaps/botleagues/GameController.java | 22 ++++++-- .../src/nl/camilstaps/botleagues/MyGame.java | 62 ++++++++++++++++++++++ 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java b/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java index 0ad9d2c..73fa1da 100644 --- a/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java +++ b/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java @@ -1,8 +1,9 @@ -/** - * - */ package nl.camilstaps.botleagues; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; + /** * The idea is to let this be a generic class that can be used for any game. * It should take care of functions like: @@ -10,7 +11,20 @@ package nl.camilstaps.botleagues; * * Starting up bots * * Sending data to bots * * Receiving data from bots + * + * @author Camil Staps */ public abstract class GameController { - + + ArrayList contestants; + + protected void addContestant(String contestant) throws IOException { + ProcessBuilder pb = new ProcessBuilder("java", contestant); + contestants.add(new Contestant(pb.start())); + } + + protected void rank() { + Collections.sort(contestants); + } + } diff --git a/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java index ecce818..4dd5410 100644 --- a/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java +++ b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java @@ -3,10 +3,72 @@ */ package nl.camilstaps.botleagues; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +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. */ public class MyGame extends GameController { + + private int[] scores; + + public static void main(String[] args) { + @SuppressWarnings("unused") + MyGame game = new MyGame(args); + } + + public MyGame(String[] bots) { + try { + for (String bot : bots) { + addContestant(bot); + } + scores = new int[bots.length]; + + for (int i = 0; i < 10; i++) { + doRound(); + } + System.out.println(getWinner()); + } catch (IOException e) { + System.err.println(e.getMessage()); + } + } + + public void doRound() { + Random rand = new Random(); + int n = rand.nextInt(100) + 1; + + try { + int[] guesses = new int[contestants.size()]; + int i = 0; + for (Contestant contestant : contestants) { + Process process = contestant.getProcess(); + BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream())); + writer.write("Guess"); + + int answer = Integer.parseInt(reader.readLine()); + guesses[i++] = Math.abs(n - answer); + } + + + } catch (IOException e) { + } + } + + public void incrementScore(int i) { + scores[i]++; + } + + public Contestant getWinner() { + rank(); + return contestants.get(0); + } + } -- cgit v1.2.3 From 0b4b1bc0d4b35bc5c899b77e17dc7a4315482634 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Tue, 17 Feb 2015 20:58:02 +0100 Subject: Updated gamecontroller example --- .../src/nl/camilstaps/botleagues/Contestant.java | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 trunk/GameController/src/nl/camilstaps/botleagues/Contestant.java diff --git a/trunk/GameController/src/nl/camilstaps/botleagues/Contestant.java b/trunk/GameController/src/nl/camilstaps/botleagues/Contestant.java new file mode 100644 index 0000000..13333d2 --- /dev/null +++ b/trunk/GameController/src/nl/camilstaps/botleagues/Contestant.java @@ -0,0 +1,29 @@ +package nl.camilstaps.botleagues; + +public class Contestant implements Comparable { + + private final Process process; + private int score = 0; + + public Contestant(Process p) { + process = p; + } + + public void setScore(int new_score) { + score = new_score; + } + + public int getScore() { + return score; + } + + public Process getProcess() { + return process; + } + + @Override + public int compareTo(Contestant arg0) { + return ((Integer) getScore()).compareTo(arg0.getScore()); + } + +} -- cgit v1.2.3 From da97b5c9fc4dd114661f1c81b7883fe9b5c95fcf Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Wed, 18 Feb 2015 20:51:44 +0100 Subject: removed useless javadoc --- trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java index 4dd5410..528200d 100644 --- a/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java +++ b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java @@ -1,6 +1,3 @@ -/** - * - */ package nl.camilstaps.botleagues; import java.io.BufferedReader; -- cgit v1.2.3 From 5eec279028878d9bcf8dc83a3cd4ede5eba98bf3 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Wed, 18 Feb 2015 22:05:10 +0100 Subject: Fixed process builder --- .../nl/camilstaps/botleagues/GameController.java | 7 +++++-- .../src/nl/camilstaps/botleagues/MyGame.java | 23 +++++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java b/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java index 73fa1da..6fb9974 100644 --- a/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java +++ b/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java @@ -1,5 +1,6 @@ package nl.camilstaps.botleagues; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -16,10 +17,12 @@ import java.util.Collections; */ public abstract class GameController { - ArrayList contestants; + ArrayList contestants = new ArrayList<>(); - protected void addContestant(String contestant) 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); + pb.directory(directory); contestants.add(new Contestant(pb.start())); } diff --git a/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java index 528200d..9b486e2 100644 --- a/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java +++ b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java @@ -2,6 +2,7 @@ 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; @@ -23,7 +24,8 @@ public class MyGame extends GameController { 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]; @@ -41,20 +43,35 @@ public class MyGame extends GameController { Random rand = new Random(); int n = rand.nextInt(100) + 1; + System.err.println("Contestants have to guess " + n); + try { 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 a " + guesses[i - 1] + " difference."); } - + 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) { + incrementScore(i); + } + } } catch (IOException e) { } } -- cgit v1.2.3 From 023d99e5b06a0a77bd4ae0a21f2186280557d6b2 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Wed, 18 Feb 2015 22:35:51 +0100 Subject: Added comments --- .../src/nl/camilstaps/botleagues/Contestant.java | 47 ++++++++++++++++++++++ .../nl/camilstaps/botleagues/GameController.java | 36 ++++++++++++++++- .../src/nl/camilstaps/botleagues/MyGame.java | 47 +++++++++++++++------- 3 files changed, 113 insertions(+), 17 deletions(-) diff --git a/trunk/GameController/src/nl/camilstaps/botleagues/Contestant.java b/trunk/GameController/src/nl/camilstaps/botleagues/Contestant.java index 13333d2..77fab8e 100644 --- a/trunk/GameController/src/nl/camilstaps/botleagues/Contestant.java +++ b/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 + */ public class Contestant implements Comparable { + /** 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/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java b/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java index 6fb9974..77eea76 100644 --- a/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java +++ b/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java @@ -4,6 +4,7 @@ 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. @@ -17,17 +18,48 @@ import java.util.Collections; */ public abstract class GameController { - ArrayList contestants = new ArrayList<>(); + /** The contestants in this game */ + List contestants = new ArrayList<>(); + /** + * 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); pb.directory(directory); - contestants.add(new Contestant(pb.start())); + 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/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java index 9b486e2..e7c222d 100644 --- a/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java +++ b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java @@ -11,16 +11,34 @@ 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 */ 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) { @@ -28,8 +46,6 @@ public class MyGame extends GameController { 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(); } @@ -39,6 +55,11 @@ 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; @@ -46,6 +67,8 @@ public class MyGame extends GameController { 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) { @@ -58,9 +81,10 @@ public class MyGame extends GameController { int answer = Integer.parseInt(reader.readLine()); guesses[i++] = Math.abs(n - answer); - System.err.println("he says " + answer + ", that's a " + guesses[i - 1] + " difference."); + 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) { @@ -69,20 +93,13 @@ public class MyGame extends GameController { } for (i = 0; i < guesses.length; i++) { if (guesses[i] == lowest) { - incrementScore(i); + 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); - } - } -- cgit v1.2.3 From d2fe82b594f4c3d6121c8e37b58ee8fcf0f79322 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Wed, 18 Feb 2015 22:57:19 +0100 Subject: Updated readme; added todo about time limit --- trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java index e7c222d..79a9868 100644 --- a/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java +++ b/trunk/GameController/src/nl/camilstaps/botleagues/MyGame.java @@ -58,7 +58,9 @@ 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. + * Take a number n in mind and let all the contestants guess. The contestants that are the closest to n get a point. + * + * @todo Maximum execution time waiting for a contestant to answer */ public void doRound() { Random rand = new Random(); -- cgit v1.2.3 From 60d7b005231d6feb538fc4f423a58a16617b26d6 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Thu, 19 Feb 2015 10:47:00 +0100 Subject: Added java <1.7 compatibility --- trunk/GameController/src/nl/camilstaps/botleagues/GameController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java b/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java index 77eea76..1054215 100644 --- a/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java +++ b/trunk/GameController/src/nl/camilstaps/botleagues/GameController.java @@ -19,7 +19,7 @@ import java.util.List; public abstract class GameController { /** The contestants in this game */ - List contestants = new ArrayList<>(); + List contestants = new ArrayList(); /** * Add a new contestant -- cgit v1.2.3 From 255d3adf2cc68ccb37a3b4a252152a068aedbcd2 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Thu, 19 Feb 2015 10:55:49 +0100 Subject: Added ant buildfile --- trunk/GameController/.gitignore | 1 + trunk/GameController/build.xml | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 trunk/GameController/build.xml diff --git a/trunk/GameController/.gitignore b/trunk/GameController/.gitignore index b630aee..5bda502 100644 --- a/trunk/GameController/.gitignore +++ b/trunk/GameController/.gitignore @@ -3,6 +3,7 @@ # Directories # /build/ /bin/ +/dist/ target/ # OS Files # diff --git a/trunk/GameController/build.xml b/trunk/GameController/build.xml new file mode 100644 index 0000000..bed4b30 --- /dev/null +++ b/trunk/GameController/build.xml @@ -0,0 +1,38 @@ + + + Controls a Botleagues game + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3 From 725e0dbdbe3e80649bac13f9645cd908cbd93b11 Mon Sep 17 00:00:00 2001 From: Camil Staps Date: Thu, 19 Feb 2015 11:07:01 +0100 Subject: changed ant buildfile for default eclipse settings --- trunk/GameController/build.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trunk/GameController/build.xml b/trunk/GameController/build.xml index bed4b30..31b3d59 100644 --- a/trunk/GameController/build.xml +++ b/trunk/GameController/build.xml @@ -4,7 +4,7 @@ - + @@ -35,4 +35,4 @@ - \ No newline at end of file + -- cgit v1.2.3