# Question
Title: Asymmetrical KOTH: Catch the Cat (Catcher Thread)
***UPDATE***: **The gist-files are updated (including new submissions) as the Controller.java did not catch Exceptions (only errors). It does now catch errors and exceptions and also prints them.**

*This challenge consists of two threads, this is the catcher thread, the cat thread can be found here.*

The controller can be downloaded here.

This is an asymmetrical KOTH: Each submission is either a *cat* or a *catcher*. There are games between each pair of each a cat and a catcher. The cats and the catchers have separate rankings.

## Catcher

There is a cat on a hexagonal grid. Your task is to catch it as fast as possible. Every turn, you can place a water bucket on one grid cell in order to prevent the cat from being able to go there. But the cat is not (perhaps) that dumb, and whenever you place a bucket, the cat will move to another grid cell. Since the grid is hexagonal, the cat can go in 6 different directions. Your goal is to surround the cat with water buckets, the faster the better.

## Cat

You know the catcher wants to catch you by placing water buckets around you. Of course you try to evade, but as you are a lazy cat (as cats are) you exactly take one step at the time. This means you cannot stay on the same place you, but you have to move to one of the six surrounding spots. Whenever you see that the catcher placed a new water bucket you go to another cell. Of course you try to evade as long as possible.

## Grid

The grid is hexagonal, but as we do not have hexagonal data structures, we take a `11 x 11` square 2d array and mimic the hexagonal 'behavior' that the cat can only move in 6 directions:

The topology is toroidal, that means if you step on a cell 'outside' of the array, you will just be transferred to the corresponding cell on the other side of the array.

## Game

The cat starts out at given position in the grid. The catcher can do the first move, then the cat and its catcher alternate moves until the cat is caught. The number of steps is the score for that game. The cat tries to get a score as great as possible, the catcher tries to get a score as low as possible. The average sum over all the games you participated in will be the score of your submission. There are two separate rankings, one for the cat, one for the catchers.

# Controller

The given controller is written in Java. As a catcher or a cat you each have to each complete implement a Java class (there are already some primitive examples) and place it in the `players` package (and update the list of cats/catchers in the Controller class), but you also may write additional functions within that class. The controller comes with each two working examples of simple cats/catcher classes.

The field is a `11 x 11` 2D- `int` array that stores the values of the current states of the cells. If a cell is empty, it has value `0`, if there is a cat it has value `-1` and if there is a bucket there is a `1`.

There are a few given functions you can use: `isValidMove()`/`isValidPosition()` are for checking whether your move (cat) / position (catcher) is valid.

Each time it is your turn, your function `takeTurn()` is called. The argument contains the a copy of the current grid an has methods like `read(i,j)` for reading the cell at `(i,j)`, as well as `isValidMove()/ isValidPosition()` that checks the validity of your answer. This also manages the wrapping over of the toroidal topology, that means even if the grid is only 11 x 11, you still can access the cell (-5,13).

The method should return a `int` array of two elements, which represent possible moves. For the cats these are `{-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}` which represent the relative position of where the cat wants to go, and the catchers return the absolute coordinates of where they want to place a bucket `{i,j}`.

If your method produces an invalid move, your submission will be disqualified. The move is considered as invalid, if at your destination is already a bucket or the move is not allowed / destination already occupied (as a cat), or if there is already a bucket/cat (as a catcher). You can check that before hand with the given functions.

Your submission should work reasonably fast. If your method takes longer than 200ms for each step it will also be disqualified. (Preferably much less...)

The programs are allowed to store information between the steps.

## Submissions

* You can make as many submissions as you want.
* Please do not significantly alter submissions you've already submitted.
* Please each submissions in a new answer.
* Each submission should preferably have it's unique name.
* The submission should consist of the code of your class as well as a description that tells us how your submission works.
* You can write the line `<!-- language: lang-java -->` before your source code in order to get automatic syntax highlighting.

## Scoring

All *cats* will compete against all *catchers* the same number of times. I'll try to update the current scores frequently, the winners will be determined when the activity has decreased.

This challenge is inspired by this old flash game

Thanks @PhiNotPi for testing and giving some constructive feedback.

## Current Scores (100 Games per pairing)

| Name (Catcher) | Score | Rank | Author |
| --- | --- | --- | --- |
| RandCatcher | 191674 | 8 | flawr |
| StupidFill | 214246 | 9 | flawr |
| Achilles | 76820 | 6 | The E |
| Agamemnon | 74844 | 5 | The E |
| CloseCatcher | 54920 | 4 | randomra |
| ForwordCatcher | 94246 | 7 | MegaTom |
| Dijkstra | 46500 | 2 | TheNumberOne |
| HexCatcher | 48832 | 3 | randomra |
| ChoiceCatcher | 43828 | 1 | randomra |

| Name (Cat) | Score | Rank | Author |
| --- | --- | --- | --- |
| RandCat | 77928 | 7 | flawr |
| StupidRightCat | 81794 | 6 | flawr |
| SpiralCat | 93868 | 5 | CoolGuy |
| StraightCat | 82452 | 9 | CoolGuy |
| FreeCat | 106304 | 3 | randomra |
| RabidCat | 77770 | 8 | cain |
| Dijkstra's Cat | 114670 | 1 | TheNumberOne |
| MaxCat | 97768 | 4 | Manu |
| ChoiceCat | 113356 | 2 | randomra |

# Answer
# Achilles

Achilles isn't too bright but he is ruthlessly efficient. First he stops the cat from using the wrap around of the board, then he divides the board into two. Then he keeps on dividing the part of the board the cat is in into half until the cat is trapped.

Demonstration RandCat vs Achilles

```
package players;
/**
 * @author The E
 */
import main.*;

public class Achilles implements Catcher
{
    public Achilles() {

    }
    @Override
    public String getName() {

        return "Achilles";
    }

    @Override
    public int[] takeTurn(Field f) {
        try{
        if(f.read(0, f.SIZE-1)!=Field.BUCKET)
        {
            //Make the first line

            for(int j = 0; j<f.SIZE; j++)
            {
                if(f.read(0, j) == Field.EMPTY)
                {
                    return new int[]{0,j};
                }
            }
            return WasteGo(f);

        }
        else if (f.read(f.SIZE-1, 0)!=Field.BUCKET)
        {
            //Make the second line
            for(int i = 0; i<f.SIZE; i++)
            {
                if(f.read(i, 0) == Field.EMPTY)
                {
                    return new int[]{i,0};
                }
            }
            //The cat got in the way
            for(int j = 0; j<f.SIZE; j++)
            {
                if(f.read(1, j) == Field.EMPTY)
                {
                    return new int[]{1,j};
                }
            }
            return WasteGo(f);
        }
        else
        {
            return TrapCat(1,1,f.SIZE-1, f.SIZE-1, false, f);

        }
        }
        catch (Exception e)
        {
            return WasteGo(f);
        }
    }
    private int[] TrapCat(int i1, int j1, int i2, int j2, Boolean direction, Field f) {
        for(int a = 0; a<f.SIZE+10; a++)
        {
            if(direction)
            {

                int height = j2-j1+1;
                int row = j1 + height/2;
                for(int i = i1; i<=i2; i++)
                {
                    if(f.read(i, row)==Field.EMPTY)
                    {
                        return new int[]{i,row};
                    }
                }

                    //Done that Row
                    //Find cat
                    if(f.findCat()[1]>row)
                    {
                        //he's above the line
                        j1 = row+1;
                        direction = !direction;
                        //return TrapCat(i1, row+1, i2, j2, !direction, f);
                    }
                    else
                    {
                        //he's below the line
                        j2 = row - 1;
                        direction = !direction;
                        //return TrapCat(i1, j1, i2, row-1, !direction, f);
                    }

            }
            else
            {
                int bredth = i2-i1+1;
                int column = i1 + bredth/2;
                //Continue making the line
                for(int j = j1; j<=j2; j++)
                {
                    if(f.read(column,j)==Field.EMPTY)
                    {
                        return new int[]{column,j};
                    }
                }

                    //Done that Column
                    //Find cat
                    if(f.findCat()[0]>column)
                    {
                        //he's right of the line
                        i1 = column + 1;
                        direction = !direction;
                        //return TrapCat(column+1, j1, i2, j2, !direction, f);
                    }
                    else
                    {
                        //he's left of the line
                        i2 = column -1;
                        direction = !direction;
                        //return TrapCat(i1, j1, column-1, j2, !direction, f);
                    }

            }
        }
        return WasteGo(f);
    }
    private int[] WasteGo(Field f) {
        for (int i = 0; i<f.SIZE;i++)
        {
            for(int j=0;j<f.SIZE;j++)
            {
                if(f.read(i,j)==Field.EMPTY)
                {
                    return new int[]{i,j};
                }
            }
        }
        //Something drastic happened
        return new int[]{0,0};
    }

}

```
> 6 votes

# Answer
# Agamemnon

Agamemnon splits the cats area in half with a vertical line until the cat only has a strip of width 2 to move in, at which point he traps the cat.

Agamemnon vs RandCat:

```
package players;
/**
 * @author The E
 */
import main.*;

    public class Agamemnon implements Catcher {
        boolean up = true;
        @Override
        public String getName() {
            return "Agamemnon";
        }

        @Override
        public int[] takeTurn(Field f) {
            //First Make Line in column 1
            for(int j = 0; j<f.SIZE; j++)
            {
                if(f.read(0, j)==Field.EMPTY)
                {
                    return new int[]{0,j};
                }
            }
            //Then in column SIZE/2
            for(int j = 0; j<f.SIZE; j++)
            {
                if(f.read(f.SIZE/2, j)==Field.EMPTY)
                {
                    return new int[]{f.SIZE/2,j};
                }
            }
            //Then work out where the cat is
            int left, right;
            int cati = f.findCat()[0];
            if(cati<f.SIZE/2)
            {
                left = 1;
                right = f.SIZE/2-1;
            }
            else
            {
                left = f.SIZE/2+1;
                right = f.SIZE-1;
            }
            while(right-left>1)
            {
                //If the cat is not in a two width column
                //Split the area the cat is in in half
                int middleColumn = (left+right)/2;
                for(int j = 0; j<f.SIZE; j++)
                {
                    if(f.read(middleColumn, j)==Field.EMPTY)
                    {
                        return new int[]{middleColumn,j};
                    }
                }
                //If we got here we had finished that column
                //So update left and/or right
                if(cati<middleColumn)
                {
                    //he's left of the middle Column
                    right = middleColumn - 1;
                }
                else
                {
                    //he's right of the middle Column
                    left = middleColumn+1;
                }
                //Repeat
            }
            //Otherwise try to trap the cat
            //Make a line up and down on the opposite side of the cat
            int catj = f.findCat()[1];
            if(left!=right){
                if(cati==left)
                {
                    if(f.read(right, catj)==Field.EMPTY)
                    {
                        return new int[]{right, catj};
                    }
                    if(f.read(right, catj-1)==Field.EMPTY)
                    {
                        return new int[]{right, catj-1};
                    }
                    if(f.read(right, catj+1)==Field.EMPTY)
                    {
                        return new int[]{right, catj+1};
                    }

                }
                else
                {
                    if(f.read(left, catj)==Field.EMPTY)
                    {
                        return new int[]{left, catj};
                    }
                    if(f.read(left, catj-1)==Field.EMPTY)
                    {
                        return new int[]{left, catj-1};
                    }
                    if(f.read(left, catj+1)==Field.EMPTY)
                    {
                        return new int[]{left, catj+1};
                    }

                }
            }
            //Alternate between above and below
            if(up)
            {
                up = !up;
                if(f.read(cati, catj+1)==Field.EMPTY)
                {

                    return new int[]{cati, catj+1};
                }
            }
            up = !up;
            if(f.read(cati, catj-1)==Field.EMPTY)
            {

                return new int[]{cati, catj-1};
            }
            return WasteGo(f);
        }

        private int[] WasteGo(Field f) {
            for (int i = 0; i<f.SIZE;i++)
            {
                for(int j=0;j<f.SIZE;j++)
                {
                    if(f.read(i,j)==Field.EMPTY)
                    {
                        return new int[]{i,j};
                    }
                }
            }
            //Something drastic happened
            return new int[]{0,0};
        }
    }

```

This catcher does consistently better than Achilles and I think he's different enough to warrant a new answer.
> 5 votes

# Answer
# HexCatcher

If the catcher can get the cat in the inside of a big hexagon with 3 units sides where the corners of the hexagon are already occupied by buckets, the catcher can keep the cat in this area and catch him. The hexagon looks like this:

This is what HexCatcher tries to achieve. It mentally tiles the field with these big hexagons in a way that each corner cell is part of 3 big hexagons.

If there is a chance to keep the cat in the current area by connecting two corners next to the cat, the bot will do that. (E.g. in the image if the cat is at 7,5 we choose 7,6 even if only the 6,6 and 8,5 cells are occupied yet.)

If the previous is not an option we chooses to play a corner which is a part of the area where the cat is. If all such corners are already chosen (like in the image) we choose a cell next to the cat.

Multiple small improvements are possible such as handling wrap-around better (the tiling breaks there) or doing the last couple moves optimally. I might do some of these. If it is not allowed, I will just append it (out of competition) for the ones interested.

DijkstrasCat vs HexCatcher:

```
package players;
/**
 * @author randomra
 */
import main.Field;

public class HexCatcher implements Catcher {
    public String getName() {
        return "HexCatcher";
    }

    final int[][] o = { { -1, 1 }, { 0, 1 }, { -1, 0 }, { 1, 0 }, { 0, -1 },
            { 1, -1 } };// all valid moves
    final int[][] t = { { -2, 2 }, { 0, 2 }, { -2, 0 }, { 2, 0 }, { 0, -2 },
            { 2, -2 } };// all valid double moves in one direction
    final int[][] h = { { -1, 2 }, { -2, 1 }, { -1, -1 }, { 1, -2 }, { 2, -1 },
            { 1, 1 } };// all valid moves in not one direction
    int opp = 0;

    public int[] takeTurn(Field f) {
        int[] p = f.findCat();
        // center of the hexagon the cat is in
        int[] c = { ((int) p[0] / 3) * 3 + 1, ((int) p[1] / 3) * 3 + 1 };
        // change priority of catching direction at every turn
        opp = 1 - opp;

        // check missing corner piece next to cat
        for (int i = 0; i < 6; i++) {
            int ind = (i + opp * 3) % 6;
            boolean close = false;
            for (int k = 0; k < 6; k++) {
                if (c[0] + h[ind][0] == p[0] + o[k][0]
                        && c[1] + h[ind][1] == p[1] + o[k][1]) {
                    close = true;
                }
            }
            if (f.read(c[0] + h[ind][0], c[1] + h[ind][1]) == 0 && close) {
                return new int[] { c[0] + h[ind][0], c[1] + h[ind][1] };
            }
        }
        // cut off escape route if needed
        for (int i = 0; i < 6; i++) {
            int ind = (i + opp * 3) % 6;
            if (f.read(c[0] + o[ind][0], c[1] + o[ind][1]) == -1
                    && f.read(c[0] + t[ind][0], c[1] + t[ind][1]) == 0) {
                return new int[] { c[0] + t[ind][0], c[1] + t[ind][1] };
            }
        }
        // check any missing corner piece in the area
        for (int i = 0; i < 6; i++) {
            int ind = (i + opp * 3) % 6;
            if (f.read(c[0] + h[ind][0], c[1] + h[ind][1]) == 0) {
                return new int[] { c[0] + h[ind][0], c[1] + h[ind][1] };
            }
        }
        // choose an empty cell next to the cat
        for (int i = 0; i < 6; i++) {
            int ind = (i + opp * 3) % 6;
            if (f.read(p[0] + o[ind][0], p[1] + o[ind][1]) == 0) {
                return new int[] { p[0] + o[ind][0], p[1] + o[ind][1] };
            }
        }
        return null;
    }
}

```
> 5 votes

# Answer
# Dijkstra

He doesn't like cats very much (:`v{ >`

FreeCat vs Dijkstra ~~(needs updated)~~:

```
package players;

import main.Controller;
import main.Field;

import java.util.*;

/**
 * @author TheNumberOne
 *
 * Catches the cat.
 */

public class Dijkstra implements Catcher{

    private static final int[][][] CACHE;

    static {
        CACHE = new int[Controller.FIELD_SIZE][Controller.FIELD_SIZE][2];
        for (int x = 0; x < Controller.FIELD_SIZE; x++){
            for (int y = 0; y < Controller.FIELD_SIZE; y++){
                CACHE[x][y] = new int[]{x,y};
            }
        }
    }

    private static final int[][] possibleMoves = {{-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}};
    @Override
    public String getName() {
        return "Dijkstra";
    }

    @Override
    public int[] takeTurn(Field f) {
        long startTime = System.nanoTime();

        final int[] theCat = f.findCat();
        int[] bestMove = {-1,1};
        int[] bestOpenness = {Integer.MAX_VALUE, 0};
        List<int[]> possiblePositions = new ArrayList<>();
        for (int x = 0; x < 11; x++){
            for (int y = 0; y < 11; y++){
                int[] pos = {x,y};
                if (f.isValidPosition(pos)){
                    possiblePositions.add(pos);
                }
            }
        }
        Collections.sort(possiblePositions, new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                return distance(o1, theCat) - distance(o2, theCat);
            }
        });
        for (int i = 0; i < possiblePositions.size() && System.nanoTime() - startTime < Controller.MAX_TURN_TIME/2; i++){
            int[] pos = possiblePositions.get(i);
            int before = f.field[pos[0]][pos[1]];
            f.placeBucket(pos);
            int[] openness = openness(theCat, f, true);
            if (openness[0] < bestOpenness[0] ||
                    (openness[0] == bestOpenness[0] &&
                            (openness[1] > bestOpenness[1])
                    )
                    ){
                bestOpenness = openness;
                bestMove = pos;
            }
            f.field[pos[0]][pos[1]] = before;
        }
        return bestMove;
    }

    /**
     *
     * @param pos The pos to calculate the openness of.
     * @param f The field to use.
     * @return Two integers. The first integer represents the number of reachable hexagons.
     * The second integer represents how strung out the squares are relative to the pos.
     */
    public static int[] openness(int[] pos, Field f, boolean catZeroWeight){
        Map<int[], Integer> lengths = new HashMap<>();
        PriorityQueue<int[]> open = new PriorityQueue<>(10,new Comparator<int[]>() {
            Map<int[], Integer> lengths;
            @Override
            public int compare(int[] o1, int[] o2) {
                return lengths.get(o1) - lengths.get(o2);
            }
            public Comparator<int[]> init(Map<int[], Integer> lengths){
                this.lengths = lengths;
                return this;
            }
        }.init(lengths));
        Set<int[]> closed = new HashSet<>();
        lengths.put(pos, catZeroWeight ? 0 : 6 - pointsAround(pos, f).size());
        open.add(pos);
        while (open.size() > 0){
            int[] top = open.remove();
            if (closed.contains(top)){
                continue;
            }
            closed.add(top);
            int l = lengths.get(top);
            List<int[]> pointsAround = pointsAround(top, f);

            for (ListIterator<int[]> iter = pointsAround.listIterator(); iter.hasNext();){
                int[] point = iter.next();
                if (closed.contains(point)){
                    iter.remove();
                }
            }

            for (int[] p : pointsAround){
                int length = l + 7 - pointsAround(p, f).size();
                if (lengths.containsKey(p)){
                    length = Math.min(length, lengths.get(p));
                }
                lengths.put(p, length);
                open.add(p);
            }
        }
        int sum = 0;
        for (int integer : lengths.values()){
            sum += integer;
        }
        return new int[]{lengths.size(),sum};
    }

    public static int distance(int[] p1, int[] p2){
        p2 = Arrays.copyOf(p2, 2);
        while (p2[0] < p1[0]){
            p2[0] += 11;
        }
        while (p2[1] < p2[0]){
            p2[1] += 11;
        }
        int lowestDistance = 0;
        for (int dx = 0; dx == 0; dx -= 11){
            for (int dy = 0; dy == 0; dy -= 11){
                lowestDistance = Math.min(lowestDistance,Math.min(Math.abs(p1[0]-p2[0]-dx),Math.min(Math.abs(p1[1]-p2[1]-dy),Math.abs(p1[0]+p1[1]-p2[0]-dx-p2[1]-dy))));
            }
        }
        return Math.min(Math.abs(p1[0]-p2[0]),Math.min(Math.abs(p1[1]-p2[1]),Math.abs(p1[0]+p1[1]-p2[0]-p2[1])));
    }

    public static int[] normalize(int[] p){
        return CACHE[(p[0]%11+11)%11][(p[1]%11+11)%11];
    }

    public static List<int[]> pointsAround(int[] p, Field f){
        int[] cat = f.findCat();
        List<int[]> locations = new ArrayList<>();
        for (int[] move : possibleMoves){
            int[] location = normalize(new int[]{p[0]+move[0], p[1] + move[1]});
            if (f.isValidPosition(location) || Arrays.equals(cat, location)){
                locations.add(location);
            }
        }
        return locations;
    }
}

```

**How he tries to catch the cat:**

He analyzes all squares of the board and tries to find the square that minimizes the openness of the board, and maximizes how much the board is strung out; in relation to the cat. The openness and stringiness of a board are computed using a modification of his famous algorithm.

**Openness:**

The openness of a board relative to a position is the number of reachable positions from that position.

**Stringiness:**

The stringiness of a board relative to a position is the sum of the distances between the reachable positions and the position.

**With last update:**

Now, he is much better at catching ~~FreeCat and his own cat~~ all cats. ~~Unfortunately, he is also much worse at catching the crazy uncooperative cats. He could be improved by detecting if the cat is one of the crazy ones and then acting as CloseCatcher.~~

Bug fixed.
> 3 votes

# Answer
# CloseCatcher

Chooses one of the positions where the cat could step in the next step. It chooses the one which would give the most possible paths after 3 steps for the cat if it would move there and the field wouldn't change.

Code is almost identical to my Cat entry, FreeCat, which chooses the direction in a very similar way.

SpiralCat vs CloseCatcher:

```
package players;
/**
 * @author randomra
 */

import main.Field;
import java.util.Arrays;

public class CloseCatcher implements Catcher {
    public String getName() {
        return "CloseCatcher";
    }

    final int[][] turns = { { -1, 1 }, { 0, 1 }, { -1, 0 }, { 1, 0 },
            { 0, -1 }, { 1, -1 } };// all valid moves
    final int turnCheck = 3;

    public int[] takeTurn(Field f) {

        int[] pos = f.findCat();
        int[] bestMove = { 0, 1 };
        int bestMoveCount = -1;
        for (int[] t : turns) {
            int[] currPos = { pos[0] + t[0], pos[1] + t[1] };
            int moveCount = free_count(currPos, turnCheck, f);
            if (moveCount > bestMoveCount) {
                bestMoveCount = moveCount;
                bestMove = t;
            }
        }
        int[] bestPos = { pos[0] + bestMove[0], pos[1] + bestMove[1] };
        return bestPos;
    }

    private int free_count(int[] pos, int turnsLeft, Field f) {
        if (f.isValidPosition(pos) || Arrays.equals(pos, f.findCat())) {
            if (turnsLeft == 0) {
                return 1;
            }
            int routeCount = 0;
            for (int[] t : turns) {
                int[] currPos = { pos[0] + t[0], pos[1] + t[1] };
                int moveCount = free_count(currPos, turnsLeft - 1, f);
                routeCount += moveCount;
            }
            return routeCount;
        }
        return 0;
    }

}

```
> 2 votes

# Answer
# ForwordCatcher

Places a bucket in front of the cat, or if that is taken, places behind.

RabidCat vs ForwordCatcher:

```
package players;

import main.Field;
import java.util.Arrays;

public class ForwordCatcher implements Catcher {
    public String getName() {
        return "ForwordCatcher";
    }

    private int[] lastPos = {0,0};

    public int[] takeTurn(Field f) {
        int[] temp = lastPos;
        int[] pos = f.findCat();
        lastPos = pos;
        int[] Move = {pos[0]*2-temp[0], pos[1]*2-temp[1]};
        if(f.isValidPosition(Move)){return Move;}
        if(f.isValidPosition(temp)){return temp;}
        Move[0] = pos[0];Move[1] = pos[1]+1;
        return Move;
    }
}

```
> 2 votes

# Answer
# ChoiceCatcher

Uses the same scoring mechanism as my ChoiceCat entry. There is a little modification which helps to choose relevant cells at the first few steps as ChoiceCat doesn't care about the first few buckets as it doesn't see them as threat.

ChoiceCatcher seems to score considerably better than the current catchers.

ChoiceCat vs ChoiceCatcher:

```
package players;
/**
 * @author randomra
 */
import java.util.Arrays;

import main.Field;

public class ChoiceCatcher implements Catcher {

    private class Values {
        public final int size;
        private double[][] f;

        Values(int size) {
            this.size = size;
            f = new double[size][size];
        }

        public double read(int[] p) {
            int i = p[0];
            int j = p[1];
            i = (i % size + size) % size;
            j = (j % size + size) % size;
            return f[i][j];
        }

        private double write(int[] p, double v) {
            int i = p[0];
            int j = p[1];
            i = (i % size + size) % size;
            j = (j % size + size) % size;
            return f[i][j] = v;
        }
    }

    final int[][] turns = { { -1, 1 }, { 0, 1 }, { 1, 0 }, { 1, -1 },
            { 0, -1 }, { -1, 0 } };// all valid moves CW order
    final int stepCheck = 5;

    public String getName() {
        return "ChoiceCatcher";
    }

    @Override
    public int[] takeTurn(Field f) {
        int[] bestPos = null;
        double bestPosValue = Double.MAX_VALUE;
        for (int i = 0; i < f.SIZE; i++) {
            for (int j = 0; j < f.SIZE; j++) {
                if (f.read(i, j) == Field.EMPTY) {
                    Field myField = new Field(f);
                    myField.placeBucket(new int[] { i, j });
                    double posValue = catTurnValue(myField);
                    if (posValue < bestPosValue) {
                        bestPosValue = posValue;
                        bestPos = new int[] { i, j };
                    }
                }
            }
        }
        return bestPos;
    }

    private double catTurnValue(Field f) {

        int[] pos = f.findCat();
        double[] values = new double[6];
        int count=0;
        for (int[] t : turns) {
            int[] currPos = { pos[0] + t[0], pos[1] + t[1] };
            double moveValue = movePosValue(currPos, f);
            values[count++]=moveValue;
        }
        Arrays.sort(values);
        return values[5];
    }

    private double movePosValue(int[] pos, Field f) {

        Values v = new Values(f.SIZE);

        for (int ring = stepCheck; ring >= 0; ring--) {
            for (int phase = 0; phase < 2; phase++) {
                for (int sidepos = 0; sidepos < Math.max(1, ring); sidepos++) {
                    for (int side = 0; side < 6; side++) {
                        int[] evalPos = new int[2];
                        for (int coord = 0; coord < 2; coord++) {
                            evalPos[coord] = pos[coord] + turns[side][coord]
                                    * sidepos + turns[(side + 1) % 6][coord]
                                    * (ring - sidepos);
                        }
                        if (phase == 0) {
                            if (ring == stepCheck) {
                                // on outmost ring, init value
                                v.write(evalPos, -1);
                            } else {
                                v.write(evalPos, posValue(evalPos, v, f));
                            }
                        } else {
                            // finalize position value for next turn
                            v.write(evalPos, -v.read(evalPos));
                        }
                    }
                }
            }
        }

        return -v.read(pos);
    }

    private double posValue(int[] pos, Values v, Field f) {
        if (f.read(pos[0], pos[1]) == Field.BUCKET) {
            return 0;
        }
        int count = 0;
        int maxRoutes = 2;
        double[] product = new double[6];
        for (int[] t : turns) {
            int[] tPos = new int[] { pos[0] + t[0], pos[1] + t[1] };
            if (v.read(tPos) > 0) {
                product[count] = 1 - 1 / (v.read(tPos) + 1);
                count++;
            }
        }
        Arrays.sort(product);
        double fp = 1;
        for (int i = 0; i < Math.min(count, maxRoutes); i++) {
            fp *= product[5 - i];
        }
        double fp2 = 1;
        for (int i = 0; i < Math.min(count, 6); i++) {
            fp2 *= product[5 - i];
        }
        double retValue = Math.min(count, maxRoutes) + fp;
        double retValue2 = Math.min(count, 6) + fp2;
        return -retValue - retValue2 / 1000000;
    }

}

```
> 2 votes

# Answer
# RandCatcher

This was made just for testing the controller and just randomly places the buckets (very inefficiently).

```
package players;

import main.Field;

public class RandCatcher implements Catcher {
    public String getName(){
        return "RandCatcher";
    }
    public int[] takeTurn(Field f){
        int[] pos = {0,0};
        do {
            pos[0] = (int) (Math.random()*f.SIZE);
            pos[1] = (int) (Math.random()*f.SIZE);
        } while( f.isValidPosition(pos)==false );
        return pos;
    }

}

```
> 1 votes

# Answer
# StupidFillCatcher

This was made just for testing the controller. It just fills up column by column until the cat is caught.

```
package players;

import main.Field;

public class StupidFillCatcher implements Catcher {
    public String getName(){
        return "StupidFillCatcher";
    }
    public int[] takeTurn(Field f){
        for(int i=0; i < f.SIZE; i++){
            for(int j=0; j < f.SIZE; j++){
                if(f.isValidPosition(new int[] {i,j})){
                    return new int[] {i,j};
                }
            }
        }
        return new int[] {0,0};
    }

}

```
> 1 votes

---
Tags: king-of-the-hill, hexagonal-grid, java, asymmetric
---


# Question
Title: Asymmetrical KOTH: Catch the Cat (Cat Thread)
***UPDATE***: **The gist-files are updated (including new submissions) as the Controller.java did not catch Exceptions (only errors). It does now catch errors and exceptions and also prints them.**

*This challenge consists of two threads, this is the cat thread, the catcher thread can be found here.*

The controller can be downloaded here.

This is an asymmetrical KOTH: Each submission is either a *cat* or a *catcher*. There are games between each pair of each a cat and a catcher. The cats and the catchers have separate rankings.

## Catcher

There is a cat on a hexagonal grid. Your task is to catch it as fast as possible. Every turn, you can place a water bucket on one grid cell in order to prevent the cat from being able to go there. But the cat is not (perhaps) that dumb, and whenever you place a bucket, the cat will move to another grid cell. Since the grid is hexagonal, the cat can go in 6 different directions. Your goal is to surround the cat with water buckets, the faster the better.

## Cat

You know the catcher wants to catch you by placing water buckets around you. Of course you try to evade, but as you are a lazy cat (as cats are) you exactly take one step at the time. This means you cannot stay on the same place you, but you have to move to one of the six surrounding spots. Whenever you see that the catcher placed a new water bucket you go to another cell. Of course you try to evade as long as possible.

## Grid

The grid is hexagonal, but as we do not have hexagonal data structures, we take a `11 x 11` square 2d array and mimic the hexagonal 'behavior' that the cat can only move in 6 directions:

The topology is toroidal, that means if you step on a cell 'outside' of the array, you will just be transferred to the corresponding cell on the other side of the array.

## Game

The cat starts out at given position in the grid. The catcher can do the first move, then the cat and its catcher alternate moves until the cat is caught. The number of steps is the score for that game. The cat tries to get a score as great as possible, the catcher tries to get a score as low as possible. The average sum over all the games you participated in will be the score of your submission. There are two separate rankings, one for the cat, one for the catchers.

# Controller

The given controller is written in Java. As a catcher or a cat you each have to each complete implement a Java class (there are already some primitive examples) and place it in the `players` package (and update the list of cats/catchers in the Controller class), but you also may write additional functions within that class. The controller comes with each two working examples of simple cats/catcher classes.

The field is a `11 x 11` 2D- `int` array that stores the values of the current states of the cells. If a cell is empty, it has value `0`, if there is a cat it has value `-1` and if there is a bucket there is a `1`.

There are a few given functions you can use: `isValidMove()`/`isValidPosition()` are for checking whether your move (cat) / position (catcher) is valid.

Each time it is your turn, your function `takeTurn()` is called. The argument contains the a copy of the current grid an has methods like `read(i,j)` for reading the cell at `(i,j)`, as well as `isValidMove()/ isValidPosition()` that checks the validity of your answer. This also manages the wrapping over of the toroidal topology, that means even if the grid is only 11 x 11, you still can access the cell (-5,13).

The method should return a `int` array of two elements, which represent possible moves. For the cats these are `{-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}` which represent the relative position of where the cat wants to go, and the catchers return the absolute coordinates of where they want to place a bucket `{i,j}`.

If your method produces an invalid move, your submission will be disqualified. The move is considered as invalid, if at your destination is already a bucket or the move is not allowed / destination already occupied (as a cat), or if there is already a bucket/cat (as a catcher). You can check that before hand with the given functions.

Your submission should work reasonably fast. If your method takes longer than 200ms for each step it will also be disqualified. (Preferably much less...)

The programs are allowed to store information between the steps.

## Submissions

* You can make as many submissions as you want.
* Please do not significantly alter submissions you've already submitted.
* Please each submissions in a new answer.
* Each submission should preferably have it's unique name.
* The submission should consist of the code of your class as well as a description that tells us how your submission works.
* You can write the line `<!-- language: lang-java -->` before your source code in order to get automatic syntax highlighting.

## Scoring

All *cats* will compete against all *catchers* the same number of times. I'll try to update the current scores frequently, the winners will be determined when the activity has decreased.

This challenge is inspired by this old flash game

Thanks @PhiNotPi for testing and giving some constructive feedback.

## Current Scores (100 Games per pairing)

| Name (Catcher) | Score | Rank | Author |
| --- | --- | --- | --- |
| RandCatcher | 191962 | 8 | flawr |
| StupidFill | 212688 | 9 | flawr |
| Achilles | 77214 | 6 | The E |
| Agamemnon | 74896 | 5 | The E |
| CloseCatcher | 54776 | 4 | randomra |
| ForwordCatcher | 93814 | 7 | MegaTom |
| Dijkstra | 47558 | 2 | TheNumberOne |
| HexCatcher | 48644 | 3 | randomra |
| ChoiceCatcher | 43834 | 1 | randomra |

| Name (Cat) | Score | Rank | Author |
| --- | --- | --- | --- |
| RandCat | 77490 | 9 | flawr |
| StupidRightCat | 81566 | 6 | flawr |
| SpiralCat | 93384 | 5 | CoolGuy |
| StraightCat | 80930 | 7 | CoolGuy |
| FreeCat | 106294 | 3 | randomra |
| RabidCat | 78616 | 8 | cain |
| Dijkstra's Cat | 115094 | 1 | TheNumberOne |
| MaxCat | 98400 | 4 | Manu |
| ChoiceCat | 113612 | 2 | randomra |

# Answer
# FreeCat

Chooses the move which would give it the most possible paths after 3 steps if the field wouldn't change.

FreeCat vs Achilles:

```
package players;
/**
 * @author randomra
 */

import java.util.Arrays;

import main.Field;

public class FreeCat implements Cat {

    final int[][] turns = { { -1, 1 }, { 0, 1 }, { -1, 0 }, { 1, 0 },
            { 0, -1 }, { 1, -1 } };// all valid moves
    final int turnCheck = 3;

    public String getName() {
        return "FreeCat";
    }

    public int[] takeTurn(Field f) {

        int[] pos = f.findCat();
        int[] bestMove = { 0, 1 };
        int bestMoveCount = -1;
        for (int[] t : turns) {
            int[] currPos = { pos[0] + t[0], pos[1] + t[1] };
            int moveCount = free_count(currPos, turnCheck, f);
            if (moveCount > bestMoveCount) {
                bestMoveCount = moveCount;
                bestMove = t;
            }
        }
        return bestMove;
    }

    private int free_count(int[] pos, int turnsLeft, Field f) {
        if (f.isValidPosition(pos) || Arrays.equals(pos, f.findCat())) {
            if (turnsLeft == 0) {
                return 1;
            }
            int routeCount = 0;
            for (int[] t : turns) {
                int[] currPos = { pos[0] + t[0], pos[1] + t[1] };
                int moveCount = free_count(currPos, turnsLeft - 1, f);
                routeCount += moveCount;
            }
            return routeCount;
        }
        return 0;
    }
}

```
> 5 votes

# Answer
# Dijkstra's Cat

He learned and applies his master's master algorithm. Note that he is dependent on some of the methods in his corresponding catcher's class.

Dijkstra's Cat vs Hexcatcher(needs updated):

```
package players;

import main.Field;
import players.Dijkstra; //Not needed import. Should already be available.

/**
 * @author TheNumberOne
 *
 * Escapes from the catcher.
 * Uses Dijkstras methods.
 */

public class DijkstrasCat implements Cat{

    private static final int[][] possibleMoves = {{-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}};
    @Override
    public String getName() {
        return "Dijkstra's Cat";
    }

    @Override
    public int[] takeTurn(Field f) {
        int[] me = f.findCat();
        int[] bestMove = {-1,1};
        int bestOpenness = Integer.MAX_VALUE;
        for (int[] move : possibleMoves){
            int[] newPos = Dijkstra.normalize(new int[]{me[0]+move[0],me[1]+move[1]});
            if (!f.isValidMove(move)){
                continue;
            }
            int openness = Dijkstra.openness(newPos, f, true)[1];
            if (openness < bestOpenness || (openness == bestOpenness && Math.random() < .5)){
                bestOpenness = openness;
                bestMove = move;
            }
        }
        return bestMove;
    }
}

```

**How he works:**

He tries to find the move that minimizes the stringiness of the board in relation to himself. For more information, see the corresponding catcher's post.

**With update:**

He now avoids the strange geometric shapes that the water buckets sometimes form.
> 3 votes

# Answer
# MaxCat

I tried implementing the Minimax algorithm. However, it doesn't perform very well because of the limited time. **Edit:** It now uses multithreading, but (atleast on my computer) I can't set the depth any higher. Otherwise a timeout occurs. Using a PC with 6 or more cores, this submission would be much better :)

MaxCat vs Dijkstra:

```
package players;

import java.util.ArrayList;
import java.util.List;

import main.Field;

public class MaxCat implements Cat {
    final int[][] turns = { { -1, 1 }, { 0, 1 }, { -1, 0 }, { 1, 0 }, { 0, -1 }, { 1, -1 } };

    public String getName() {
        return "MaxCat";
    }

    public int[] takeTurn(Field f) {
        List<CatThread> threads = new ArrayList<>();
        int[] pos = f.findCat();
        for (int[] turn : turns) {
            if(f.read(pos[0]+turn[0], pos[1]+turn[1]) == Field.EMPTY){
                CatThread thread = new CatThread();
                thread.bestMove = turn;
                thread.field = new Field(f);
                thread.start();
                threads.add(thread);
            }
        }
        for (CatThread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {}
        }
        int best = Integer.MIN_VALUE;
        int[] bestMove = { -1, 1 };
        for (CatThread thread : threads) {
            if (thread.score > best) {
                best = thread.score;
                bestMove = thread.bestMove;
            }
        }
        return bestMove;
    }

    class CatThread extends Thread {
        private Field field;
        private int[] bestMove;
        private int score;
        private final int DEPTH = 3;

        @Override
        public void run() {
            score = max(DEPTH, Integer.MIN_VALUE, Integer.MAX_VALUE);
        }

        int max(int depth, int alpha, int beta) {
            int pos[] = field.findCat();
            if (depth == 0 || field.isFinished()) {
                int moveCount = 0;
                for (int[] turn : turns) {
                    if(field.read(pos[0]+turn[0], pos[1]+turn[1]) == Field.EMPTY)
                        moveCount++;
                }
                return DEPTH-depth + moveCount;
            }
            int maxValue = alpha;
            for (int[] turn : turns) {
                if(field.read(pos[0]+turn[0], pos[1]+turn[1]) == Field.EMPTY) {
                    field.executeMove(turn);
                    int value = min(depth-1, maxValue, beta);
                    field.executeMove(new int[]{-turn[0], -turn[1]});
                    if (value > maxValue) {
                        maxValue = value;
                        if (maxValue >= beta)
                            break;
                    }
                }
            }
            return maxValue;
        }

        int min(int depth, int alpha, int beta) {
            if (depth == 0 || field.isFinished()) {
                int moveCount = 0;
                for (int[] turn : turns) {
                    int pos[] = field.findCat();
                    if(field.read(pos[0]+turn[0], pos[1]+turn[1]) == Field.EMPTY)
                        moveCount++;
                }
                return -depth - moveCount;
            }
            int[][] f = field.field;
            int minValue = beta;
            List<int[]> moves = generateBucketMoves();
            for (int[] move : moves) {
                f[move[0]][move[1]] = Field.BUCKET;
                int value = max(depth-1, alpha, minValue);
                f[move[0]][move[1]] = Field.EMPTY;
                if (value < minValue) {
                    minValue = value;
                    if (minValue <= alpha)
                        break;
                }
            }
            return minValue;
        }

        private List<int[]> generateBucketMoves() {
            int[][] f = field.field;
            List<int[]> list = new ArrayList<>();
            for (int i = 0; i < f.length; i++) {
                for (int j = 0; j < f[i].length; j++) {
                    if (f[i][j] == Field.EMPTY) {
                        list.add(new int[]{i,j});
                    }
                }
            }
            return list;
        }
    }
}

```
> 3 votes

# Answer
# SpiralCat

Moves in a spiral way. It

* Tries to move to the top-left circle
* If not possible, tries to move to the top right circle
* If not possible, tries to move to the right circle
* If not possible, tries to move to the bottom right circle
* If not possible, tries to move to the bottom left circle

SpiralCat vs Agamemnon:

```
package players;
/**
 * @author Cool Guy
 */

import main.Field;

public class SpiralCat implements Cat{
    public String getName(){
        return "SpiralCat";
    }
    public int[] takeTurn(Field f){
        int[][] turns = {{-1,1},{0,1},{1,0},{1,-1},{0,-1},{-1,0}};//all valid moves
        int[] move;
        int i = -1;
        do {
            i++;
            move = turns[i];
        } while(f.isValidMove(move) == false);
        return move;
    }
}

```
> 2 votes

# Answer
## RabidCat

RabidCat has hydrophobia, so he is afraid of the water buckets. He finds the nearest one and runs in the opposite direction.

RabidCat vs ForwordCatcher:

```
package players;

import java.util.Random;

import main.Field;

/**
* Run away from water buckets
* @author cain
*
*/

public class RabidCat implements Cat {

public RabidCat() {
}

@Override
public String getName() {
    return "RabidCat";
}

@Override
public int[] takeTurn(Field f) {
    int[][] directions = {{-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}};

    //where am I?
    int[] position = {0,0};
    for(int i = 0; i < 12; i++){
        for(int j = 0; j < 12; j++){
            if(f.read(i,j) == -1){
                position[0] = i;
                position[1] = j;
            }
        }
    }

    //Find the closest water
    int direction = 0;
    for(int d = 0; d < 10; d++){
        if(f.read(position[0] + d, position[1] - d) == 1 && f.isValidMove(directions[0])){
            direction = 1;
            break;
        }
        if(f.read(position[0], position[1] - d) == 1 && f.isValidMove(directions[1])){
            direction = 2;
            break;
        }
        if(f.read(position[0] + d, position[1]) == 1 && f.isValidMove(directions[2])){
            direction = 3;
            break;
        }
        if(f.read(position[0] - d, position[1]) == 1 && f.isValidMove(directions[3])){
            direction = 4;
            break;
        }
        if(f.read(position[0], position[1] + d) == 1 && f.isValidMove(directions[4])){
            direction = 5;
            break;
        }
        if(f.read(position[0] - d, position[1] + d) == 1 && f.isValidMove(directions[5])){
            direction = 6;
            break;
        }
    }

    //If there is no water near, wander
    while(direction == 0){
        Random rand = new Random();
        direction = rand.nextInt(6) + 1;
        if(!f.isValidMove(directions[direction - 1])){
            direction = 0;
        }
    }
    return directions[direction - 1];
}

}

```
> 2 votes

# Answer
# ChoiceCat

For every possible new cat positions we check its goodness and choose the best one. Goodness is the function of the two best neighbour cells who are further away from the cat position than the position whose score we calculate. We use only two cells because one can be blocked and the cat only needs one more to get away. Our function prefers two fairly good cells than one great and one bad. Positions with buckets have a score of 0 and the furthest free cells have a score of 1.

ChoiceCat seems to score better than the current cats.

ChoiceCat vs ChoiceCatcher:

```
package players;
/**
 * @author randomra
 */
import java.util.Arrays;

import main.Field;

public class ChoiceCat implements Cat {

    private class Values {
        public final int size;
        private double[][] f;

        Values(int size) {
            this.size = size;
            f = new double[size][size];
        }

        public double read(int[] p) {
            int i = p[0];
            int j = p[1];
            i = (i % size + size) % size;
            j = (j % size + size) % size;
            return f[i][j];
        }

        private double write(int[] p, double v) {
            int i = p[0];
            int j = p[1];
            i = (i % size + size) % size;
            j = (j % size + size) % size;
            return f[i][j] = v;
        }
    }

    final int[][] turns = { { -1, 1 }, { 0, 1 }, { 1, 0 }, { 1, -1 },
            { 0, -1 }, { -1, 0 } };// all valid moves CW order
    final int stepCheck = 5;

    public String getName() {
        return "ChoiceCat";
    }

    public int[] takeTurn(Field f) {

        int[] pos = f.findCat();
        int[] bestMove = { 0, 1 };
        double bestMoveValue = -1;
        for (int[] t : turns) {
            int[] currPos = { pos[0] + t[0], pos[1] + t[1] };
            double moveValue = movePosValue(currPos, f);
            if (moveValue > bestMoveValue) {
                bestMoveValue = moveValue;
                bestMove = t;
            }
        }
        return bestMove;
    }

    private double movePosValue(int[] pos, Field f) {

        Values v = new Values(f.SIZE);

        for (int ring = stepCheck; ring >= 0; ring--) {
            for (int phase = 0; phase < 2; phase++) {
                for (int sidepos = 0; sidepos < Math.max(1, ring); sidepos++) {
                    for (int side = 0; side < 6; side++) {
                        int[] evalPos = new int[2];
                        for (int coord = 0; coord < 2; coord++) {
                            evalPos[coord] = pos[coord] + turns[side][coord]
                                    * sidepos + turns[(side + 1) % 6][coord]
                                    * (ring - sidepos);
                        }
                        if (phase == 0) {
                            if (ring == stepCheck) {
                                // on outmost ring, init value
                                v.write(evalPos, -1);
                            } else {
                                v.write(evalPos, posValue(evalPos, v, f));
                            }
                        } else {
                            // finalize position value for next turn
                            v.write(evalPos, -v.read(evalPos));
                        }
                    }
                }
            }
        }

        return -v.read(pos);
    }

    private double posValue(int[] pos, Values v, Field f) {
        if (f.read(pos[0], pos[1]) == Field.BUCKET) {
            return 0;
        }
        int count = 0;
        double[] product = new double[6];
        for (int[] t : turns) {
            int[] tPos = new int[] { pos[0] + t[0], pos[1] + t[1] };
            if (v.read(tPos) > 0) {
                product[count] = 1 - 1 / (v.read(tPos) + 1);
                count++;
            }
        }
        Arrays.sort(product);
        double fp = 1;
        for (int i = 0; i < Math.min(count,2); i++) {
            fp *= product[5-i];
        }
        double retValue = Math.min(count,2) + fp;
        return -retValue;
    }
}

```
> 2 votes

# Answer
# StupidRightCat

This was made just for testing the controller. The cat move right whenever possible, otherwise moves in a random direction.

```
package players;

import main.Field;

public class StupidRightCat implements Cat{
    public String getName(){
        return "StupidRightCat";
    }
    public int[] takeTurn(Field f){
        int[][] turns = {{-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}};//all valid moves
        int[] move;

        if(f.isValidMove(turns[3])){
            return turns[3];
        } else {
            do {
                move = turns[(int) (turns.length * Math.random())];
            } while(f.isValidMove(move)==false);
            return move;//chose one at random
        }
    }
}

```
> 1 votes

# Answer
# RandCat

This was made just for testing the controller. The cat just moves randomly.

```
package players;

import main.Field;

public class RandCat implements Cat{
    public String getName(){
        return "RandCat";
    }
    public int[] takeTurn(Field f){
        int[][] turns = {{-1,1},{0,1},{-1,0},{1,0},{0,-1},{1,-1}};//all valid moves
        int[] move;
        do {
            move = turns[(int) (turns.length * Math.random())];
        } while(f.isValidMove(move)==false);
        return move;//chose one at random
    }
}

```
> 1 votes

# Answer
# StraightCat

This cat moves straight.

At the start, it chooses a random direction and keeps moving in this direction until it cannot in which case, it shifts the direction in a clockwise manner to the next valid direction and repeats this process.

StraightCat vs Agamemnon:

```
package players;
/**
 * @author Cool Guy
 */

import main.Field;

public class StraightCat implements Cat{

    int lastDirection = -1; //Holds the last direction the cat moved
    public String getName(){
        return "StraightCat";
    }
    public int[] takeTurn(Field f){
        int[][] turns = {{-1,1},{0,1},{1,0},{1,-1},{0,-1},{-1,0}};//all valid moves

        if(lastDirection == -1)
          lastDirection = (int) (turns.length * Math.random());

        int[] move = turns[lastDirection];
        int i = lastDirection;

        while(true)
        {
            if(f.isValidMove(move))
                break;
            i = (i+1)%6;
            lastDirection = i;
            move = turns[i];
        }
        return move;
    }
}

```
> 1 votes

---
Tags: king-of-the-hill, hexagonal-grid, java, asymmetric
---


title: ASCII art "Hello-World!"

text:
# Question
Title: ASCII art "Hello-World!"
Your goal is to write the shortest program that outputs "Hello-World!" as ASCII art.

Rules :

* It must be human readable, I don't care about it's size (cols/rows)
* Output must contain only spaces (" "), sharps ("#") and newlines
* The output must work with a monospaced font (but the letters doesn't necessary use a monospaced font)
* In the result, each character must be separated from each other by at least one space

Please add a title with the language and the number of bytes in your code.

# Answer
> 18 votes
I absolutely enjoyed this one

# Perl, 126 116 114 102 98 87 (69) chars (ascii only & no external fonts)

## As of now shortest ascii solution which doesn't use any external fonts.

Well, I wanted to present some elegant solution but @Ilmari Karonen challenged me with `unpack`... shouldn't have done that :-)

Well, this 92 88 **69 chars** code generates the uglish unreadable output identical to @Ilmari Karonen's:

```
say map{y/01/ #/r}unpack"((b6)7a)*",'eT@j@DE
UUBjdeE
wTujjTA
eUBTddE'

```

More elegant variant without unpack (88 chars):

```
map{print$"x$_,$/x/4/,"#"x!/7/}7&ord,7&ord>>3for'HRyYOKLIIjIRHBa@AJIAIIIJaQHQNSRH'=~/./g

```

But I think such |.|e||.-|||.,d! thing is nothing which resembles Hello-World! and shouldn't be allowed, so real solution goes here - unpack variant, **87 chars**:

```
say map{y/01/ #/r}unpack"((b6)9a)*",'E`D@HB@Hd
EcD@HB@Hd
ggDsIbaIf
e`dDhRRHE
ECICPaQPf'

```

Output:

More elegant variant at 98 chars:

```
map{print$"x$_,$/x/1/,"#"x!/7/}7&ord,7&ord>>3for'PW{nw^QD[w}vK@X@PcP@jCDjXQk[rRRbSQD\CWbXeX'=~/./g

```

Output:

Older solution (114 chars), different type of coding:

```
print'#'x(3&ord),$"x($:=15&ord>>2),$/x!$:for'EmM}U}]MBEQSM}U}]MBOFNMQOKUMSKUOBEM]MMM]IIIMIUQIAEQWMMgFROYQOB'=~/./g

```

Output:

# Answer
> 47 votes
# JavaScript, 178 bytes

```
c=document.createElement("canvas").getContext("2d");c.fillText("Hello-World!",0,7);d=c.getImageData(1,0,56,7).data;s="";for(i=3;i<1568;i+=4){s+=d[i]?"#":" ";s+=(i+1)%224?"":"\n"}

```

That works in Firefox 27 Scratchpad.

```
#   #        #  #          #   #   #          #     #  #
#   #        #  #          #  # #  #          #     #  #
#   #   ##   #  #   ##      # # # #   ##   ## #   ###  #
#####  #  #  #  #  #  #     # # # #  #  #  #  #  #  #  #
#   #  ####  #  #  #  # ##  # # # #  #  #  #  #  #  #  #
#   #  #     #  #  #  #     # # # #  #  #  #  #  #  #
#   #   ###  #  #   ##       #   #    ##   #  #   ###  #

```

# Answer
> 37 votes
# Mathematica ~~101 99~~ 98

This rasterizes the expression, obtains the binary image data, converts each 1 to "#", each 0 to "" (empty space) and displays output in a 12 by 130 character grid.

```
GraphicsGrid[ImageData@ImageResize[Binarize@Rasterize@Style["Hello-World!",99],130]
  /.{1→"",0→"#"}]

```

One character economized thanks to Jonathan Van Matre.

# Answer
> 26 votes
## Delphi 85 bytes

```
var s:tstringlist;begin s:=tstringlist.Create;s.LoadFromFile('\a');Write(s.Text);end.

```

I know, its not the prettiest solution but there was no rule that said you couldnt use external resources.
Result:

# Answer
> 15 votes
# Perl 5, 54 bytes / 71 printable ASCII chars

> **Note:** This is the second version of this answer. For the original 64-byte / 95-char version using PHP and gzinflate(), see the history of this answer.

Here's the 71-char printable ASCII version:

```
y/01/ #/,say for unpack'(B40)4',unpack u,'4I*`1`(JJI!$FFNRJU52HIJ0*))H'

```

The 54-byte version contains non-printable characters, so I'm providing it as a hex dump. On Unixish systems, you can use `xxd -r` to turn the hex dump back into an executable Perl script:

```
0000000: 792f 3031 2f20 232f 2c73 6179 2066 6f72  y/01/ #/,say for
0000010: 2075 6e70 6163 6b27 2842 3430 2934 272c   unpack'(B40)4',
0000020: 27a4 a011 008a aaa4 1126 9aec aad5 54a8  '........&....T.
0000030: a6a4 0a24 9a27                           ...$.'

```

Both need to be run with `perl -M5.010` to enable the Perl 5.10+ `say` feature. They will produce the following output:

(Shown as a screenshot, because the huge line-height on SE makes ASCII art ugly and hard to read. The lower case "e" is kind of awkward, but I believe this qualifies as readable, if only barely so.)

---

**Ps.** If the output of the solution above feels too minimalistic for you, here's a **92-character** variant that produces output similar to Tomas's solution:

```
y/01/ #/,say for unpack'(B56)*',unpack u,'CH!(`"(`"":,2``B``@GGDC\'(C#(YI!)("I)"2*,),`4,03D'

```

Here's a screenshot:

---

**Pps.** I'm pretty sure *this* (**GolfScript, 51 chars**) is the shortest printable-ASCII solution, if you don't count the ones that just call banner / FIGLet or that cheat in some other way:

```
'iJ@Q@HmURBIMM{JkUUJeMRAQIM'{2base(;{' #'=}/}%39/n*

```

The output is the same as for my 71-char Perl solution above.

# Answer
> 8 votes
# Shell + Figlet (35)

```
$ figlet -w 90 -f banner Hello-World!
#     #                                   #     #                             ###
#     # ###### #      #       ####        #  #  #  ####  #####  #      #####  ###
#     # #      #      #      #    #       #  #  # #    # #    # #      #    # ###
####### #####  #      #      #    # ##### #  #  # #    # #    # #      #    #  #
#     # #      #      #      #    #       #  #  # #    # #####  #      #    #
#     # #      #      #      #    #       #  #  # #    # #   #  #      #    # ###
#     # ###### ###### ######  ####         ## ##   ####  #    # ###### #####  ###

```

# Answer
> 8 votes
## Python 260 215 186 152

```
>>> print'eJyNkFEKwDAIQ/93isC7/x3LyIJullHrR1BfJSIJPUHTlmiUPHbxC7L56wNCgZAxv3SjDWIxsoOb\nzMaBwyHYPJ5sVPNYxXism74vcIsFZlYyrg=='.decode('base64').decode('zip')
#   #        #  #          #   #   #          #     #  #
#   #        #  #          #  # #  #          #     #  #
#   #   ##   #  #   ##      # # # #   ##   ## #   ###  #
#####  #  #  #  #  #  #     # # # #  #  #  #  #  #  #  #
#   #  ####  #  #  #  # ##  # # # #  #  #  #  #  #  #  #
#   #  #     #  #  #  #     # # # #  #  #  #  #  #  #
#   #   ###  #  #   ##       #   #    ##   #  #   ###  #

```

## Python 196 183 130 114 (but uglyer)

```
>>> print'eJxTVlBWgCAgAQHKqBywAJeyAgJCZREcZWUYyaUMIpUVEKqRNcLEueDqEaZBLVVWQDITADIdFBw='.decode('base64').decode('zip')
# #  #  # #        # # #        #   # #
# # # # # #  #     # # #  #  ## #  ## #
### ##  # # # # ## # # # # # #  # # #
# #  ## # #  #      # #   #  #  #  ## #

```

I used zipped data in base64 encoding. and the code decode it from base64 encoding and then unzipping it.

# Answer
> 7 votes
# PHP — 183 bytes

Using sebcap26's ASCII art as the source...

```
foreach(str_split(base64_decode('iASAERACCYgEgBKQAgmIxIwKoxo5+SSSCqSSSYnkksqkkkmJBJIKpJJIiOSMBEMSOQ'))as$i=>$j)echo strtr(sprintf("%8s%s",decbin(ord($j)),($i+1)%7?"":"\n"),'01',' #');

#   #        #  #          #   #   #          #     #  #
#   #        #  #          #  # #  #          #     #  #
#   #   ##   #  #   ##      # # # #   ##   ## #   ###  #
#####  #  #  #  #  #  #     # # # #  #  #  #  #  #  #  #
#   #  ####  #  #  #  # ##  # # # #  #  #  #  #  #  #  #
#   #  #     #  #  #  #     # # # #  #  #  #  #  #  #
#   #   ###  #  #   ##       #   #    ##   #  #   ###  #

```

# Answer
> 6 votes
## Brainfuck, 372 Byte

(I know. but just for completeness, there has to be brainfuck ^^ It'S not going to get much shorter, as there are little repetitions. First and second line loop already...)

```
++++++++[>++++>++++<<-]>+++>>++++++++++>>+>++[-<<<<<.>.<.>..>>>[-<<<.>>>]<[-<<<.>>>]<<..<.>>>++[-<<.<.>..........<.>....>>]<<<.>.<.>>.>+>>]<<<<<...>.<.>.<.>.<.>.<.>..<..>..<...>.<.>..<.>..<.>..<..>...<..>.<.>..<...>.<.>>.<<.>.<.>.<.>...<.>.<.>.<.>..<.>.....<.>.<...>.<.>.<.>..<.>.<.>...<.>.<.>..<.>>.<<.>.<.>.<...>.<.>.<.>..<..>.......<..>.<..>...<..>..<.>...<.>..<..>..<.

```

Interpreter here: http://koti.mbnet.fi/villes/php/bf.php

---

```
# #     # #          #     #          #    # #
# #  #  # #          #     #          #    # #
### # # # #  ##  ### #  #  #  ##   ## #  ### #
# # #   # # #  #     # ### # #  # #   # #  #
# # ### # #  ##       ## ##   ##  #   #  ##  #

```

---

Combining @ASKASK's number generator and image with my loops and some additional tuning, we get:

## Brainfuck, ~~343 339 336~~ 334 Bytes

Looks uglier than my original version though.

```
+++++[->++++++>+++++++>++<<<]>++>>>+>>++[-<<<<.<.>.<..>>>[-<<<.>>>]>[-<<<.>>>]<<<<..>.<.>>>++[-<<.<.........>.<...>>>]<<.<.>.>.>>+>]<<<<..<<+++++[->>.<.<]>.>.<..>...<.>.<.>.<.>.<..>.<...>..<.>.<..>..<.>.>.<.<.>.<.>.<...>.<.>.<.>.<.>.<.....<++++++[->>.<.<]>..>.<.>.<.>.>.<.<.>.<..>.<..>.<.>.<..>.<.......>...<...>.<..>.<...>.<..>.<..>.

```

(image see @ASKASK's Answer)

# Answer
> 5 votes
# EcmaScript 6, 172 161

```
'¡I%e!c0ĄJ¥eìo0¸ËefMs0µKcÊIs0´Ê¢1éo'.split(0).map(s=>s.split('').map(c=>{for(i=8,s='';i--;)s+=(c.charCodeAt(0)-33)&(1<<i)?'#':' ';return s;}).join('')).join('\n')

```

Output:

```
#         # #        #   #   #           #    #
###   ##  # #  ##    #   #   #  ##  # ## #  ###
#  # #### # # #  #   #   #   # #  # ##   # #  #
#  # #    # # #  #    # # # #  #  # #    # #  #
#  #  ### # #  ##      #   #    ##  #    #  ###

```

Explanation:

> The ASCII text is compacted into a string where each bit represent a *pixel*:
>
> * `0` for `SPACE`
> * `1` for `#`
>
> An offset of 33 is applied in order to get only printable characters.

# Answer
> 4 votes
# Sclipting, 38 characters (76 bytes)

```
갦륈똄릵꺕녔꺒녪냕녪낷뚕년꺒녦냉괄낵要감嚙긂밃⓶掘⓶終丟併껧뜴꼧밍替現겠合終

```

## Output:

```
# # ## #  #   #     #   #  #  ##  #  ##  #
# # #  #  #  # #    #   # # # # # #  # # #
### ## #  #  # # ## # # # # # ##  #  # # #
# # #  #  #  # #    # # # # # # # #  # #
# # ## ## ##  #      # #   #  # # ## ##  #

```

# Answer
> 3 votes
# Brainfuck, 362 bytes

Sorry @johannes-h, I saw yours and was inspired to make my own. It uses a combination of faster number generation at the beginning and a simpler picture to generate the result in less bytes. It does not however use loops anywhere else so it is up for optimization.

```
+++++[->++++++>+++++++>++<<<]>++>.<.>.<.....>.<.>.<.........>.<...>.<.........>.<...>.<.>.>.<.<.>.<..>.<..>.<.>.<.........>.<...>.<.........>.<...>.<.>.>.<...<.>.<.>.<.>.<.>.<..>.<..>...<.>.<.>.<.>.<..>.<...>..<.>.<..>..<.>.>.<.<.>.<.>.<...>.<.>.<.>.<.>.<.....>.<.>.<.>.<.>.<.>.<.>.<...>.<.>.<.>.>.<.<.>.<..>.<..>.<.>.<..>.<.......>...<...>.<..>.<...>.<..>.<..>.

```

which generates:

# Answer
> 3 votes
# ImageMagick + sed, 71 bytes

I don't see any other ImageMagick entries, so here's my late stake in the ground:

```
convert +antialias label:Hello-World! xpm:-|sed '8,+9y/ /#/;s/[^#]/ /g'

```

I think the `sed` portion can probably be golfed some more.

Try it online.

Output:

```

  #    #          #  #            ##   #    #            #      #  #
  #    #          #  #             #   ##  ##            #      #  #
  #    #          #  #             #  ###  #             #      #  #
  #    #   ####   #  #  ####       #  # #  #  ####   # # #  ### #  #
  ######  #    #  #  # ##  ##      #  # #  # ##  ##  ##  # ##  ##  #
  #    #  ######  #  # #    # ###   # #  # # #    #  #   # #    #  #
  #    #  #       #  # #    #       ##   ##  #    #  #   # #    #  #
  #    #  ##  ##  #  # ##  ##       ##   ##  ##  ##  #   # ##  ##
  #    #   ####   #  #  ####        ##   ##   ####   #   #  ### #  #

```

# Answer
> 2 votes
## **Postscript, ~~154~~ 133**

```
<~GasbQ8I>GO#QsOD7:?,pa&5XCgo@jeLPX:a4F9kN1nu1B@8KjD"^]WgY[MA.2VBjpTNo5$Pi%uI9Lr>,9`~>/FlateDecode filter 999 string readstring pop =

```

i.e.

```
    <~GasbQ8I>GO#QsOD7:?,pa&5XCgo@jeLPX:a4F9kN1nu1B@8KjD"^]WgY[MA.2VBjpTNo5$Pi%uI
9Lr>,9`~>
/FlateDecode filter
999 string readstring pop
=

```

ASCII-only source, inspiration for ASCII-art was Johannes H.'s answer :-)

```
# #     # #         #    #          #    # #
# #  #  # #         #    #          #    # #
### # # # #  ##  ## #    #  ##   ## #  ### #
# # #   # # #  #    # ## # #  # #   # #  #
# # ### # #  ##      #  #   ##  #   #  ##  #

```

(more readable in terminal)

## **Perl, 102**

```
print$-%44?'':"\n",vec(unpack(u,'<!040`A!:4@`A`*%7918REEM1":T4)75E(#&1"0``'),$-++,1)?'#':' 'for 0..219

```

Same output as above. I know I lost to both Perl answers above, but I publish it anyway. At least I tried and was moving in the right direction (and hadn't seen shortest answer) :-).

# Answer
> 2 votes
# Pure Bash, no external utilities - 133 characters:

```
c=" #";for x in 0x{5250088045,55520A914D,74556AAA54,535205124D};do while((s=(t=x)^(x/=2)*2,t));do L=${c:s:1}$L;done;echo "$L";L=;done

```

Uses right and left shift (divide and multiply by 2) and xor to find the one bits.

Font data stolen from Blender/Ilmari Karonen.

Tested in Bash 3.2 and 4.2

By the way, this is only 166 characters:

```
echo "# #  #  # #        #   #        #   # #
# # # # # #  #     # # #  #   # #  ## #
### #   # # # # ## # # # # # #  # # #
# #  ## # #  #      # #   #  #  #  ## #"

```

# Answer
> 1 votes
# Python 3, 114

```
print('\n'.join(bin(x)[2:]for x in[353530052677,366448644429,499649260116,357858349645]).translate({48:32,49:35}))

```

Output (4-character tall **e** and **W** stolen from @Ilmari Karonen):

```
# #  #  # #        #   #        #   # #
# # # # # #  #     # # #  #   # #  ## #
### #   # # # # ## # # # # # #  # # #
# #  ## # #  #      # #   #  #  #  ## #

```

And a shorter one (107):

```
print('\n'.join(bin(x)[2:]for x in[11993933918769,16391913257513,12021315382193]).translate({48:32,49:35}))

```

Output:

```
# # ### #   #   ###   # # ### ##  #   ##   #
### ### #   #   # #   # # # # ### #   # #  #
# # ### ### ### ###   ### ### # # ### ##   #

```

# Answer
> 1 votes
## Python 154 Characters, (Char 5X7 in size)

```
print'\n'.join(map(''.join,zip(*(''.join("# "[int(e)]for e in"{:07b}".format(ord(c))[1:])for c in"€÷÷÷€ÿñêêòÿ€ÿ€ÿñîîñÿûûÿŸáþÁ¿ÁþáŸÿñîîñÿàïÿ€ÿÿñîî€ÿ‚"))))

```

**Output**

```
#   #      # #         #   #   #         #     # #
#   #      # #         #  # #  #         #     # #
#   #  ##  # #  ##      # # # #   ##  ## #   ### #
##### #  # # # #  #     # # # #  #  # #  #  #  # #
#   # #### # # #  # ##  # # # #  #  # #  #  #  # #
#   # #    # # #  #     # # # #  #  # #  #  #  #
#   #  ### # #  ##       #   #    ##  #  #   ### #

```

# Answer
> 1 votes
# bash, ~~175~~ 170 bytes

You need to *waste* quite a few characters in order to produce a *pretty output*!

```
base64 -d<<<H4sICKaT9FICAzAxAK2RQQ7AIAgE776CZP7/x1ZjERebcJAL0QybhcV6YdWizAPNaUatQQLFpj6h+c/XA05WF9Wtk9WJcxz4oe6e1YPQa7Wiut2wfjJ16STY30lSnNIlzvdpHhd6MiTOB65NYc+LAgAA|zcat

```

Output:

```
#     #                                         #     #                                   ###
#     #  ######  #       #        ####          #  #  #   ####   #####   #       #####    ###
#     #  #       #       #       #    #         #  #  #  #    #  #    #  #       #    #   ###
#######  #####   #       #       #    #  #####  #  #  #  #    #  #    #  #       #    #    #
#     #  #       #       #       #    #         #  #  #  #    #  #####   #       #    #
#     #  #       #       #       #    #         #  #  #  #    #  #   #   #       #    #   ###
#     #  ######  ######  ######   ####           ## ##    ####   #    #  ######  #####    ###

```

# Answer
> 1 votes
Shell, 20 characters:

```
banner Hello-world\!

```

For this to work, of course you need the `banner` program. On Debian, you can get it by installing the `bsdmainutils` package.

This prints a beautifully rendered version of your message, designed to be printed on one of the old continuous-feed printers, so the output of the above text is 322 lines long by 123 columns wide, and you turn the printout on its side to read the message. You could hang the resulting paper on the wall as a banner, hence the name.

http://en.wikipedia.org/wiki/Banner\_%28Unix%29

EDIT: Looks like Debian also has the `sysvbanner` package, which installs a banner program that prints the text horizontally for display on a terminal. However, this only prints the first 10 characters of the message, so it is kind of annoying for this code-golf problem!

# Answer
> 1 votes
# Bash:

## (~~103~~ 89 Bytes)

### Code:

```
base64 -d<<<rohBEmRiqIihFVRS7IitVWRSqIihVVRQru5Aoldi|xxd -b|sed -e's/ //g;s/1/#/g;s/0/ /g'|cut -b'9-55'

```

### Output:

```
# # ### #   #    #     #   #  #  ##  #   ##   #
# # #   #   #   # #    #   # # # # # #   # #  #
### ##  #   #   # # ## # # # # # ##  #   # #  #
# # #   #   #   # #    # # # # # # # #   # #
# # ### ### ###  #      # #   #  # # ### ##   #

```

Smaller, but less readable (Based on http://mckgyver.pbworks.com/f/1240440791/3PixelFont.jpg):

### Code:

```
base64 -d<<<V0nCLsmQdklaqslQV23BTq2Q|xxd -b|sed -e's/ //g;s/1/#/g;s/0/ /g;'|cut -c'9-52'

```

### Output:

```
 # # ### #  #  ###    #   # ### ##  #  ##  #
 ### ##  #  #  # # ## # # # # # ##  #  # # #
 # # ### ## ## ###     # #  ### # # ## ##  #

```

# Answer
> 1 votes
Authors: xem, aemkei, p01, jonas

Execute this in the JS console.

## JavaScript, cross-browser,~~133~~ ~~132~~ ~~126~~ 117 bytes

```
for(i=s="";l=[43117609029,64070269789,46349920852,46890400349][i++];)for(j=0,s+="\n";c=l.toString(2)[j++];)s+=" #"[c]

```

## JavaScript, ES6, works on Firefox, 108 bytes

```
[,0xa0a028045,0xeeae2bb5d,0xacaabaa54,0xaeae2ba5d].map(a=>a.toString(2).replace(/./g,b=>' #'[b])).join('\n')

```

## Result:

```
>
# #     # #       # #        #   # #
### ### # # ###   # # ### ## # ### #
# # ##  # # # # # ### # # #  # # #
# # ### # # ###   # # ### #  # ### #

```

# Answer
> 1 votes
# Javascript / ES6 (108 bytes)

Copy into console:

```
[,0xa0a028045,0xeeae2bb5d,0xacaabaa54,0xaeae2ba5d].map(a=>a.toString(2).replace(/./g,b=>' #'[b])).join('\n')

```

Output:

```
"
# #     # #       # #        #   # #
### ### # # ###   # # ### ## # ### #
# # ##  # # # # # ### # # #  # # #
# # ### # # ###   # # ### #  # ### #"

```

(Needs ECMAScript6 compatible browser ie. Firefox 22+)

Inspired by @maximeeuziere, @p01, @aemkei

# Answer
> 1 votes
# HTML, 209 characters

```
<pre># #     # #                      #   # #
# #     # #        # # #         #   # #
###  ## # #  #     # # #  #  ##  #  ## #
# # ##  # # # # ## # # # # # # # # # #
# # ### # #  #      # #   #  #   # ### #</pre>
```

Does this count? :)

# Answer
> 0 votes
**F# - 204 characters**

```
for s in(Seq.map(Seq.unfold(function|0L->None|i->Some(" #".[int(i%2L)],i/2L)))[173948798213L;174770890021L;191304848727L;182715110773L;45277009173L;191279670629L])do printfn"%s"(new string(Seq.toArray s))

```

Output:

```
# #     # #        # #         #   # #
# #  #  # #  #     # #  #   ## #   # #
### # # # # # #    # # # # #   #  ## #
# # ### # # # # ## # # # # #   # # # #
# # #   # # # #    ### # # #   # # #
# #  ## # #  #     # #  #  #   #  ## #

```

# Answer
> 0 votes
# Python + pyfiglet -- 87 characters

```
from pyfiglet import figlet_format
print(figlet_format('Hello-World!', font='banner'))

```

### Output

```
#     #                                   #     #                             ###
#     # ###### #      #       ####        #  #  #  ####  #####  #      #####  ###
#     # #      #      #      #    #       #  #  # #    # #    # #      #    # ###
####### #####  #      #      #    # ##### #  #  # #    # #    # #      #    #  #
#     # #      #      #      #    #       #  #  # #    # #####  #      #    #
#     # #      #      #      #    #       #  #  # #    # #   #  #      #    # ###
#     # ###### ###### ######  ####         ## ##   ####  #    # ###### #####  ###

```

To install `pyfiglet`, run:

```
$ pip install pyfiglet

```

# Answer
> 0 votes
# Python with pyfiglet: 66 using argv, 69 without

## 66:

```
from pyfiglet import*
print(figlet_format(sys.argv[1],font='3x5'))

```

## 69:

```
from pyfiglet import*
print(figlet_format('Hello-World!',font='3x5'))

```

firs must be called as, for example:

python asciiart.py 'Hello-World!'

second:

python asciiart.py.

Output:

```
    # #      #   #          # #          #    #  #
    # # ###  #   #  ###     # # ### ###  #  ###  #
    ### ##   #   #  # # ### ### # # #    #  # #  #
    # # ###  ##  ## ###     ### ### #    ## ###
    # #                     # #                  #

```

(Well, it looks kinda crappy with this font. Nevertheless :) )

\[edit\] removed obsolete dash from the argument.

# Answer
> 0 votes
# Javascript 137 (134)

Uses the bits of integers to represent sharps an white spaces. Tested with Firefox 27.

**137 character**

```
s="";[0xadb73eead9,g=0xa9252aaa94,0xed252aac95,g+1,0xad272aee99].map(n=>{for(;n>0;n/=2)n%2?[s="#"+s,n--]:s=" "+s;s="\n"+s});console.log(s)

# # ## #  #  ###  # # # ### ### #  ##  #
# # #  #  #  # #  # # # # # # # #  # # #
### ## #  #  # #  # # # # # ##  #  # # #
# # #  #  #  # #  # # # # # # # #  # #
# # ## ## ## ###  ##### ### # # ## ##  #"

```

**134 character (rotated 180°)**

```
s="";[0xadb73eead9,g=0xa9252aaa94,0xed252aac95,g+1,0xad272aee99].map(n=>{s+="\n";for(;n>0;n/=2)n%2?[s+="#",n--]:s+=" "});console.log(s)

"
#  ## ## # # ### #####  ### ## ## ## # #
  # #  # # # # # # # #  # #  #  #  # # #
# # #  #  ## # # # # #  # #  #  # ## ###
# # #  # # # # # # # #  # #  #  #  # # #
#  ##  # ### ### # # #  ###  #  # ## # #"

```

# Answer
> 0 votes
# Python3 (126)

There's an additional space between the chars to make it better readable. So technically it's a 125 character solution.

```
print(' '.join(['','\n'][i%40==0]+['#',' '][int('72liw1j4glyc34dum02j2a4ipxa8b7vvp65x511',36)//2**i%2==0]for i in range(200)))

```

Output:

```
#   #   # #   #     #     # # #     #   #   #   # # #   # # #   #     # #     #
#   #   #     #     #     #   #     #   #   #   #   #   #   #   #     #   #   #
# # #   # #   #     #     #   #     #   #   #   #   #   # #     #     #   #   #
#   #   #     #     #     #   #     #   #   #   #   #   #   #   #     #   #
#   #   # #   # #   # #   # # #     # # # # #   # # #   #   #   # #   # #     #

```

# Answer
> 0 votes
# Bash ~~37~~, 33

```
toilet<<<"Hello-world"|tr \"m \#

 #    #        ###    ###                                       ###        #
 #    #  ###     #      #     ###         #     #  ###    # ##    #     ####
 ###### ##  #    #      #    ## ##        ## # ## ## ##   ##  #   #    ## ##
 #    # #####    #      #    #   #   ###   #####  #   #   #       #    #   #
 #    # #####    ###    ###  #####          # #   #####   #       ###  #####

```

Which is the same as:

```
echo "Hello-world" | toilet

```

From `man toilet`

> TOIlet - display large colourful character

With `tr "'\"m" "#"` all `"` chars are replaced with `#`.

# Answer
> 0 votes
# Smalltalk, 151

although this golf game is already over, for the reference:

```
i:=((Form extent:115@14)displayString:'Hello world'x:0y:12;asImage).0to:13 do:[:y|i valuesAtY:y from:0to:114 do:[:x :p|({$#.$ }at:p+1)print].Stdout cr]

```

output:

```
 ***  ***             ***       ***                                                         ***           **
  *    *                *         *                                                           *            *
  *    *                *         *                                                           *            *
  *    *     ***        *         *        ***              ***   ***    ***     *** ***      *        *** *
  ******    *   *       *         *       *   *              *     *    *   *      **   *     *       *   **
  *    *   *     *      *         *      *     *             *  *  *   *     *     *          *      *     *
  *    *   *******      *         *      *     *              * * *    *     *     *          *      *     *
  *    *   *            *         *      *     *              * * *    *     *     *          *      *     *
  *    *    *    *      *         *       *   *               ** **     *   *      *          *       *   **
 ***  ***    ****    *******   *******     ***                *   *      ***     ******    *******     *** **

```

# Answer
> 0 votes
**C#, ~~205~~ ~~203~~ 202 bytes**

I'm storing the text as an array of 5 longs, each representing a row in the display. I iterate over the array, and use bitwise comparison to work out if each bit is a # (1) or a space (0).

```
class G{static void Main(){foreach(var c in new long[]{0x14401100505,0x16589102525,0x15455575557,0x5455505535,0x16448A02565})for(int i=0;i<42;i++)System.Console.Write((i>40)?"\n":(c&1L<<i)>0?"#":" ");}}

```

# Answer
> -1 votes
# "cURL", 16 characters:

> program: (computer science) a sequence of instructions that a computer can interpret and execute;

```
curl floris.us/h

```

Produces:

```
#   #      #  #           #   #          #     #  #
#   #  ##  #  #   ##      #   #  ##   ## #   ###  #
##### #### #  #  #  # ### # # # #  # #   #  #  #  #
#   # #    #  #  #  #     # # # #  # #   #  #  #
#   #  ##   #  #  ##       # #   ##  #    #  ###  #

```

I guess if I had a cooler domain, it would be shorter...

# Answer
> -4 votes
# Shell + pyfiglet, 31 characters

pyfiglet can run as a shell tool, so we can simply go like this:

```
pyfiglet -f'3x5' 'Hello-World!'

```

which gives us:

```
# #      #   #          # #          #    #  #
# # ###  #   #  ###     # # ### ###  #  ###  #
### ##   #   #  # # ### ### # # #    #  # #  #
# # ###  ##  ## ###     ### ### #    ## ###
# #                     # #                  #

```

Looks much better with less line spacing.

Letters are separated with one space, and in terminal it's well readable.

---
Tags: code-golf, ascii-art, hello-world
---