text:
Food shortage in the Snakepit
Food shortage in the Snakepit
For the first time in 35 years, the snakepit is running out of food. The inhabitant snakes now have to fight each other in order to survive this food shortage. Only one snake can stand at the top of the food chain!

Leaderboard
Not here yet!
Last update on February, 24th
Link to visualizations of last matches

Description
If you want to fight for the last remaining apples/cherries/whatever, you have to provide a snake in form of a program that accepts a given input and returns its next move.
The only twist is that you're not alone in your pit. Another snake will try to get the rare food too! But it's dark inside the snakepit so you can only see yourself and the apple. Crashing into your opponent will result in your death, just like biting yourself or hitting a wall. Additionally, because apples are rare these days, you starve if your opponent ate enough to reach a length of 7.
The snakepit is a two-dimensional map with a width and height of 15, while the outermost tiles build an impassable wall:
  0 1 2 . . . c d e
0 # # # # # # # # #
1 #               #
2 #           x   #
. #               #
. #               #
. #               #
c #               #
d #               #
e # # # # # # # # #

Coordinates are zero-indexed, so the point where the x is would be 12,2.
Your bot will be called with two arguments:

The location of the food
The locations of your body segments, separated by /

It should then write one of the following to stdout:

L for a quarter left turn as its next move
R for a quarter right turn
Anything else for a move in the same direction

Example:
Projects/Snakepit> python bot.py 12,2 4,8/4,9/3,9/2,9
'R'
Projects/Snakepit>

Rules
Your bot is allowed to:

Output anything, because anything is a valid move
Read/write files in its own directory which is located under ./snakes/ThisIsYourSnake
Run on Ubuntu 14.04 and Windows 7 (it actually has to)

Your bot must not:

Read/write files outside its own directory
Use external resources such as the internet
Have a runtime above 10 seconds per execution

You have to provide in your answer:

The source code of the bot
A bot/snake name
(Your own name)
A command to run your bot

If you want to make my life easier, please provide a line like CoolSnake MyOwnName python bot.py.

Scoring
Your snake gets a point for winning a game against another snake. A game is won under the following circumstances:

Your opponent hits himself, you or a wall
You reach length 7

Additionally, both snakes starve after 200 cycles.
Each snake will fight 10 matches for their survival against each other snake.

Example Bots
Just to give you an idea, I'll provide these two (participating) example snakes:
SneakySnake
#!/usr/bin/env python

import sys, random

def main(food, me) :
    food = [int(i) for i in food.split(",")]
    me = [[int(i) for i in seg.split(",")] for seg in me.split("/")]
    head = me[0]
    v = [head[0] - me[1][0], head[1] - me[1][1]]

    if food[0] < head[0] :
        vn = [-1, 0]
    elif food[0] > head[0] :
        vn = [1, 0]
    elif food[0] == head[0] :
        if food[1] < head[1] :
            vn = [0, -1]
        elif food[1] > head[1] :
            vn = [0, 1]

    if v == vn :
        return "..."
    elif [-v[1], v[0]] == vn :
        return "R"
    elif [v[1], -v[0]] == vn :
        return "L"
    else :
        return random.choice(("R", "L"))

if __name__ == "__main__" :
    print main(*sys.argv[1:3])

SneakySnake Cipher python bot.py

ViciousViper
#!/usr/bin/env python

import sys, random

def main(food, me) :
    food = [int(i) for i in food.split(",")]
    me = [[int(i) for i in seg.split(",")] for seg in me.split("/")]
    head = me[0]
    v = [head[0] - me[1][0], head[1] - me[1][1]]
    vn = [food[0] - head[0], food[1] - head[1]]
    if 0 not in vn :
        vn[v.index(0)-1] = 0
    vn[vn.index(0)-1] = vn[vn.index(0)-1] / abs(vn[vn.index(0)-1])

    if v == vn :
        return "..."
    elif [v[0] + vn[0], v[1] + vn[1]] == [0, 0] :
        return random.choice(("R", "L"))
    else :
        return "R" if [-v[1], v[0]] == vn else "L"

if __name__ == "__main__" :
    print main(*sys.argv[1:3])

ViciousViper Cipher python bot.py

And their matches:

Control program
You can find the control program on github, along with all bots and records of past matches.
Requirements:

Python 2 + the libraries numpy and pillow (you can check if they are present via python -c "import numpy, PIL", if it throws errors the modules are missing)
Copying the full folder structure is required in order for the controller to work
Register your bot(s) in the ./snakes/list.txt file in the style of CoolSnake MyOwnName Command To Run My Bot
Place your bot inside a directory with its name under ./snakes
Neither your, nor your bot's name is allowed to contain whitespaces!

Usage:

python run.py [-h] [-n int] [-s int] [-l int] [-c int] [-g]

python run.py will run the tournament with all bots registered in list.txt and the standard properties. Advanced options are:

-h displays a help message
-n int rounds of battles for each combination of opponents
-s int determines the size of the grid (width and height)
-l int sets the required length to win
-c int sets the limit of cycles
-g or --no-gifs creates no gifs of the matches

I suppose ties result in no points (like if both snakes run into each other, or hit the wall on the same turn)?

I'm not sure how much interesting interacting strategies you'll get if bots have almost no way of knowing where any other bots are.

Since we're limited to length <7, even knowing where the opponent is only matters for avoidance. You're not really long enough to do anything but the simplest of blocking. I suspect that most matches will just come down to who was closest to each food as it spawned.

Will we know if we are facing a new bot or the same as the one in the last match? Like the data files will be deleted if a new bot will be the opponent. (We probably want to find out the tactic of the opponent through matches.)

I had an amazing plan for how to do really really well in this. Then I read the rules more. If you can't see the other snake your options are really "take the direct path" or "take some longer path". Neither are very interesting if it is just dumb luck avoiding the other snake.

I don't think you guys have thought this through. When your enemy takes an apple, you know exactly where he is. You can then predict the path he will take to the current apple. You may figure out you can reach it first with no chance of collision, or you may lay a trap by dragging your tail across his likely path. You can also estimate his strategy by how long it takes him to get an apple, or when he has collided with your tail in previous games. And, of course, he knows that you know that he knows...etc. Excellent puzzle Cipher +1.

The idea behind this was like CarpetPython said, it's about finding the right balance between playing hide-and-seek and actual Snake

I'm thinking about creating a separated tournament with more focus on the original game and stuff like seeing your opponent, increased length limit, etc. Anyone interested?

@CarpetPython: +1 for the insight

@CarpetPython There was a bit of talk in chat about that, but I'm unconvinced it will matter that much in practice. Hopefully I'm wrong, but we'll see :)

Zen - C++
This Codémon is not here to eat but to fight. He knows that a dead enemy will not stole his apples.

Name|   Author   |Launch with
Zen GholGoth21 Zen.exe

Strategy
Everybody (excepted CircleOfLife) rush to the apples, but not Zen, not always. If the enemy can reach the food before him, he simply wait at the center (what? but what are you doing here, CircleOfLife?). Else, Zen goes at the apple and turns around while waiting that something happens. In fact, he uses the apple as a bait.
I didn't coded anything against the curious strategy of CircleOfLife because he can only win with very very much luck.
The code
This is the complete code of the C++ project. Cut the 11 source files and the Makefile and compile with make
$ cat src/* Makefile
/*
 * @file    Enemy.cpp
 * @author  GholGoth21
 * @date    Créé le 1 mars 2015 à 14:10
 */

#include "Enemy.h"

#include <fstream>

Enemy::Enemy()
{
}

Enemy::~Enemy()
{
}

std::ostream &operator<<(std::ostream &os, const Enemy& e)
{
    return os<<e.m_pos<<" "<<e.m_date;
}

std::istream &operator>>(std::istream &is, Enemy& e)
{
    return is>>e.m_pos>>e.m_date;
}

int Enemy::distTo(int2 const &target, int date) const
{
    return m_pos.distTo(target)-(date-m_date);
}

bool Enemy::recentActivity(int2 const &pos, int date, int maxDelay) const
{
    return pos.distTo(m_pos)<=date-m_date && date-m_date<=maxDelay;
}
/*
 * @file    Enemy.h
 * @author  GholGoth21
 * @date    Créé le 1 mars 2015 à 14:10
 */

#ifndef ENEMY_H
#define ENEMY_H

#include "int2.h"

class Enemy
{
public:
    Enemy();
    virtual ~Enemy();

public:
    void setPos(int2 const &pos, int date) { m_pos=pos; m_date=date; }
    int distTo(int2 const &target, int date) const;
    int2 const &pos() const { return m_pos; }
    bool recentActivity(int2 const &pos, int date, int maxDelay) const;
    friend std::ostream &operator<<(std::ostream &os, const Enemy& e);
    friend std::istream &operator>>(std::istream &is, Enemy& e);

private:
    int2 m_pos;
    int m_date;
};

#endif  /* ENEMY_H */
/*
 * @file    Snake.cpp
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:47
 */

#include "Snake.h"
#include "enums.h"
#include "StrManip.h"
#include "Enemy.h"

#include <vector>
#include <cmath>

Snake::Snake(std::string const &body)
{
    std::vector<std::string> posList;
    split(body, '/', posList);
    for(auto &pos : posList)
        m_body.push_back(int2(pos));
}

Snake::~Snake()
{
}

Command Snake::move(int2 food, int date, Enemy const &enemy)
{
    Command bestCommand[Command::count];

    int myDist=curPos().distTo(food);
    int enemyDist=enemy.distTo(food,date);

    if(myDist>=enemyDist && enemyDist>2)
    {
        orderCommand(int2(MAPSIZE/2,MAPSIZE/2), bestCommand);
        for(int i=0; i<Command::count; i++)
            if(validCommand(bestCommand[i]) && !enemy.recentActivity(nextPos(bestCommand[i]),date,5))
                return bestCommand[i];
    }
    if((myDist==1 && enemyDist>((len()-1)/2)*2+3) || enemyDist<-5)
    {
        orderCommand(food, bestCommand);
        for(int i=0; i<Command::count; i++)
            if(validCommand(bestCommand[i]))
                return bestCommand[i];
    }
    int2 embushPoint;
    int minDist=-1;
    foreach_enum(Direction, d)
    {
        int2 point(food+d.vector());
        int dist=point.quadDistTo(enemy.pos());
        if(dist<minDist || minDist<0)
        {
            minDist=dist;
            embushPoint=point;
        }
    }
    if(curPos().distTo(embushPoint)<enemy.distTo(embushPoint,date)-((len()-1)/2)*2)
    {
        int minimalAction=-1;
        int qMinDist = curPos().quadDistTo(embushPoint);
        Command minimalCommand;
        foreach_enum(Command, c)
        {
            int2 np=nextPos(c);
            int qDist = np.quadDistTo(embushPoint);
            if((qDist<minimalAction || minimalAction<0) && qDist>qMinDist && validCommand(c))
            {
                minimalAction=qDist;
                minimalCommand=c;
            }
        }
        return minimalCommand;
    }
    else
    {
        orderCommand(embushPoint, food, bestCommand);
        for(int i=0; i<Command::count; i++)
            if(validCommand(bestCommand[i]) && nextPos(bestCommand[i])!=food)
                return bestCommand[i];
    }

    return Command::forward;
}

bool Snake::validCommand(Command c) const
{
    if(!c.isValid())
        return false;
    int2 np = nextPos(c);
    if(!(0<np.x && np.x<MAPSIZE-1 && 0<np.y && np.y<MAPSIZE-1))
        return false;
    for(unsigned int i=2; i<m_body.size()-1; i++)
        if(np==m_body.at(i))
            return false;
    return true;
}

bool Snake::isStarting() const
{
    if(m_body.size()==3)
    {
        if(m_body.at(0)==int2(3,(MAPSIZE)/2) && m_body.at(1)==int2(2,(MAPSIZE)/2) && m_body.at(2)==int2(1,(MAPSIZE)/2))
            return true;
        else if(m_body.at(0)==int2(MAPSIZE-4,(MAPSIZE)/2) && m_body.at(1)==int2(MAPSIZE-3,(MAPSIZE)/2) && m_body.at(2)==int2(MAPSIZE-2,(MAPSIZE)/2))
            return true;
    }
    return false;
}

void Snake::orderCommand(int2 target, Command *tab)
{
    int weight[Command::count];
    foreach_enum(Command, c)
    {
        int2 np = nextPos(c);
        weight[c]=np.quadDistTo(target);
        tab[c]=c;
    }
    for(int i=0; i<Command::count-1; i++)
    {
        while(i>=0 && weight[tab[i]]>weight[tab[i+1]])
        {
            varSwitch(tab[i], tab[i+1]);
            i--;
        }
    }
}

void Snake::orderCommand(int2 target1, int2 target2, Command *tab)
{
    int weight[Command::count];
    foreach_enum(Command, c)
    {
        int2 np = nextPos(c);
        weight[c]=np.quadDistTo(target1)+np.quadDistTo(target2);
        tab[c]=c;
    }
    for(int i=0; i<Command::count-1; i++)
    {
        while(i>=0 && weight[tab[i]]>weight[tab[i+1]])
        {
            varSwitch(tab[i], tab[i+1]);
            i--;
        }
    }
}
/*
 * @file    Snake.h
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:47
 */

#ifndef SNAKE_H
#define SNAKE_H

#include "int2.h"

#include <vector>

#define MAPSIZE 15

class Enemy;

class Snake
{
public:
    Snake(std::string const &body);
    virtual ~Snake();

public:
    Command move(int2 food, int date, Enemy const &enemy);
    Direction curDir() const { return (m_body.at(0)-m_body.at(1)).direction(); }
    int2 curPos() const { return m_body.at(0); }
    int2 nextPos(Command c) const { return curPos()+curDir().applyCommand(c).vector(); }
    bool validCommand(Command c) const;
    bool isStarting() const;
    void orderCommand(int2 target, Command *tab);
    void orderCommand(int2 target1, int2 target2, Command *tab);
    int len() const { return m_body.size(); }

private:
    std::vector<int2> m_body;
};

#endif  /* SNAKE_H */
/*
 * @file    StrManip.cpp
 * @author  GholGoth21
 * @date    Créé le 7 février 2015 à 17:26
 */

#include "StrManip.h"

#include <sstream>

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems)
{
    std::stringstream ss(s);
    std::string item;
    while(std::getline(ss, item, delim))
        elems.push_back(item);
    return elems;
}

int atoi(std::string const &text)
{
    std::stringstream ss(text);
    int val;
    ss >> val;
    return val;
}
/*
 * @file    StrManip.h
 * @author  GholGoth21
 * @date    Créé le 7 février 2015 à 17:26
 */

#ifndef STRMANIP_H
#define STRMANIP_H

#include <string>
#include <vector>

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems);
int atoi(std::string const &text);

#endif  /* STRMANIP_H */
/*
 * @file    enums.cpp
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:55
 */

#include "enums.h"
#include "int2.h"

Command Direction::turnTo(Direction newDir) const
{
    if(!isValid() || !newDir.isValid())
        return Command::count; //Invalid
    else if((m_value==Direction::up && newDir==Direction::left) || (m_value==Direction::left && newDir==Direction::down) ||
            (m_value==Direction::down && newDir==Direction::right) || (m_value==Direction::right && newDir==Direction::up))
        return Command::left;
    else if((m_value==Direction::up && newDir==Direction::right) || (m_value==Direction::right && newDir==Direction::down) ||
            (m_value==Direction::down && newDir==Direction::left) || (m_value==Direction::left && newDir==Direction::up))
        return Command::right;
    else if(m_value==newDir)
        return Command::forward;
    else
        return Command::count; // Invalid
}

Direction Direction::applyCommand(Command c) const
{
    if(c==Command::forward)
        return m_value;
    else if(c==Command::left)
    {
        switch(m_value)
        {
            case Direction::left:
                return Direction::down;
            case Direction::up:
                return Direction::left;
            case Direction::right:
                return Direction::up;
            case Direction::down:
                return Direction::right;
            default:
                break;
        }
    }
    else if(c==Command::right)
    {
        switch(m_value)
        {
            case Direction::left:
                return Direction::up;
            case Direction::up:
                return Direction::right;
            case Direction::right:
                return Direction::down;
            case Direction::down:
                return Direction::left;
            default:
                break;
        }
    }
    return Direction::count; // Invalid
}

int2 Direction::vector() const
{
    switch(m_value)
    {
        case Direction::left:
            return int2(-1,0);
        case Direction::up:
            return int2(0,-1);
        case Direction::right:
            return int2(1,0);
        case Direction::down:
            return int2(0,1);
        default:
            return int2(0,0);
    }
}

std::ostream &operator<<(std::ostream &os, const Command& c)
{
    switch(c.m_value)
    {
        case Command::left:
            return os<<"L";
        case Command::right:
            return os<<"R";
        default:
            return os<<"F";
    }
}
/*
 * @file    enums.h
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:55
 */

#ifndef ENUMS_H
#define ENUMS_H

#include <ostream>

struct int2;

#define DECL_ENUM_STRUCT(_name) \
_name() : m_value(static_cast<Type>(0)) {} \
_name(Type value) : m_value(value) {} \
_name(int value) : m_value(static_cast<Type>(value)) {} \
static Type begin() { return static_cast<Type>(0); } \
static Type end() { return count; } \
_name &operator++() { m_value=static_cast<Type>(static_cast<int>(m_value)+1); return *this; } \
operator int() const { return static_cast<Type>(m_value); } \
Type m_value;

#define foreach_enum(_type,_var) for(_type _var = _type::begin(); _var<_type::end(); ++_var)

struct Command
{
    enum Type
    {
        left,
        forward,
        right,
        count
    };

    bool isValid() const { return m_value<count; }
    friend std::ostream &operator<<(std::ostream &os, const Command& c);

    DECL_ENUM_STRUCT(Command)
};

struct Direction
{
    enum Type
    {
        left,
        up,
        right,
        down,
        count
    };

    bool isValid() const { return m_value<count; }
    Command turnTo(Direction newDir) const;
    Direction applyCommand(Command c) const;
    int2 vector() const;
    DECL_ENUM_STRUCT(Direction)
};

#endif  /* ENUMS_H */
/*
 * @file    int2.cpp
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:37
 */

#include "int2.h"
#include "enums.h"
#include "StrManip.h"

#include <vector>
#include <cmath>

int2::int2()
{
}

int2::~int2()
{
}

int2::int2(std::string const &text)
{
    std::vector<std::string> posList;
    split(text, ',', posList);
    x=atoi(posList.at(0));
    y=atoi(posList.at(1));
}

Direction int2::direction() const
{
    if(x==0 && y==0)
        return Direction::count; // Invalid
    else if(y>=std::abs(x))
        return Direction::down;
    else if(x>=std::abs(y))
        return Direction::right;
    else if(x<=-std::abs(y))
        return Direction::left;
    else
        return Direction::up;
}

Direction int2::secondary() const
{
    if(x==0 || y==0)
        return Direction::count; //Invalid
    else if(y<=std::abs(x) && y>=0)
        return Direction::down;
    else if(x<=std::abs(y) && x>=0)
        return Direction::right;
    else if(x>=-std::abs(y) && x<=0)
        return Direction::left;
    else
        return Direction::up;
}

int int2::distTo(int2 const &other) const
{
    return std::abs(x-other.x)+std::abs(y-other.y);
}

int int2::quadDistTo(int2 const &other) const
{
    return sq(x-other.x)+sq(y-other.y);
}

int2 int2::operator+(int2 const &other) const
{
    return int2(x+other.x,y+other.y);
}

int2 int2::operator-(int2 const &other) const
{
    return int2(x-other.x,y-other.y);
}

std::ostream &operator<<(std::ostream &os, const int2& c)
{
    return os<<c.x<<","<<c.y;
}

std::istream &operator>>(std::istream &is, int2& c)
{
    std::string text;
    is>>text;
    c=int2(text);
    return is;
}
/*
 * @file    int2.h
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:37
 */

#ifndef INT2_H
#define INT2_H

#include "enums.h"

#include <string>

struct int2
{
public:
    int2();
    int2(int p_x, int p_y) : x(p_x), y(p_y) {}
    int2(std::string const &text);
    virtual ~int2();

public:
    Direction direction() const;
    Direction secondary() const;
    int distTo(int2 const &other) const;
    int quadDistTo(int2 const &other) const;
    int2 operator+(int2 const &other) const;
    int2 operator-(int2 const &other) const;
    bool operator==(int2 const &other) const { return x==other.x && y==other.y; }
    bool operator!=(int2 const &other) const { return x!=other.x || y!=other.y; }
    friend std::ostream &operator<<(std::ostream &os, const int2& c);
    friend std::istream &operator>>(std::istream &is, int2& c);

public:
    int x;
    int y;
};

inline int sq(int val) { return val*val; }
template<typename T>
inline void varSwitch(T &a, T &b) { T tmp=a; a=b; b=tmp; }

#endif  /* INT2_H */
/*
 * @file    main.cpp
 * @author  GholGoth21
 * @date    Créé le 28 février 2015 à 17:23
 */

#include "int2.h"
#include "Snake.h"
#include "Enemy.h"

#include <cstdlib>
#include <iostream>
#include <fstream>

using namespace std;

/*
 * @brief La fonction principale du programme.
 * @param argc Le nombre de paramètres passés en ligne de commandes.
 * @param argv La liste des paramètres passés en ligne de commandes.
 */
int main(int argc, char** argv)
{
    /* Error handling */
    if(argc<3)
    {
        cerr<<"Error : not enough arguments on the command line."<<endl;
        cout<<"F"<<endl;
        return 1;
    }

    /* Init and load */
    int2 prevFood;
    int date = 0;
    Enemy enemy;
    ifstream load("PreviousState.txt");
    if(load)
    {
        load>>date;
        load>>prevFood;
        load>>enemy;
        load.close();
    }
    int2 food(argv[1]);
    Snake me(argv[2]);
    if(me.isStarting())
    {
        date=0;
        if(me.curPos().x<MAPSIZE/2)
            enemy.setPos(int2(MAPSIZE-4,MAPSIZE/2), 0);
        else
            enemy.setPos(int2(3,MAPSIZE/2), 0);
    }
    else if(prevFood!=food && me.curPos()!=prevFood)
    {
        enemy.setPos(prevFood, date);
    }

    /* Moving */
    cout<<me.move(food,date,enemy)<<endl;

    /* Saving */
    ofstream save("PreviousState.txt");
    if(save)
    {
        save<<++date<<endl;
        save<<food<<endl;
        save<<enemy<<endl;
        save.close();
    }
    return 0;
}
# Makefile
HEADERS = $(wildcard $(SRCPATH)/*.h)
SOURCES = $(wildcard $(SRCPATH)/*.cpp)
OBJECTS = $(patsubst $(SRCPATH)/%.cpp,$(BUILDPATH)/%.o,$(SOURCES))
M = Makefile

CFLAGS = -Wall -std=c++11

BINPATH = bin
BUILDPATH = build
SRCPATH = src

ifeq ($(OS),Windows_NT)
EXE = Zen.exe
else
EXE = Zen
endif

$(BINPATH)/$(EXE): $(BINPATH) $(BUILDPATH) $(OBJECTS)
    g++ -o $@ $(OBJECTS)

$(BUILDPATH)/%.o: $(SRCPATH)/%.cpp $(HEADERS) $M
    g++ $(CFLAGS) -o $@ -c $<

$(BINPATH) $(BUILDPATH):
    mkdir $@

clean:
    rm $(OBJECTS)

Or download the zip file : Zen.zip
Results
|     Name     |   Master   | Score |
|--------------|------------|-------|
| Zen          | GholGoth21 | 24    |
| SneakySnake  | Cipher     | 10    |
| ViciousViper | Cipher     | 6     |
| CircleOfLife | Manu       | 4     |

And some typical battles (ViciousViper vs Zen and SneakySnake vs Zen) :

Edit : I add this very intersting battle against CircleOfLife :

Nice strategy. Could you upload your project somewhere as a zip so others could use it more easily?

CircleOfLife (Java)
CircleOfLife Manu java CircleOfLife (Compile with javac CircleOfLife.java)
Runs towards the middle and stays there. I hope that some submissions will crash into it on their way to the food.
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

public class CircleOfLife {
    private static final int UP = 0;
    private static final int DOWN = 1;
    private static final int LEFT = 2;
    private static final int RIGHT = 3;
    private static final String GO_RIGHT = "R";
    private static final String GO_LEFT = "L";
    private static final String GO_FORWARD = "F";
    private static int currentDirection = UP;
    private static List<Point> snakeParts = new ArrayList<>();

    public static void main(String[] args) {
        String[] parts = args[1].split("/");
        for (String part : parts) {
            String[] pos = part.split(",");
            int x = Integer.parseInt(pos[0]);
            int y = Integer.parseInt(pos[1]);
            snakeParts.add(new Point(x,y));
        }
        Point head = snakeParts.get(0);
        Point neck = snakeParts.get(1);
        if (head.y - neck.y == 1) {
            currentDirection = DOWN;
        } else if (head.x - neck.x == -1) {
            currentDirection = LEFT;
        } else if (head.x - neck.x == 1) {
            currentDirection = RIGHT;
        }
        if (isInMiddle(head)) {
            makeCircle();
        } else {
            runToMiddle();
        }
    }

    private static void makeCircle() {
        if (!isInMiddle(snakeParts.get(1))) {
            System.out.println(GO_FORWARD);
            return;
        }
        Point head = snakeParts.get(0);
        Point neck = snakeParts.get(1);
        String output = GO_FORWARD;
        if (head.x == 8 && neck.x == 8) {
            output = currentDirection == UP ? GO_LEFT : GO_RIGHT;
        } else if (head.x == 7 && neck.x == 7) {
            output = currentDirection == UP ? GO_RIGHT : GO_LEFT;
        } else if (head.y == 8 && neck.y == 8) {
            output = currentDirection == RIGHT ? GO_LEFT : GO_RIGHT;
        } else if (head.y == 7 && neck.y == 7) {
            output = currentDirection == RIGHT ? GO_RIGHT : GO_LEFT;
        }
        System.out.println(output);
    }

    private static void runToMiddle() {
        Point head = snakeParts.get(0);
        int dX = 8 - head.x;
        int dY = 8 - head.y;
        String output = GO_FORWARD;

        if (Math.abs(dX) > Math.abs(dY)) {
            switch (currentDirection) {
                case DOWN: output = dX < 0 ? GO_RIGHT : GO_LEFT; break;
                case UP: output = dX < 0 ? GO_LEFT : GO_RIGHT; break;
                case RIGHT: output = dX < 0 ? GO_RIGHT : GO_FORWARD; break;
                case LEFT: output = dX < 0 ? GO_FORWARD : GO_RIGHT; break;
            }
        } else {
            switch (currentDirection) {
                case DOWN: output = dY < 0 ? GO_RIGHT : GO_FORWARD; break;
                case UP: output = dY < 0 ? GO_FORWARD : GO_RIGHT; break;
                case RIGHT: output = dY < 0 ? GO_LEFT : GO_RIGHT; break;
                case LEFT: output = dY < 0 ? GO_RIGHT : GO_LEFT; break;
            }
        }
        System.out.println(output);
    }

    public static boolean isInMiddle(Point snakePart) {
        if ((snakePart.x == 7 || snakePart.x == 8) &&
                (snakePart.y == 7 || snakePart.y == 8)) {
            return true;
        }
        return false;
    }
}


text:
Tips for golfing in ><> (Fish)
Since I've been seeing more ><> submissions floating around lately, I thought it might be a good idea to have a tips page.
Please stick to one tip per post, unless they are closely related.
Official Python interpreter
Official Interpreter on TIO
Online interpreter (some bugs present, but good for most cases)
Another Online Interpreter

I just realized while looking at the esolang page: the creator of ><> has a name that might sound like "harpoon".

How can I print a new-line in fish?

@CaptainMan You can output code points with o, and since newline \n is ASCII 10 you can do ao.

@Sp thanks, I was trying CR instead of LF and was pushing d instead of a.

Checking against 0
Using ?! instead of 0=? typically saves a byte.
However, just a standard ? may sometimes be better if you can afford a bit of restructuring
?!vA
  B

versus
?vB
 A

Checking for EOF
When EOF is reached, ><> pushes a -1 onto the stack, which can be checked in one of two ways:
:0(?
:1+?

For the purposes of checking for EOF, these two are negations, so which one is more beneficial depends on the structure of your program.

Jump to circumvent starting new lines
Starting a new line sometimes means wasting a lot of leading whitespace on the next line. In such a situation, jumping can be useful.
For instance,
[lots of code here]>[loop body]v
                   ^ ......... <

can be made to fit on one line like so:
[lots of code here][loop body][jump]

For a practical example, here's the Hello World program on one line:
"!dlroW ,olleH"l?!;oe0.

Using jumps as a conditional
Some times you'll wind up writing programs in ><> that require you to do different things upon receiving different inputs. Usually, you'd use conditionals (?) and direction changers to parse this. In some cases, that works fine (especially when there are fewer types of input to handle), but sometimes you end up with something looking like this. (Ignore the fact that this code can be reduced using some other tricks, it's just for demonstration)
i:"a"=?v:"b"=?v"c"=?v>
  .00n1< .00n2<.00n3<

While this is fine, it does have some whitespace (which I personally never like seeing) and it has a lot of repetition (=?v and .00n). Instead of that, you could use a jump and different lines as your conditionals. Here's an example:
i:"a")$"b")+1+0$.>
v1
v2
v3
<.00n

This shaves 10 bytes off. Here's what's happening:
i: We duplicate the input once so we can evaluate it twice
"a")$"b")+ This could be its own sort of tip, but what I'm doing here is checking to see if the input is greater than the character "a" and then if it's greater than the character "b" and adding the result. For "a," this will yield 0, for "b," 1, and for "c," 2.
1+0$. This is where the magic happens; we take the result of this previous simplification and add 1 (giving 1 for "a", 2 for "b", 3 for "c"), then push 0 and swap the values. When we reach the jump, this will move to the line corresponding to the value we've assigned to those characters (e.g. line 1 for "a"). N.B. Line 0 is the top of the program.

Using modulus to simplify input
This might be too simple of a tip, so if it is I'll just replace it or delete it.
Let's say you want to take input of two characters, "a" and "b" and return 1, and 2 for each, respectively. You'd probably use conditionals for this, since it makes the most sense, and I'll be using a more condensed form for this specific example.
i:"a")+1+n

This checks to see if the input is greater than "a" and adds 1. Since "a" will return 0 and "b" 1, this will give 1 and 2. This does the job pretty well, but in the case of our inputs, we could go even further.
i:3%n

In mod 3, 97, which is "a"s numerical equivalent, becomes 1, and 98, which is "b"s, becomes 2. For two different numbers, there is guaranteed a mod which gives unique results for both. For more than two, there is a mod that gives unique results, but I don't have the mathematical prowess to find the smallest one in a simple way (e.g. if you have the set {100,101,102,103}, mod 104 would give unique results for each value in it but not in a very helpful fashion). However, in most cases, with input being restricted to a couple alphabetical characters, you can often find a mod that works.
To find the smallest modulus that yields unique results for two numbers, a, and, b, you do as follows. Take the absolute value of the difference of a and b (|a - b|) and find the smallest number, n, which does not divide it. e.g. for 97 and 98, |98 - 97| = 1, and so 2 would be the smallest mod (but for our test program, this gives 1 for 97 and 0 for 98, so mod 3 is better).

Writing code that can run two ways
Trampolines (!) are very handy when you want your code to be run forwards and backwards (or up and down). These scenarios are somewhat unlikely, but for palindrome or similar challenges this tip could be useful.
Here's an example: I want to run some code once, then loop through the stack discarding values until I reach 0, and then go down. The pointer enters this loop from the >. You could use a jump to accomplish this, e.g.
?!v80.>ao (let's say I want to print a newline first)
but if the code we want to run once (the code past the >) makes the line longer than 16 characters, we no longer can use the jump in three characters. However, this is an example where it is trivial to run forwards and backwards...
?!v!?<>ao>
Going forwards, we print a newline and then hit ?!v which discards the value if it it isn't 0, then because of the trampoline we skip the next ? and go backwards. The same thing happens and the loop continues until we hit a 0.
This is an oddly specific example, but there are some (perhaps not many) applications.

Use char codes to store big numbers and use g to use them more than once
Typically, you'd encode a large number as a char code, for example if you need 1001 you might write 'ϩ' In utf-8 this character is encoded as 2 bytes. If you need this number again you can use [coordinates]g to get the char code at that position. This saves 1 byte as long as the character is in the 16 by 16 top left square.
For example
'ϩ'o'ϩ'o;

vs
'ϩ'o10go;

Same number of characters but 1 byte shorter

Use the code as infinite length array
You can store values in the source code area with the g and p commands. For example, you could use the 7th row as a array and access it like this:
i3g
This is significantly shorter than if you used the stack:
i[{:}]
The stack has a additional disadvantage is you need to compensate for any other data you want on the stack. The code box is always accessible regardless of the state of your stack. You can also easily create multiple arrays, or even a 2-dimentional array this way.
You don't even need to keep the row free, ><> will automatically add rows or columns when you write to them. You can read and write any number, even those not normally valid in source code, like line breaks and floating point numbers. This is a valid program that prints 0.5:
12,00p00gn;

Even if there is no character "0.5". This does not seem to work the same for strings.

Use i as a shorthand for -1 for programs that take no input, or after the input is exhausted
Pusing -1 is always a bit tricky, requiring 01- (3 bytes). However, the i command pushes -1 if there is no input. This can save 2 bytes.
For example to invert a number normally requites 0$- (3 bytes) but if you don't take input you can do i* (2 bytes)

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
Sierpinskified Code
Write a rectangular block of text that when arranged into a Sierpinski carpet, using same-sized blocks of spaces for the empty portions, creates a program that outputs the iteration number of the carpet.
For example, if your text block is
TXT
BLK

then running the program
TXTTXTTXT
BLKBLKBLK
TXT   TXT
BLK   BLK
TXTTXTTXT
BLKBLKBLK

should output 1 because the shape of the program represents the first iteration of the Sierpinski carpet.
Similarly, running
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXT   TXTTXT   TXTTXT   TXT
BLK   BLKBLK   BLKBLK   BLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXTTXTTXT         TXTTXTTXT
BLKBLKBLK         BLKBLKBLK
TXT   TXT         TXT   TXT
BLK   BLK         BLK   BLK
TXTTXTTXT         TXTTXTTXT
BLKBLKBLK         BLKBLKBLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK
TXT   TXTTXT   TXTTXT   TXT
BLK   BLKBLK   BLKBLK   BLK
TXTTXTTXTTXTTXTTXTTXTTXTTXT
BLKBLKBLKBLKBLKBLKBLKBLKBLK

should output 2 because this is the shape of the second Sierpinski carpet iteration.
Running the text block as is
TXT
BLK

should output 0 because it can be considered the zeroth iteration.
This should work for all further iterations. (At least theoretically, assuming the computer has the memory and all.)
Details

Programs may not read or access information about their source code. Treat this like a strict quine challenge.
Output goes to stdout or similar alternative. Only output the number and an optional trailing newline. There is no input.
The text block may contain any characters that are not considered line terminators. The text block may contain spaces.
The "empty space" in the carpet must consist entirely of space characters.
You may optionally assume all the programs have a trailing newline.

You can use this stack snippet to generate a carpet for a given text block at any iteration:

<textarea id='i'placeholder='code block...'rows='8'cols='32'></textarea>
Iterations <input id='n'type='text' value='1'>

<button type='button'onclick='f()'>Generate</button>

<textarea id='o'placeholder='output...'rows='8'cols='32'style='background-color:#eee'readonly></textarea>

Scoring
The submission whose initial text block is smallest by area (width times height) is the winner. The TXT\nBLK example is 3 by 2 for a score of 6. (Basically the shortest code wins, hence the code-golf tag.)
Tiebreaker goes to the submission that uses the fewest distinct characters in their text block. If still tied, answer posted first wins.

CJam, 9 bytes
I think this can be improved, but for now, lets go with it...
];U):U8mL

How it works:
];             "Wrap everything on stack in an array and discard it";
               "Before this point, the only thing on array can be the log 8 result of";
               "last updated value of U, or nothing, if its the first code";
  U):U         "Increment by 1 and update the value of U (which is pre initialized to 0)";
      8mL      "Take log base 8 of U. This is the property of Sierpinski carpet that";
               "the occurrence of the code is 8 to the power iteration count, indexed 0";

Try it online here

piet - 32*6 = 192

I filled the empty space with the checker pattern. I think it makes the Sierpinski a bit trippier.
Here is the second iteration:

original : 32*7

><>, 11 * 2 = 22
";n"00pbi1v
+$3*:@3-0.>

Here we take a different approach by using ><>'s jump/teleport functionality.
The program only executes blocks in the top row, running the 1st/2nd block, then the 3rd/4th blocks, 9th/10th blocks, 27th/28th blocks, etc. (going up in powers of 3). As the top row has 3^n blocks, only n blocks are executed before the program wraps back to the start, outputs the top of the stack and halts (due to the n instruction placed via p).
The program exploits the rule "There is no input.", as the i command pushes -1 onto the stack if EOF is met. So to test this you'll need to pipe in an empty file.

Previous submission, 7 * 4 = 28
l"v"10p
v>:1=?v
3  ;n{<
<^}+1{,

The first line continuously pushes the length of the stack for every block, and changes the first " quote to a down arrow v using the p put command. By the time the first line is over, the stack looks like
[0, 1, 2, .., 3^n]

(Note that the initial l is used twice.)
The last three lines then count how many times we need to divide by 3 before we hit 1 (since ><> doesn't have a log function). The bottom zero is used to keep track of the count.

Perl, 26
$_+=.91/++$n;
die int."\n";

This uses the harmonic series to approximate the base 3 logarithm. I think it works, but I've only tried it for small numbers. Thanks to squeamish ossifrage for the idea of using die.
Old version (34):

$n--or$n=3**$s++;
print$s-1if!$o++;

That's very neat!

Perl, 30 (15×2)
First of all, I'm going to claim that 10 iterations is a reasonable limit, not 232. After 10 iterations, a program consisting of N bytes will have expanded to (N × 320) bytes (plus line breaks), which is over 3 gigabytes even for N=1. A 32-bit architecture would be completely unable to handle 11 iterations. (And obviously there aren't enough particles in the universe for 232 iterations).
So here's my solution:
$n++; $_=log$n;
print int;exit;

This works by incrementing the variable $n in the first line and calculating its logarithm at each step. The second line prints the integer part of this logarithm and quits.
A simple logarithm to base e (2.718..) is close enough to give correct results for the first 10 iterations.

According to the OP, it should theoretically work for all iterations.

@NathanMerrill Well, OK. But to comply with the original spec it would also have had to work in alternate universes. The question has been edited since then.

I changed the question because of the good points made here. I agree that using natural log is rather a gray area, but honestly I'm not too concerned since this isn't winning.

Most of these submissions keep control only in the top row of 3^n x 1 tiles. If you just generate that segment of the carpet, you can scale quite a bit further. Almost certainly to where rounding errors will break you.

@captncraig Yes, but if I made a hyperdimensional Sierpinski cube then the program would scale a lot less. So what?

I think your solution passes fine. But hanging your argument for validity on the impracticality of verifying it mechanically seems a bit weak. Even if we can't physically generate and execute it, most of these solution can be theoretically proven (even if just by intuition) to scale.

As I mentioned already, the original question asked for code that could scale to a "reasonable" number of iterations (up to 2^32). If you do the maths, you'll find that even a single byte would expand to in excess of 10^4098440370 bytes after that many iterations. I proposed an answer that I thought was a bit more reasonable, but since then the word "reasonable" has disappeared from the question :-/. Look, I'm done here. Just downvote this answer if you don't like it.

even 32-bit architectures can deal with +4gig files, the file functions just need to accept 64 bit ints

Golfscript, 9 * 2 = 18
0+
,3base,(}

(Note that the first line has trailing spaces to make it rectangular)
I couldn't find a log function for Golfscript, so base had to do.
Golfscript starts off with an empty string, so 0+ just increases the length of the string by 1 (by coersion). By the time the first line is over, the stack will have a string of length 3^n, which we take the log base 3 of before we super comment. n is then automatically printed.

You could save 2 chars by using an integer instead of a string and hence saving the , on the second line. First line: 0or); second line 3base,(}. The other obvious target is the ( on the second line. This is trickier, but can also be removed by replacing the first line with 1+~abs( for a 7*2 rectangle.

C, 12x8 = 96
Inspired by @ciamej, I've reduced it.  It uses that divide by 3 trick, plus the realization that the carpet effectively converts an if into a while loop.
The code was tested on gcc/Ubuntu for iterations up to 3.
#ifndef A //
#define A //
x;main(a){//
a++;/*    */
if(a/=3)x++;
printf(   //
"%d",x);} //
#endif    //

Previous Solution: C, 11x12
Not a size winner, but hey, it's C.
It finds log2 of the blockcount by bitshifting, then uses some magic numbers and int truncation to estimate log3. The math should work up to 26 iterations (a 42 bit number).
#ifndef A//
#define A//
int n=0;//_
int main//_
(v,c){//___
n+=1;/*..*/
while(n//__
>>=1)v++;//
n=.3+.62*v;
printf(//__
"%d",n);}//
#endif//__

Hi, I've posted a shortened version of your solution.

Nice trick with that if! ;)

CJam, 9 bytes
The idea of using ] is from Optimizer, but it uses a very different method to count.
X~]:X,8mL

Try it online
How it works:
X~          "push X and dump its contents.  On the zeroth iteration, X is a single number, but later is it an array.";
  ]         "wrap everything into an array.  The stack would contain the contents of X plus the result of the previous instance of the code";
   :X       "store this array back into X.  X is now 1 element longer";
     ,      "take the length of X";
      8mL   "do a base-8 logarithm of it";

Two other 9 byte solutions
]X+:X,8mL

],X+:X8mL

This actually ties Optimizer, even with the tiebreaker. :P Tiebreakerbreaker: earlier post wins.

I think it's a good solution regardless.  I haven't been able to beat 9 chars.

I think the general approach is same only (and which is the only approach which makes sense) - Have a variable, increment it by 1 somehow.

Python 2, 15 * 3 = 45
m=n=0;E=exit  ;
m+=1;n+=m>3**n;
print n;E()   ;

Another implementation of the count-first-row-then-log-three-and-exit idea. Can probably still be golfed a fair bit more.

><> (Fish), 12 * 3 = 36
A more straightforward ><> solution:
'v'00p0l1+
>  :2-?v$1+v
^$+1$,3< ;n<

We first run the top row of the top blocks. 'v'00p puts v at the very first position of the whole program directing the program pointer downwards when it gets back to the start after reaching the end of the line. Before that every block pushes 0 and the length of the stack + 1 onto it. (stack will be 0 2 0 4 0 6 ...)
On the first half of the second and third we count how many times we can divide the top stack element before we get 2 (we store this in the second to top element).
At the end we output the second to top element of the stack.

bc, 2*16+1 = 33
The extra +1 in the score is because the -l bc option is required:
a+=1;
l(a)/l(3);halt;

Golfscript, 7 * 2 = 14
1+~abs(
3base,}

This is inspired by Sp3000's answer, and in particular by the desire to optimise the long second line. 3base, is as short as a base-3 logarithm will get in GS, and the super-comment } is clearly optimal.
What's required for the first line is to map the empty string '' from the initial stdin to 0, and then to map each non-negative integer to its successor. In this way we end the first line with 3^n - 1 on the stack, and 3base, doesn't require any decrement.

C, 13x8
#ifndef A//__
#define A//__
x;a;main(){//
a++;;;;;;;;;;
while(a/=3)//
x++;printf(//
"%d",x);}//__
#endif//_____

Perl, 76
I know there's probably not much point in posting this since it's already been thoroughly beaten, but here's my current solution anyways.
$_++;
if(not$_&$_-1){print log()/log 8;$_--}

@Alex That doesn't seem to work, even at the 1st iteration.

Yes, it works as it stands.  Have you tested your method?

Mine works on ideone: http://ideone.com/othumP.

Gotcha. I missed an important detail that kept it from working before. You're right, my suggestion is incorrect.

PHP, 22×2 = 44 27×2 = 54
<?php $i++          ?>
<?php die(log($i,3))?>

Just another take on count-log3-out. Not very small, but my first golf ;)

On PCG.SE like everywhere else, please check the documentation before posting :) .

@Blackhole Good catch! Thanks

Lua, 3 * 17 = 51
Same strategy as most people:
x=(x or 0)+1;
y=math.log(x,3)
print(y)os.exit()

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/