Wrapper for Non-Java Submissions
NOTE MAP_SIZE support has been added. If you care, please update your submission accordingly.
This is community wiki entry for a wrapper, usable by those who want to play but don't like/don't know Java. Please use it, have fun, and I'm happy to help you get things set up.
It's pretty late here as I'm finishing up, so other Java coders, please look this over and suggest improvements. If you can, do so via my github repository by filing an issue or submitting a patch. Thanks!
This entire is being distributed with the UNLICENSE, please follow/fork it from its github repository. Submit patches there if you find issues and I'll update this post.
Current Examples of Wrapper in Use
plannapus: WolfCollectiveMemory in R
toothbrush: Toothbrush in ECMAScript
How to use
What follows are instructions on the protocol for-inter process communication via PIPES I have defined for remote Wolves. Note I've skipped MAP_SIZE as this doesn't appear to exist, in spite of its presence in OP's problem statement. If it does appear, I'll update this post.
IMPORTANT NOTES:
- Only a single invocation of your external process will be made (so wrap your processing logic in an infinite loop. This also lets you keep any processing in-memory, instead of using disk)
- All communication is to this single external process via STDIN and STDOUT
- You must explicitly flush all output sent to STDOUT, and make sure it is newline-terminated
Specification
Remote scripts are supported by a simple protocol via STDIN and STDOUT hooks, and is split into initialization, Move, and Attack.
In each case communication with your process will be via STDIN, and a reply is necessary from STDOUT.
If a reply is not received in 1 second, your process will be assumed to be dead and an exception will be thrown.
All characters will be encoded in UTF-8, for consistency. Every input will terminate with a newline character, and your process should terminate every output reply with a newline as well.
WARNING Be sure to flush your output buffer after every write, to ensure the Java wrapper sees your output. Failure to flush may cause your remote Wolf to fail.
Note that only a single process will be created, all Wolves must be managed within that one process. Read on for how this spec will help.
Initialization
STDIN: S<id><mapsize>
\n
STDOUT: K<id>
\n
<id>
: 00
or 01
or ... or 99
Explanation:
The character S
will be sent followed by two numeric characters 00
, 01
, ..., 99
indicating which of the 100 wolves is being initialized. In all future communication with that specific wolf, the same <id>
will be used.
Following the ID, a variable length sequence of numeric characters will be be sent. This is the size of the map. You'll know the sequence of numeric characters is over when you reach the newline (\n
).
To ensure your process is alive, you must reply with the character K
followed by the same <id>
you received. Any other reply will result in an exception, killing your wolves.
Movement
STDIN: M<id><C0><C1>...<C7><C8>
\n
STDOUT: <mv><id>
\n
<Cn>
: W
or
or B
or S
or L
W
: Wolf
: Empty Space
B
: Bear
S
: Stone
L
: Lion
<mv>
: H
or U
or L
or R
or D
H
: Move.HOLD
U
: Move.UP
L
: Move.LEFT
R
: Move.RIGHT
D
: Move.DOWN
Explanation:
The character M
will be sent followed by the two character <id>
to indicate which Wolf needs to choose a move. Following that, 9 characters will be sent representing that Wolf's surroundings, in row order (top row, middle row, bottom row from leftmost to rightmost).
Reply with one of the valid movement characters <mv>
, followed by the Wolf's two digit <id>
for confirmation.
Attack
STDIN: A<id><C>
\n
STDOUT: <atk><id>
\n
<C>
: W
or B
or S
or L
<atk>
: R
or P
or S
or D
R
: Attack.ROCK
P
: Attack.PAPER
S
: Attack.SCISSORS
D
: Attack.SUICIDE
Explanation:
The character A
will be sent followed by the two character <id>
to indicate which Wolf is participating in an attack. This is followed by a single character <C>
indicating which type of thing is attacking, either a W
olf, B
ear, S
tone, or L
ion.
Reply with one of the <atk>
characters listed above, indicating what your response to the attack is, following by the two digit <id>
for confirmation.
And that's it. There's no more to it. If you lose an attack, that <id>
will never be sent to your process again, that's how you will know your Wolf has died -- if a complete Movement round has passed without that <id>
ever being sent.
Conclusion
Note that any exceptions will kill all the Wolves of your remote type, as only a single "Process" is constructed of your remote wolf, for all wolves of your type that get created.
In this repository you'll find the Wolf.java
file. Search and replace the following strings to set up your bot:
Replace <invocation>
with the command line argument that will properly execute your process.
Replace <custom-name>
with a unique name for your Wolf.
For an example look at the repository, where I have WolfRandomPython.java
that invokes my example remote, the PythonWolf.py
(a Python 3+ Wolf).
Rename the file to be Wolf<custom-name>.java
, where <custom-name>
is replaced with the name you chose above.
To test your Wolf, compile the Java program (javac Wolf<custom-name>.java
), and follow Rusher's instructions to include it in the simulation program.
Important: Be sure to provide clear, concise instructions on how to compile/execute your actual Wolf, which follows the scheme I've outlined above.
Good luck, and may nature be ever in your favor.
The Wrapper Code
Remember, you MUST do the searches and replaces outlined about for this to work. If your invocation is particularly hairy, please contact me for assistance.
Note there is a main
method in this wrapper, to allow rudimentary "pass/fail" testing on your local box. To do so, download the Animal.java class from the project, and remove the package animals;
line from both files. Replace the MAP_SIZE line in Animal.java with some constant (like 100). Compile them using javac Wolf<custom-name>.java
an execute via java Wolf<custom-name>
.
package animals;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
/**
* Remote Wolf<custom-name> wrapper class.
*/
public class Wolf<custom-name> extends Animal {
/**
* Simple test script that sends some typical commands to the
* remote process.
*/
public static void main(String[]args){
Wolf<custom-name>[] wolves = new Wolf<custom-name>[100];
for(int i=0; i<10; i++) {
wolves[i] = new Wolf<custom-name>();
}
char map[][] = new char[3][3];
for (int i=0;i<9;i++)
map[i/3][i%3]=' ';
map[1][1] = 'W';
for(int i=0; i<10; i++) {
wolves[i].surroundings=map;
System.out.println(wolves[i].move());
}
for(int i=0; i<10; i++) {
System.out.println(wolves[i].fight('S'));
System.out.println(wolves[i].fight('B'));
System.out.println(wolves[i].fight('L'));
System.out.println(wolves[i].fight('W'));
}
wolfProcess.endProcess();
}
private static WolfProcess wolfProcess = null;
private static Wolf<custom-name>[] wolves = new Wolf<custom-name>[100];
private static int nWolves = 0;
private boolean isDead;
private int id;
/**
* Sets up a remote process wolf. Note the static components. Only
* a single process is generated for all Wolves of this type, new
* wolves are "initialized" within the remote process, which is
* maintained alongside the primary process.
* Note this implementation makes heavy use of threads.
*/
public Wolf<custom-name>() {
super('W');
if (Wolf<custom-name>.wolfProcess == null) {
Wolf<custom-name>.wolfProcess = new WolfProcess();
Wolf<custom-name>.wolfProcess.start();
}
if (Wolf<custom-name>.wolfProcess.initWolf(Wolf<custom-name>.nWolves, MAP_SIZE)) {
this.id = Wolf<custom-name>.nWolves;
this.isDead = false;
Wolf<custom-name>.wolves[id] = this;
} else {
Wolf<custom-name>.wolfProcess.endProcess();
this.isDead = true;
}
Wolf<custom-name>.nWolves++;
}
/**
* If the wolf is dead, or all the wolves of this type are dead, SUICIDE.
* Otherwise, communicate an attack to the remote process and return
* its attack choice.
*/
@Override
public Attack fight(char opponent) {
if (!Wolf<custom-name>.wolfProcess.getRunning() || isDead) {
return Attack.SUICIDE;
}
try {
Attack atk = Wolf<custom-name>.wolfProcess.fight(id, opponent);
if (atk == Attack.SUICIDE) {
this.isDead = true;
}
return atk;
} catch (Exception e) {
System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
isDead = true;
return Attack.SUICIDE;
}
}
/**
* If the wolf is dead, or all the wolves of this type are dead, HOLD.
* Otherwise, get a move from the remote process and return that.
*/
@Override
public Move move() {
if (!Wolf<custom-name>.wolfProcess.getRunning() || isDead) {
return Move.HOLD;
}
try {
Move mv = Wolf<custom-name>.wolfProcess.move(id, surroundings);
return mv;
} catch (Exception e) {
System.out.printf("Something terrible happened, this wolf has died: %s", e.getMessage());
isDead = true;
return Move.HOLD;
}
}
/**
* The shared static process manager, that synchronizes all communication
* with the remote process.
*/
static class WolfProcess extends Thread {
private Process process;
private BufferedReader reader;
private PrintWriter writer;
private ExecutorService executor;
private boolean running;
public boolean getRunning() {
return running;
}
public WolfProcess() {
process = null;
reader = null;
writer = null;
running = true;
executor = Executors.newFixedThreadPool(1);
}
public void endProcess() {
running = false;
}
/**
* WolfProcess thread body. Keeps the remote connection alive.
*/
public void run() {
try {
System.out.println("Starting Wolf<custom-name> remote process");
ProcessBuilder pb = new ProcessBuilder("<invocation>".split(" "));
pb.redirectErrorStream(true);
process = pb.start();
System.out.println("Wolf<custom-name> process begun");
// STDOUT of the process.
reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
System.out.println("Wolf<custom-name> reader stream grabbed");
// STDIN of the process.
writer = new PrintWriter(new OutputStreamWriter(process.getOutputStream(), "UTF-8"));
System.out.println("Wolf<custom-name> writer stream grabbed");
while(running){
this.sleep(0);
}
reader.close();
writer.close();
process.destroy(); // kill it with fire.
executor.shutdownNow();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Wolf<custom-name> ended catastrophically.");
}
}
/**
* Helper that invokes a read with a timeout
*/
private String getReply(long timeout) throws TimeoutException, ExecutionException, InterruptedException{
Callable<String> readTask = new Callable<String>() {
@Override
public String call() throws Exception {
return reader.readLine();
}
};
Future<String> future = executor.submit(readTask);
return future.get(timeout, TimeUnit.MILLISECONDS);
}
/**
* Sends an initialization command to the remote process
*/
public synchronized boolean initWolf(int wolf, int map_sz) {
while(writer == null){
try {
this.sleep(0);
}catch(Exception e){}
}
boolean success = false;
try{
writer.printf("S%02d%d\n", wolf, map_sz);
writer.flush();
String reply = getReply(5000l);
if (reply != null && reply.length() >= 3 && reply.charAt(0) == 'K') {
int id = Integer.valueOf(reply.substring(1));
if (wolf == id) {
success = true;
}
}
if (reply == null) {
System.out.println("did not get reply");
}
} catch (TimeoutException ie) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to initialize, timeout\n", wolf);
} catch (Exception e) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to initialize, %s\n", wolf, e.getMessage());
}
return success;
}
/**
* Send an ATTACK command to the remote process.
*/
public synchronized Attack fight(int wolf, char opponent) {
Attack atk = Attack.SUICIDE;
try{
writer.printf("A%02d%c\n", wolf, opponent);
writer.flush();
String reply = getReply(1000l);
if (reply.length() >= 3) {
int id = Integer.valueOf(reply.substring(1));
if (wolf == id) {
switch(reply.charAt(0)) {
case 'R':
atk = Attack.ROCK;
break;
case 'P':
atk = Attack.PAPER;
break;
case 'S':
atk = Attack.SCISSORS;
break;
case 'D':
atk = Attack.SUICIDE;
break;
}
}
}
} catch (TimeoutException ie) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to attack, timeout\n", wolf);
} catch (Exception e) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to attack, %s\n", wolf, e.getMessage());
}
return atk;
}
/**
* Send a MOVE command to the remote process.
*/
public synchronized Move move(int wolf, char[][] map) {
Move move = Move.HOLD;
try{
writer.printf("M%02d", wolf);
for (int row=0; row<map.length; row++) {
for (int col=0; col<map[row].length; col++) {
writer.printf("%c", map[row][col]);
}
}
writer.print("\n");
writer.flush();
String reply = getReply(1000l);
if (reply.length() >= 3) {
int id = Integer.valueOf(reply.substring(1));
if (wolf == id) {
switch(reply.charAt(0)) {
case 'H':
move = Move.HOLD;
break;
case 'U':
move = Move.UP;
break;
case 'L':
move = Move.LEFT;
break;
case 'R':
move = Move.RIGHT;
break;
case 'D':
move = Move.DOWN;
break;
}
}
}
} catch (TimeoutException ie) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to move, timeout\n", wolf);
} catch (Exception e) {
endProcess();
System.out.printf("Wolf<custom-name> %d failed to move, %s\n", wolf, e.getMessage());
}
return move;
}
}
}
Am I allowed to name my wolf "Wolf"? – TheNumberOne – 2015-01-08T18:30:38.287
2@TheBestOne Of course. Everyone can name their wolf "Wolf" if they want to. – Rainbolt – 2015-01-08T18:55:04.130
Does this run on my computer? So can I use my gpu-accelerated simulator for my wolf to foresee actions quicker? – huseyin tugrul buyukisik – 2015-09-05T20:00:35.523
1@huseyintugrulbuyukisik Read the section labelled "Getting Started and Testing Instructions" and try to follow the instructions. If you get stuck, then I will be more than happy to help you get the project running on your computer. – Rainbolt – 2015-09-08T13:00:11.843
How mannered animals they are! They don't believe in violence. :D – Arjun – 2016-05-23T05:13:29.357
So what happens if
move()
returnsnull
? – RamenChef – 2017-10-26T14:09:14.423@RamenChef You get disqualified for not following instructions. See the requirement "Must return a Move." Unfortunately,
– Rainbolt – 2017-10-26T15:50:26.947null
is not aMove
. Here's proof.Is this still being updated? – FireCubez – 2018-10-11T13:55:30.883
Oh, nevermind, I just looked at the date it was posted – FireCubez – 2018-10-11T13:56:07.217
When you say "simulation begins ... with 100 of each animal"... does that mean 100 per "breed" of wolf? – Martin Ender – 2014-04-04T19:03:10.000
@m.buettner Correct. Simulation starts with 100 of each Wolf submission (breed), 100 Stones, 100 Lions, and 100 Bears. – Rainbolt – 2014-04-04T19:04:43.893
1@m.buettner I'm tempted to write a wrapper that would allow non-java submissions, if Rusher doesn't forbid me from doing so :D – ProgrammerDan – 2014-04-04T19:13:43.553
@ProgrammerDan If it does not cripple the controller or force the tester (me) to download a compiler/interpreter for every submission, I will add your wrapper, and then community wiki the challenge so that I gain no more rep from it. I would be happy to see it work. – Rainbolt – 2014-04-04T19:25:21.710
5@Rusher That sounds terrible. I could just community wiki my answer that contains the Wrapper. As for the compiler/interpreter issue, I suppose it'd be up to the submittee to provide you with clear instructions on usage, and if the instructions where unclear or too complex, you could reject the submission :) – ProgrammerDan – 2014-04-04T19:27:43.300
4"* You are provided with the size of the map in the following form:
int MAP_SIZE
" I'm having trouble figuring out how to use this. Netbeans says there's no instance of the stringMAP_SIZE
in any of the files in the project. – undergroundmonorail – 2014-04-04T21:53:50.2001
To help testing, I modified your
– Geobits – 2014-04-05T04:16:00.010Game.toString()
to use aStringBuilder
instead of countless concats. It speeds things up dramatically(I also took out thesleep()
in my copy). The mod is here on pastebin.6how about trees showing paper? – Mukul Kumar – 2014-04-05T05:32:38.710
2@m.buettner wrapper posted, ping me with questions on how to use, but if your language/interpreter of choice supports piped inputs and outputs, you are good to go. – ProgrammerDan – 2014-04-05T06:27:54.063
@ProgrammerDan awesome! I think if I have to set up javac on my machine anyway, I might just write an answer in Java right away, though. But it's certainly helpful for people who don't know any Java at all. – Martin Ender – 2014-04-05T09:34:28.623
3@Rusher, I think some people are doing this already, but is inter-Wolf communication allowed via static members (within your own breed)? – Martin Ender – 2014-04-05T09:35:55.687
10@m.buettner Allowed. Go forth and build your hive-minded wolf. – Rainbolt – 2014-04-05T15:02:51.333
@ProgrammerDan MAP_SIZE bug fixed. All wolves should be able to access it now. It is inherited from Animal. Download the new controller from the same link in the question. – Rainbolt – 2014-04-05T17:15:40.383
Ah, the nostalgia of intro programming courses – geoff – 2014-04-05T22:46:06.170
When is the deadline for entering? – Kevin – 2014-04-06T04:34:02.517
1One more thing, just to clarify: if animals move through each other (i.e. swap places) there is no fight? – Martin Ender – 2014-04-06T08:18:56.137
3@Kevin No foreseeable deadline. I will update this post with results as I learn how to compile them (I'm currently learning how to run an R program). If, in a few months, I get tired of updating it, I'll just slap a timer on it. – Rainbolt – 2014-04-06T15:49:26.750
@m.buettner If they swap places, there is no fight. In other words, you don't "collide" halfway between cells. – Rainbolt – 2014-04-06T15:51:11.097
3Wow this is awesome. I sense a whole new breed of computer gaming here haha. – Andrew Gies – 2014-04-06T20:04:49.023
1
If you want players to be able to run the program themselves to see the winner, you could ensure that everyone is using the same random number generator (in a deterministic order) and promise to seed it with a future random number.
– Jeremy Stein – 2014-04-07T20:01:13.630Does this need JDK 8? – user3188175 – 2014-04-07T20:44:54.377
What is the syntax for the surrounding char[][] array? By that I mean, assuming my character is in position 1,1, does Move.UP imply that I will move to position 0,1 or 1,0 or 1,2 or 2,1? It might be nice if this was explicitly stated. – Sheph – 2014-04-07T20:58:23.893
@Sheph Good question. I edited the "Tools" section to reflect your orientation on the board. – Rainbolt – 2014-04-07T21:13:50.277
@user3188175 Yes. I messed up and included one line of code that requires Java 8. I blame the ever changing ArrayList syntax! – Rainbolt – 2014-04-07T21:16:43.220
Is there a good graphical representation of the playing field that I'm just not seeing, or do I have to write one myself? (e.g. johnchen902's display) – apnorton – 2014-04-07T23:50:42.357
2@anorton The default testing program includes a graphical output when run. It doesn't look exactly like johnchen902's, but it shows the position/species of each creature. Get it from the link in the OP's "Testing Instructions" section. – Geobits – 2014-04-08T01:23:49.757
@anorton It looks like johnchen902 modified the display to show his wolves in another color. Mine doesn't do that, but it should be a pretty easy tweak. – Rainbolt – 2014-04-08T03:35:43.187
Sort of expected this, installed NetBeans on Debian, downloaded the project, at first NetBeans refused to open it, I deleted nbproject directory like some people advised, now running the project is impossible. Ideas? – Llamageddon – 2014-04-08T09:06:35.727
1
@Asmageddon First, do you have JDK 8? If not, download it. If so, follow the instructions at this link to point NetBeans to the right Java platform. http://stackoverflow.com/a/6951067/3224483
– Rainbolt – 2014-04-08T13:01:13.253@Asmageddon Second, if nothing else works, just create a new project and add the .java source files yourself to
\yourproject\src\
. I have mine separated into two folders ->\Wild\src\animals
and\Wild\src\wild
. You could even copy and paste the code from the .java files. – Rainbolt – 2014-04-08T13:07:12.337"Simulation begins at ~25% board capacity with 100 of each Animal pseudorandomly distributed across the board." Is the "~25%" part of that an artifact of old design? Although it may be a close estimate for certain numbers of species, it isn't for others, and just seems to add unnecessary (mis?)information. – Runer112 – 2014-04-08T13:07:57.823
@Runer112 Please provide a number of submissions where you think the math does not work out, and then I'll be able to help you. – Rainbolt – 2014-04-08T13:18:41.377
I notice that most of the wolfs fights ended to be psadorandom as there is more chances that it will be even, than victory. I suggest to edit the rules to include 3 breaking even attempts before using psadorandom victory, how ever it will make the lion much weaker so apply this rule only on wolfs fights. – Ilya Gazman – 2014-04-08T13:33:06.813
1@Ilya_Gazman I appreciate the suggestion, but I generally can't edit the rules after posting the challenge in a way that would affect answers already submitted. I can only add clarifications to the already existing rules (and hope I don't piss anyone off). – Rainbolt – 2014-04-08T13:40:23.617
@Rusher It seems you probably won't have to worry about it with the number of submissions coming in, but for numbers of submissions less than about 15, it would't be a great estimate, getting progressively worse with fewer submissions. – Runer112 – 2014-04-08T16:09:34.790
@Runer112 Since you say it gets progressively worse close as it gets lower, we'll take n=1 submissions. sqrt(1+3)20 gives us a 4040 board size. That's 1600 cells. Fill 1600 cells with 100 each Wolves, Bears, Lions, and Stones, and that makes 400 Animals. 400 is exactly 25% of 1600. Where exactly did the math go wrong? – Rainbolt – 2014-04-08T16:21:30.687
@Rusher Well, that was a math failure on my part. Ignore that completely, then. :) – Runer112 – 2014-04-08T16:24:27.673
1@Rusher Also, a slight concern. Right now, animal surroundings are undated immediately before that animal moves, meaning that the surroundings reported will reflect the new positions of animals that have already moved that tick. However, this behavior means that there may be multiple animals on one spot, and (I think?) you resolve this by choosing to show the animal that was there first. Is this ideal? If not, one way to possibly improve it might be to modify the choosing logic to choose the "most dangerous" animal. Another way might be to update all surroundings, and only then move animals. – Runer112 – 2014-04-08T16:25:06.353
1@Runer112 Surroundings reported reflect the board as it was before ANYONE moved. I make a brand new game board every iteration, but I pull surroundings from the old board. After every move has been made, I just replace the old board with the new one, and then collapse the cells. I even took care of the cases where 3 or 4 Animals land on the same cell. It wouldn't be fair if the first Animal had to fight everyone, so fighters are selected randomly until only one remains. – Rainbolt – 2014-04-08T16:27:15.843
1@Rusher It sounds like I'm just being really stupid today... All my doubts about your design have been ill-founded. Looks like your design has been great all along! And I've been having a lot of fun trying to make a decent wolf for myself. – Runer112 – 2014-04-08T16:30:30.793
1
@Runer112 As long as you are pointing out flaws in good faith, don't be discouraged from challenging the design further. It obviously isn't perfect. The particular concern you came up with is even related to a bug of one of the biggest Java games of all time - http://minecraft.gamepedia.com/South-East_rule
– Rainbolt – 2014-04-08T16:37:23.3573@Rusher I've got you this time! If both animals in a fight choose to commit suicide, I would think both shouhd die. But currently it's classified as a tie and only one randomly chosen one dies. :P – Runer112 – 2014-04-08T18:54:53.807
1@Runer112 I had to dig into my code before finding out that you are correct! I'll fix it (although I doubt it will change much for the suicidal wolves), add the newest submissions, upload the updated project files, and post new results sometime in the next couple of days. – Rainbolt – 2014-04-08T19:04:36.623
1As a helper to those confused. If given an enum Cell with the following members (in order){TOP_LEFT,TOP,TOP_RIGHT,LEFT,MID,RIGHT,BOT_LEFT,BOT,_BOT_RIGHT;}, you can derive the character of a given position using the enum with the function: char get(Cell c) {int x = c.ordinal()%3; int y = c.ordinal()/3; return surroundings[y][x];} – Sheph – 2014-04-08T19:57:50.203
@Rusher Updated Stone Eating Wolf. Please use updated version :) – Averroes – 2014-04-08T21:36:39.327
@Rusher Updated MimicWolf, I should be able to double my max with this update ^^ – Sahar Rabinoviz – 2014-04-09T00:31:00.837
3It seems that the surviving wolves are the ones that avoid encounters with other wolves and lions. I think it would be great to do some other king of the hill challenge similar to this but adding sheeps (that can breed if the encounter instead of kill themselves) and wolves that actual have to hunt them down to survive. Wolves that don't hunt starve and die. – Averroes – 2014-04-09T10:48:43.263
@Rusher So, you're not including CamoWolf? -_- It's not against the rules, and you can't just say "I don't like this one so I'm not including it"... – Doorknob – 2014-04-09T12:58:40.213
2
@Averroes I'm working on something like that, but will be waiting until the current competitions die down some before posting.
– Geobits – 2014-04-09T13:04:03.0932I am so starting on my wolf once I get home. I'm thinking of a Wolf that instinctually runs away from everything, unless someone's already done that. – Zibbobz – 2014-04-09T14:46:25.607
@Geobits I would suggest keeping the rules very simple like this competition as that sparks creativity. However one change I would like that would have made the wolves behaviour more interesting is to have a concept of a "health" per animal so that attacking can be strategic and not a thing to avoid as it is in this competition. – Moogie – 2014-04-09T20:54:31.110
2@Moogie The competition is what it is, and changing it invalidate the 32 submissions already posted. Let's just say we learned how to make an even better challenge next time. Also, welcome to Code Golf! – Rainbolt – 2014-04-09T20:57:46.003
@Rusher Thanks for the welcome :) Please do not take offence at my comment. I have had lots of fun! – Moogie – 2014-04-09T21:21:57.880
Here are evaluations of the Java wolves when we increase the number of lions: http://chat.stackexchange.com/transcript/message/14837457#14837457
– Justin – 2014-04-10T07:45:59.097@Rusher StoneEatingWolf updated – Averroes – 2014-04-10T16:28:42.180
Why are there two "MimicWolf" in the Google Drive scoreboard? – justhalf – 2014-04-11T04:47:25.237
Unnoficial codegolf score: Surviving rate / Bytes of code – Averroes – 2014-04-11T07:23:27.353
Your explanation of the surroundings matrix doesn't make any sense. If it is a zero indexed 3x3 matrix, how can it have indices larger than 2? – Tim Seguine – 2014-04-11T14:10:16.747
3@TimSeguine The way Stack Exchange identifies links is with constructs like [1], [2], [3], etc. When I edited the links in my post, it also changed my indices. I think it's a bug. Anyway, I fixed it. – Rainbolt – 2014-04-11T14:15:15.733
Would it be possible to put the version you are using to generate the scoreboard on the google drive (i.e. the one with all of the current wolf classes)? – Tim Seguine – 2014-04-11T15:25:20.780
@TimSeguine Sure, when I get around to it. I have a MTG tournament this weekend so possibly Sunday or Monday evening? Anyway, to even run it you'll have to download Mono, Rscript, Node.js, compile some stuff by hand, and then cross your fingers and hope it works. I might also post a version that only includes Java wolves that you can simply download and run, and a version that has colors if the author allows me to steal his code. I'm also going to increase the number of trials and include some actual statistics in the spreadsheet. – Rainbolt – 2014-04-11T15:49:11.557
1Okay, sounds good. I just figured since you already did the work of incorporating ~40 wolves into the project, it would make it easier for people to test without having to duplicate that work. – Tim Seguine – 2014-04-11T16:10:10.713
@Rusher, ETA for scoreboard update? Can you make a new sheet with the date so we can track changes over time? Still packaging those wolves and game update? – MatthewMMorrow – 2014-04-22T20:27:46.697
1@MatthewMMorrow Tonight. Will package the java only wolves (the rest can be added manually and all require additional downloads anyway). Will create a new sheet as requested. – Rainbolt – 2014-04-22T22:35:02.847
2@Rusher Since the most successful wolves rely on HOLD, I think it would be pretty interesting to take it out, maybe as a side challenge? – Trent – 2014-04-26T09:00:28.267
@FizzBuzz I added your suggestion for a side challenge to the bottom of the post. – Rainbolt – 2014-04-28T13:59:03.940
@Rusher Surprisingly harder than expected. I thought my algorithm was decent enough that I could just remove HOLD and be good to go...no such luck, it performs terribly! – Trent – 2014-04-29T07:53:11.690
I'd really like to participate and build an epic collaborative wolf, but Java file io intimidates me ;_; – cjfaure – 2014-05-07T09:14:03.040
@Trimsty It's intimidating at first, but then you realize that you can hook a Scanner to a File, a String, a Stream, or to STDIN and it becomes easy. And you construct a File like
File f = new File(path);
. Easy right? – Rainbolt – 2014-05-07T13:05:38.000@Rusher Oooohhhh. I like Python's more though xD – cjfaure – 2014-05-07T13:38:29.620
Hey, my wolf is no-hold capable. You only need to comment hold line in movemap. – mleko – 2014-05-13T17:15:46.470