4
\$\begingroup\$

Chat room: https://chat.stackexchange.com/rooms/106513/easter-bunny-challenge

Git repo: https://github.com/AJFaraday/easter_bunny_hunt

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. He'll hop away from where the most people are.

When the Easter Bunny™️ hops, we all know he'll leave behind an Easter egg.

Grab an Easter egg for 1 point. Grab the Easter Bunny for 10 points.

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 bunny can hop to any position up to 4 spaces away in both the x and y axes. It will decide where it will hop to by the position of the kids.

The bunny can see kids within 5 spaces of it in any direction (I'm using square distances for simplicity). For each axis, (ignoring the kids in a line with it) it will move away from the most kids it can see. e.g.

  • If it can see 1 kid to the right, and none to the left. it will hop 1 step to the west.
  • If it can see 3 below, and 1 above, it will hop 2 step north.
  • If there are 2 north, 1 south, and 2 west. it will hop directly to a space 1 step south and 2 steps west.

Important quirks:

  • The bunny ignores kids on the same row when working out it's north/south hop, and in the same column for it's east/west.
  • If it can't see any kids, it will stay still until it can.
  • If the left/right and up/down counts are equal, it will reamin rooted to the spot, like a rabbit in the headlights.

The game ends when:

  • The Easter Bunny™️ leaves the garden.
  • The Easter Bunny™️ drops his last egg.
  • The kids catch the bunny.
  • The game reaches the configurable turn limit

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.

How to hunt the 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)

The functions should each have this fingerprint:

function(api) {
}

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

The 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 thess 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

    { 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 qhere all the eggs are

    [ {x: 25, y: 25} ]

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

Change my_entry to your own team name.

  • git clone https://github.com/AJFaraday/easter_bunny_hunt.git
  • cd easter_bunny_hunt
  • npm install -g terser
  • cp template.js teams/my_entry.js
  • (Write your team code)
  • script/run.sh my_entry to watch the game
  • script/run.sh to see all results (if you import more entries)

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

# 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
          }
        ]
      }
    );

Competition rules

Official scoreboard will be updated roughly once a day.

This will run until the 19th of April, one week after Easter Sunday (in the traditions which celebrate Easter Sunday on the 12th of April this year).

\$\endgroup\$
  • 1
    \$\begingroup\$ Is this intended to be tagged [king-of-the-hill]? \$\endgroup\$ – my pronoun is monicareinstate Apr 9 at 15:24
  • \$\begingroup\$ @mypronounismonicareinstate I'd like to tag it king of the hill, but it will be removed if I do. A king of the Hill is only when entries interact with each other. The challenge here is to find a high-scoring path through a task. \$\endgroup\$ – AJFaraday Apr 9 at 15:26
  • 2
    \$\begingroup\$ If so, can this be tagged [ai-player]? update: it's not a winning criterion though, merely a tag; should also probably have [code-challenge] \$\endgroup\$ – my pronoun is monicareinstate Apr 9 at 15:27
  • 1
    \$\begingroup\$ Am I correct that the bunny does not move if it sees one kid above and one kid below, for example? \$\endgroup\$ – pppery Apr 9 at 15:49
  • 1
    \$\begingroup\$ @RGS it means it looks up to 5 squares away on both axes, describing a square which is visible to the bunny. \$\endgroup\$ – AJFaraday Apr 9 at 17:04
5
\$\begingroup\$

The Run of Doom, score 109

var kid_api = function (api) {
    var bunny = api.bunny();
    var kids = api.kids();
    for (var i = 0;i<kids.length;i++) {
        if(kids[i].me) {
            var me = kids[i];
            if (me.x < 24) {
                return api.east();
            } else if (me.x > 24) {
                return api.west();
            } else {
                var s = api.shared_storage();
                var my_data = s[i];
                if (!my_data) {
                    return;
                }else if (my_data.backaway == bunny.eggs_remaining) {
                    return;
                }else if(bunny.y == me.y + my_data.y && bunny.eggs_remaining != 1) {
                    s[2] = Object.assign({}, s.opposites[my_data.func])
                    s[0] = Object.assign({}, s.opposites[my_data.func])
                    s[2-i].backaway = bunny.eggs_remaining;
                    s[i].backaway = 1;
                    api[s[i].func]();
                } else if (me.y + my_data.y < 0 || me.y + my_data.y > 49) {
                    s[i] = null;
                } else {
                    api[my_data.func]();
                }
            }
        }
    }
}
Teams.push(
  {
    name: 'the_run_of_doom',
    shared_storage: {
        2: {"func": "north", "y": -1},
        0: null,
        "opposites": {
            "south":{"func": "north", "y":-1},
            "north":{"func":"south", "y":1}
        },
    },
    functions: [
      kid_api,
      function(api) {
        // NE kid
      },
      kid_api,
      function(api) {
        // SW kid
      }
    ]
  }
);

Uses only two kids: one that starts on the north side, and one that starts on the south side (this version uses NW and SE, but it could be rewritten to use NE and SW, or NE and SE, or NW and SW fairly easily). With a little more effort, one could do this with any combination of two kids.

A score of 110 isn't possible, since the game always ends immediately after the bunny drops the last egg, so I believe this answer is unbeatable.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Maybe you should rename it The Hog of Eggs! T_T \$\endgroup\$ – Noodle9 Apr 9 at 17:25
  • \$\begingroup\$ No, I think I like "The Run of Doom", given it describes the pattern of the easter bunny; repeatedly bolting from one edge of the garden to the other without actually ever getting away. \$\endgroup\$ – pppery Apr 9 at 17:26
2
\$\begingroup\$

random - 0 to 33 points

Totally random kids!

Teams.push(
  {
    name: 'random',
    shared_storage: {
      sequence: 'abcd',
      take_step: function(api) {
        var char = api.shared_storage().sequence[Math.floor(Math.random() * 5)];
        if(char) {
          api[api.my_storage()['key'][char]]();
        }
      }
    },
    functions: [
      function(api) {
        // NW kid
        if(!api.my_storage()['key']) {
          api.my_storage()['key'] = {'a': 'east', 'b': 'south', 'c': 'west', 'd': 'north'}
        }
        api.shared_storage().take_step(api);
      },
      function(api) {
        // NE kid
        if(!api.my_storage()['key']) {
          api.my_storage()['key'] = {'a': 'east', 'b': 'south', 'c': 'west', 'd': 'north'}
        }
        api.shared_storage().take_step(api);
      },
      function(api) {
        // SE kid
        if(!api.my_storage()['key']) {
          api.my_storage()['key'] = {'a': 'east', 'b': 'south', 'c': 'west', 'd': 'north'}
        }
        api.shared_storage().take_step(api);
      },
      function(api) {
        // SW kid
        if(!api.my_storage()['key']) {
          api.my_storage()['key'] = {'a': 'east', 'b': 'south', 'c': 'west', 'd': 'north'}
        }
        api.shared_storage().take_step(api);
      }
    ]
  }
);
| improve this answer | |
\$\endgroup\$

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.