From 35ff18a5beda685e59ca898026570d67b7ead333 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Mon, 28 Jun 2010 10:23:45 +0800 Subject: [PATCH] Work towards C SDK (#11). Frenchie is still broken. --- .gitignore | 1 + src/link/C/.gitignore | 2 +- src/link/C/Makefile | 8 +- src/link/C/README | 24 +++ src/link/C/agents-broken/c_frenchie.c | 105 ------------ src/link/C/agents/c_frenchie.c | 157 ++++++++++++++++++ src/link/C/agents/c_lucifer.c | 1 - .../C/c-link-lib.xcodeproj/project.pbxproj | 2 + src/link/C/c_link.c | 5 + src/link/C/c_link.h | 9 +- src/link/externAgent.py | 8 +- src/simulate.py | 2 +- 12 files changed, 207 insertions(+), 117 deletions(-) create mode 100644 src/link/C/README delete mode 100644 src/link/C/agents-broken/c_frenchie.c create mode 100644 src/link/C/agents/c_frenchie.c diff --git a/.gitignore b/.gitignore index 047c57f..4baac77 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ build/ # gcc noise *.o *.a +*.dSYM # old skool .svn diff --git a/src/link/C/.gitignore b/src/link/C/.gitignore index fbde527..c51cee3 100644 --- a/src/link/C/.gitignore +++ b/src/link/C/.gitignore @@ -1,2 +1,2 @@ -agents/ !agents/*.c +agents/* diff --git a/src/link/C/Makefile b/src/link/C/Makefile index ccefb00..7d3e68c 100644 --- a/src/link/C/Makefile +++ b/src/link/C/Makefile @@ -1,8 +1,8 @@ CC=gcc AR=ar -CFLAGS=-Wall -I. -LDFLAGS=-lc_link -L. +myCFLAGS=$(CFLAGS) -Wall -I. +myLDFLAGS=-lc_link -L. LINKSRCS=c_link.c LINKOBJS=$(LINKSRCS:.c=.o) @@ -18,10 +18,10 @@ $(LINKLIB): $(LINKOBJS) $(AGENTS): $(AGENTSRCS) $(LINKLIB) @echo Building $@ - $(CC) $(CFLAGS) $(LDFLAGS) $@.c -o $@ + $(CC) $(myCFLAGS) $(myLDFLAGS) $@.c -o $@ .c.o: c_link.h - $(CC) -c $(CFLAGS) $< -o $@ + $(CC) -c $(myCFLAGS) $< -o $@ .PHONY : clean clean: diff --git a/src/link/C/README b/src/link/C/README new file mode 100644 index 0000000..7f0a970 --- /dev/null +++ b/src/link/C/README @@ -0,0 +1,24 @@ +Welcome to the C SDK and link library. + +== Compiling and testing the sample bots == + +Run "make" in this directory. To include them in the + +== Making your own agent == +See wiki page. + += Testing your own agent = +Edit src/simulate.py. +Your agents live in link.C.c_agents +Add them to Agents to get them to do battle. + +For example, this code imports c_angel, c_lucifer, c_streetfighter and +c_frenchie, as well as the python sample agents, and then battles c_lucifer, +python Frenchie, c_streetfighter and c_angel. It goes at the top of simulate.py. + +# Import and add your agents here: +from link.C.c_agents import c_angel, c_lucifer, c_streetfighter, c_frenchie + +from SampleAgents import Angel, Lucifer, Dummy, Frenchie, Streetfighter +Agents = [c_lucifer, Frenchie, c_streetfighter, c_angel] + diff --git a/src/link/C/agents-broken/c_frenchie.c b/src/link/C/agents-broken/c_frenchie.c deleted file mode 100644 index 78866a6..0000000 --- a/src/link/C/agents-broken/c_frenchie.c +++ /dev/null @@ -1,105 +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 -#include - -/* 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]; -int haveLostToFoe[]; - -/* 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: - attack.promisedAttack = paper; - break; - case paper: - attack.promisedAttack = scissors; - break; - default: /* attack = scissors */ - attack.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; - } - return defence; -} - -/* 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/agents/c_frenchie.c b/src/link/C/agents/c_frenchie.c new file mode 100644 index 0000000..a14ee92 --- /dev/null +++ b/src/link/C/agents/c_frenchie.c @@ -0,0 +1,157 @@ +/* + * 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 +#include +#include + +/* 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 + (note that this is only a guess, not an upper limit. Do *not* take it as + gospel on the number of agents you're going to see. */ +#define NUMBEROFAGENTSGUESS 100 + +/* The name of the n-th foe who has beaten us */ +char (*defeatingFoes)[MAXFOENAMELEN] = NULL; + +/* The length of the array, and how far we are along it */ +size_t foesLen = 0; +unsigned int foesCount = 0; + +/* an internal function - have I lost to a given foe? */ +int haveLostTo( char * foeName ) { + int foe; + + /* check every foe we know to have defeated us */ + for (foe=0; foe Yes\n", me, foeName ); + return 1; + } + } + + /* this foe not found */ + return 0; +} + + +ATTACKTYPE Attack( char * foeName ) { + ATTACKTYPE attack; + + attack.realAttack = RandomAttack(); + + /* have I lost to this foe? */ + if ( haveLostTo(foeName) ) { + /* Assume they are lying (FIXME: I'm not entirely sure why the python + does what it does: I'm just duplicating.) */ + switch (attack.realAttack) { + case rock: + attack.promisedAttack = scissors; + break; + case paper: + attack.promisedAttack = rock; + break; + default: /* attack = scissors */ + attack.promisedAttack = paper; + break; + } + } else { + /* be nice! */ + attack.promisedAttack = attack.realAttack; + } + + + return attack; +} + + +ITEMTYPE Defend( char * foeName, ITEMTYPE foePromisedAttack ) { + ITEMTYPE defence; + + if (haveLostTo(foeName)) { + /* They've screwed us in the past, assume they're lying and go for the + kill. */ + switch (foePromisedAttack) { + case rock: + defence = scissors; + break; + case paper: + defence = rock; + break; + default: + defence = paper; + break; + } + } else { + /* be nice! */ + defence = foePromisedAttack; + } + + return defence; +} + +/* 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 (defeatingFoes == NULL) { + defeatingFoes = calloc( NUMBEROFAGENTSGUESS, sizeof( MAXFOENAMELEN*sizeof(char) ) ); + 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; + + fprintf( stderr, "%d\tsaving loss from %s\n", me, foeName ); + + /* if we've already lost the foe, don't store again */ + for (foe=0; foe