This KoTH is inspired by <a href="https://www.youtube.com/channel/UCKzJFdi57J53Vr_BkTfN3uQ">Primer's Natural Selection Simulation</a>. Your bot is a blob. In order to survive, you must eat pellets to regain energy, which is used to move. With extra energy, blobs can split into two.

###Energy and Movement

Your blob starts off each round with 100 energy, and it has no limit on the amount of energy it can collect. Each round is run in turns, with each blob having the option to move North, East, South, or West in any given turn, or stand still. Moving uses 1 energy, and standing still uses 0.25 energy. The map's side length is `ceil(0.25 * blobCount) * 2 - 1` units, with a minimum of 9 units. All blobs start on the edge of the map, with one placed in each corner and every subsequent blob being placed 2 units away from any others. Every 30 turns, a wave of pellets are placed in random spots around the map, at least 1 unit from any edge. Each time a wave of pellets appears, the quantity of pellets (originally twice the number of blobs or the width of the map, whichever is larger) in the next wave is decreased by 1, forcing the number of blobs to decrease over time. Each pellet restores between 5 and 15 energy. When a blob's energy is less than or equal to 0, it dies.

###Eating

If two or more blobs attempt to occupy the same location, the one with the most energy will eat the others, receiving their energy.

###Detection and Information

Blobs can see any pellets or other blobs within a distance of 4 units. When their functions are called, blobs are provided with:

- The side length of the map
- The position of the blob on the map
- The positions of all pellets within their search radius, as well as their values
- The positions of all blobs within their search radius, as well as their UIDs
- The energy, UID, and locations of the blob whose function is being executed
- A storage object unique to the blob
- A storage object shared by all blobs related to the blob through splitting

###Splitting

If a blob has more than 100 energy, it can choose to split. Splitting costs 100 energy, and any remaining energy is divided evenly between the two blobs. All blobs are either originals or split copies, with every copy tracing back to an original. All of these together are "relatives." All relatives have one communal storage object. Relatives can still eat each other, and can split, use their own storage object, or collect energy without affecting others.

###Functions, Storage, and UIDs

In order to allow more complex learning behaviors, all blobs will be given an integer UID (Unique Identifer). These UIDs will be randomly generated each map, preventing strategies based on individual targets. When a blob's function is called, it is passed four arguments:

1. The side length of the map as an integer
2. An object with two arrays: `pellets`, and `blobs`. Both arrays contain objects, both having a `pos` property containing the pellet or blob's position formatted as `[x,y]`. Pellets will have an `energy` property, while blobs will have a `uid` property
3. An object containing various properties of the blob it is passed to: `energy`, `uid`, and `pos`. The `pos` array is formatted as `[x,y]`
4. An object containing the two storage objects of the blob. A `self` property contains an individual storage object which can be modified however the blob sees fit (by manipulating properties of the object that is passed), and a `communal` property which can be modified by any relative.

Blobs are not moved immediately to prevent earlier/later turns having an advantage. All movements are processed in groups (All collisions/eating, then all pellets, then splitting, etc.) If a blob lands on a pellet or smaller blob and, in the process uses its last energy, the blob will still consume the pellet/energy independent of whether that would would bring its total energy above 0.

In order for relative blobs to recognize one another, the communal storage must be used for each blob to record its UID in an array, or through some other system.

###Return Values

In order to move or split, the return value of the function is used. First, the meaning of the cardinal directions in terms of coordinates:

- North = -Y
- East = +X
- South = +Y
- West = -X

Note that `[0,0]` is the _top left corner_, and Y increases as you go down. The return value of the function should follow these rules:

- **To do Nothing:** Return nothing, 0, null, undefined, false, or any other value that equates to false
- **To Move:** Return one of four global variables: North, East, South, or West, which equate to "north", "east", "south", or "west" (which could also be used as a return value)
- **To Split:** Return the global variable SplitNorth, SplitEast, SplitSouth, or SplitWest, the direction indicating where to place the new blob

If a split command is returned and the amount of energy required is greater than or equal to the energy of the blob, nothing will happen. Blobs will not be able to leave the map.

###Predefined Library Functions

There are a few basic functions available by default, to save some time:

**taxiDist(pt1, pt2)**

Returns the taxicab distance between two points (X distance plus Y distance).

```javascript
taxiDist([0, 0], [2, 2]) //4
taxiDist([3, 4], [1, 5]) //3
taxiDist([1.25, 1.3], [1.3, 1.4]) //0.15
taxiDist([0, 0], [5, 2.5], 2.5) //3
taxiDist([0, 0], [2, 4], 2.5) //2.4
```

**hypotDist(pt1, pt2)**

Returns distance between two points according to the pythagorean theorem

```javascript
hypotDist([0, 0], [5, 12]) //13
hypotDist([4, 6], [8, 9]) //5
hypotDist([0, 1], [2, 1]) //2
hypotDist([1, 1], [2, 2]) //sqrt(2)
```

**modDir(dist, amt)**

Takes the inputted distance, rotates 90 degrees clockwise `amt` times, then returns the new value.

```javascript
modDist(North, 1) //East
modDist(East, 2) //West
modDist(West, 3) //South
modDist(South, 4) //South
```

###Example Blob

This blob will not move until it finds a pellet nearby. Then, it will move in the direction it thinks is most likely to reward it. If its energy is ever above 150, it will split.

```javascript
function(map, near, me, storage) {
    if (me.energy > 150)
        return SplitNorth;
    if (!near.pellets.length)
        return null;
    var dirs = [0, 0, 0, 0];
    for (let p, i = 0; i < near.pellets.length; i++) {
        p = near.pellets[i];
        dirs[0] += me.pos[1] - p.pos[1];
        dirs[1] += p.pos[0] - me.pos[0];
        dirs[2] += p.pos[1] - me.pos[1];
        dirs[3] += me.pos[0] - p.pos[0];
    }
    return [North, East, South, West][dirs.indexOf(Math.max(...dirs))];
}
```

###Rules

- <a href="https://codegolf.meta.stackexchange.com/questions/1061/loopholes-that-are-forbidden-by-default">Standard Loopholes</a> are prohibited. Also, no Unstandard Loopholes.
- No blob may attempt to modify or read any data not passed to it via its parameters
- No blob may attempt to modify a return-value variable to sabotage other blobs
- A round lasts until the only remaining blobs are relatives
- No blob may modify data by injecting functions into its parameters which modify values using the `this` keyword
- All submissions must either be in Javascript or a language which is not too different from Javascript (Python, for example). All answers will be converted to Javascript for the competition.
- The winner is the blob which has collected the highest amount of energy in total across all rounds (from either pellets or consuming smaller blobs that are not relatives)

**Controller:** https://gist.github.com/RedwolfPrograms/1facc0afe24c5dfd3ada8b8a2c493242

**Chatroom:** https://chat.stackexchange.com/rooms/93370/hungry-blobs-koth

**Note: If anything seems out of place, please let me know as a few mistakes were left from an earlier version. Please do this before voting to close as unclear!**