AI Competition!

Posted by ludamad on Oct. 3, 2008, 8:16 p.m.

Hello boys and girls. If you know me, you would know that I am very interested in artificial intelligence, and game theory. So I decided to create a competition combining the two! Horribly complicated? Nope. Let me explain.

THE TASK: To create a GML script that plays the most effective strategy - against other entries - for the game described below.

THE GAME:

Every turn you have three options:

DEFEND: You gain 1 point this round and stop the opponent from stealing.

STEAL: You take 2 points from your opponent (added to your own score). This does not work if your opponent chose to defend.

BANK: You gain 2 points.

Every AI entry plays against other AI entries for 200 rounds. Your goal is to have the highest score at the end of all the playing. That is, you add the total score from all the rounds.

THE ENGINE:

http://64digits.com/users/ludamad/AI-Engine.gm6

To add a script to the players there, create a new script, and alter both the constant NUM_PLAYERS and the create event of object Arbiter.

Sample AI's are provided.

The script has the following rules:

-You may only access local variables, and constants.

-You may create any local variables you need. These are wiped after the 200 rounds against an AI are played.

-You may not use functions I deem dangerous. Use common sense and don't try to cheat.

To use the engine, load the game and press space. It will then show the scores for each script.

Additional Stuff:

-Up to two entries, I will make sure they are not explicitly cooperating however. You will win if either of your AI's is on top.

-The game is not rock paper scissors. Banking is inherently more useful.

-Try to make a script that beats the preset examples. However, remember your AI cannot fully expect what the other AIs will be like.

Any questions, just ask. I wrote this rather sketchingly.

Writing a good AI:

This is obviously your task to figure out, but the sample AI's can give some insight. Although stealing looks all nice and fancy, you gain AND remove, it can be seen that the Thief performs quite miserably. This is simply because stealing fails against both stealing and defending.

Here are some preset things you can use:

SCRIPTS TO HELP YOU:

X represents BANK, DEFEND, or STEAL

counter( x ) : Returns the best possible move against move x, good for fighting predictability.

simulate( x1, x2 ) : Returns the value (for the player who played x1) if x1 is played against x2. Good for analysis.

STORED VALUES TO HELP YOU:

Move - the index of the last move, starts at -1. Use Move==-1 to check if it is the first move.

MyMove [] - the array of moves you have played

TheirMove [] - the array of moves your opponent has played

Score - your current score (nothing about your opponent's) for this game

DEFEND - 2

STEAL - 1

BANK - 0

Comments

Nighthawk 16 years, 2 months ago

Oh boy, this sounds fun. ^_^

s 16 years, 2 months ago

Also, a grapher mod whoever

Turn off the room's background drawing and set the dimensions to 400x400 (Arbiter's draw event might want draw_set_color(-1) if you want text) and in Arbiter's create put graph1=somescript;graph2=somescript

Then put

///*GRAPHER

if obj1.SCRIPT^obj2.SCRIPT=graph1^graph2{

switch obj1.MyMoves[i]{

case 0:draw_set_color(c_navy)

break;case 1:draw_set_color(c_maroon)

break;case 2:draw_set_color(c_green)}

draw_rectangle(i*2,0,i*2+2,200,0)

switch obj2.MyMoves[i]{

case 0:draw_set_color(c_navy)

break;case 1:draw_set_color(c_maroon)

break;case 2:draw_set_color(c_green)}

draw_rectangle(i*2,200,i*2+2,400,0)

draw_set_color(0)

draw_rectangle(i*2-1,399-obj1.Score,i*2+1,401-obj1.Score,0)

draw_set_color(-1)

draw_rectangle(i*2-1,399-obj2.Score,i*2+1,401-obj2.Score,0)

//*/

at the end of the EvalRound script (Before the last })

While at it, might also want to put event_perform(ev_keypress,vk_space) at the end of Arbiter's creation event

Cesar 16 years, 2 months ago

What the hell do we win?

noshenim 16 years, 2 months ago

$300

SteveKB 16 years, 2 months ago

choice=floor(random(3))

if(choice=0){return DEFEND}else{

if(choice=1){return STEAL}else{return BANK}}

lulz rock paper scissors is fun

lol forgots to return :p

Cesar 16 years, 2 months ago

//SAMPLE AI CREATED BY SERPREX. TOTALLY EDITED BY RAWRSPOON

//An AI that plays the counter against the move that the opponent has played the most

if Move==-1

{return BANK}//Let's bank for the first round

var v, r;

v=Move//Count down variable

pred[BANK]=0//Counters set

pred[STEAL]=0

pred[DEFEND]=0

while(v>=0)

{

pred[counter(TheirMoves[v])]+=1;

v-=1;//Counting move totals

}

v=max(pred[BANK],pred[STEAL],pred[DEFEND])//Compares for highest

if v=pred[BANK]

{

r=random(pred[BANK])

if (r<(pred[BANK]*.75)) return BANK;

if (r<(pred[BANK]*.90)) return STEAL;

return DEFEND; //totally weighs out stuff

}

if v=pred[DEFEND]

{

r=random(pred[DEFEND])

if (r<(pred[DEFEND]*.75)) return DEFEND;

if (r<(pred[DEFEND]*.90)) return BANK;

return STEAL

}

{

r=random(pred[STEAL])

if (r<(pred[DEFEND]*.75)) return STEAL;

if (r<(pred[DEFEND]*.90)) return DEFEND;

return BANK

}

My entry to be humbled by Metabot

s 16 years, 2 months ago

@meow44=That AI is implemented in the example, and it sucks

SteveKB 16 years, 2 months ago

I know that's why I lulzed at it

omicron1 16 years, 2 months ago

Made one that reliably beats 'cautious banker' and 'tit for tat.' It's a modified determiner - checks only recent moves, and will be a tit-for-tat unless its opponent is using an exclusive (or nearly exclusive) strategy.

if Move==-1

{return BANK}//Let's bank for the first round

var v;

v=Move//Count down variable

pred[BANK]=0//Counters set

pred[STEAL]=0

pred[DEFEND]=0

pred2[BANK]=0//Counters set

pred2[STEAL]=0

pred2[DEFEND]=0

while(v>=max(0,Move-5))

{

pred[counter(TheirMoves[v])]+=1;

v-=1;//Counting move totals

}

v=max(pred[BANK],pred[STEAL],pred[DEFEND])//Compares for highest

q=pred[BANK]+pred[STEAL]+pred[DEFEND];

if q/max(1,pred[BANK])<1.5 return BANK;

else if q/max(1,pred[STEAL])<1.5 return BANK;

else if q/max(1,pred[DEFEND])<1.5 return DEFEND;

else

{

if Move==-1

return choose(DEFEND,BANK)//On the first move, either banks or defends

return counter(TheirMoves[Move]);

}

ludamad 16 years, 2 months ago

omicron, you seem to want to either defend or bank on the first move - but at the top it always banks on the first move. Did you accidentally leave something? And just to make everyone feel bad, my AI script Metabot (which is banned from actually winning of course) beat both Rawr's and omicrons consistently in both 1 on 1 and in a game environment. Meaning of course that such a thing is possible. To show you how much a script can accomplish heres a sample score between the current Metabot and omicron's AI:

Metabot: 307

OmicronAI: 96

This was 200 rounds of play.

However beating both cautious banker and tit for tat isn't an easy feat. Cautious banker is proving especially capable at high levels of AI play.