Jump to content
BrainDen.com - Brain Teasers
  • 0


unreality
 Share

Question

Here's the challenge: write a little code snippet in java or just generic pseudocode or even just describe your algorithm (you don't even have to know programming, I can just convert your algorithm for you!) that plays ROCK PAPER SCISSORS against an enemy... that enemy is another algorithm!

THE GAME

We all know the game rock paper scissors could use a little strategy... sure there is some psychological merit to it, but most of it is luck. Well, that's about to change.... you will create a deterministic algorithm that will battle against other algorithms for the ultimate title of ROCK PAPER SCISSORS CHAMPION!!! There will be no randomness functions, no chance, no luck. It's about skill. Is your algorithm a simple numerical ninja? Or is it a complex meta-algorithm that attempts to counterguess the enemy's strategy? MAY THE BEST ALGORITHM WIN!!!!!

TECHNICAL SPECS

Your algorithm has access to three different inputs: it has an array of all the moves its used previously. This array is called a. There is another array, b, that contains the moves used by the enemy in this match. You also have a variable, i, that denotes the round number (i=0 is the first round, i=1 is the next round, then i=2, etc).

Right now I have the global var numRounds set to 50. Ie, there will be 50 rounds before we see whose won more games. Let me know if you think that number should be something else.

0 = ROCK

1 = PAPER

2 = SCISSORS

[rock beats scissors, scissors beats paper, paper beats rock]

the arrays a & b are of the datatype int and hold zeroes, ones and twos up to a or b. a and all values after that in the array is NULL, same with b. So the array is only defined from a[0] to a[i-1] or equivalent for b.

For the very first round, i=0, there will be nothing in the arrays. So if your algorithm uses previous data to make future decisions, you'll need to have some primer value for i=0

For anyone interested, here is my java code that runs all this:



// ROCK PAPER SCISSORS CONTEST FOR BRAINDEN

//  BY UNREALITY

//    ENJOY

import java.util.Scanner;

public class ropasc

{

    public static int numGames = 50;

// rock: 0

// paper: 1

// scissors: 2


    private int[] myTurns; private String myName;



    public ropasc(String name)

    {

        myName = name;

        myTurns = new int[numGames];

    }


    public int[] get()

    {

        return myTurns;

    }


    public String getName()

    {

        return myName;

    }


    public int next(int[] enemy, int i)

    {

        int x=0;

        if (myName=="Test1") x = test1(myTurns, enemy, i);

        if (myName=="Test2") x = test2(myTurns, enemy, i);

        if (myName=="Test3") x = test3(myTurns, enemy, i);

        // etc. Could use "java.lang.reflect.*" to do this more elegantly but this way is simpler

        myTurns[i] = x;

        return x;

    }


    public int test1(int[] a, int[] b, int i)

    {

        if (i==0) return 2;

        return b[i-1];

    }


    public int test2(int[] a, int[] b, int i)

    {

        return i % 3;

    }


    public int test3(int[] a, int[] b, int i)

    {

        int sum = 0;

        for (int z=0; z<i; z++)

        {

            sum += (a[z] + b[z]);

        }

        sum %= 3;

        return sum;

    }


    public static String conv(int k)

    {

            if (k==0) return "ROCK";

            if (k==1) return "PAPER";

            if (k==2) return "SCISSORS";

            return "";

    }


    public static void main(String[] args)

    {


        String na = "", nb = "";

     /*   String na = "Test1"; // these two lines

        String nb = "Test2"; // will be the only ones changed to switch who is fighting whom */

        // how about, instead get user input?

        Scanner inp = new Scanner(System.in);

        System.out.print("\n\nFirst Algorithm: ");

        na = inp.next();

        System.out.print("\nSecond Algorithm: ");

        nb = inp.next();


        System.out.print(na + " vs " + nb + "\n\n");

        ropasc rps1 = new ropasc(na);

        ropasc rps2 = new ropasc(nb);

        int res1 = 0, res2 = 0, win1 = 0, win2 = 0, result = 2;

        for (int i=0; i< numGames; i++)

        {

            res1 = rps1.next(rps2.get(), i);

            res2 = rps2.next(rps1.get(), i);

            result = (2+res1+res2) % 3;

            if (result==1) win2++;

            if (result==0) win1++;

            System.out.println(conv(res1) + " vs " + conv(res2));

        }

        String zprint ="";

        if (win1>win2) zprint = rps1.getName() + " wins " + win1 + " games to " + win2 + "!!!\n";

        if (win1<win2) zprint = rps2.getName() + " wins " + win2 + " games to " + win1 + "!!!\n";

        if (win1==win2) { zprint = "Both players won " + win1 + " games! The match was a tie\n"; } else { zprint += "There were " + (numGames - win1 - win2) + " ties\n"; }

        System.out.print(zprint);

    }

}

New entrants will be like this:

public int nameOfAlgorithmint[] a, int[] b, int i)

{

// body here

}

and will be inserted into the program after the algorithm method for test3

All algorithms must return one of these three integers: 0 (ROCK), 1 (PAPER), 2 (SCISSORS)!!!

good luck and post here with remarks, questions, etc.... let's get a signup list?

1) Unreality

2) ...

should we shoot for eight people?

REMEMBER YOU DONT NEED TO KNOW PROGRAMMING... you just need to make a killer algorithm that's a whiz at R/P/S :) I can write the actual code for it for you if you want!

Link to comment
Share on other sites

  • Answers 257
  • Created
  • Last Reply

Top Posters For This Question

Recommended Posts

  • 0

As for the question of whether a one point margin should be a tie, I think that would be reasonable since a single point isn't very significant out of fifty games. I don't think that there should be any reason to extend the number of games since there are situations where they could wind up going indefinitely if you say that a certain number of ties require retrying. Maybe they always tie, or at least always alternate wins. No amount of extensions would solve that.

Unfortunately, my program isn't working to my liking, so it's going to take some work to get it the way I want it for T2... :angry:

Link to comment
Share on other sites

  • 0

alright, a one point margin is now counted as a tie :)

furthermore there was an out-of-bounds exception error in the above algorithm for most/least enemy/me moves, I fixed it, here we go:


int[] achose = new int[3];

               int[] bchose = new int[3];

               for (int vv=0; vv<i; vv++) { achose[a[vv]]++; bchose[b[vv]]++; }

               int enemy_least = ROCK, me_least = ROCK, enemy_most = ROCK, me_most = ROCK;

               int enemy_times_used_least = 0, me_times_used_least = 0, enemy_times_used_most = 0, me_times_used_most = 0;

               int tiebreaker;


               if (achose[PAPER] > achose[ROCK]) me_most = PAPER;

               if (achose[SCISSORS] > achose[me_most]) me_most = SCISSORS;

               me_times_used_most = achose[me_most]; tiebreaker = me_most;

               if (achose[me_most] == achose[(me_most+1)%3] || achose[me_most] == achose[(me_most+2)%3]) { tiebreaker = -2; // two-way tie

               if (achose[me_most] == achose[(me_most+1)%3] && achose[me_most] == achose[(me_most+2)%3]) tiebreaker = -3; /* three way tie */ }

               me_most = tiebreaker;


               if (bchose[PAPER] > bchose[ROCK]) enemy_most = PAPER;

               if (bchose[SCISSORS] > bchose[enemy_most]) enemy_most = SCISSORS;

               enemy_times_used_most = bchose[enemy_most]; tiebreaker = enemy_most;

               if (bchose[enemy_most] == bchose[(enemy_most+1)%3] || bchose[enemy_most] == bchose[(enemy_most+2)%3]) { tiebreaker = -2; // two-way tie

               if (bchose[enemy_most] == bchose[(enemy_most+1)%3] && bchose[enemy_most] == bchose[(enemy_most+2)%3]) tiebreaker = -3; /* three way tie */ }

               enemy_most = tiebreaker;


               if (achose[PAPER] < achose[ROCK]) me_least = PAPER;

               if (achose[SCISSORS] < achose[me_least]) me_least = SCISSORS;

               me_times_used_least = achose[me_least]; tiebreaker = me_least;

               if (achose[me_least] == achose[(me_least+1)%3] || achose[me_least] == achose[(me_least+2)%3]) { tiebreaker = -2; // two-way tie

               if (achose[me_least] == achose[(me_least+1)%3] && achose[me_least] == achose[(me_least+2)%3]) tiebreaker = -3; /* three way tie */ }

               me_least = tiebreaker;


               if (bchose[PAPER] < bchose[ROCK]) enemy_least = PAPER;

               if (bchose[SCISSORS] < bchose[enemy_least]) enemy_least = SCISSORS;

               enemy_times_used_least = bchose[enemy_least]; tiebreaker = enemy_least;

               if (bchose[enemy_least] == bchose[(enemy_least+1)%3] || bchose[enemy_least] == bchose[(enemy_least+2)%3]) { tiebreaker = -2; // two-way tie

               if (bchose[enemy_least] == bchose[(enemy_least+1)%3] && bchose[enemy_least] == bchose[(enemy_least+2)%3]) tiebreaker = -3; /* three way tie */ }

               enemy_least = tiebreaker;

Link to comment
Share on other sites

  • 0

I just realized that the entire thing about adding extra rounds is unnecessary. Ties are always won by recency, so every set of five WILL be every subsequent quintet.

The first is mine, the second is just random

ROCK vs ROCK

ROCK vs PAPER

ROCK vs PAPER

ROCK vs PAPER

ROCK vs SCISSORS

(paper)

SCISSORS vs PAPER

SCISSORS vs ROCK

SCISSORS vs ROCK

SCISSORS vs SCISSORS

SCISSORS vs PAPER

(paper, paper)

SCISSORS vs PAPER

SCISSORS vs ROCK

SCISSORS vs ROCK

SCISSORS vs SCISSORS

SCISSORS vs ROCK

(paper, paper, rock)

SCISSORS vs PAPER

SCISSORS vs ROCK

SCISSORS vs ROCK

SCISSORS vs SCISSORS

SCISSORS vs ROCK

(paper, paper, rock, rock)

PAPER vs ...

Should be enough to get the pattern, I hope!

Link to comment
Share on other sites

  • 0

yeah we can use those in it. I'm keeping all algorithms made. And as far as new programs go, I'm a little swamped but so far I've made darth1 and izzy1 and I'm currently working on izzy2 to be followed by the rest of darth's :) Dawh's working on his I know and at some point I'll devise my own (I've had a few ideas bouncing around my head)

Link to comment
Share on other sites

  • 0

I apologize about the lengthy time it took to get back to you unreality.

hope it didn't screw things up too badly.

not quite sure what to write for the second phase of the contest,

but I'll think of something :-)

Link to comment
Share on other sites

  • 0

i've been pretty busy but right now so far all of Darth's programs are in, so are two of Izzy's and two of Mr. Apple Pi's. I know dawh is working on his and soon I'll be able to work on my own. If anyone else has PMed me about making their algorithm for them and wasn't mentioned here, PM me again cuz I've been pretty busy, sorry :blush: Anyway, we should be ready soon for T2

Link to comment
Share on other sites

  • 0

So here's the list of programs so far:

String[] names = { "hawk", "test1", "test2", "test3", "izzy", "phil", "backatyou", "dnoob", "rand", "allrock", "jarze", "medji" , "mr_apple_pi", "darth1", "izzy1", "izzy2", "darth2", "darth3", "mrapple1", "medji1", "medji2", "patternSeeker", "phil1" };

I assume that "test2" will be in T2 as just a sample program, and so far Mr. Apple has two programs he wants to use:

* mr_apple_pi (the one he used in T1)

* mrapple1

izzy has two programs she wants to use:

* izzy1

* izzy2

I don't know if she wants to use her original "izzy" one, invent another one, or just have two.

DarthNoob has three all new ones:

* darth1

* darth2

* darth3

Medji has two new programs:

* medji1

* medji2

And I don't know if he wants to use his original "medji" as the third, come up with a new one, or just have two.

dawh has submitted one so far:

* patternSeeker

so has phillip1882:

* phil1

Phil do you want to use your "phil" algo from T1 in addition to "phil1"?

I think JarZe wants to reuse his from T1 but I don't know for sure

Link to comment
Share on other sites

  • 0

Cooool.

Also, regarding ties:

It's possible that during the first 25 rounds, one program pwns, but over the next 25 rounds, the opponent starts pwning, and that if the game would be allowed to continue with more rounds, the opponent would continue to win. So how about, if there's a tie, you could manually look at to see if there's any trends that would mean one programmer would eventually come on top, or if it would be a cyclical thing where they would keep tying forever.

Or does a program even deserve to win if it needs more than 50 rounds?

Link to comment
Share on other sites

  • 0

50 rounds is sufficient... beyond that it's just arbitrary. And if one pwns the first 25 and the other pwns the next 25, implying the cycle, then it's a tie, rightfully so. Fifty rounds is enough to grasp the trend, and if they differ by only win, it's counted as a tie, so that's accounted for.

Though the number 50 it's just one constant at the top... I could make it 100, or even 500 if you want. The more rounds the more accurate I suppose (note some programs would need to extend sampling arrays if that changed, but other than that it's not a big deal). Though I think 50 is very sufficient... in the scheme of your algorithms, there won't be a big extrapolated difference between 50 rounds and 500 rounds

Link to comment
Share on other sites

  • 0

50 rounds is sufficient... beyond that it's just arbitrary. And if one pwns the first 25 and the other pwns the next 25, implying the cycle, then it's a tie, rightfully so. Fifty rounds is enough to grasp the trend, and if they differ by only win, it's counted as a tie, so that's accounted for.

Though the number 50 it's just one constant at the top... I could make it 100, or even 500 if you want. The more rounds the more accurate I suppose (note some programs would need to extend sampling arrays if that changed, but other than that it's not a big deal). Though I think 50 is very sufficient... in the scheme of your algorithms, there won't be a big extrapolated difference between 50 rounds and 500 rounds

What I'm trying to say that there is a chance that there might not be a cycle of 25 rounds each, and rather one algorithm wins the first 25 - and the other wins every single other set of 25 afterwards.

Granted, the likelihood of that happening is incredibly low... I kinda just realized I'm nitpicking at nothing. Haha

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...