6
\$\begingroup\$

The garden is a 2-dimensional grid with 49 rows and 49 columns.

The Easter Bunny™️ is in the center of the garden, minding his own business, holding on to 100 Easter eggs.

Unfortunately, there's a team of 4 children who aren't content to collect chocolate eggs, they want to capture the Easter Bunny™.

The game starts with 4 kids, one in each corner of the garden.

The kids can take 1 step each turn, in one of the 4 cardinal directions (North, South, East or West). When they've each taken a step (or decided not to), the bunny will take a move.

The kids can only see the Easter Bunny or it's eggs when they are 5 steps away or nearer.

Kids visibility (yellow) and movement options (green):

kid visibility diagram

The bunny can hop up to 2 spaces away on both axes (describing a 5 x 5 square he can hop to).

The Easter Bunny™ can only see the kids when they are 5 steps away or nearer.

Bunny's visibility (yellow) and movement options (green)

bunny visibility diagram

Neither kids nor the Easter Bunny™ can leave the garden.

The game ends when:

  • The Easter Bunny™️ drops his last egg.
  • The kids catch the bunny.
  • The game reaches turn 1000.

The Goals:

  • The Easter Bunny™ wants to give the children as many Easter Eggs as possible while evading capture.
  • The kids want to collect as many eggs as possible, AND catch the Easter Bunny™.

This means that:

  • The Easter Bunny™ will ONLY score points if it evades capture by dropping it's last egg, or by finishing the time limit.
  • The team of kids will ONLY score points if they capture the Easter Bunny™.
  • In either case the points scored is the number of eggs the kids have picked up.

The challenge is to write behaviour for the Easter Bunny™ or for the team of kids. Your code will be run against all of the other kind of entry.

Config

You can edit conig.js to change two things about the run:

  • match_limit will allow you to end the game when you decide (competition will use 1,000 turns)
  • turn_time (ms) will set the interval when the game is rendering.

As the kids:

(See instructions for the bunny below)

Your goal is to collect as many eggs as you can, and then catch the Easter Bunny™.

Your code will take the form of an array of 4 JS functions, which will each control a kid starting in these positions (in this order):

  • North West (0, 0)
  • North East (0, 48)
  • South East (48, 48)
  • South West (48, 0)

If you're watching a match, these are represented by the numbers 1 to 4.

The functions should each have this fingerprint:

function(api) {
}

api is your function's interface to the game (see below).

The Kid API

The api object presents these four movement functions:

  • api.north()
  • api.east()
  • api.south()
  • api.west()

If any of these are called during your function, the kid will take one step in that direction (or the last called of these four directions). If none of these are called during your function, the kid will stand still.

It also provides information about the state of the game with these methods:

  • api.my_storage() - an object you can use to store data and functions for just this kid.
  • api.shared_storage() - an object you can use to store data and functions for the whole team.
  • api.turn() - Returns a number of turns taken in this game so far.
  • api.bunny() - Returns an object of bunny-related info if the bunny can be seen

    { x: 24, y: 24, eggs_left: 100 }

  • api.kids() tells you where all the kids are

    [ {x: 0, y: 0, me: true}. ... ]

  • api.eggs() tells you where the eggs are that your child can currently see:

    { x: 25, y: 25, age: 10 }

Age is the number of turns since the bunny dropped the egg.

Kid Template

Teams.push(
  {
    name: 'template',
    shared_storage: {},
    functions: [
      function(api) {
        // NW kid
      },
      function(api) {
        // NE kid
      },
      function(api) {
        // SE kid
      },
      function(api) {
        // SW kid
      }
    ]
  }
);
  • name must be a single-word identifier, if you want to run just a single entry.
  • shared_storage sets the initial state of api.shared_storage, it can be used to set data and functions for your team.
  • The array functions is the behaviour of the 4 kids chasing the bunny.

How to participate

You will need nodejs installed.

Change my_entry to your own team name.

  • git clone https://github.com/AJFaraday/easter_bunny_hunt.git
  • npm install terser -g
  • cd easter_bunny_hunt
  • cp team_template.js teams/my_entry.js
  • (Write your team code)
  • script/run.sh my_entry basic to watch a game. The first entry is the name of your team, the second is the name of an entry in bunnies/.
  • script/run.sh to run all matches and see all results (if you import more entries)

When you're happy with the result, copy it in to an answer like so:


    # Team: my_entry - 10 points

    Any description you want to add goes here

        Teams.push(
          {
            name: 'template',
            shared_storage: {},
            functions: [
              function(api) {
                // NW kid
              },
              function(api) {
                // NE kid
              },
              function(api) {
                // SE kid
              },
              function(api) {
                // SW kid
              }
            ]
          }
        );

Then have a try at writing an entry for the Easter Bunny™.

As the Bunny

Your goal is to give away as many easter eggs as you can and, crucially, to evade capture.

The bunny starts at the centre of the garden, at coordinates 24, 24.

Your code takes the form of a function with this finger print which runs once a turn, after the children have moved.

function(api) {
}

The Bunny API

The api object provides this method to tell the bunny how to move:

  • api.hop(x, y)

The two arguments tell the bunny where to hop to relative to it's current position:

  • They can have values from -2 through to 2.
  • If x is positive, it will hop east, negative, it'll hop west.
  • If y is positive, it will hop south, negative, it'll hop north.
  • If the values provided are out of range, it will force it to 2 or -2.
  • Each time the bunny hops, it leaves behind an Easter egg.

It also provides this functions to give you storage between turns:

  • api.storage() - Returns an object you can use to store variables.

    And these functions to give you information about the game:

  • api.turn() - Returns the turn number the game is currently at.

  • api.eggs() - Returns the positions of all Easter eggs in the garden.

    { x: 25, y: 25, age: 10 }

  • api.bunny() - Provides information on the current state of the bunny

    { x: 24, y: 24, eggs_left: 100 }

  • api.kids() - Provides information on all the kids the bunny can currently see.

    { x: 0, y: 0 }

Bunny Template

Bunnies.push(
  {
    name: 'template',
    storage: {},
    function: function(api) {

    }
  }
);
  • name is the name of your bunny behaviour. Keep it to 1 word (underscores allowed).
  • storage is the current state of your storage object, available via the api.
  • function is the function which will be run every turn to control the bunny.

How to participate

You will need nodejs installed.

Change my_entry to your own bunny name.

  • git clone https://github.com/AJFaraday/easter_bunny_hunt.git
  • npm install terser -g
  • cd easter_bunny_hunt
  • cp bunny_template.js bunnies/my_entry.js
  • (Write your team code)
  • script/run.sh get_egg my_entry to watch a game. The first argument is the name of a team in teams/, the second is the name your bunny.
  • script/run.sh to run all matches and see all results (if you import more entries)

When you're happy with the result, copy it in to an answer like so:

    # Bunny: my_entry - 10 points

    Any description you want to add goes here

    Bunnies.push(
      {
        name: 'template',
        storage: {},
        function: function(api) {

        }
      }
    );

Then have a try at writing an entry for a team of kids.

\$\endgroup\$
  • \$\begingroup\$ Was this posted in the sandbox? (I didn't see it there, but I might have simply not looked into it for too long) Proof that 4 children can't catch a bunny: a bunny has 24 target cells, and even impossibly well-placed children only cover 20 (unless I missed a rule) \$\endgroup\$ – the default. Apr 11 '20 at 12:55
  • 1
    \$\begingroup\$ It was not, but it is an adaptation of a challenge I posted a couple of days ago \$\endgroup\$ – AJFaraday Apr 11 '20 at 12:56
  • \$\begingroup\$ oops: I noticed that my proof is wrong because the kids might be able to force the bunny to go to a corner, where it has less than 24 target cells... \$\endgroup\$ – the default. Apr 11 '20 at 13:01
  • \$\begingroup\$ There should be separate posts for kids and bunnies. \$\endgroup\$ – pppery Apr 11 '20 at 13:16
  • \$\begingroup\$ @mypronounismonicareinstate ahh, yes. The edge of the garden is key. \$\endgroup\$ – AJFaraday Apr 11 '20 at 13:20
4
\$\begingroup\$

Bunny: smartish (2 points, but, of course, as of posting)

Hops to the middle when it doesn't see anybody, and tries to escape the kids (using an algorithm I probably implemented incorrectly).

Bunnies.push(
{
    name: 'smartish',
    storage: {},
    function: function(api)
    {
        let x = api.bunny().x;
        let y = api.bunny().y;
        if(api.kids().length == 0)
        {
            //hop towards middle
            let dx = 24 - x;
            let dy = 24 - y;
            api.hop(dx, dy);
            return;
        }
        //else build an array of safe cells
        safe = [[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1],[1,1,1,1,1]];
        for(let i in api.kids())
        {
            let kid = api.kids()[i];
            let dx = x - kid.x;
            let dy = y - kid.y;
            if(dx >= -2 && dx <= 2 && dy >= -2 && dy <= 2)
                safe[dx+2][dy+2] = false;
            dx++;
            if(dx >= -2 && dx <= 2 && dy >= -2 && dy <= 2)
                safe[dx+2][dy+2] = false;
            dx -= 2;
            if(dx >= -2 && dx <= 2 && dy >= -2 && dy <= 2)
                safe[dx+2][dy+2] = false;
            dx++; dy++;
            if(dx >= -2 && dx <= 2 && dy >= -2 && dy <= 2)
                safe[dx+2][dy+2] = false;
            dy -= 2;
            if(dx >= -2 && dx <= 2 && dy >= -2 && dy <= 2)
                safe[dx+2][dy+2] = false;
            dy++;
        }
        //find the farthest safe cell and hop there
        let bestx = 0, besty = 0, bestd = 0;
        for(let dx = -2; dx <= 2; dx++)
        for(let dy = -2; dy <= 2; dy++)
        {
            if(!safe[dx+2][dy+2]) continue;
            let d = 9999;
            for(let kid of api.kids())
                d = Math.min(d, (kid.x-x)*(kid.x-x) + (kid.y-y)*(kid.y-y));
            if(d > bestd)
                bestd = d, bestx = dx, besty = dy;
        }
        api.hop(bestx, besty);
    }
}
);
\$\endgroup\$
  • \$\begingroup\$ I think the kids could push you in a corner, once they find you, by always staying between the center and you, forming a blockade. But if, instead, you hopped towards a random point in an area avoiding a 10-wide area around the border, you'd be uncatchable \$\endgroup\$ – Jeffrey Jul 28 '20 at 17:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.