cleanup
authorDaniel Axtens <[email protected]>
Mon, 3 May 2010 02:23:26 +0000 (10:23 +0800)
committerDaniel Axtens <[email protected]>
Mon, 3 May 2010 02:23:26 +0000 (10:23 +0800)
52 files changed:
issues [deleted file]
issues.txt [new file with mode: 0644]
link/C/c-link-lib/.gitignore [deleted file]
link/C/c-link-lib/Makefile [deleted file]
link/C/c-link-lib/agents/c-angel.c [deleted file]
link/C/c-link-lib/agents/c-frechie.c [deleted file]
link/C/c-link-lib/agents/c-lucifer.c [deleted file]
link/C/c-link-lib/agents/c-streetfighter.c [deleted file]
link/C/c-link-lib/c-link-lib.xcodeproj/project.pbxproj [deleted file]
link/C/c-link-lib/c_link.c [deleted file]
link/C/c-link-lib/c_link.h [deleted file]
link/Mathematica/pyml.tar.gz [deleted file]
link/Mathematica/pythonika-1.0.tar.gz [deleted file]
rps/trunk/LICENSE [deleted file]
rps/trunk/README [deleted file]
rps/trunk/SampleAgents.py [deleted file]
rps/trunk/SampleAgents.py.old [deleted file]
rps/trunk/SampleAgents.pyc [deleted file]
rps/trunk/djaAgents.py [deleted file]
rps/trunk/djaAgents.pyc [deleted file]
rps/trunk/rpsconst.py [deleted file]
rps/trunk/rpsconst.pyc [deleted file]
rps/trunk/selectAlgorithms.py [deleted file]
rps/trunk/simulate.py [deleted file]
rps/trunk/uccProgComp.py [deleted file]
rps/trunk/uccProgComp.py.old [deleted file]
rps/trunk/uccProgComp.pyc [deleted file]
src/LICENSE [new file with mode: 0644]
src/README [new file with mode: 0644]
src/SampleAgents.py [new file with mode: 0644]
src/SampleAgents.py.old [new file with mode: 0644]
src/SampleAgents.pyc [new file with mode: 0644]
src/djaAgents.py [new file with mode: 0644]
src/djaAgents.pyc [new file with mode: 0644]
src/link/C/c-link-lib/.gitignore [new file with mode: 0644]
src/link/C/c-link-lib/Makefile [new file with mode: 0644]
src/link/C/c-link-lib/agents/c-angel.c [new file with mode: 0644]
src/link/C/c-link-lib/agents/c-frechie.c [new file with mode: 0644]
src/link/C/c-link-lib/agents/c-lucifer.c [new file with mode: 0644]
src/link/C/c-link-lib/agents/c-streetfighter.c [new file with mode: 0644]
src/link/C/c-link-lib/c-link-lib.xcodeproj/project.pbxproj [new file with mode: 0644]
src/link/C/c-link-lib/c_link.c [new file with mode: 0644]
src/link/C/c-link-lib/c_link.h [new file with mode: 0644]
src/link/Mathematica/pyml.tar.gz [new file with mode: 0644]
src/link/Mathematica/pythonika-1.0.tar.gz [new file with mode: 0644]
src/rpsconst.py [new file with mode: 0644]
src/rpsconst.pyc [new file with mode: 0644]
src/selectAlgorithms.py [new file with mode: 0644]
src/simulate.py [new file with mode: 0755]
src/uccProgComp.py [new file with mode: 0644]
src/uccProgComp.py.old [new file with mode: 0644]
src/uccProgComp.pyc [new file with mode: 0644]

diff --git a/issues b/issues
deleted file mode 100644 (file)
index 393bd1a..0000000
--- a/issues
+++ /dev/null
@@ -1,6 +0,0 @@
- - number of agents can spiral out of control very quickly, e.g. if Frenchie and Angel start duking it out. 
- - points table doesn't agree with technicalities doc
- - agents die after MAX_AGE fights, not MAX_AGE rounds
- - code seems to trust y ou not to mnokey around with your stats...?
- - no way to tell an external agent that their services are no longer required.
-  * amend to provide a BYE command
diff --git a/issues.txt b/issues.txt
new file mode 100644 (file)
index 0000000..d6a2c4e
--- /dev/null
@@ -0,0 +1,7 @@
+ - number of agents can spiral out of control very quickly, e.g. if Frenchie and Angel start duking it out. 
+   * Need to make supervisor smart enough to kill montonically increasing sequences.
+ - points table doesn't agree with technicalities doc
+ - agents die after MAX_AGE fights, not MAX_AGE rounds
+ - code seems to trust you not to monkey around with your stats...?
+ - coding styles are inconsistent throughout
+ - layout still needs some work
diff --git a/link/C/c-link-lib/.gitignore b/link/C/c-link-lib/.gitignore
deleted file mode 100644 (file)
index fbde527..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-agents/
-!agents/*.c
diff --git a/link/C/c-link-lib/Makefile b/link/C/c-link-lib/Makefile
deleted file mode 100644 (file)
index 10e306b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-CC=gcc
-AR=ar
-
-CFLAGS=-Wall -I.
-LDFLAGS=-lc_link -L.
-
-LINKSRCS=c_link.c
-LINKOBJS=$(LINKSRCS:.c=.o)
-LINKLIB=libc_link.a
-
-AGENTSRCS=$(wildcard agents/*.c)
-AGENTS=$(AGENTSRCS:.c=)
-
-all: $(LINKSRCS) $(LINKLIB) $(AGENTS)
-       
-$(LINKLIB): $(LINKOBJS)
-       $(AR) rcs $(LINKLIB) $(LINKOBJS)
-       
-$(AGENTS): $(AGENTSRCS) 
-       @echo Building $<
-       $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
-
-.c.o: c_link.h
-       $(CC) -c $(CFLAGS) $< -o $@
-
-.PHONY : clean
-clean:
-       rm $(LINKOBJS) $(LINKLIB) $(AGENTS)
diff --git a/link/C/c-link-lib/agents/c-angel.c b/link/C/c-link-lib/agents/c-angel.c
deleted file mode 100644 (file)
index c6c8687..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  c-angel.c
- *  c-link-lib
- *
- *  Created by Daniel Axtens on 20/04/10.
- *  Licensed under an MIT-style license: see the LICENSE file for details.
- *
- */
-
-#include <c_link.h>
-
-/* Implement the angel bot, which always tells the truth
-   and expects others to do the same */
-
-ATTACKTYPE Attack( char * foe_name ) {
-       ATTACKTYPE attack;
-       
-       attack.realAttack =  RandomAttack();            /* Chooses randomly from Rock, Paper, Scissors */ 
-       attack.promisedAttack = attack.realAttack;      /* Tells the truth for its bluff */
-
-       return attack;
-}
-
-ITEMTYPE Defend( char * foeName, ITEMTYPE foePromisedAttack ) {
-       return foePromisedAttack;       /* Trusts them to be going for a tie */
-}
-
-/* You need to define a results function, even if it isn't used
-   (otherwise the linker will complain) */
-void Results( char * foeName, int isInstigatedByYou, ITEMTYPE yourItem, 
-                        ITEMTYPE theirItem, ITEMTYPE promisedItem) {
-       
-       return; /* Ignore whatever just happened. */
-}
-
-/* same for Cleanup() */
-
-void Cleanup() {
-       return;
-}
\ No newline at end of file
diff --git a/link/C/c-link-lib/agents/c-frechie.c b/link/C/c-link-lib/agents/c-frechie.c
deleted file mode 100644 (file)
index ed2ba09..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *  c-frechie.c
- *  c-link-lib
- *
- *  Created by Daniel Axtens on 22/04/10.
- *  Licensed under an MIT-style license: see the LICENSE file for details.
- *
- */
-
-#include <c_link.h>
-#include <stdlib.h>
-
-/* Implement the frenchie bot, that is by default nice but will 
-   permanently turn against any agent that betrays it.
-   This is trickier in C than in any other language, for a number of reasons:
-     - there's no classes in C, so we can't just write a generic learning agent
-       and subclass it.
-     - your agent has no idea how many agents it's going to battle, or how many
-       battles it is going to fight, so you've got to do dynamic memory allocation.
-        (anyone who tries to read the source of the supervisor to find out is liable
-         to have their program break unexpectedly)
- */
-
-/* To simplify things, we just look at whether we have lost to a particular agent.
-   Unlike in the Python version, we don't keep a generic list
-   This is also done in a inefficient (O(bot-cout)) way.
-   Implementing a faster version is left as an exercise to the DSA student. */
-
-/* Our guess at the number of agents I'm going to fight in my lifetime */
-#define NUMBEROFAGENTSGUESS 100
-
-/* The name of the n-th foe we've seen, as well as a 0/1 have we lost to them */
-char foesNames[][MAXFOENAMELEN] = NULL;
-int haveLostToFoe[] = NULL;
-
-/* The length of the array, and how far we are along it */
-size_t foesLen = 0;
-unsigned int foesCount = 0;
-
-
-ATTACKTYPE Attack( char * foe_name ) {
-       ATTACKTYPE attack;
-       
-       attack.realAttack =  RandomAttack();
-       
-       /* Here we choose the thing that will hurt them if they go for the kill */
-       switch (attack.realAttack) {
-               case rock:
-                       result.promisedAttack = paper;
-                       break;
-               case paper:
-                       result.promisedAttack = scissors;
-                       break;
-               default: /* attack = scissors */
-                       result.promisedAttack = rock;
-                       break;
-       }
-       return attack;
-}
-
-/* Here we assume they are lying, trying to kill us. And we try to kill them. */
-ITEMTYPE Defend( char * foeName, ITEMTYPE foePromisedAttack ) {
-       ITEMTYPE defence;
-       switch (foePromisedAttack) {
-               case rock:
-                       defence = scissors;
-                       break;
-               case paper:
-                       defence = rock;
-                       break;
-               default:
-                       defence = paper;
-                       break;
-       }
-}
-
-/* This is so much less fun in C */
-void Results( char * foeName, int isInstigatedByYou, ITEMTYPE yourItem, 
-                        ITEMTYPE theirItem, ITEMTYPE promisedItem) {
-       
-    int foe;
-    
-    /* check to see if we've initialised our arrays */
-       if (foesNames == NULL) {
-        foesNames = calloc( NUMBEROFAGENTSGUESS, sizeof( foesNames[0] ) );
-        haveLostToFoe = calloc( NUMBEROFAGENTSGUESS, sizeof( haveLostToFoe[0] ) );
-        foesLen = NUMBEROFAGENTSGUESS;
-    }
-    
-    /* figure out if we lost, which is the only thing we care about
-       if we didn't, move on. */
-    if (RESULTOF[yourItem][theirItem] != lose) return;
-    
-    /* try and find existing foe */
-    
-    return;
-}
-
-/* same for Cleanup() */
-
-void Cleanup() {
-       free(foesNames);
-    free(haveLostToFoe);
-}
\ No newline at end of file
diff --git a/link/C/c-link-lib/agents/c-lucifer.c b/link/C/c-link-lib/agents/c-lucifer.c
deleted file mode 100644 (file)
index 1dabc34..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *  c-lucifer.c
- *  c-link-lib
- *
- *  Created by Daniel Axtens on 20/04/10.
- *  Licensed under an MIT-style license: see the LICENSE file for details.
- *
- */
-
-
-#include <c_link.h>
-
-/* Implement the lucifer bot, which always lies expecting people to be good
-   and always goes for the kill */
-
-ATTACKTYPE Attack( char * foe_name ) {
-       ATTACKTYPE attack;
-       
-       attack.realAttack =  RandomAttack();
-       
-       /* Here we choose the thing that will hurt them if they go for a tie */
-       switch (attack.realAttack) {
-               case rock:
-                       result.promisedAttack = scissors;
-                       break;
-               case paper:
-                       result.promisedAttack = rock;
-                       break;
-               default: /* attack = scissors */
-                       result.promisedAttack = paper;
-                       break;
-       }
-       attack.promisedAttack = result.realAttack;      /* Tells the truth for its bluff */
-       
-       return attack;
-}
-
-/* Here we trust that they are telling the truth. And we try to kill them. */
-ITEMTYPE Defend( char * foeName, ITEMTYPE foePromisedAttack ) {
-       ITEMTYPE defence;
-       switch (foePromisedAttack) {
-               case rock:
-                       defence = paper;
-                       break;
-               case paper:
-                       defence = scissors;
-                       break;
-               default:
-                       defence = rock;
-                       break;
-       }
-}
-
-/* You need to define a results function, even if it isn't used
- (otherwise the linker will complain) */
-void Results( char * foeName, int isInstigatedByYou, ITEMTYPE yourItem, 
-                        ITEMTYPE theirItem, ITEMTYPE promisedItem) {
-       
-       return; /* Ignore whatever just happened. */
-}
-
-/* same for Cleanup() */
-
-void Cleanup() {
-       return;
-}
\ No newline at end of file
diff --git a/link/C/c-link-lib/agents/c-streetfighter.c b/link/C/c-link-lib/agents/c-streetfighter.c
deleted file mode 100644 (file)
index c63939d..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  c-streetfighter.c
- *  c-link-lib
- *
- *  Created by Daniel Axtens on 20/04/10.
- *  Licensed under an MIT-style license: see the LICENSE file for details.
- *
- */
-
-
-#include <c_link.h>
-
-/* Implement the streetfighter bot, which thinks everyone has it in for him. */
-
-ATTACKTYPE Attack( char * foe_name ) {
-       ATTACKTYPE attack;
-       
-       attack.realAttack =  RandomAttack();
-       
-       /* Here we choose the thing that will hurt them if they go for the kill */
-       switch (attack.realAttack) {
-               case rock:
-                       result.promisedAttack = paper;
-                       break;
-               case paper:
-                       result.promisedAttack = scissors;
-                       break;
-               default: /* attack = scissors */
-                       result.promisedAttack = rock;
-                       break;
-       }
-       return attack;
-}
-
-/* Here we assume they are lying, trying to kill us. And we try to kill them. */
-ITEMTYPE Defend( char * foeName, ITEMTYPE foePromisedAttack ) {
-       ITEMTYPE defence;
-       switch (foePromisedAttack) {
-               case rock:
-                       defence = scissors;
-                       break;
-               case paper:
-                       defence = rock;
-                       break;
-               default:
-                       defence = paper;
-                       break;
-       }
-}
-
-/* You need to define a results function, even if it isn't used
- (otherwise the linker will complain) */
-void Results( char * foeName, int isInstigatedByYou, ITEMTYPE yourItem, 
-                        ITEMTYPE theirItem, ITEMTYPE promisedItem) {
-       
-       return; /* Ignore whatever just happened. */
-}
-
-/* same for Cleanup() */
-
-void Cleanup() {
-       return;
-}
diff --git a/link/C/c-link-lib/c-link-lib.xcodeproj/project.pbxproj b/link/C/c-link-lib/c-link-lib.xcodeproj/project.pbxproj
deleted file mode 100644 (file)
index 80d9803..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-// !$*UTF8*$!
-{
-       archiveVersion = 1;
-       classes = {
-       };
-       objectVersion = 45;
-       objects = {
-
-/* Begin PBXFileReference section */
-               2291A1BB117EDB9600854CBE /* c_link.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = c_link.c; sourceTree = "<group>"; };
-               2291A1BD117EE3FD00854CBE /* c-angel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "c-angel.c"; sourceTree = "<group>"; };
-               2291A1BE117EE3FD00854CBE /* c-lucifer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "c-lucifer.c"; sourceTree = "<group>"; };
-               2291A1BF117EE3FD00854CBE /* c-streetfighter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "c-streetfighter.c"; sourceTree = "<group>"; };
-               2291A1EC117FF85D00854CBE /* c-frechie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "c-frechie.c"; sourceTree = "<group>"; };
-               22F652F5117C679300A3793D /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
-               22F652F6117C6C9500A3793D /* c_link.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = c_link.h; sourceTree = "<group>"; };
-/* End PBXFileReference section */
-
-/* Begin PBXGroup section */
-               08FB7794FE84155DC02AAC07 /* c-link-lib */ = {
-                       isa = PBXGroup;
-                       children = (
-                               2291A1BC117EE3FD00854CBE /* agents */,
-                               22F652F6117C6C9500A3793D /* c_link.h */,
-                               2291A1BB117EDB9600854CBE /* c_link.c */,
-                               22F652F5117C679300A3793D /* Makefile */,
-                       );
-                       name = "c-link-lib";
-                       sourceTree = "<group>";
-               };
-               2291A1BC117EE3FD00854CBE /* agents */ = {
-                       isa = PBXGroup;
-                       children = (
-                               2291A1BD117EE3FD00854CBE /* c-angel.c */,
-                               2291A1BE117EE3FD00854CBE /* c-lucifer.c */,
-                               2291A1BF117EE3FD00854CBE /* c-streetfighter.c */,
-                               2291A1EC117FF85D00854CBE /* c-frechie.c */,
-                       );
-                       path = agents;
-                       sourceTree = "<group>";
-               };
-/* End PBXGroup section */
-
-/* Begin PBXLegacyTarget section */
-               D28A88AD04BDD90700651E21 /* c-link-lib */ = {
-                       isa = PBXLegacyTarget;
-                       buildArgumentsString = "$(ACTION)";
-                       buildConfigurationList = 1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "c-link-lib" */;
-                       buildPhases = (
-                       );
-                       buildToolPath = /usr/bin/make;
-                       buildWorkingDirectory = "";
-                       dependencies = (
-                       );
-                       name = "c-link-lib";
-                       passBuildSettingsInEnvironment = 1;
-                       productName = "c-link-lib";
-               };
-/* End PBXLegacyTarget section */
-
-/* Begin PBXProject section */
-               08FB7793FE84155DC02AAC07 /* Project object */ = {
-                       isa = PBXProject;
-                       buildConfigurationList = 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "c-link-lib" */;
-                       compatibilityVersion = "Xcode 3.1";
-                       hasScannedForEncodings = 1;
-                       mainGroup = 08FB7794FE84155DC02AAC07 /* c-link-lib */;
-                       projectDirPath = "";
-                       projectRoot = "";
-                       targets = (
-                               D28A88AD04BDD90700651E21 /* c-link-lib */,
-                       );
-               };
-/* End PBXProject section */
-
-/* Begin XCBuildConfiguration section */
-               1DEB919008733D9F0010E9CD /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               COPY_PHASE_STRIP = NO;
-                               DEBUGGING_SYMBOLS = YES;
-                               GCC_DYNAMIC_NO_PIC = NO;
-                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
-                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
-                               GCC_OPTIMIZATION_LEVEL = 0;
-                               OTHER_CFLAGS = "";
-                               OTHER_LDFLAGS = "";
-                               PRODUCT_NAME = "c-link-lib";
-                       };
-                       name = Debug;
-               };
-               1DEB919108733D9F0010E9CD /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               COPY_PHASE_STRIP = YES;
-                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
-                               OTHER_CFLAGS = "";
-                               OTHER_LDFLAGS = "";
-                               PRODUCT_NAME = "c-link-lib";
-                       };
-                       name = Release;
-               };
-               1DEB919408733D9F0010E9CD /* Debug */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_32_BIT)";
-                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
-                               GCC_WARN_UNUSED_VARIABLE = YES;
-                               ONLY_ACTIVE_ARCH = YES;
-                               PREBINDING = NO;
-                               SDKROOT = macosx10.6;
-                       };
-                       name = Debug;
-               };
-               1DEB919508733D9F0010E9CD /* Release */ = {
-                       isa = XCBuildConfiguration;
-                       buildSettings = {
-                               ARCHS = "$(ARCHS_STANDARD_32_BIT)";
-                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
-                               GCC_WARN_UNUSED_VARIABLE = YES;
-                               PREBINDING = NO;
-                               SDKROOT = macosx10.6;
-                       };
-                       name = Release;
-               };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
-               1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "c-link-lib" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1DEB919008733D9F0010E9CD /* Debug */,
-                               1DEB919108733D9F0010E9CD /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-               1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "c-link-lib" */ = {
-                       isa = XCConfigurationList;
-                       buildConfigurations = (
-                               1DEB919408733D9F0010E9CD /* Debug */,
-                               1DEB919508733D9F0010E9CD /* Release */,
-                       );
-                       defaultConfigurationIsVisible = 0;
-                       defaultConfigurationName = Release;
-               };
-/* End XCConfigurationList section */
-       };
-       rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
-}
diff --git a/link/C/c-link-lib/c_link.c b/link/C/c-link-lib/c_link.c
deleted file mode 100644 (file)
index 680450e..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- *  c_link.c
- *  c-link-lib
- *
- *  Created by Daniel Axtens on 19/04/10.
- *  Licensed under an MIT-style license: see the LICENSE file for details.
- *
- */
-
-#include "c_link.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <time.h>
-
-/* You don't need to read this file.
-   All you have to do is implement the bot functions defined in <c_link.h>
-   This file sets up the I/O for you, as well as some utility functions and tables. 
- */
-
-char ITEMNAMES[3][MAXITEMLEN] = {"Rock", "Paper", "Scissors"};
-
-/* rock-rock     rock-paper     rock-scissors 
-   paper-rock    paper-paper    paper-scissors
-   scissors-rock scissors-paper scissors-scissors */  
-   
-RESULTTYPE RESULTOF[3][3] = { { tie, lose, win },
-                              { win, tie, lose },
-                              { lose, win, tie } };
-
-
-ITEMTYPE RandomAttack() {
-       return (ITEMTYPE)rand()%3;
-}
-
-ITEMTYPE stringToItem( char * str ) {
-       if (strcasecmp( str, "Rock" ) == 0) return rock;
-       if (strcasecmp( str, "Paper" ) == 0) return paper;
-       if (strcasecmp( str, "Scissors" ) == 0) return scissors;
-       /* If we reach this point, we've got real problems. */
-       fprintf( stderr, "Attempt to convert invalid string \"%s\" into an ITEMTYPE! Aborting.\n", str );
-       exit(EXIT_FAILURE);
-       return -1;
-}
-       
-
-int main( int argc, char * argv[] ) {
-       srand( time( NULL ) );
-       
-       char command[MAXCOMMANDLEN];
-       char foeName[MAXFOENAMELEN];
-       char yourItem[MAXITEMLEN], theirItem[MAXITEMLEN], promisedItem[MAXITEMLEN];
-       char didYouInstigate[MAXBOOLLEN], childSpawned[MAXBOOLLEN];
-       int pointChange;
-       
-       ATTACKTYPE attack;
-       ITEMTYPE defence;
-       
-       scanf( "%s", command );
-       
-       while (strcasecmp("BYE",command) != 0) {
-               
-               if (strcasecmp("ATTACK", command) == 0) {
-                       scanf( "%s", foeName );
-                       attack = Attack( foeName );
-                       printf("ATTACKING %s %s\n", ITEMNAMES[attack.realAttack], ITEMNAMES[attack.promisedAttack]);
-               
-               } else if (strcasecmp("DEFEND", command) == 0) {
-                       scanf( "%s %s", foeName, promisedItem );
-                       defence = Defend(foeName, stringToItem(promisedItem));
-                       printf("DEFENDING %s\n", ITEMNAMES[defence]);
-               
-               } else if (strcasecmp("RESULTS", command) == 0) {
-                       scanf( "%s %s %s %s %s %d %s", foeName, didYouInstigate, yourItem, theirItem, promisedItem, &pointChange, childSpawned );
-                       Results(foeName, (strcasecmp("False",didYouInstigate)==0),
-                                       stringToItem(yourItem), stringToItem(theirItem), stringToItem(promisedItem));
-                       printf("OK\n");
-               }
-       
-               // read the next command!
-               scanf( "%s", command );
-       }
-       
-       Cleanup();
-       
-       return 0;
-}
\ No newline at end of file
diff --git a/link/C/c-link-lib/c_link.h b/link/C/c-link-lib/c_link.h
deleted file mode 100644 (file)
index 84e9bce..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- *  c_link.h
- *  c-link-lib
- *
- *  Created by Daniel Axtens on 19/04/10.
- *  Licensed under an MIT-style license: see the LICENSE file for details.
- *
- */
-
-#include <stdio.h>
-
-#define MAXCOMMANDLEN  15
-#define MAXFOENAMELEN  50
-#define MAXITEMLEN             10
-#define MAXBOOLLEN             6
-
-/********** Type definitions **********/
-
-/* The type of item used in an attack or defence */
-typedef enum {rock, paper, scissors} ITEMTYPE;
-
-/* A result of a battle */
-typedef enum {win, lose, tie} RESULTTYPE;
-
-
-/* An attack, consisting of the real attack and the attack promised */
-typedef struct {
-       ITEMTYPE realAttack;
-       ITEMTYPE promisedAttack;
-} ATTACKTYPE;
-
-
-/********** Utility Function definitions **********/
-/* These are implemented in c-link.c, and automagically linked in */
-
-/* prints a debug message. Same arguments as printf().
-   (you can't use printf because it is used to talk between
-    the agent and supervisor) 
- */
-
-#define debugmsg(x...) sprintf(stderr, x)
-
-/* Returns a random item */
-
-ITEMTYPE RandomAttack();
-
-/* A useful translation table
-   eg printf( "I use %s.\n", ITEMNAMES[rock] ); */
-
-extern char ITEMNAMES[3][MAXITEMLEN];
-
-/* Another useful table - what's the result of the 
-   first item vs the second item? */
-extern RESULTTYPE RESULTOF[3][3];
-
-/********** Bot Function definitions **********/
-/* You need to provide implementations for these to create a bot */
-
-/* Defend( foeName : string - the name of your foe;
-           foePromisedAttack : ITEMTYPE - the item your foe promised to use
-         ) : ITEMTYPE - the item you wish to use to defend;
- Called when your agent needs to defend itself.
- */
-ITEMTYPE Defend( char * foeName, ITEMTYPE foePromisedAttack );
-
-
-/* Attack( foeName : string - the name of your foe
-                ) : ATTACKTYPE - the real and promised attack you wish to use
-
- Called when your agent needs to attack another agent.
- */
-ATTACKTYPE Attack( char * foeName );
-
-
-/* Results( foeName : string - the name of your foe;
-            isInstigatedByYou : 0=you defended/1=you attacked;
-                       yourItem : ITEMTYPE - the item you used;
-            theirItem : ITEMTYPE - the item they used;
-            promisedItem : ITEMTYPE - the item that was promised
-          );
-
- Called after your agent battles another agent, to tell you how the battle goes.
- */
-void Results( char * foeName, int isInstigatedByYou, ITEMTYPE yourItem, 
-                         ITEMTYPE theirItem, ITEMTYPE promisedItem);
-
-/* Cleanup();
-
-   Called when your agent is no longer needed, either due to the round ending
-   or due to your agent being eliminated.
-
- */
-void Cleanup();
\ No newline at end of file
diff --git a/link/Mathematica/pyml.tar.gz b/link/Mathematica/pyml.tar.gz
deleted file mode 100644 (file)
index 498748f..0000000
Binary files a/link/Mathematica/pyml.tar.gz and /dev/null differ
diff --git a/link/Mathematica/pythonika-1.0.tar.gz b/link/Mathematica/pythonika-1.0.tar.gz
deleted file mode 100644 (file)
index 6611f5d..0000000
Binary files a/link/Mathematica/pythonika-1.0.tar.gz and /dev/null differ
diff --git a/rps/trunk/LICENSE b/rps/trunk/LICENSE
deleted file mode 100644 (file)
index e25c106..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2008 Luke Williams
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/rps/trunk/README b/rps/trunk/README
deleted file mode 100644 (file)
index 8587cf5..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-Hi there,
-
-Thanks for taking interest in the UCC Programming Competition 2008. If you 
-don't already know what it's all about, check out the information provided in 
-the docs directory, which contains a full and authoritative* description for
-the running of the competition.
-
-This file is by no means complete, and not ready for circulation.
-
-The first thing you'll probably want to do is see it work. Try running:
-
-./simulate -v
-
-to see the sample agents duke it out for up to 150 rounds (the current sample
-agents suck - rounds either go for seconds or for ages). After that, take a
-look at sampleAgents.py to see how agents are implemented on top of the
-BaseAgent and LearningAgent classes. When you're ready to try out your own,
-edit the first few lines of simulate.py to include your agent.
-
-...and if all you're interested in is participating, that's it! You can stop
-reading, and start work on the agent that will outsmart them all!
-
-Contributor instructions:
-
-BaseAgent, LearningAgent and Supervisor are all implemented in uccProgComp.py.
-The 'select' algorithm, responsible for choosing agents for battle and
-determining when a round is finished, is the hottest part of the code and the
-most open to discussion and change. 
-
-Unfortunately, it is not an easy bit of code to understand. Once upon a time,
-in builds long past, it used friendly O(n) operations and conveniently wasted
-memory on simple tasks. After hours of profiling, it is a little more complex,
-but with a bit of background to how the supervisor operates you shouldn't have
-much trouble working out the rest:
-
-1.) A copy of the current population list is made at the beginning of the round
-representing the agents who can still fight. This reduces finding valid agents
-from O(n) to O(1). I call it the 'remaining' list.
-2.) Agents must remember their index in the population list. This is because it
-would be O(n) to determine their index in the population list (to remove them
-when they die) from their index in the 'remaining' list. Agents have this value
-stored at the beginning of the round - O(n) at the beginning of the round is
-far preferable to O(n) for every death.
-3.) The actual removal of agents from the population list must happen all at
-once in reverse numeric index order at the end of the round so that the stored
-index that agents have does not become stale. 
-
-There are problems. It's not perfect, but it's relatively fast and powerful and
-quite easy to adjust or reimplement once you get your head around it. I'm very
-much open to suggestion for improvement (especially in the form of patches) and
-welcome all help, constructive criticism, derisive criticism and death threats.
-
-Things to be done:
-
-1.) Pretty graphs! Iterate () returns a collection of statistics about each of
-the classes, which can be seen used in simulate.py. There are plenty of
-plotting packages out there that can turn this information into impressive
-charts.
-2.) More built-in functionality for BaseAgent and LearningAgent. They could
-both do with a few more utility functions for competitors to use.
-3.) A more succint set of rules and documentation.
-
-Thanks for reading!
-Luke
-
-* Or rather, it wil by the time this package is ready for distribution.
diff --git a/rps/trunk/SampleAgents.py b/rps/trunk/SampleAgents.py
deleted file mode 100644 (file)
index 6da30ba..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-'''SampleAgents.py - A collection of sample agents for playing Rock Paper Scissors.
-Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
-Requires Python 2.5.
-
-Licensed under an MIT-style license: see the LICENSE file for details.
-'''
-
-from uccProgComp import BaseAgent, LearningAgent, RandomAttack
-from rpsconst import *
-
-# Angel is a very simple bot that always tells the truth and expects others to do the same.
-class Dummy (BaseAgent):
-       def Attack (self, foe):
-               return Paper, Paper
-       def Defend (self, foe, bluff):
-               return bluff
-
-class Angel (BaseAgent):
-       def Attack (self, foe):
-               attack = RandomAttack ()        # Chooses randomly from Rock, Paper, Scissors
-               return attack, attack           # Tells the truth for its bluff.
-       def Defend (self, foe, bluff):
-               return bluff                    # Trusts them to be going for a tie.
-
-# Lucifer here is the opposite. He always lies expecting people to be good and always goes for the kill.
-class Lucifer (BaseAgent):
-       def Attack (self, foe):
-               attack = RandomAttack ()
-               if attack == Rock: bluff = Scissors     # Here we choose the thing
-               elif attack == Paper: bluff = Rock      # that will hurt them
-               else: bluff = Paper                     # if they go for a tie.
-               return attack, bluff
-       def Defend (self, foe, bluff):
-               if bluff == Rock: attack = Paper        # Here we trust that they
-               elif bluff == Paper: attack = Scissors  # are telling the truth.
-               else: attack = Rock                     # And we try to kill them.
-               return attack
-#      def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
-#              BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
-#              print "I just scored " + str(pointDelta) + " points!"
-
-
-# Streetfighter assumes everyone has it in for him.
-class Streetfighter (BaseAgent):
-       def Attack (self, foe):
-               attack = RandomAttack ()
-               if attack == Rock: bluff = Paper        # Here we choose the thing
-               elif attack == Paper: bluff = Scissors  # that will hurt them
-               else: bluff = Rock                      # if they try to kill us.
-               return attack, bluff
-       def Defend (self, foe, bluff):
-               if bluff == Rock: attack = Scissors     # Here we assume that they
-               elif bluff == Paper: attack = Rock      # are lying, trying to kill us.
-               else: attack = Paper                    # And we try to kill them.
-               return attack
-
-# This is our first bot with any sort of learning capability, based on the LearningAgent base.
-# Experienced programmers might opt to write their own learning code based on BaseAgent, but it's up to you.
-# Frenchie is a simple bot that is by default nice but will permanently turn against any agent that betrays it.
-class Frenchie (LearningAgent):
-       def Attack (self, foe):
-               attack = RandomAttack ()
-               if Loss in LearningAgent.GetWinHistory (self, foe):
-                       if attack == Rock: bluff = Scissors
-                       elif attack == Paper: bluff = Rock
-                       else: bluff = Paper
-               else:
-                       bluff = attack
-               return attack, bluff
-       def Defend (self, foe, bluff):
-               if Loss in LearningAgent.GetWinHistory (self, foe):
-                       if bluff == Rock: attack = Scissors     # They've fucked us in the past,
-                       elif bluff == Paper: attack = Rock      # so we assume they're lying and
-                       else: attack = Paper                    # hoping we go for a kill.
-               else:
-                       attack = bluff
-               return attack
-
-
-# If you want to implement your own Results () callback, you have to call the parent class's first:
-class Blank (BaseAgent):
-       def Attack (self, foe):
-               return Paper, Paper
-       def Defend (self, foe, bluff):
-               return bluff
-       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
-               BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
-               # Now you can do your own thing
-
diff --git a/rps/trunk/SampleAgents.py.old b/rps/trunk/SampleAgents.py.old
deleted file mode 100644 (file)
index d307214..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-'''SampleAgents.py - A collection of sample agents for playing Rock Paper Scissors.
-Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
-Requires Python 2.5.
-
-Licensed under an MIT-style license: see the LICENSE file for details.
-'''
-
-from uccProgComp import BaseAgent, LearningAgent, RandomAttack
-from rpsconst import *
-
-# Angel is a very simple bot that always tells the truth and expects others to do the same.
-class Dummy (BaseAgent):
-       def Attack (self, foe):
-               return Paper, Paper
-       def Defend (self, foe, bluff):
-               return bluff
-
-class Angel (BaseAgent):
-       def Attack (self, foe):
-               attack = RandomAttack ()        # Chooses randomly from Rock, Paper, Scissors
-               return attack, attack           # Tells the truth for its bluff.
-       def Defend (self, foe, bluff):
-               return bluff                    # Trusts them to be going for a tie.
-
-# Lucifer here is the opposite. He always lies expecting people to be good and always goes for the kill.
-class Lucifer (BaseAgent):
-       def Attack (self, foe):
-               attack = RandomAttack ()
-               if attack == Rock: bluff = Scissors     # Here we choose the thing
-               elif attack == Paper: bluff = Rock      # that will hurt them
-               else: bluff = Paper                     # if they go for a tie.
-               return attack, bluff
-       def Defend (self, foe, bluff):
-               if bluff == Rock: attack = Paper        # Here we trust that they
-               elif bluff == Paper: attack = Scissors  # are telling the truth.
-               else: attack = Rock                     # And we try to kill them.
-               return attack
-#      def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
-#              BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
-#              print "I just scored " + str(pointDelta) + " points!"
-
-
-# Streetfighter assumes everyone has it in for him.
-class Streetfighter (BaseAgent):
-       def Attack (self, foe):
-               attack = RandomAttack ()
-               if attack == Rock: bluff = Paper        # Here we choose the thing
-               elif attack == Paper: bluff = Scissors  # that will hurt them
-               else: bluff = Rock                      # if they go for a tie.
-               return attack, bluff
-       def Defend (self, foe, bluff):
-               if bluff == Rock: attack = Paper        # Here we trust that they
-               elif bluff == Paper: attack = Scissors  # are telling the truth.
-               else: attack = Rock                     # And we try to kill them.
-               return attack
-
-# This is our first bot with any sort of learning capability, based on the LearningAgent base.
-# Experienced programmers might opt to write their own learning code based on BaseAgent, but it's up to you.
-# Frenchie is a simple bot that is by default nice but will permanently turn against any agent that betrays it.
-class Frenchie (LearningAgent):
-       def Attack (self, foe):
-               attack = RandomAttack ()
-               if Loss in LearningAgent.GetWinHistory (self, foe):
-                       if attack == Rock: bluff = Scissors
-                       elif attack == Paper: bluff = Rock
-                       else: bluff = Paper
-               else:
-                       bluff = attack
-               return attack, bluff
-       def Defend (self, foe, bluff):
-               if Loss in LearningAgent.GetWinHistory (self, foe):
-                       if bluff == Rock: attack = Scissors     # They've fucked us in the past,
-                       elif bluff == Paper: attack = Rock      # so we assume they're lying and
-                       else: attack = Paper                    # hoping we go for a kill.
-               else:
-                       attack = bluff
-               return attack
-
-
-# If you want to implement your own Results () callback, you have to call the parent class's first:
-class Blank (BaseAgent):
-       def Attack (self, foe):
-               return Paper, Paper
-       def Defend (self, foe, bluff):
-               return bluff
-       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
-               BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
-               # Now you can do your own thing
-
diff --git a/rps/trunk/SampleAgents.pyc b/rps/trunk/SampleAgents.pyc
deleted file mode 100644 (file)
index 7b91932..0000000
Binary files a/rps/trunk/SampleAgents.pyc and /dev/null differ
diff --git a/rps/trunk/djaAgents.py b/rps/trunk/djaAgents.py
deleted file mode 100644 (file)
index 6912c7f..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-from uccProgComp import BaseAgent, LearningAgent, RandomAttack
-from rpsconst import *
-
-# BOFH is something of a cross between Frechie and Lucifer
-
-class BOFH (LearningAgent):
-       def Attack (self, foe):
-               attack = RandomAttack ()
-               
-               return attack, bluff
-       def Defend (self, foe, bluff):
-               if bluff == Rock: attack = Scissors     # Here we assume that they
-               elif bluff == Paper: attack = Rock      # are lying, trying to kill us.
-               else: attack = Paper                    # And we try to kill them.
-               return attack
-
-       def Attack (self, foe):
-               attack = RandomAttack ()
-               if len(LearningAgent.GetWinHistory (self, foe)) > 0:
-                       if attack == Rock: bluff = Paper        # Here we choose the thing
-                       elif attack == Paper: bluff = Scissors  # that will hurt them
-                       else: bluff = Rock                      # if they try to kill us.
-               else:
-                       if attack == Rock: bluff = Scissors     # Here we choose the thing
-                       elif attack == Paper: bluff = Rock      # that will hurt them
-                       else: bluff = Paper                     # if they go for a tie.
-               return attack, bluff
-               
-       def Defend (self, foe, bluff):
-               if len(LearningAgent.GetWinHistory (self, foe)) > 0:
-                       if bluff == Rock: attack = Scissors     # They've fucked us in the past,
-                       elif bluff == Paper: attack = Rock      # so we assume they're lying and
-                       else: attack = Paper                    # hoping we go for a kill.
-               else:
-                       if bluff == Rock: attack = Paper        # Here we trust that they
-                       elif bluff == Paper: attack = Scissors  # are telling the truth.
-                       else: attack = Rock                     # And we try to kill them.
-               return attack
-
-#Fish is somewhat intelligent; it builds up trust and then stabs you in the back.
-# If Fish detects that a bot is being predictably nice (tie 2+ times in a row), it will attack.
-# If Fish detects that a bot has betrayed it (Loss), it will attack.
-# Otherwise, Fish is nice.
-
-class Fish (LearningAgent):
-       def Attack (self, foe):
-               #print "Attacking" , foe
-               #print LearningAgent.GetWinHistory (self, foe)
-               attack = RandomAttack ()
-               
-               history = LearningAgent.GetWinHistory (self, foe)
-               
-               #no history; be nice
-               if len(history) == 0:
-                       bluff = attack
-               
-               #if we just lost to them, try to destroy them.
-               elif Loss == history[-1] or (len(history)>1 and [Tie,Tie] == history[-2:-1]):
-                       if attack == Rock: bluff = Scissors
-                       elif attack == Paper: bluff = Rock
-                       else: bluff = Paper
-               else:
-                       bluff = attack
-               return attack, bluff
-               
-               
-       def Defend (self, foe, bluff):
-               
-               history = LearningAgent.GetWinHistory (self, foe)
-               
-               if len(history) > 0 and Loss == history[-1]:
-                       if bluff == Rock: attack = Scissors     # They've fucked us in the past,
-                       elif bluff == Paper: attack = Rock      # so we assume they're lying and
-                       else: attack = Paper                    # hoping we go for a kill.
-               else:
-                       attack = bluff
-               return attack
\ No newline at end of file
diff --git a/rps/trunk/djaAgents.pyc b/rps/trunk/djaAgents.pyc
deleted file mode 100644 (file)
index 9d72619..0000000
Binary files a/rps/trunk/djaAgents.pyc and /dev/null differ
diff --git a/rps/trunk/rpsconst.py b/rps/trunk/rpsconst.py
deleted file mode 100644 (file)
index 5bf1ea5..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-'''rpsconst.py - A precarious collection of constants for RPS simulation.
-Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
-
-Licensed under an MIT-style license: see the LICENSE file for details.
-'''
-
-Rock = 0
-Paper = 1
-Scissors = 2
-Attacker = 0
-Defender = 1
-Tie = 2
-Bluff = 0
-Truth = 1
-Win = 3
-Loss = 4
-# EOF. Stop reading now, kid, you'll only hurt yourself.
-resultTable = [[Tie,Defender,Attacker],[Attacker,Tie,Defender],[Defender, Attacker, Tie]]
-pointsTable = [[0,0],[0,0],[0,0]]
diff --git a/rps/trunk/rpsconst.pyc b/rps/trunk/rpsconst.pyc
deleted file mode 100644 (file)
index 6feecaf..0000000
Binary files a/rps/trunk/rpsconst.pyc and /dev/null differ
diff --git a/rps/trunk/selectAlgorithms.py b/rps/trunk/selectAlgorithms.py
deleted file mode 100644 (file)
index 41be346..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# Alternative (obsolete) algorithms for selecting agents for battle.
-# They're all a bit crap and only here for comparison purposes.
-
-
-# Selects an opponent and removes it from the list of remaining potential opponents.
-       # This is just an example, but the fact that the first agent will miss out on having
-       # a fight picked with it it, and that the last agent won't get to pick a fight, seems
-       # to not matter very much. Can probably be left as-is.
-       def ChoosePair (self):
-               # This approach forces each agent to defend once and attack once per round.
-               # Keep track of the remaining population.
-               remaining = self.population[:]
-               agentID = random.randint (0,len(remaining)-1)
-               defender = remaining.pop (agentID) # Not really a defender (try to work it out)!
-               while len (remaining) > 1:
-                       if defender.GetPoints () < 1:   # If the agent died before it got a chance to attack
-                               attackerID = random.randint (0,len(remaining)-1)
-                               attacker = remaining.pop (attackerID)
-                       else: attacker = defender
-                       defenderID = random.randint (0,len(remaining)-1)
-                       defender = remaining.pop (defenderID)
-                       yield attacker, defender
-
diff --git a/rps/trunk/simulate.py b/rps/trunk/simulate.py
deleted file mode 100755 (executable)
index 13a20fa..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/python2.5
-'''simulate.py - Runs a full simulation of the UCC Programming Competition with the provided agents.
-Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
-
-Licensed under an MIT-style license: see the LICENSE file for details.
-'''
-
-# Import and add your agents here:
-from djaAgents import BOFH
-from SampleAgents import Angel, Lucifer, Dummy, Frenchie, Streetfighter
-Agents = [Angel, Lucifer, Frenchie, Streetfighter, BOFH]
-
-####################################
-# Developers only past this point! #
-####################################
-
-import sys
-from uccProgComp import Supervisor
-
-maxIterations = 150
-startingPopulations = 10
-verbose = False
-trials = 1
-usage = "Usage: rps [-v] [-i iterations=150] [-n starting_populations=10] [-t trials=1]"
-for i in range (1,len(sys.argv)):
-       if sys.argv[i] == "-i":
-               try:
-                       maxIterations = int(sys.argv[i+1])
-                       i += 1
-                       continue
-               except:
-                       print usage
-                       sys.exit(1)
-       elif sys.argv[i] == "-n":
-               try:
-                       startingPopulations = int(sys.argv[i+1])
-                       i += 1
-                       continue
-               except:
-                       print usage
-                       sys.exit(1)
-       elif sys.argv[i] == "-t":
-               try:
-                       trials = int(sys.argv[i+1])
-                       i += 1
-                       continue
-               except:
-                       print usage
-                       sys.exit(1)
-
-       elif sys.argv[i] == "-v":
-               verbose = True
-
-
-iteration = 0
-trial = 0
-winners = {}
-while trial < trials:
-       sup = Supervisor ()
-       for Agent in Agents: sup.RegisterAgent (Agent)
-       sup.GeneratePopulation (startingPopulations)
-
-       trial += 1
-       iteration = 0
-       while iteration < maxIterations and not sup.IsGameOver ():
-               iteration += 1
-               sup.Iterate ()
-               if not verbose: continue
-               print "Iteration %d:" % iteration
-               for key, value in sup.GetStats ().iteritems():
-                       print "%s: Population=%d, Newborns=%d, Deaths=%d" % (key, value[0], value[1], value[2])
-       winner = ("Error", -1)
-       for key, value in sup.GetStats ().iteritems ():
-               #print key, value
-               if value[0] > winner[1]:
-                       winner = (key, value[0])
-       if winner[0] in winners: winners[winner[0]] += 1
-       else: winners[winner[0]] = 1
-       #print "Winner: %s" % winner[0]
-
-print "SCOREBOARD OVER %d TRIALS OF %d ROUNDS EACH" % (trials, maxIterations)
-rawscoreboard = sorted ( [(score,player) for (player,score) in winners.items ()] , reverse=True )
-scoreboard = []
-for score, player in rawscoreboard:
-       print "%s: %s" % (player, score)
-
diff --git a/rps/trunk/uccProgComp.py b/rps/trunk/uccProgComp.py
deleted file mode 100644 (file)
index 0eee563..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-'''uccProgComp.py - A supervisor candidate for Rock Paper Scissors.
-Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
-Requires Python 2.5.
-
-Licensed under an MIT-style license: see the LICENSE file for details.
-'''
-
-
-import random, uuid
-random.seed ()
-
-from rpsconst import *
-
-DEFAULT_HEALTH = 50
-REPRODUCE_HEALTH = 100
-DIE_HEALTH = 0
-MAX_AGE = 100
-
-DEBUG_MODE = False
-
-# Game dynamics - these are not final:
-#               WINNER          TRUTH          ATTPoints, DEFPoints
-pointsTable    [Attacker]      [False] =       (2, -2)
-pointsTable    [Attacker]      [True]  =       (2, -2)
-pointsTable    [Defender]      [False] =       (-2, 2)
-pointsTable    [Defender]      [True]  =       (-2, 2)
-pointsTable    [Tie]           [False] =       (0, 0)
-pointsTable    [Tie]           [True]  =       (1, 1)
-
-def Debug (f):
-       def g (*args):
-               if DEBUG_MODE:
-                       print f.__name__, args[1].__class__.__name__, args[1].GetID ()
-               return f (*args)
-       return g
-
-class BaseAgent:
-       def __init__ (self):
-               self.id = uuid.uuid4().int
-               self.__points = DEFAULT_HEALTH
-               # The index will be changing all the time. It can go stale as soon as something dies.
-               # So use it cautiously.
-               self.__currentIndex = 0
-               self.__reproduced = False
-               self.__age = 0
-
-       def GetCurrentIndex (self):
-               return self.__currentIndex
-       
-       def SetCurrentIndex (self, index):
-               self.__currentIndex = index
-
-       def GetID (self):
-               return self.id
-       
-       def GetPoints (self):
-               return self.__points
-
-       def SetPoints (self, points):
-               self.__points = points
-
-       def Defend (self, foe, bluff):
-               return Rock
-       
-       def Attack (self, foe):
-               return Rock
-
-       def IsDead (self):
-               return self.__points <= DIE_HEALTH
-
-       def Reproduced (self):
-               self.__points = DEFAULT_HEALTH
-               self.__reproduced = True
-
-       def HasReproduced (self):
-               return self.__reproduced
-
-       def SetReproduced (self, repro):
-               self.__reproduced = repro
-
-       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
-               self.__points += pointDelta
-               self.__age += 1
-               if self.__age > MAX_AGE: self.__points = DIE_HEALTH
-
-class LearningAgent (BaseAgent):
-       def __init__ (self):
-               BaseAgent.__init__ (self)
-               self.winHistory = {}
-       
-       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
-               BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
-               if wasAttacker:
-                       if winner == Attacker: result = Win
-                       elif winner == Tie: result = Tie
-                       else: result = Loss
-               else:
-                       if winner == Attacker: result = Loss
-                       elif winner == Tie: result = Tie
-                       else: result = Win
-                       
-               if foeName in self.winHistory: self.winHistory [foeName].append (result)
-               else: self.winHistory [foeName] = [result]
-
-       def GetWinHistory (self, foeName):
-               if foeName in self.winHistory: return self.winHistory [foeName]
-               else: return []
-
-class Supervisor:
-       def __init__ (self):
-               # The full list of living agents
-               self.population = []
-               # A list of classes for each agent type
-               self.agentTypes = []
-               # The current iteration
-               self.iteration = 0
-               self.agentStats = {}
-               self.pendingDeaths = []
-
-       def RegisterAgent (self, agent):
-               self.agentTypes.append (agent)
-
-       def GeneratePopulation (self, nAgentsPerClass):
-               for Agent in self.agentTypes:
-                       for i in range (0,nAgentsPerClass): self.population.append (Agent ())
-                       self.agentStats [str(Agent)] = [nAgentsPerClass,0,0]
-
-       def Iterate (self):
-               self.ClearStats ()
-               self.UpdateIndexes ()
-               self.iteration += 1
-               for attacker, defender in self.Select ():
-                       attack, bluff = attacker.Attack (defender.GetID ())
-                       defense = defender.Defend (attacker.GetID (), bluff)
-                       winner = resultTable [attack] [defense]
-                       attPoints, defPoints = pointsTable [winner][attack == bluff]
-                       attacker.Results (defender.GetID (), True, winner, attack, defense, bluff, attPoints)
-                       defender.Results (attacker.GetID (), False, winner, attack, defense, bluff, defPoints)
-                       if attacker.IsDead (): self.KillAgent (attacker)
-                       elif attacker.GetPoints () >= REPRODUCE_HEALTH: self.SpawnAgent (attacker)
-                       if defender.IsDead (): self.KillAgent (defender)
-                       elif defender.GetPoints () >= REPRODUCE_HEALTH: self.SpawnAgent (defender)
-
-       def IsGameOver (self):
-               if self.population == []: return True
-               liveAgents = [id for id,stats in self.agentStats.iteritems () if stats[0] > 0]
-               print liveAgents
-               if len(liveAgents) < 2: return True
-               return False
-       
-       # This is needed because when we pick the players we also need a way of identifying them in the
-       # population list without manually searching each time. O(n) each iteration is better than O(n)
-       # each death. It also resets the check for if the agent has reproduced this round.
-       def UpdateIndexes (self):
-               for agentID in reversed(sorted(self.pendingDeaths)): del self.population [agentID]
-               for index, agent in enumerate(self.population): 
-                       agent.SetCurrentIndex (index)
-                       agent.SetReproduced (False)
-               self.pendingDeaths = []
-
-       @Debug
-       def KillAgent (self, agent):
-               self.pendingDeaths.append (agent.GetCurrentIndex ())
-               stat = self.agentStats [str(agent.__class__)]
-               stat [0] -= 1
-               stat [2] += 1
-
-       @Debug
-       def SpawnAgent (self, agent):
-               child = agent.__class__ ()
-               self.population.append (child)
-               agent.Reproduced ()
-               stat = self.agentStats [str(agent.__class__)]
-               stat [0] += 1
-               stat [1] += 1 
-
-       def Select (self):
-               # This approach causes agents to keep fighting until they've either died or reproduced.
-               remaining = self.population[:]
-               attackerID = defenderID = random.randint (0,len(remaining)-1)
-               attacker = defender = remaining [attackerID]
-               while len (remaining) >= 2:
-                       # Check to see if the attacker from last round needs to be dropped.
-                       if attacker.IsDead () or attacker.HasReproduced ():
-                               remaining.pop (attackerID)
-                               if not len(remaining) >= 2: continue
-                               if defenderID > attackerID: defenderID -= 1
-                       # Check to see if the defender from last round is up for some attacking.
-                       if defender.IsDead () or defender.HasReproduced ():
-                               remaining.pop (defenderID)
-                               if not len(remaining) >= 2: continue
-                               attackerID = random.randint (0,len(remaining)-1)
-                               attacker = remaining [attackerID]
-                       else:
-                               attacker = defender
-                               attackerID = defenderID
-                       defender = None
-                       defenderID = random.randint (0,len(remaining)-2)
-                       if defenderID >= attackerID: defenderID += 1
-                       defender = remaining [defenderID]
-
-                       yield attacker, defender
-
-       def GetStats (self):
-               return self.agentStats
-
-       def ClearStats (self):
-               for agent in self.agentTypes: self.agentStats [str(agent)] = self.agentStats [str(agent)] [:1] + [0,0]
-
-def RandomAttack ():
-       return random.randint (0,2)
diff --git a/rps/trunk/uccProgComp.py.old b/rps/trunk/uccProgComp.py.old
deleted file mode 100644 (file)
index 17ffa2a..0000000
+++ /dev/null
@@ -1,211 +0,0 @@
-'''uccProgComp.py - A supervisor candidate for Rock Paper Scissors.
-Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
-Requires Python 2.5.
-
-Licensed under an MIT-style license: see the LICENSE file for details.
-'''
-
-
-import random, uuid
-random.seed ()
-
-from rpsconst import *
-
-DEFAULT_HEALTH = 50
-REPRODUCE_HEALTH = 100
-DIE_HEALTH = 0
-MAX_AGE = 100
-
-DEBUG_MODE = False
-
-# Game dynamics - these are not final:
-#               WINNER          TRUTH          WINNER, LOSER
-pointsTable    [Attacker]      [False] =       (2, -2)
-pointsTable    [Attacker]      [True]  =       (2, -2)
-pointsTable    [Defender]      [False] =       (-2, 2)
-pointsTable    [Defender]      [True]  =       (-2, 2)
-pointsTable    [Tie]           [False] =       (-1, -1)
-pointsTable    [Tie]           [True]  =       (1, 1)
-
-def Debug (f):
-       def g (*args):
-               if DEBUG_MODE:
-                       print f.__name__, args[1].__class__.__name__, args[1].GetID ()
-               return f (*args)
-       return g
-
-class BaseAgent:
-       def __init__ (self):
-               self.id = uuid.uuid4().int
-               self.__points = DEFAULT_HEALTH
-               # The index will be changing all the time. It can go stale as soon as something dies.
-               # So use it cautiously.
-               self.__currentIndex = 0
-               self.__reproduced = False
-               self.__age = 0
-
-       def GetCurrentIndex (self):
-               return self.__currentIndex
-       
-       def SetCurrentIndex (self, index):
-               self.__currentIndex = index
-
-       def GetID (self):
-               return self.id
-       
-       def GetPoints (self):
-               return self.__points
-
-       def SetPoints (self, points):
-               self.__points = points
-
-       def Defend (self, foe, bluff):
-               return Rock
-       
-       def Attack (self, foe):
-               return Rock
-
-       def IsDead (self):
-               return self.__points <= DIE_HEALTH
-
-       def Reproduced (self):
-               self.__points = DEFAULT_HEALTH
-               self.__reproduced = True
-
-       def HasReproduced (self):
-               return self.__reproduced
-
-       def SetReproduced (self, repro):
-               self.__reproduced = repro
-
-       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
-               self.__points += pointDelta
-               self.__age += 1
-               if self.__age > MAX_AGE: self.__points = DIE_HEALTH
-
-class LearningAgent (BaseAgent):
-       def __init__ (self):
-               BaseAgent.__init__ (self)
-               self.winHistory = {}
-       
-       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
-               BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
-               if wasAttacker:
-                       if winner == Attacker: result = Win
-                       elif winner == Tie: result = Tie
-                       else: result = Loss
-               else:
-                       if winner == Attacker: result = Loss
-                       elif winner == Tie: result = Tie
-                       else: result = Win
-                       
-               if foeName in self.winHistory: self.winHistory [foeName].append (result)
-               else: self.winHistory [foeName] = [result]
-
-       def GetWinHistory (self, foeName):
-               if foeName in self.winHistory: return self.winHistory [foeName]
-               else: return []
-
-class Supervisor:
-       def __init__ (self):
-               # The full list of living agents
-               self.population = []
-               # A list of classes for each agent type
-               self.agentTypes = []
-               # The current iteration
-               self.iteration = 0
-               self.agentStats = {}
-               self.pendingDeaths = []
-
-       def RegisterAgent (self, agent):
-               self.agentTypes.append (agent)
-
-       def GeneratePopulation (self, nAgentsPerClass):
-               for Agent in self.agentTypes:
-                       for i in range (0,nAgentsPerClass): self.population.append (Agent ())
-                       self.agentStats [str(Agent)] = [nAgentsPerClass,0,0]
-
-       def Iterate (self):
-               self.ClearStats ()
-               self.UpdateIndexes ()
-               self.iteration += 1
-               for attacker, defender in self.Select ():
-                       attack, bluff = attacker.Attack (defender.GetID ())
-                       defense = defender.Defend (attacker.GetID (), bluff)
-                       winner = resultTable [attack] [defense]
-                       attPoints, defPoints = pointsTable [winner][attack == bluff]
-                       attacker.Results (defender.GetID (), True, winner, attack, defense, bluff, attPoints)
-                       defender.Results (attacker.GetID (), False, winner, attack, defense, bluff, defPoints)
-                       if attacker.IsDead (): self.KillAgent (attacker)
-                       elif attacker.GetPoints () >= REPRODUCE_HEALTH: self.SpawnAgent (attacker)
-                       if defender.IsDead (): self.KillAgent (defender)
-                       elif defender.GetPoints () >= REPRODUCE_HEALTH: self.SpawnAgent (defender)
-
-       def IsGameOver (self):
-               if self.population == []: return True
-               liveAgents = [id for id,stats in self.agentStats.iteritems () if stats[0] > 0]
-               print liveAgents
-               if len(liveAgents) < 2: return True
-               return False
-       
-       # This is needed because when we pick the players we also need a way of identifying them in the
-       # population list without manually searching each time. O(n) each iteration is better than O(n)
-       # each death. It also resets the check for if the agent has reproduced this round.
-       def UpdateIndexes (self):
-               for agentID in reversed(sorted(self.pendingDeaths)): del self.population [agentID]
-               for index, agent in enumerate(self.population): 
-                       agent.SetCurrentIndex (index)
-                       agent.SetReproduced (False)
-               self.pendingDeaths = []
-
-       @Debug
-       def KillAgent (self, agent):
-               self.pendingDeaths.append (agent.GetCurrentIndex ())
-               stat = self.agentStats [str(agent.__class__)]
-               stat [0] -= 1
-               stat [2] += 1
-
-       @Debug
-       def SpawnAgent (self, agent):
-               child = agent.__class__ ()
-               self.population.append (child)
-               agent.Reproduced ()
-               stat = self.agentStats [str(agent.__class__)]
-               stat [0] += 1
-               stat [1] += 1 
-
-       def Select (self):
-               # This approach causes agents to keep fighting until they've either died or reproduced.
-               remaining = self.population[:]
-               attackerID = defenderID = random.randint (0,len(remaining)-1)
-               attacker = defender = remaining [attackerID]
-               while len (remaining) >= 2:
-                       # Check to see if the attacker from last round needs to be dropped.
-                       if attacker.IsDead () or attacker.HasReproduced ():
-                               remaining.pop (attackerID)
-                               if not len(remaining) >= 2: continue
-                               if defenderID > attackerID: defenderID -= 1
-                       # Check to see if the defender from last round is up for some attacking.
-                       if defender.IsDead () or defender.HasReproduced ():
-                               remaining.pop (defenderID)
-                               if not len(remaining) >= 2: continue
-                               attackerID = random.randint (0,len(remaining)-1)
-                               attacker = remaining [attackerID]
-                       else:
-                               attacker = defender
-                               attackerID = defenderID
-                       defender = None
-                       defenderID = random.randint (0,len(remaining)-2)
-                       if defenderID >= attackerID: defenderID += 1
-                       defender = remaining [defenderID]
-
-                       yield attacker, defender
-
-       def GetStats (self):
-               return self.agentStats
-
-       def ClearStats (self):
-               for agent in self.agentTypes: self.agentStats [str(agent)] = self.agentStats [str(agent)] [:1] + [0,0]
-
-def RandomAttack ():
-       return random.randint (0,2)
diff --git a/rps/trunk/uccProgComp.pyc b/rps/trunk/uccProgComp.pyc
deleted file mode 100644 (file)
index 77283f4..0000000
Binary files a/rps/trunk/uccProgComp.pyc and /dev/null differ
diff --git a/src/LICENSE b/src/LICENSE
new file mode 100644 (file)
index 0000000..e25c106
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (c) 2008 Luke Williams
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/src/README b/src/README
new file mode 100644 (file)
index 0000000..8587cf5
--- /dev/null
@@ -0,0 +1,66 @@
+Hi there,
+
+Thanks for taking interest in the UCC Programming Competition 2008. If you 
+don't already know what it's all about, check out the information provided in 
+the docs directory, which contains a full and authoritative* description for
+the running of the competition.
+
+This file is by no means complete, and not ready for circulation.
+
+The first thing you'll probably want to do is see it work. Try running:
+
+./simulate -v
+
+to see the sample agents duke it out for up to 150 rounds (the current sample
+agents suck - rounds either go for seconds or for ages). After that, take a
+look at sampleAgents.py to see how agents are implemented on top of the
+BaseAgent and LearningAgent classes. When you're ready to try out your own,
+edit the first few lines of simulate.py to include your agent.
+
+...and if all you're interested in is participating, that's it! You can stop
+reading, and start work on the agent that will outsmart them all!
+
+Contributor instructions:
+
+BaseAgent, LearningAgent and Supervisor are all implemented in uccProgComp.py.
+The 'select' algorithm, responsible for choosing agents for battle and
+determining when a round is finished, is the hottest part of the code and the
+most open to discussion and change. 
+
+Unfortunately, it is not an easy bit of code to understand. Once upon a time,
+in builds long past, it used friendly O(n) operations and conveniently wasted
+memory on simple tasks. After hours of profiling, it is a little more complex,
+but with a bit of background to how the supervisor operates you shouldn't have
+much trouble working out the rest:
+
+1.) A copy of the current population list is made at the beginning of the round
+representing the agents who can still fight. This reduces finding valid agents
+from O(n) to O(1). I call it the 'remaining' list.
+2.) Agents must remember their index in the population list. This is because it
+would be O(n) to determine their index in the population list (to remove them
+when they die) from their index in the 'remaining' list. Agents have this value
+stored at the beginning of the round - O(n) at the beginning of the round is
+far preferable to O(n) for every death.
+3.) The actual removal of agents from the population list must happen all at
+once in reverse numeric index order at the end of the round so that the stored
+index that agents have does not become stale. 
+
+There are problems. It's not perfect, but it's relatively fast and powerful and
+quite easy to adjust or reimplement once you get your head around it. I'm very
+much open to suggestion for improvement (especially in the form of patches) and
+welcome all help, constructive criticism, derisive criticism and death threats.
+
+Things to be done:
+
+1.) Pretty graphs! Iterate () returns a collection of statistics about each of
+the classes, which can be seen used in simulate.py. There are plenty of
+plotting packages out there that can turn this information into impressive
+charts.
+2.) More built-in functionality for BaseAgent and LearningAgent. They could
+both do with a few more utility functions for competitors to use.
+3.) A more succint set of rules and documentation.
+
+Thanks for reading!
+Luke
+
+* Or rather, it wil by the time this package is ready for distribution.
diff --git a/src/SampleAgents.py b/src/SampleAgents.py
new file mode 100644 (file)
index 0000000..6da30ba
--- /dev/null
@@ -0,0 +1,89 @@
+'''SampleAgents.py - A collection of sample agents for playing Rock Paper Scissors.
+Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
+Requires Python 2.5.
+
+Licensed under an MIT-style license: see the LICENSE file for details.
+'''
+
+from uccProgComp import BaseAgent, LearningAgent, RandomAttack
+from rpsconst import *
+
+# Angel is a very simple bot that always tells the truth and expects others to do the same.
+class Dummy (BaseAgent):
+       def Attack (self, foe):
+               return Paper, Paper
+       def Defend (self, foe, bluff):
+               return bluff
+
+class Angel (BaseAgent):
+       def Attack (self, foe):
+               attack = RandomAttack ()        # Chooses randomly from Rock, Paper, Scissors
+               return attack, attack           # Tells the truth for its bluff.
+       def Defend (self, foe, bluff):
+               return bluff                    # Trusts them to be going for a tie.
+
+# Lucifer here is the opposite. He always lies expecting people to be good and always goes for the kill.
+class Lucifer (BaseAgent):
+       def Attack (self, foe):
+               attack = RandomAttack ()
+               if attack == Rock: bluff = Scissors     # Here we choose the thing
+               elif attack == Paper: bluff = Rock      # that will hurt them
+               else: bluff = Paper                     # if they go for a tie.
+               return attack, bluff
+       def Defend (self, foe, bluff):
+               if bluff == Rock: attack = Paper        # Here we trust that they
+               elif bluff == Paper: attack = Scissors  # are telling the truth.
+               else: attack = Rock                     # And we try to kill them.
+               return attack
+#      def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
+#              BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
+#              print "I just scored " + str(pointDelta) + " points!"
+
+
+# Streetfighter assumes everyone has it in for him.
+class Streetfighter (BaseAgent):
+       def Attack (self, foe):
+               attack = RandomAttack ()
+               if attack == Rock: bluff = Paper        # Here we choose the thing
+               elif attack == Paper: bluff = Scissors  # that will hurt them
+               else: bluff = Rock                      # if they try to kill us.
+               return attack, bluff
+       def Defend (self, foe, bluff):
+               if bluff == Rock: attack = Scissors     # Here we assume that they
+               elif bluff == Paper: attack = Rock      # are lying, trying to kill us.
+               else: attack = Paper                    # And we try to kill them.
+               return attack
+
+# This is our first bot with any sort of learning capability, based on the LearningAgent base.
+# Experienced programmers might opt to write their own learning code based on BaseAgent, but it's up to you.
+# Frenchie is a simple bot that is by default nice but will permanently turn against any agent that betrays it.
+class Frenchie (LearningAgent):
+       def Attack (self, foe):
+               attack = RandomAttack ()
+               if Loss in LearningAgent.GetWinHistory (self, foe):
+                       if attack == Rock: bluff = Scissors
+                       elif attack == Paper: bluff = Rock
+                       else: bluff = Paper
+               else:
+                       bluff = attack
+               return attack, bluff
+       def Defend (self, foe, bluff):
+               if Loss in LearningAgent.GetWinHistory (self, foe):
+                       if bluff == Rock: attack = Scissors     # They've fucked us in the past,
+                       elif bluff == Paper: attack = Rock      # so we assume they're lying and
+                       else: attack = Paper                    # hoping we go for a kill.
+               else:
+                       attack = bluff
+               return attack
+
+
+# If you want to implement your own Results () callback, you have to call the parent class's first:
+class Blank (BaseAgent):
+       def Attack (self, foe):
+               return Paper, Paper
+       def Defend (self, foe, bluff):
+               return bluff
+       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
+               BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
+               # Now you can do your own thing
+
diff --git a/src/SampleAgents.py.old b/src/SampleAgents.py.old
new file mode 100644 (file)
index 0000000..d307214
--- /dev/null
@@ -0,0 +1,89 @@
+'''SampleAgents.py - A collection of sample agents for playing Rock Paper Scissors.
+Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
+Requires Python 2.5.
+
+Licensed under an MIT-style license: see the LICENSE file for details.
+'''
+
+from uccProgComp import BaseAgent, LearningAgent, RandomAttack
+from rpsconst import *
+
+# Angel is a very simple bot that always tells the truth and expects others to do the same.
+class Dummy (BaseAgent):
+       def Attack (self, foe):
+               return Paper, Paper
+       def Defend (self, foe, bluff):
+               return bluff
+
+class Angel (BaseAgent):
+       def Attack (self, foe):
+               attack = RandomAttack ()        # Chooses randomly from Rock, Paper, Scissors
+               return attack, attack           # Tells the truth for its bluff.
+       def Defend (self, foe, bluff):
+               return bluff                    # Trusts them to be going for a tie.
+
+# Lucifer here is the opposite. He always lies expecting people to be good and always goes for the kill.
+class Lucifer (BaseAgent):
+       def Attack (self, foe):
+               attack = RandomAttack ()
+               if attack == Rock: bluff = Scissors     # Here we choose the thing
+               elif attack == Paper: bluff = Rock      # that will hurt them
+               else: bluff = Paper                     # if they go for a tie.
+               return attack, bluff
+       def Defend (self, foe, bluff):
+               if bluff == Rock: attack = Paper        # Here we trust that they
+               elif bluff == Paper: attack = Scissors  # are telling the truth.
+               else: attack = Rock                     # And we try to kill them.
+               return attack
+#      def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
+#              BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
+#              print "I just scored " + str(pointDelta) + " points!"
+
+
+# Streetfighter assumes everyone has it in for him.
+class Streetfighter (BaseAgent):
+       def Attack (self, foe):
+               attack = RandomAttack ()
+               if attack == Rock: bluff = Paper        # Here we choose the thing
+               elif attack == Paper: bluff = Scissors  # that will hurt them
+               else: bluff = Rock                      # if they go for a tie.
+               return attack, bluff
+       def Defend (self, foe, bluff):
+               if bluff == Rock: attack = Paper        # Here we trust that they
+               elif bluff == Paper: attack = Scissors  # are telling the truth.
+               else: attack = Rock                     # And we try to kill them.
+               return attack
+
+# This is our first bot with any sort of learning capability, based on the LearningAgent base.
+# Experienced programmers might opt to write their own learning code based on BaseAgent, but it's up to you.
+# Frenchie is a simple bot that is by default nice but will permanently turn against any agent that betrays it.
+class Frenchie (LearningAgent):
+       def Attack (self, foe):
+               attack = RandomAttack ()
+               if Loss in LearningAgent.GetWinHistory (self, foe):
+                       if attack == Rock: bluff = Scissors
+                       elif attack == Paper: bluff = Rock
+                       else: bluff = Paper
+               else:
+                       bluff = attack
+               return attack, bluff
+       def Defend (self, foe, bluff):
+               if Loss in LearningAgent.GetWinHistory (self, foe):
+                       if bluff == Rock: attack = Scissors     # They've fucked us in the past,
+                       elif bluff == Paper: attack = Rock      # so we assume they're lying and
+                       else: attack = Paper                    # hoping we go for a kill.
+               else:
+                       attack = bluff
+               return attack
+
+
+# If you want to implement your own Results () callback, you have to call the parent class's first:
+class Blank (BaseAgent):
+       def Attack (self, foe):
+               return Paper, Paper
+       def Defend (self, foe, bluff):
+               return bluff
+       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
+               BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
+               # Now you can do your own thing
+
diff --git a/src/SampleAgents.pyc b/src/SampleAgents.pyc
new file mode 100644 (file)
index 0000000..7b91932
Binary files /dev/null and b/src/SampleAgents.pyc differ
diff --git a/src/djaAgents.py b/src/djaAgents.py
new file mode 100644 (file)
index 0000000..6912c7f
--- /dev/null
@@ -0,0 +1,77 @@
+from uccProgComp import BaseAgent, LearningAgent, RandomAttack
+from rpsconst import *
+
+# BOFH is something of a cross between Frechie and Lucifer
+
+class BOFH (LearningAgent):
+       def Attack (self, foe):
+               attack = RandomAttack ()
+               
+               return attack, bluff
+       def Defend (self, foe, bluff):
+               if bluff == Rock: attack = Scissors     # Here we assume that they
+               elif bluff == Paper: attack = Rock      # are lying, trying to kill us.
+               else: attack = Paper                    # And we try to kill them.
+               return attack
+
+       def Attack (self, foe):
+               attack = RandomAttack ()
+               if len(LearningAgent.GetWinHistory (self, foe)) > 0:
+                       if attack == Rock: bluff = Paper        # Here we choose the thing
+                       elif attack == Paper: bluff = Scissors  # that will hurt them
+                       else: bluff = Rock                      # if they try to kill us.
+               else:
+                       if attack == Rock: bluff = Scissors     # Here we choose the thing
+                       elif attack == Paper: bluff = Rock      # that will hurt them
+                       else: bluff = Paper                     # if they go for a tie.
+               return attack, bluff
+               
+       def Defend (self, foe, bluff):
+               if len(LearningAgent.GetWinHistory (self, foe)) > 0:
+                       if bluff == Rock: attack = Scissors     # They've fucked us in the past,
+                       elif bluff == Paper: attack = Rock      # so we assume they're lying and
+                       else: attack = Paper                    # hoping we go for a kill.
+               else:
+                       if bluff == Rock: attack = Paper        # Here we trust that they
+                       elif bluff == Paper: attack = Scissors  # are telling the truth.
+                       else: attack = Rock                     # And we try to kill them.
+               return attack
+
+#Fish is somewhat intelligent; it builds up trust and then stabs you in the back.
+# If Fish detects that a bot is being predictably nice (tie 2+ times in a row), it will attack.
+# If Fish detects that a bot has betrayed it (Loss), it will attack.
+# Otherwise, Fish is nice.
+
+class Fish (LearningAgent):
+       def Attack (self, foe):
+               #print "Attacking" , foe
+               #print LearningAgent.GetWinHistory (self, foe)
+               attack = RandomAttack ()
+               
+               history = LearningAgent.GetWinHistory (self, foe)
+               
+               #no history; be nice
+               if len(history) == 0:
+                       bluff = attack
+               
+               #if we just lost to them, try to destroy them.
+               elif Loss == history[-1] or (len(history)>1 and [Tie,Tie] == history[-2:-1]):
+                       if attack == Rock: bluff = Scissors
+                       elif attack == Paper: bluff = Rock
+                       else: bluff = Paper
+               else:
+                       bluff = attack
+               return attack, bluff
+               
+               
+       def Defend (self, foe, bluff):
+               
+               history = LearningAgent.GetWinHistory (self, foe)
+               
+               if len(history) > 0 and Loss == history[-1]:
+                       if bluff == Rock: attack = Scissors     # They've fucked us in the past,
+                       elif bluff == Paper: attack = Rock      # so we assume they're lying and
+                       else: attack = Paper                    # hoping we go for a kill.
+               else:
+                       attack = bluff
+               return attack
\ No newline at end of file
diff --git a/src/djaAgents.pyc b/src/djaAgents.pyc
new file mode 100644 (file)
index 0000000..9d72619
Binary files /dev/null and b/src/djaAgents.pyc differ
diff --git a/src/link/C/c-link-lib/.gitignore b/src/link/C/c-link-lib/.gitignore
new file mode 100644 (file)
index 0000000..fbde527
--- /dev/null
@@ -0,0 +1,2 @@
+agents/
+!agents/*.c
diff --git a/src/link/C/c-link-lib/Makefile b/src/link/C/c-link-lib/Makefile
new file mode 100644 (file)
index 0000000..10e306b
--- /dev/null
@@ -0,0 +1,28 @@
+CC=gcc
+AR=ar
+
+CFLAGS=-Wall -I.
+LDFLAGS=-lc_link -L.
+
+LINKSRCS=c_link.c
+LINKOBJS=$(LINKSRCS:.c=.o)
+LINKLIB=libc_link.a
+
+AGENTSRCS=$(wildcard agents/*.c)
+AGENTS=$(AGENTSRCS:.c=)
+
+all: $(LINKSRCS) $(LINKLIB) $(AGENTS)
+       
+$(LINKLIB): $(LINKOBJS)
+       $(AR) rcs $(LINKLIB) $(LINKOBJS)
+       
+$(AGENTS): $(AGENTSRCS) 
+       @echo Building $<
+       $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
+
+.c.o: c_link.h
+       $(CC) -c $(CFLAGS) $< -o $@
+
+.PHONY : clean
+clean:
+       rm $(LINKOBJS) $(LINKLIB) $(AGENTS)
diff --git a/src/link/C/c-link-lib/agents/c-angel.c b/src/link/C/c-link-lib/agents/c-angel.c
new file mode 100644 (file)
index 0000000..c6c8687
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  c-angel.c
+ *  c-link-lib
+ *
+ *  Created by Daniel Axtens on 20/04/10.
+ *  Licensed under an MIT-style license: see the LICENSE file for details.
+ *
+ */
+
+#include <c_link.h>
+
+/* Implement the angel bot, which always tells the truth
+   and expects others to do the same */
+
+ATTACKTYPE Attack( char * foe_name ) {
+       ATTACKTYPE attack;
+       
+       attack.realAttack =  RandomAttack();            /* Chooses randomly from Rock, Paper, Scissors */ 
+       attack.promisedAttack = attack.realAttack;      /* Tells the truth for its bluff */
+
+       return attack;
+}
+
+ITEMTYPE Defend( char * foeName, ITEMTYPE foePromisedAttack ) {
+       return foePromisedAttack;       /* Trusts them to be going for a tie */
+}
+
+/* You need to define a results function, even if it isn't used
+   (otherwise the linker will complain) */
+void Results( char * foeName, int isInstigatedByYou, ITEMTYPE yourItem, 
+                        ITEMTYPE theirItem, ITEMTYPE promisedItem) {
+       
+       return; /* Ignore whatever just happened. */
+}
+
+/* same for Cleanup() */
+
+void Cleanup() {
+       return;
+}
\ No newline at end of file
diff --git a/src/link/C/c-link-lib/agents/c-frechie.c b/src/link/C/c-link-lib/agents/c-frechie.c
new file mode 100644 (file)
index 0000000..ed2ba09
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *  c-frechie.c
+ *  c-link-lib
+ *
+ *  Created by Daniel Axtens on 22/04/10.
+ *  Licensed under an MIT-style license: see the LICENSE file for details.
+ *
+ */
+
+#include <c_link.h>
+#include <stdlib.h>
+
+/* Implement the frenchie bot, that is by default nice but will 
+   permanently turn against any agent that betrays it.
+   This is trickier in C than in any other language, for a number of reasons:
+     - there's no classes in C, so we can't just write a generic learning agent
+       and subclass it.
+     - your agent has no idea how many agents it's going to battle, or how many
+       battles it is going to fight, so you've got to do dynamic memory allocation.
+        (anyone who tries to read the source of the supervisor to find out is liable
+         to have their program break unexpectedly)
+ */
+
+/* To simplify things, we just look at whether we have lost to a particular agent.
+   Unlike in the Python version, we don't keep a generic list
+   This is also done in a inefficient (O(bot-cout)) way.
+   Implementing a faster version is left as an exercise to the DSA student. */
+
+/* Our guess at the number of agents I'm going to fight in my lifetime */
+#define NUMBEROFAGENTSGUESS 100
+
+/* The name of the n-th foe we've seen, as well as a 0/1 have we lost to them */
+char foesNames[][MAXFOENAMELEN] = NULL;
+int haveLostToFoe[] = NULL;
+
+/* The length of the array, and how far we are along it */
+size_t foesLen = 0;
+unsigned int foesCount = 0;
+
+
+ATTACKTYPE Attack( char * foe_name ) {
+       ATTACKTYPE attack;
+       
+       attack.realAttack =  RandomAttack();
+       
+       /* Here we choose the thing that will hurt them if they go for the kill */
+       switch (attack.realAttack) {
+               case rock:
+                       result.promisedAttack = paper;
+                       break;
+               case paper:
+                       result.promisedAttack = scissors;
+                       break;
+               default: /* attack = scissors */
+                       result.promisedAttack = rock;
+                       break;
+       }
+       return attack;
+}
+
+/* Here we assume they are lying, trying to kill us. And we try to kill them. */
+ITEMTYPE Defend( char * foeName, ITEMTYPE foePromisedAttack ) {
+       ITEMTYPE defence;
+       switch (foePromisedAttack) {
+               case rock:
+                       defence = scissors;
+                       break;
+               case paper:
+                       defence = rock;
+                       break;
+               default:
+                       defence = paper;
+                       break;
+       }
+}
+
+/* This is so much less fun in C */
+void Results( char * foeName, int isInstigatedByYou, ITEMTYPE yourItem, 
+                        ITEMTYPE theirItem, ITEMTYPE promisedItem) {
+       
+    int foe;
+    
+    /* check to see if we've initialised our arrays */
+       if (foesNames == NULL) {
+        foesNames = calloc( NUMBEROFAGENTSGUESS, sizeof( foesNames[0] ) );
+        haveLostToFoe = calloc( NUMBEROFAGENTSGUESS, sizeof( haveLostToFoe[0] ) );
+        foesLen = NUMBEROFAGENTSGUESS;
+    }
+    
+    /* figure out if we lost, which is the only thing we care about
+       if we didn't, move on. */
+    if (RESULTOF[yourItem][theirItem] != lose) return;
+    
+    /* try and find existing foe */
+    
+    return;
+}
+
+/* same for Cleanup() */
+
+void Cleanup() {
+       free(foesNames);
+    free(haveLostToFoe);
+}
\ No newline at end of file
diff --git a/src/link/C/c-link-lib/agents/c-lucifer.c b/src/link/C/c-link-lib/agents/c-lucifer.c
new file mode 100644 (file)
index 0000000..1dabc34
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  c-lucifer.c
+ *  c-link-lib
+ *
+ *  Created by Daniel Axtens on 20/04/10.
+ *  Licensed under an MIT-style license: see the LICENSE file for details.
+ *
+ */
+
+
+#include <c_link.h>
+
+/* Implement the lucifer bot, which always lies expecting people to be good
+   and always goes for the kill */
+
+ATTACKTYPE Attack( char * foe_name ) {
+       ATTACKTYPE attack;
+       
+       attack.realAttack =  RandomAttack();
+       
+       /* Here we choose the thing that will hurt them if they go for a tie */
+       switch (attack.realAttack) {
+               case rock:
+                       result.promisedAttack = scissors;
+                       break;
+               case paper:
+                       result.promisedAttack = rock;
+                       break;
+               default: /* attack = scissors */
+                       result.promisedAttack = paper;
+                       break;
+       }
+       attack.promisedAttack = result.realAttack;      /* Tells the truth for its bluff */
+       
+       return attack;
+}
+
+/* Here we trust that they are telling the truth. And we try to kill them. */
+ITEMTYPE Defend( char * foeName, ITEMTYPE foePromisedAttack ) {
+       ITEMTYPE defence;
+       switch (foePromisedAttack) {
+               case rock:
+                       defence = paper;
+                       break;
+               case paper:
+                       defence = scissors;
+                       break;
+               default:
+                       defence = rock;
+                       break;
+       }
+}
+
+/* You need to define a results function, even if it isn't used
+ (otherwise the linker will complain) */
+void Results( char * foeName, int isInstigatedByYou, ITEMTYPE yourItem, 
+                        ITEMTYPE theirItem, ITEMTYPE promisedItem) {
+       
+       return; /* Ignore whatever just happened. */
+}
+
+/* same for Cleanup() */
+
+void Cleanup() {
+       return;
+}
\ No newline at end of file
diff --git a/src/link/C/c-link-lib/agents/c-streetfighter.c b/src/link/C/c-link-lib/agents/c-streetfighter.c
new file mode 100644 (file)
index 0000000..c63939d
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  c-streetfighter.c
+ *  c-link-lib
+ *
+ *  Created by Daniel Axtens on 20/04/10.
+ *  Licensed under an MIT-style license: see the LICENSE file for details.
+ *
+ */
+
+
+#include <c_link.h>
+
+/* Implement the streetfighter bot, which thinks everyone has it in for him. */
+
+ATTACKTYPE Attack( char * foe_name ) {
+       ATTACKTYPE attack;
+       
+       attack.realAttack =  RandomAttack();
+       
+       /* Here we choose the thing that will hurt them if they go for the kill */
+       switch (attack.realAttack) {
+               case rock:
+                       result.promisedAttack = paper;
+                       break;
+               case paper:
+                       result.promisedAttack = scissors;
+                       break;
+               default: /* attack = scissors */
+                       result.promisedAttack = rock;
+                       break;
+       }
+       return attack;
+}
+
+/* Here we assume they are lying, trying to kill us. And we try to kill them. */
+ITEMTYPE Defend( char * foeName, ITEMTYPE foePromisedAttack ) {
+       ITEMTYPE defence;
+       switch (foePromisedAttack) {
+               case rock:
+                       defence = scissors;
+                       break;
+               case paper:
+                       defence = rock;
+                       break;
+               default:
+                       defence = paper;
+                       break;
+       }
+}
+
+/* You need to define a results function, even if it isn't used
+ (otherwise the linker will complain) */
+void Results( char * foeName, int isInstigatedByYou, ITEMTYPE yourItem, 
+                        ITEMTYPE theirItem, ITEMTYPE promisedItem) {
+       
+       return; /* Ignore whatever just happened. */
+}
+
+/* same for Cleanup() */
+
+void Cleanup() {
+       return;
+}
diff --git a/src/link/C/c-link-lib/c-link-lib.xcodeproj/project.pbxproj b/src/link/C/c-link-lib/c-link-lib.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..80d9803
--- /dev/null
@@ -0,0 +1,150 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 45;
+       objects = {
+
+/* Begin PBXFileReference section */
+               2291A1BB117EDB9600854CBE /* c_link.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = c_link.c; sourceTree = "<group>"; };
+               2291A1BD117EE3FD00854CBE /* c-angel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "c-angel.c"; sourceTree = "<group>"; };
+               2291A1BE117EE3FD00854CBE /* c-lucifer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "c-lucifer.c"; sourceTree = "<group>"; };
+               2291A1BF117EE3FD00854CBE /* c-streetfighter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "c-streetfighter.c"; sourceTree = "<group>"; };
+               2291A1EC117FF85D00854CBE /* c-frechie.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "c-frechie.c"; sourceTree = "<group>"; };
+               22F652F5117C679300A3793D /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
+               22F652F6117C6C9500A3793D /* c_link.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = c_link.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXGroup section */
+               08FB7794FE84155DC02AAC07 /* c-link-lib */ = {
+                       isa = PBXGroup;
+                       children = (
+                               2291A1BC117EE3FD00854CBE /* agents */,
+                               22F652F6117C6C9500A3793D /* c_link.h */,
+                               2291A1BB117EDB9600854CBE /* c_link.c */,
+                               22F652F5117C679300A3793D /* Makefile */,
+                       );
+                       name = "c-link-lib";
+                       sourceTree = "<group>";
+               };
+               2291A1BC117EE3FD00854CBE /* agents */ = {
+                       isa = PBXGroup;
+                       children = (
+                               2291A1BD117EE3FD00854CBE /* c-angel.c */,
+                               2291A1BE117EE3FD00854CBE /* c-lucifer.c */,
+                               2291A1BF117EE3FD00854CBE /* c-streetfighter.c */,
+                               2291A1EC117FF85D00854CBE /* c-frechie.c */,
+                       );
+                       path = agents;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXLegacyTarget section */
+               D28A88AD04BDD90700651E21 /* c-link-lib */ = {
+                       isa = PBXLegacyTarget;
+                       buildArgumentsString = "$(ACTION)";
+                       buildConfigurationList = 1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "c-link-lib" */;
+                       buildPhases = (
+                       );
+                       buildToolPath = /usr/bin/make;
+                       buildWorkingDirectory = "";
+                       dependencies = (
+                       );
+                       name = "c-link-lib";
+                       passBuildSettingsInEnvironment = 1;
+                       productName = "c-link-lib";
+               };
+/* End PBXLegacyTarget section */
+
+/* Begin PBXProject section */
+               08FB7793FE84155DC02AAC07 /* Project object */ = {
+                       isa = PBXProject;
+                       buildConfigurationList = 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "c-link-lib" */;
+                       compatibilityVersion = "Xcode 3.1";
+                       hasScannedForEncodings = 1;
+                       mainGroup = 08FB7794FE84155DC02AAC07 /* c-link-lib */;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               D28A88AD04BDD90700651E21 /* c-link-lib */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin XCBuildConfiguration section */
+               1DEB919008733D9F0010E9CD /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = NO;
+                               DEBUGGING_SYMBOLS = YES;
+                               GCC_DYNAMIC_NO_PIC = NO;
+                               GCC_ENABLE_FIX_AND_CONTINUE = YES;
+                               GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+                               GCC_OPTIMIZATION_LEVEL = 0;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               PRODUCT_NAME = "c-link-lib";
+                       };
+                       name = Debug;
+               };
+               1DEB919108733D9F0010E9CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               COPY_PHASE_STRIP = YES;
+                               GCC_ENABLE_FIX_AND_CONTINUE = NO;
+                               OTHER_CFLAGS = "";
+                               OTHER_LDFLAGS = "";
+                               PRODUCT_NAME = "c-link-lib";
+                       };
+                       name = Release;
+               };
+               1DEB919408733D9F0010E9CD /* Debug */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               ONLY_ACTIVE_ARCH = YES;
+                               PREBINDING = NO;
+                               SDKROOT = macosx10.6;
+                       };
+                       name = Debug;
+               };
+               1DEB919508733D9F0010E9CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               PREBINDING = NO;
+                               SDKROOT = macosx10.6;
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "c-link-lib" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               1DEB919008733D9F0010E9CD /* Debug */,
+                               1DEB919108733D9F0010E9CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "c-link-lib" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               1DEB919408733D9F0010E9CD /* Debug */,
+                               1DEB919508733D9F0010E9CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/src/link/C/c-link-lib/c_link.c b/src/link/C/c-link-lib/c_link.c
new file mode 100644 (file)
index 0000000..680450e
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ *  c_link.c
+ *  c-link-lib
+ *
+ *  Created by Daniel Axtens on 19/04/10.
+ *  Licensed under an MIT-style license: see the LICENSE file for details.
+ *
+ */
+
+#include "c_link.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+
+/* You don't need to read this file.
+   All you have to do is implement the bot functions defined in <c_link.h>
+   This file sets up the I/O for you, as well as some utility functions and tables. 
+ */
+
+char ITEMNAMES[3][MAXITEMLEN] = {"Rock", "Paper", "Scissors"};
+
+/* rock-rock     rock-paper     rock-scissors 
+   paper-rock    paper-paper    paper-scissors
+   scissors-rock scissors-paper scissors-scissors */  
+   
+RESULTTYPE RESULTOF[3][3] = { { tie, lose, win },
+                              { win, tie, lose },
+                              { lose, win, tie } };
+
+
+ITEMTYPE RandomAttack() {
+       return (ITEMTYPE)rand()%3;
+}
+
+ITEMTYPE stringToItem( char * str ) {
+       if (strcasecmp( str, "Rock" ) == 0) return rock;
+       if (strcasecmp( str, "Paper" ) == 0) return paper;
+       if (strcasecmp( str, "Scissors" ) == 0) return scissors;
+       /* If we reach this point, we've got real problems. */
+       fprintf( stderr, "Attempt to convert invalid string \"%s\" into an ITEMTYPE! Aborting.\n", str );
+       exit(EXIT_FAILURE);
+       return -1;
+}
+       
+
+int main( int argc, char * argv[] ) {
+       srand( time( NULL ) );
+       
+       char command[MAXCOMMANDLEN];
+       char foeName[MAXFOENAMELEN];
+       char yourItem[MAXITEMLEN], theirItem[MAXITEMLEN], promisedItem[MAXITEMLEN];
+       char didYouInstigate[MAXBOOLLEN], childSpawned[MAXBOOLLEN];
+       int pointChange;
+       
+       ATTACKTYPE attack;
+       ITEMTYPE defence;
+       
+       scanf( "%s", command );
+       
+       while (strcasecmp("BYE",command) != 0) {
+               
+               if (strcasecmp("ATTACK", command) == 0) {
+                       scanf( "%s", foeName );
+                       attack = Attack( foeName );
+                       printf("ATTACKING %s %s\n", ITEMNAMES[attack.realAttack], ITEMNAMES[attack.promisedAttack]);
+               
+               } else if (strcasecmp("DEFEND", command) == 0) {
+                       scanf( "%s %s", foeName, promisedItem );
+                       defence = Defend(foeName, stringToItem(promisedItem));
+                       printf("DEFENDING %s\n", ITEMNAMES[defence]);
+               
+               } else if (strcasecmp("RESULTS", command) == 0) {
+                       scanf( "%s %s %s %s %s %d %s", foeName, didYouInstigate, yourItem, theirItem, promisedItem, &pointChange, childSpawned );
+                       Results(foeName, (strcasecmp("False",didYouInstigate)==0),
+                                       stringToItem(yourItem), stringToItem(theirItem), stringToItem(promisedItem));
+                       printf("OK\n");
+               }
+       
+               // read the next command!
+               scanf( "%s", command );
+       }
+       
+       Cleanup();
+       
+       return 0;
+}
\ No newline at end of file
diff --git a/src/link/C/c-link-lib/c_link.h b/src/link/C/c-link-lib/c_link.h
new file mode 100644 (file)
index 0000000..84e9bce
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ *  c_link.h
+ *  c-link-lib
+ *
+ *  Created by Daniel Axtens on 19/04/10.
+ *  Licensed under an MIT-style license: see the LICENSE file for details.
+ *
+ */
+
+#include <stdio.h>
+
+#define MAXCOMMANDLEN  15
+#define MAXFOENAMELEN  50
+#define MAXITEMLEN             10
+#define MAXBOOLLEN             6
+
+/********** Type definitions **********/
+
+/* The type of item used in an attack or defence */
+typedef enum {rock, paper, scissors} ITEMTYPE;
+
+/* A result of a battle */
+typedef enum {win, lose, tie} RESULTTYPE;
+
+
+/* An attack, consisting of the real attack and the attack promised */
+typedef struct {
+       ITEMTYPE realAttack;
+       ITEMTYPE promisedAttack;
+} ATTACKTYPE;
+
+
+/********** Utility Function definitions **********/
+/* These are implemented in c-link.c, and automagically linked in */
+
+/* prints a debug message. Same arguments as printf().
+   (you can't use printf because it is used to talk between
+    the agent and supervisor) 
+ */
+
+#define debugmsg(x...) sprintf(stderr, x)
+
+/* Returns a random item */
+
+ITEMTYPE RandomAttack();
+
+/* A useful translation table
+   eg printf( "I use %s.\n", ITEMNAMES[rock] ); */
+
+extern char ITEMNAMES[3][MAXITEMLEN];
+
+/* Another useful table - what's the result of the 
+   first item vs the second item? */
+extern RESULTTYPE RESULTOF[3][3];
+
+/********** Bot Function definitions **********/
+/* You need to provide implementations for these to create a bot */
+
+/* Defend( foeName : string - the name of your foe;
+           foePromisedAttack : ITEMTYPE - the item your foe promised to use
+         ) : ITEMTYPE - the item you wish to use to defend;
+ Called when your agent needs to defend itself.
+ */
+ITEMTYPE Defend( char * foeName, ITEMTYPE foePromisedAttack );
+
+
+/* Attack( foeName : string - the name of your foe
+                ) : ATTACKTYPE - the real and promised attack you wish to use
+
+ Called when your agent needs to attack another agent.
+ */
+ATTACKTYPE Attack( char * foeName );
+
+
+/* Results( foeName : string - the name of your foe;
+            isInstigatedByYou : 0=you defended/1=you attacked;
+                       yourItem : ITEMTYPE - the item you used;
+            theirItem : ITEMTYPE - the item they used;
+            promisedItem : ITEMTYPE - the item that was promised
+          );
+
+ Called after your agent battles another agent, to tell you how the battle goes.
+ */
+void Results( char * foeName, int isInstigatedByYou, ITEMTYPE yourItem, 
+                         ITEMTYPE theirItem, ITEMTYPE promisedItem);
+
+/* Cleanup();
+
+   Called when your agent is no longer needed, either due to the round ending
+   or due to your agent being eliminated.
+
+ */
+void Cleanup();
\ No newline at end of file
diff --git a/src/link/Mathematica/pyml.tar.gz b/src/link/Mathematica/pyml.tar.gz
new file mode 100644 (file)
index 0000000..498748f
Binary files /dev/null and b/src/link/Mathematica/pyml.tar.gz differ
diff --git a/src/link/Mathematica/pythonika-1.0.tar.gz b/src/link/Mathematica/pythonika-1.0.tar.gz
new file mode 100644 (file)
index 0000000..6611f5d
Binary files /dev/null and b/src/link/Mathematica/pythonika-1.0.tar.gz differ
diff --git a/src/rpsconst.py b/src/rpsconst.py
new file mode 100644 (file)
index 0000000..5bf1ea5
--- /dev/null
@@ -0,0 +1,19 @@
+'''rpsconst.py - A precarious collection of constants for RPS simulation.
+Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
+
+Licensed under an MIT-style license: see the LICENSE file for details.
+'''
+
+Rock = 0
+Paper = 1
+Scissors = 2
+Attacker = 0
+Defender = 1
+Tie = 2
+Bluff = 0
+Truth = 1
+Win = 3
+Loss = 4
+# EOF. Stop reading now, kid, you'll only hurt yourself.
+resultTable = [[Tie,Defender,Attacker],[Attacker,Tie,Defender],[Defender, Attacker, Tie]]
+pointsTable = [[0,0],[0,0],[0,0]]
diff --git a/src/rpsconst.pyc b/src/rpsconst.pyc
new file mode 100644 (file)
index 0000000..6feecaf
Binary files /dev/null and b/src/rpsconst.pyc differ
diff --git a/src/selectAlgorithms.py b/src/selectAlgorithms.py
new file mode 100644 (file)
index 0000000..41be346
--- /dev/null
@@ -0,0 +1,23 @@
+# Alternative (obsolete) algorithms for selecting agents for battle.
+# They're all a bit crap and only here for comparison purposes.
+
+
+# Selects an opponent and removes it from the list of remaining potential opponents.
+       # This is just an example, but the fact that the first agent will miss out on having
+       # a fight picked with it it, and that the last agent won't get to pick a fight, seems
+       # to not matter very much. Can probably be left as-is.
+       def ChoosePair (self):
+               # This approach forces each agent to defend once and attack once per round.
+               # Keep track of the remaining population.
+               remaining = self.population[:]
+               agentID = random.randint (0,len(remaining)-1)
+               defender = remaining.pop (agentID) # Not really a defender (try to work it out)!
+               while len (remaining) > 1:
+                       if defender.GetPoints () < 1:   # If the agent died before it got a chance to attack
+                               attackerID = random.randint (0,len(remaining)-1)
+                               attacker = remaining.pop (attackerID)
+                       else: attacker = defender
+                       defenderID = random.randint (0,len(remaining)-1)
+                       defender = remaining.pop (defenderID)
+                       yield attacker, defender
+
diff --git a/src/simulate.py b/src/simulate.py
new file mode 100755 (executable)
index 0000000..13a20fa
--- /dev/null
@@ -0,0 +1,86 @@
+#!/usr/bin/python2.5
+'''simulate.py - Runs a full simulation of the UCC Programming Competition with the provided agents.
+Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
+
+Licensed under an MIT-style license: see the LICENSE file for details.
+'''
+
+# Import and add your agents here:
+from djaAgents import BOFH
+from SampleAgents import Angel, Lucifer, Dummy, Frenchie, Streetfighter
+Agents = [Angel, Lucifer, Frenchie, Streetfighter, BOFH]
+
+####################################
+# Developers only past this point! #
+####################################
+
+import sys
+from uccProgComp import Supervisor
+
+maxIterations = 150
+startingPopulations = 10
+verbose = False
+trials = 1
+usage = "Usage: rps [-v] [-i iterations=150] [-n starting_populations=10] [-t trials=1]"
+for i in range (1,len(sys.argv)):
+       if sys.argv[i] == "-i":
+               try:
+                       maxIterations = int(sys.argv[i+1])
+                       i += 1
+                       continue
+               except:
+                       print usage
+                       sys.exit(1)
+       elif sys.argv[i] == "-n":
+               try:
+                       startingPopulations = int(sys.argv[i+1])
+                       i += 1
+                       continue
+               except:
+                       print usage
+                       sys.exit(1)
+       elif sys.argv[i] == "-t":
+               try:
+                       trials = int(sys.argv[i+1])
+                       i += 1
+                       continue
+               except:
+                       print usage
+                       sys.exit(1)
+
+       elif sys.argv[i] == "-v":
+               verbose = True
+
+
+iteration = 0
+trial = 0
+winners = {}
+while trial < trials:
+       sup = Supervisor ()
+       for Agent in Agents: sup.RegisterAgent (Agent)
+       sup.GeneratePopulation (startingPopulations)
+
+       trial += 1
+       iteration = 0
+       while iteration < maxIterations and not sup.IsGameOver ():
+               iteration += 1
+               sup.Iterate ()
+               if not verbose: continue
+               print "Iteration %d:" % iteration
+               for key, value in sup.GetStats ().iteritems():
+                       print "%s: Population=%d, Newborns=%d, Deaths=%d" % (key, value[0], value[1], value[2])
+       winner = ("Error", -1)
+       for key, value in sup.GetStats ().iteritems ():
+               #print key, value
+               if value[0] > winner[1]:
+                       winner = (key, value[0])
+       if winner[0] in winners: winners[winner[0]] += 1
+       else: winners[winner[0]] = 1
+       #print "Winner: %s" % winner[0]
+
+print "SCOREBOARD OVER %d TRIALS OF %d ROUNDS EACH" % (trials, maxIterations)
+rawscoreboard = sorted ( [(score,player) for (player,score) in winners.items ()] , reverse=True )
+scoreboard = []
+for score, player in rawscoreboard:
+       print "%s: %s" % (player, score)
+
diff --git a/src/uccProgComp.py b/src/uccProgComp.py
new file mode 100644 (file)
index 0000000..0eee563
--- /dev/null
@@ -0,0 +1,211 @@
+'''uccProgComp.py - A supervisor candidate for Rock Paper Scissors.
+Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
+Requires Python 2.5.
+
+Licensed under an MIT-style license: see the LICENSE file for details.
+'''
+
+
+import random, uuid
+random.seed ()
+
+from rpsconst import *
+
+DEFAULT_HEALTH = 50
+REPRODUCE_HEALTH = 100
+DIE_HEALTH = 0
+MAX_AGE = 100
+
+DEBUG_MODE = False
+
+# Game dynamics - these are not final:
+#               WINNER          TRUTH          ATTPoints, DEFPoints
+pointsTable    [Attacker]      [False] =       (2, -2)
+pointsTable    [Attacker]      [True]  =       (2, -2)
+pointsTable    [Defender]      [False] =       (-2, 2)
+pointsTable    [Defender]      [True]  =       (-2, 2)
+pointsTable    [Tie]           [False] =       (0, 0)
+pointsTable    [Tie]           [True]  =       (1, 1)
+
+def Debug (f):
+       def g (*args):
+               if DEBUG_MODE:
+                       print f.__name__, args[1].__class__.__name__, args[1].GetID ()
+               return f (*args)
+       return g
+
+class BaseAgent:
+       def __init__ (self):
+               self.id = uuid.uuid4().int
+               self.__points = DEFAULT_HEALTH
+               # The index will be changing all the time. It can go stale as soon as something dies.
+               # So use it cautiously.
+               self.__currentIndex = 0
+               self.__reproduced = False
+               self.__age = 0
+
+       def GetCurrentIndex (self):
+               return self.__currentIndex
+       
+       def SetCurrentIndex (self, index):
+               self.__currentIndex = index
+
+       def GetID (self):
+               return self.id
+       
+       def GetPoints (self):
+               return self.__points
+
+       def SetPoints (self, points):
+               self.__points = points
+
+       def Defend (self, foe, bluff):
+               return Rock
+       
+       def Attack (self, foe):
+               return Rock
+
+       def IsDead (self):
+               return self.__points <= DIE_HEALTH
+
+       def Reproduced (self):
+               self.__points = DEFAULT_HEALTH
+               self.__reproduced = True
+
+       def HasReproduced (self):
+               return self.__reproduced
+
+       def SetReproduced (self, repro):
+               self.__reproduced = repro
+
+       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
+               self.__points += pointDelta
+               self.__age += 1
+               if self.__age > MAX_AGE: self.__points = DIE_HEALTH
+
+class LearningAgent (BaseAgent):
+       def __init__ (self):
+               BaseAgent.__init__ (self)
+               self.winHistory = {}
+       
+       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
+               BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
+               if wasAttacker:
+                       if winner == Attacker: result = Win
+                       elif winner == Tie: result = Tie
+                       else: result = Loss
+               else:
+                       if winner == Attacker: result = Loss
+                       elif winner == Tie: result = Tie
+                       else: result = Win
+                       
+               if foeName in self.winHistory: self.winHistory [foeName].append (result)
+               else: self.winHistory [foeName] = [result]
+
+       def GetWinHistory (self, foeName):
+               if foeName in self.winHistory: return self.winHistory [foeName]
+               else: return []
+
+class Supervisor:
+       def __init__ (self):
+               # The full list of living agents
+               self.population = []
+               # A list of classes for each agent type
+               self.agentTypes = []
+               # The current iteration
+               self.iteration = 0
+               self.agentStats = {}
+               self.pendingDeaths = []
+
+       def RegisterAgent (self, agent):
+               self.agentTypes.append (agent)
+
+       def GeneratePopulation (self, nAgentsPerClass):
+               for Agent in self.agentTypes:
+                       for i in range (0,nAgentsPerClass): self.population.append (Agent ())
+                       self.agentStats [str(Agent)] = [nAgentsPerClass,0,0]
+
+       def Iterate (self):
+               self.ClearStats ()
+               self.UpdateIndexes ()
+               self.iteration += 1
+               for attacker, defender in self.Select ():
+                       attack, bluff = attacker.Attack (defender.GetID ())
+                       defense = defender.Defend (attacker.GetID (), bluff)
+                       winner = resultTable [attack] [defense]
+                       attPoints, defPoints = pointsTable [winner][attack == bluff]
+                       attacker.Results (defender.GetID (), True, winner, attack, defense, bluff, attPoints)
+                       defender.Results (attacker.GetID (), False, winner, attack, defense, bluff, defPoints)
+                       if attacker.IsDead (): self.KillAgent (attacker)
+                       elif attacker.GetPoints () >= REPRODUCE_HEALTH: self.SpawnAgent (attacker)
+                       if defender.IsDead (): self.KillAgent (defender)
+                       elif defender.GetPoints () >= REPRODUCE_HEALTH: self.SpawnAgent (defender)
+
+       def IsGameOver (self):
+               if self.population == []: return True
+               liveAgents = [id for id,stats in self.agentStats.iteritems () if stats[0] > 0]
+               print liveAgents
+               if len(liveAgents) < 2: return True
+               return False
+       
+       # This is needed because when we pick the players we also need a way of identifying them in the
+       # population list without manually searching each time. O(n) each iteration is better than O(n)
+       # each death. It also resets the check for if the agent has reproduced this round.
+       def UpdateIndexes (self):
+               for agentID in reversed(sorted(self.pendingDeaths)): del self.population [agentID]
+               for index, agent in enumerate(self.population): 
+                       agent.SetCurrentIndex (index)
+                       agent.SetReproduced (False)
+               self.pendingDeaths = []
+
+       @Debug
+       def KillAgent (self, agent):
+               self.pendingDeaths.append (agent.GetCurrentIndex ())
+               stat = self.agentStats [str(agent.__class__)]
+               stat [0] -= 1
+               stat [2] += 1
+
+       @Debug
+       def SpawnAgent (self, agent):
+               child = agent.__class__ ()
+               self.population.append (child)
+               agent.Reproduced ()
+               stat = self.agentStats [str(agent.__class__)]
+               stat [0] += 1
+               stat [1] += 1 
+
+       def Select (self):
+               # This approach causes agents to keep fighting until they've either died or reproduced.
+               remaining = self.population[:]
+               attackerID = defenderID = random.randint (0,len(remaining)-1)
+               attacker = defender = remaining [attackerID]
+               while len (remaining) >= 2:
+                       # Check to see if the attacker from last round needs to be dropped.
+                       if attacker.IsDead () or attacker.HasReproduced ():
+                               remaining.pop (attackerID)
+                               if not len(remaining) >= 2: continue
+                               if defenderID > attackerID: defenderID -= 1
+                       # Check to see if the defender from last round is up for some attacking.
+                       if defender.IsDead () or defender.HasReproduced ():
+                               remaining.pop (defenderID)
+                               if not len(remaining) >= 2: continue
+                               attackerID = random.randint (0,len(remaining)-1)
+                               attacker = remaining [attackerID]
+                       else:
+                               attacker = defender
+                               attackerID = defenderID
+                       defender = None
+                       defenderID = random.randint (0,len(remaining)-2)
+                       if defenderID >= attackerID: defenderID += 1
+                       defender = remaining [defenderID]
+
+                       yield attacker, defender
+
+       def GetStats (self):
+               return self.agentStats
+
+       def ClearStats (self):
+               for agent in self.agentTypes: self.agentStats [str(agent)] = self.agentStats [str(agent)] [:1] + [0,0]
+
+def RandomAttack ():
+       return random.randint (0,2)
diff --git a/src/uccProgComp.py.old b/src/uccProgComp.py.old
new file mode 100644 (file)
index 0000000..17ffa2a
--- /dev/null
@@ -0,0 +1,211 @@
+'''uccProgComp.py - A supervisor candidate for Rock Paper Scissors.
+Written by Luke Williams <[email protected]> for the UCC Programming Competition in 2008.
+Requires Python 2.5.
+
+Licensed under an MIT-style license: see the LICENSE file for details.
+'''
+
+
+import random, uuid
+random.seed ()
+
+from rpsconst import *
+
+DEFAULT_HEALTH = 50
+REPRODUCE_HEALTH = 100
+DIE_HEALTH = 0
+MAX_AGE = 100
+
+DEBUG_MODE = False
+
+# Game dynamics - these are not final:
+#               WINNER          TRUTH          WINNER, LOSER
+pointsTable    [Attacker]      [False] =       (2, -2)
+pointsTable    [Attacker]      [True]  =       (2, -2)
+pointsTable    [Defender]      [False] =       (-2, 2)
+pointsTable    [Defender]      [True]  =       (-2, 2)
+pointsTable    [Tie]           [False] =       (-1, -1)
+pointsTable    [Tie]           [True]  =       (1, 1)
+
+def Debug (f):
+       def g (*args):
+               if DEBUG_MODE:
+                       print f.__name__, args[1].__class__.__name__, args[1].GetID ()
+               return f (*args)
+       return g
+
+class BaseAgent:
+       def __init__ (self):
+               self.id = uuid.uuid4().int
+               self.__points = DEFAULT_HEALTH
+               # The index will be changing all the time. It can go stale as soon as something dies.
+               # So use it cautiously.
+               self.__currentIndex = 0
+               self.__reproduced = False
+               self.__age = 0
+
+       def GetCurrentIndex (self):
+               return self.__currentIndex
+       
+       def SetCurrentIndex (self, index):
+               self.__currentIndex = index
+
+       def GetID (self):
+               return self.id
+       
+       def GetPoints (self):
+               return self.__points
+
+       def SetPoints (self, points):
+               self.__points = points
+
+       def Defend (self, foe, bluff):
+               return Rock
+       
+       def Attack (self, foe):
+               return Rock
+
+       def IsDead (self):
+               return self.__points <= DIE_HEALTH
+
+       def Reproduced (self):
+               self.__points = DEFAULT_HEALTH
+               self.__reproduced = True
+
+       def HasReproduced (self):
+               return self.__reproduced
+
+       def SetReproduced (self, repro):
+               self.__reproduced = repro
+
+       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
+               self.__points += pointDelta
+               self.__age += 1
+               if self.__age > MAX_AGE: self.__points = DIE_HEALTH
+
+class LearningAgent (BaseAgent):
+       def __init__ (self):
+               BaseAgent.__init__ (self)
+               self.winHistory = {}
+       
+       def Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta):
+               BaseAgent.Results (self, foeName, wasAttacker, winner, attItem, defItem, bluffItem, pointDelta)
+               if wasAttacker:
+                       if winner == Attacker: result = Win
+                       elif winner == Tie: result = Tie
+                       else: result = Loss
+               else:
+                       if winner == Attacker: result = Loss
+                       elif winner == Tie: result = Tie
+                       else: result = Win
+                       
+               if foeName in self.winHistory: self.winHistory [foeName].append (result)
+               else: self.winHistory [foeName] = [result]
+
+       def GetWinHistory (self, foeName):
+               if foeName in self.winHistory: return self.winHistory [foeName]
+               else: return []
+
+class Supervisor:
+       def __init__ (self):
+               # The full list of living agents
+               self.population = []
+               # A list of classes for each agent type
+               self.agentTypes = []
+               # The current iteration
+               self.iteration = 0
+               self.agentStats = {}
+               self.pendingDeaths = []
+
+       def RegisterAgent (self, agent):
+               self.agentTypes.append (agent)
+
+       def GeneratePopulation (self, nAgentsPerClass):
+               for Agent in self.agentTypes:
+                       for i in range (0,nAgentsPerClass): self.population.append (Agent ())
+                       self.agentStats [str(Agent)] = [nAgentsPerClass,0,0]
+
+       def Iterate (self):
+               self.ClearStats ()
+               self.UpdateIndexes ()
+               self.iteration += 1
+               for attacker, defender in self.Select ():
+                       attack, bluff = attacker.Attack (defender.GetID ())
+                       defense = defender.Defend (attacker.GetID (), bluff)
+                       winner = resultTable [attack] [defense]
+                       attPoints, defPoints = pointsTable [winner][attack == bluff]
+                       attacker.Results (defender.GetID (), True, winner, attack, defense, bluff, attPoints)
+                       defender.Results (attacker.GetID (), False, winner, attack, defense, bluff, defPoints)
+                       if attacker.IsDead (): self.KillAgent (attacker)
+                       elif attacker.GetPoints () >= REPRODUCE_HEALTH: self.SpawnAgent (attacker)
+                       if defender.IsDead (): self.KillAgent (defender)
+                       elif defender.GetPoints () >= REPRODUCE_HEALTH: self.SpawnAgent (defender)
+
+       def IsGameOver (self):
+               if self.population == []: return True
+               liveAgents = [id for id,stats in self.agentStats.iteritems () if stats[0] > 0]
+               print liveAgents
+               if len(liveAgents) < 2: return True
+               return False
+       
+       # This is needed because when we pick the players we also need a way of identifying them in the
+       # population list without manually searching each time. O(n) each iteration is better than O(n)
+       # each death. It also resets the check for if the agent has reproduced this round.
+       def UpdateIndexes (self):
+               for agentID in reversed(sorted(self.pendingDeaths)): del self.population [agentID]
+               for index, agent in enumerate(self.population): 
+                       agent.SetCurrentIndex (index)
+                       agent.SetReproduced (False)
+               self.pendingDeaths = []
+
+       @Debug
+       def KillAgent (self, agent):
+               self.pendingDeaths.append (agent.GetCurrentIndex ())
+               stat = self.agentStats [str(agent.__class__)]
+               stat [0] -= 1
+               stat [2] += 1
+
+       @Debug
+       def SpawnAgent (self, agent):
+               child = agent.__class__ ()
+               self.population.append (child)
+               agent.Reproduced ()
+               stat = self.agentStats [str(agent.__class__)]
+               stat [0] += 1
+               stat [1] += 1 
+
+       def Select (self):
+               # This approach causes agents to keep fighting until they've either died or reproduced.
+               remaining = self.population[:]
+               attackerID = defenderID = random.randint (0,len(remaining)-1)
+               attacker = defender = remaining [attackerID]
+               while len (remaining) >= 2:
+                       # Check to see if the attacker from last round needs to be dropped.
+                       if attacker.IsDead () or attacker.HasReproduced ():
+                               remaining.pop (attackerID)
+                               if not len(remaining) >= 2: continue
+                               if defenderID > attackerID: defenderID -= 1
+                       # Check to see if the defender from last round is up for some attacking.
+                       if defender.IsDead () or defender.HasReproduced ():
+                               remaining.pop (defenderID)
+                               if not len(remaining) >= 2: continue
+                               attackerID = random.randint (0,len(remaining)-1)
+                               attacker = remaining [attackerID]
+                       else:
+                               attacker = defender
+                               attackerID = defenderID
+                       defender = None
+                       defenderID = random.randint (0,len(remaining)-2)
+                       if defenderID >= attackerID: defenderID += 1
+                       defender = remaining [defenderID]
+
+                       yield attacker, defender
+
+       def GetStats (self):
+               return self.agentStats
+
+       def ClearStats (self):
+               for agent in self.agentTypes: self.agentStats [str(agent)] = self.agentStats [str(agent)] [:1] + [0,0]
+
+def RandomAttack ():
+       return random.randint (0,2)
diff --git a/src/uccProgComp.pyc b/src/uccProgComp.pyc
new file mode 100644 (file)
index 0000000..77283f4
Binary files /dev/null and b/src/uccProgComp.pyc differ

UCC git Repository :: git.ucc.asn.au