title: Chess Tournament

text:
# Question
Title: Chess Tournament
This is a chess-KOTH with simplified rules (because chess itself is already complicated, playing it via a simple program doesn't make it easier). At the moment it is limited to java (version 8), but creating a wrapper-class isn't that difficult (in case someone wants to do this).

## Chessboard

The chessboard in the control program uses a modified version of the ICCF numeric notation. It is zero-based, meaning the bottom-left field is the position `0,0`, while the upper-right field is the position `7,7`.

## Modified rules

* *En passant* will be ignored.
* *Castling* isn't possible.
* The *Fifty-move rule* applies automatically (meaning the game ends in a draw).
* Promotion of pawns to queens happen automatically when they reach the end of the board.
* If a player needs longer than 2 seconds to move, he will lose the game.
* Returning an invalid move will result in losing the game.
* **To win, you have to capture the enemy king**. It isn't enough to checkmate the enemy.
* This also allows you to move your king to fields where the enemy can capture you.
* White begins the game.
* White is placed "at the bottom" of the field (y=0), black is located at the top (y=7).
* Accessing other ressources than your bot (internet, files, other bots, ...) is prohibited.

## Scoring

* Winning grants you 3 points, a draw 1 point and losing 0 points.
* Each submission will play against each other submission 10 times (5 times as white, 5 as black).

## Controller

**You can find the control program on github**.
To participate, you have to create a class inside the `player` package and it has to be a subclass of `Player`. As an example, look at TestPlayer (which will also be included in the scoring).

Each game, the controller will create a new instance of your player. Then, each turn you have to return a move. The controller provides you with a copy of the Board, which contains a 8x8 array of Fields. A field contains information about its color, its position and the piece on it, if there is one.
The controller also provides you with information about the enemy player, such as `isCheck` and `getPieces()`. Calling `getMove()` on the enemy will get you disqualified.

# Scoreboard

```
01) AlphaBetaPV:         229
02) AlphaBeta:           218
03) PieceTaker:          173
04) Cheese:              115
05) ThreeMoveMonte:      114
06) StretchPlayer:        93
07) DontThinkAhead:       81
08) SimplePlayer:         27
09) TestPlayer:           13
```

---

The contest is limited to java because it makes creating answers easier, since you can profit from the methods provided by the controller. However, if someone creates a wrapper, I will include other languages.

# Answer
## AlphaBetaPV

AlphaBetaPV stands for Alpha Beta with Principal Variation (it's not principal-variation search). With only a few more lines woven into the code of AlphaBeta.java, it beats AlphaBeta.java. And again, sorry, for only morphing and fusing codes from other internet sources into this JAVA code.

* The principal variation is stored and used for the simplest move priority to accelerate the alpha beta cut off:
    + while iterative deepening and
    + for the next move.
* Simple position evaluation:
    + Number of moves each party has (degree of freedom) to support the opening.
    + Pawn promotion to support the end game.
* Still no quiescence search.

Still playing boring.

```
package player;

import java.util.Random;
import controller.*;

public class AlphaBetaPV extends Player {
    private static final int INFINITY = Integer.MAX_VALUE;
    private static final int MAXTIME = 1800; // max time for evaluation
    private static final Random random=new Random();
    private static int seed=1;

    private long time; // time taken this turn
    private int iterativeDepth;
    private Player myOpponent;
    private int commitedDepth;

    private static Piece[] pieces = new Piece[20000];
    private static Point[] points = new Point[20000];
    private static int[] freedom = new int[20];

    private static class PV {
        Move move;
        PV next;
    }
    private PV pv= new PV();

    @Override
    public Move getMove(Board root, Player min) {
        time=System.currentTimeMillis();
        seed++; myOpponent=min;
        // use last PV for an estimate of this move
        if (pv.next!=null) pv=pv.next;
        if (pv.next!=null) pv=pv.next;
        iterative_deepening(root);
        return pv.move;
    }

    private void iterative_deepening(Board root) {
        try {
            for (iterativeDepth = (commitedDepth=Math.max(2, commitedDepth-2));; iterativeDepth++) {
                alphaBeta(root, -INFINITY, +INFINITY, iterativeDepth, this, myOpponent, 0, 0, pv, pv);
                commitedDepth=iterativeDepth;
            }
        } catch (InterruptedException e) {}
    }

    //http://chessprogramming.wikispaces.com/Alpha-Beta
    private int alphaBeta(Board root, int alpha, int beta, int d, Player max, Player min, int begin, int level, PV pv, PV pline) throws InterruptedException {
        if (d==0 || root.getKing(max) == null) return evaluate(root, d, level);
        int end = allMoves(root, max, begin, level, pv);
        PV line= new PV();
        for (int m=begin; m<end; m++) {
            Board board = root.copy();
            board.movePiece(new Move(pieces[m].copy(), points[m]));
            int score = -alphaBeta(board, -beta, -alpha, d - 1, min, max, end, level+1, pline==null?null:pline.next, line);
            if (score >= beta)
                return beta; // fail hard beta-cutoff
            if (score > alpha) {
                pline.move=new Move(pieces[m].copy(), points[m]); // store as principal variation
                pline.next=line; line=new PV();
                alpha = score; // alpha acts like max in MiniMax
            }
        }
        return alpha;
    }

    private int evaluate(Board board, int d, int level) throws InterruptedException {
        if ((System.currentTimeMillis() - time) > MAXTIME)  throw new InterruptedException();
        int minmax=2*((iterativeDepth-d)&1)-1;
        int king = 0, value=(level>1)?minmax*(freedom[level-1]-freedom[level-2]):0;
        Field[][] field = board.getFields();
        for (int x = 0; x < 8; x++) {
            for (int y = 0; y < 8; y++) {
                Piece piece = field[x][y].getPiece();
                if (piece==null) continue;

                int sign=(piece.getTeam()==getTeam())?-minmax:minmax;
                switch (piece.getType()) {
                case PAWN:      value += (  1000+2*(piece.getTeam()==Color.WHITE?y:7-y))*sign; break;
                case KNIGHT:    value +=    3000*sign; break;
                case BISHOP:    value +=    3000*sign; break;
                case ROOK:      value +=    5000*sign; break;
                case QUEEN:     value +=    9000*sign; break;
                case KING:      king  += (100000-(iterativeDepth-d))*sign; break;
                default: // value += 0;
                }
            }
        }
        return king==0?value:king;
    }

    private int allMoves(Board board, Player player, int begin, int level, PV pv) {
        random.setSeed(seed);
        int m=0;
        for (Piece piece : player.getPieces(board)) {
            for (Point point: piece.getValidDestinationSet(board)) {
                // shuffle and store
                int r=begin+random.nextInt(++m);
                points[begin+m-1]=points[r];    pieces[begin+m-1]=pieces[r];
                points[r]=point;                pieces[r]=piece;
            }
        }
        freedom[level]=m;
        if (pv!=null && pv.move!=null)  { // push PV to front
            for (int i = 0; i < m; i++) {
                if (pv.move.getPiece().equals(pieces[begin+i]) && pv.move.getDestination().equals(points[begin+i])) {
                    Point point = points[begin];    Piece piece = pieces[begin];
                    points[begin]=points[begin+i];  pieces[begin]=pieces[begin+i];
                    points[begin+i]=point;          pieces[begin+i]=piece;
                    break;
                }
            }
        }
        return begin+m;
    }
}

```
> 5 votes

# Answer
# StretchPlayer

This bot plays just like me!

By the way I am terrible at chess.

The comments explain what it is actually doing. It's a lot like my thought process.

As an added bonus, beats all other bots by a considerable margin. (so far)

EDIT: now predicts opponent by running itself as the enemy!

EDIT 2: The program made the mistake of not actually killing the king when it was wide open. It was reprimanded accordingly.

```
import java.util.List;
import java.util.Set;

import controller.*;

public class StretchPlayer extends Player{

    boolean avoidStackOverflow = false;
    @Override
    public Move getMove(Board board, Player enemy) {
        List<Piece> pieces = this.getPieces(board);
        for(Piece piece:pieces){
            //first order of business: kill the enemy king if possible
            if(piece.getValidDestinationSet(board).contains(board.getKing(enemy).getPos())){
                return new Move(piece,board.getKing(enemy).getPos());
                }
        }
        //I suppose I should protect my king.
        for(Piece ePiece:enemy.getPieces(board)){
            if(ePiece.getValidDestinationSet(board).contains(board.getKing(this).getPos())){
                //ideally I would move my king.
                for(Point p:board.getKing(this).getValidDestinationSet(board)){
                    //but I don't want it to move into a spot where the enemy can get to. That would be suicide.
                    boolean moveHere=true;
                    for(Piece enemyPiece:enemy.getPieces(board)){
                        if(enemyPiece.getValidDestinationSet(board).contains(p)){
                            moveHere=false;
                        }
                    }
                    if(moveHere){
                        return new Move(board.getKing(this),p);
                    }
                }
                //so the king can't move. But I can fix this. There has to be a way!
                for(Piece myPiece:pieces){
                    for(Point possMove:myPiece.getValidDestinationSet(board)){
                        Board newBoard = board.copy();
                        newBoard.movePiece(new Move(myPiece,possMove));
                        if(!newBoard.isCheck(this, enemy)){
                            //Aha! found it!
                            return new Move(myPiece,possMove);
                        }
                    }

                }
                //uh-oh. Better just go with the flow. I'll lose anyway.
            }
        }
        for(Piece piece:pieces){
            Set<Point> moves = piece.getValidDestinationSet(board);
            for(Piece opponentPiece:enemy.getPieces(board)){
                if(moves.contains(opponentPiece.getPos())){
                    Point futurePosition = null;
                    //search for this illusive move (no indexOf(...)?)
                    for(Point p:moves){
                        if(p.getX()==opponentPiece.getPos().getX()&&p.getY()==opponentPiece.getPos().getY()){
                            futurePosition = p;
                        }
                    }
                    //it can now kill the enemies piece. But first, it should probably check if it is going to get killed if it moves there.
                    boolean safe = true;
                    for(Piece nextMoveOpponent:enemy.getPieces(board)){
                        if(nextMoveOpponent.getValidDestinationSet(board).contains(futurePosition)&&piece.getType()!=PieceType.PAWN){
                            safe = false;
                        }
                        //it would also be beneficial if the enemy didn't kill my king next round.
                        if(nextMoveOpponent.getValidDestinationSet(board).contains(board.getKing(this).getPos())){
                            safe = false;
                        }
                    }
                    if(safe){
                        return new Move(piece, futurePosition);
                    }

                }
            }
        }
        //ok, so I couldn't kill anything. I'll just put the enemy king in check!
        for(Piece piece:pieces){
            for(Point p:piece.getValidDestinationSet(board)){
                Piece simulatedMove = piece.copy();
                simulatedMove.setPos(p);
                if(simulatedMove.getValidDestinationSet(board).contains(board.getKing(enemy).getPos())){
                    return new Move(piece,p);
                }
            }
        }
        //hmmmm... What would I do if I was the enemy?
        if(!avoidStackOverflow){
            avoidStackOverflow = true;
            Board copy = board.copy();
            Move thinkingLikeTheEnemy = this.getMove(copy, this);
            avoidStackOverflow = false;
            Board newBoard = copy;
            //I wonder what piece it's targeting...
            Piece targeted =null;
            for(Piece p:pieces){
                if(p.getPos().getX()==thinkingLikeTheEnemy.getDestination().getX()&&p.getPos().getY()==thinkingLikeTheEnemy.getDestination().getY()){
                    targeted=p;
                }
            }
            //better move that piece out of the way, if it doesn't hurt my king
            if(targeted!=null){
                for(Point p:targeted.getValidDestinations(newBoard)){
                    newBoard = board.copy();
                    newBoard.movePiece(new Move(targeted,p));
                    for(Piece enemy2:enemy.getPieces(newBoard)){
                        if(!enemy2.getValidDestinationSet(newBoard).contains(p) && !newBoard.isCheck(this, enemy)){
                            return new Move(targeted,p);
                        }
                    }
                }
                newBoard.movePiece(new Move(targeted,thinkingLikeTheEnemy.getPiece().getPos()));
                if(!newBoard.isCheck(this, enemy)){
                    return new Move(targeted,thinkingLikeTheEnemy.getPiece().getPos());
                }
            }
        }

        //well, I guess this means I couldn't kill anything. Or put the enemy in check. And the enemy didn't have anything interesting to do
        //I guess I should just push a pawn or something
        for(Piece piece:pieces){
            if(piece.getType()==PieceType.PAWN){
                if(piece.getValidDestinationSet(board).size()>0){
                    return new Move(piece,piece.getValidDestinations(board)[0]);
                }
            }
        }
        //What!?!? No Pawns? guess I'll just move the first thing that comes to mind.
        for(Piece piece:pieces){
            if(piece.getValidDestinations(board).length>0){
                //providing that doesn't put my king in danger
                Board newBoard = board.copy();
                newBoard.movePiece(new Move(piece,piece.getValidDestinations(board)[0]));
                if(!newBoard.isCheck(this, enemy)){
                    return new Move(piece,piece.getValidDestinations(board)[0]);
                }
            }
        }
        //Oh no! I can make no moves that can save me from imminent death. Better hope for a miracle!
        for(Piece p:pieces){
            if(p.getValidDestinations(board).length>0){
                return new Move(p,p.getValidDestinations(board)[0]);
            }
        }
        //a miracle happened! (if it made it here)
        return null;
    }

}

```
> 11 votes

# Answer
## PieceTaker

The code is a little bit of a mess, but it does work. Right now it wins against all other players, even if it is only given 400ms instead of the allowed 2000ms.

I'm using alpha beta pruning with iterative deepening to make sure that the AI doesn't go over the time limit. The current heuristic is very simple (only lost/taken pieces are taken into considerations; not position on the board, etc).

In the future I might also add killer heuristics and sort the moves before examining them.

```
package player;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

import controller.*;

public class PieceTaker extends Player {

    private boolean DEBUG = false;
    private Player pieceTaker;
    private static final int MAXINT = Integer.MAX_VALUE / 2;
    private static final int MININT = Integer.MIN_VALUE / 2;
    private static final boolean ITERATIVE_DEEPENING = true;
    private static final int MAX_DEPTH = 6; // max depth if not using iterative
                                            // deepening
    private static int MAXTIME = 400; // max time for evaluation (if using
                                        // iterativeDeepening). We still need to
                                        // evaluate moves, so save time for
                                        // that.
    private long time; // time taken this turn

    @Override
    public Move getMove(Board board, Player enemy) {
        pieceTaker = this;
        // generate all possible moves
        List<Move> possibleMoves = new ArrayList<>();
        List<Piece> pieces = this.getPieces(board);
        for (Piece piece : pieces) {
            Point[] destinations = piece.getValidDestinations(board);
            for (Point point : destinations) {
                possibleMoves.add(new Move(piece, point));
            }
        }

        // rate moves
        Move best = getNextMove(board, possibleMoves, enemy);
        return best;
    }

    private Move getNextMove(Board board, List<Move> possibleMoves, Player enemy) {
        time = System.currentTimeMillis();

        // wrap moves in node class and apply move
        List<Node> children = new ArrayList<>();
        for (Move move : possibleMoves) {
            Node newNode = new Node(move, board, this, enemy, 0);
            newNode.applyAndRateMove();
            children.add(newNode);
        }

        if (ITERATIVE_DEEPENING) {
            for (int depth = 1;; depth++) {
                List<Node> copy = new ArrayList<>();
                // copy nodes (so that in case time is over we still have a valid set)
                for (Node node : children) {
                    copy.add(node.copy());
                }
                // rate copy
                rateMoves(copy, depth);
                if ((System.currentTimeMillis() - time) > MAXTIME) {
                    break;
                }
                // copy rated nodes back
                children = new ArrayList<>();
                for (Node node : copy) {
                    children.add(node.copy());
                }
            }
        } else {
            rateMoves(children, MAX_DEPTH);
        }

        return getBestMove(children);
    }

    // returns node with the highest score
    private Move getBestMove(List<Node> nodes) {
        if (DEBUG) {
            System.out.println("\n");
            for (Node node : nodes) {
                System.out.println(node.toString());
            }
        }

        Collections.sort(nodes, new ComparatorNode());

        // get all nodes with top rating
        List<Node> best = new ArrayList<>();
        int bestValue = nodes.get(0).getRating();
        for (Node node : nodes) {
            if (node.getRating() == bestValue) {
                best.add(node);
            }
        }

        Random random = new Random();
        Node bestNode = best.get(random.nextInt(best.size()));
        if (DEBUG) {
            System.out.println("using: " + bestNode.toString());
        }
        return bestNode.getMove();
    }

    private void rateMoves(List<Node> nodes, int depth) {
        if (nodes.size() == 1) {
            // nothing to rate. one possible move, take it.
            return;
        }

        for (Node node : nodes) {
            int alphaBeta = alphaBeta(node, depth, MININT, MAXINT);
            node.setRating(alphaBeta);
        }
    }

    protected int alphaBeta(Node node, int depth, int alpha, int beta) {
        Player currentPlayer = node.getCurrentPlayer();
        Player otherPlayer = node.getOtherPlayer();
        // game over
        if (node.getBoard().getKing(currentPlayer) == null) {
            if (currentPlayer == this) {
                return node.getRating() - 999;
            } else {
                return node.getRating() + 999;
            }
        } else {
            // TODO check for draw and rate draw (might be good to take it)
        }
        if (depth <= 0) {
            return node.getRating(); // the rating in the move is always as seen
                                        // for player, not current player
        }

        List<Node> children = getPossibleMoves(node);
        if (otherPlayer == this) {
            for (Node child : children) {
                if ((System.currentTimeMillis() - time) > MAXTIME) {
                    break; // time over.
                }
                alpha = Math.max(alpha,
                        alphaBeta(child, depth - 1, alpha, beta));
                if (beta <= alpha) {
                    break; // cutoff
                }
            }
            return alpha;
        } else {
            for (Node child : children) {
                if ((System.currentTimeMillis() - time) > MAXTIME) {
                    break; // time over.
                }
                beta = Math.min(beta, alphaBeta(child, depth - 1, alpha, beta));
                if (beta <= alpha) {
                    break; // cutoff
                }
            }
            return beta;
        }
    }

    private List<Node> getPossibleMoves(Node node) {
        List<Node> possibleMoves = new ArrayList<>();
        List<Piece> pieces = node.getOtherPlayer().getPieces(node.getBoard());
        for (Piece piece : pieces) {
            Point[] destinations = piece.getValidDestinations(node.getBoard());
            for (Point point : destinations) {
                Node newNode = new Node(new Move(piece, point),
                        node.getBoard(), node.getOtherPlayer(),
                        node.getCurrentPlayer(), node.getRating());
                if (newNode.applyAndRateMove()) {
                    possibleMoves.clear();
                    possibleMoves.add(newNode);
                    return possibleMoves; // we won, return wining move
                }
                possibleMoves.add(newNode);
            }
        }
        return possibleMoves;
    }

    private class Node {
        private Move move;
        private Move originalMove;
        private Board board;
        private Player currentPlayer;
        private Player otherPlayer;
        private int rating;

        public Node(Move move, Board board, Player currentPlayer,
                Player otherPlayer, int rating) {
            super();
            this.move = new Move(move.getPiece().copy(), move.getDestination()
                    .copy());
            this.originalMove = new Move(move.getPiece().copy(), move
                    .getDestination().copy());
            // copy board so changes only affect this node
            this.board = board.copy();
            this.currentPlayer = currentPlayer;
            this.otherPlayer = otherPlayer;
            this.rating = rating;
        }

        @Override
        public String toString() {
            return " [" + originalMove.toString() + " (r: " + rating + ")] ";
        }

        public Node copy() {
            Node copy = new Node(new Move(originalMove.getPiece().copy(),
                    originalMove.getDestination().copy()), board.copy(),
                    currentPlayer, otherPlayer, rating);
            return copy;
        }

        public boolean applyAndRateMove() {
            // call rate before apply as it needs the unchanged board
            rateMove();
            board.movePiece(move);
            if (getBoard().getKing(currentPlayer) == null) {
                return true;
            } else {
                return false;
            }
        }

        private void rateMove() {
            Point dest = move.getDestination();
            Field destField = board.getFields()[dest.getX()][dest.getY()];

            int value = 0;
            if (destField.hasPiece()) {
                PieceType type = destField.getPiece().getType();
                switch (type) {
                case PAWN:
                    value = 1;
                    break;
                case KNIGHT:
                    value = 3;
                    break;
                case BISHOP:
                    value = 3;
                    break;
                case ROOK:
                    value = 5;
                    break;
                case QUEEN:
                    value = 9;
                    break;
                case KING:
                    value = 111;
                    break;
                default:
                    value = 0;
                }
            }

            if (currentPlayer == pieceTaker) {
                this.rating += value;
            } else {
                this.rating -= value;
            }
        }

        public Player getOtherPlayer() {
            return otherPlayer;
        }

        public Player getCurrentPlayer() {
            return currentPlayer;
        }

        public Board getBoard() {
            return board;
        }

        public int getRating() {
            return rating;
        }

        public void setRating(int r) {
            this.rating = r;
        }

        public Move getMove() {
            return originalMove;
        }
    }

    private class ComparatorNode implements Comparator<Node> {
        @Override
        public int compare(Node t, Node t1) {
            return t1.getRating() - t.getRating();
        }
    }
}

```
> 11 votes

# Answer
# Three Move Monte

This guy looks at the next three moves (mine,yours,mine) and picks the move that gives the highest score. If there are more than 60 available moves, it will just choose a random 60 on each step. Of course, if any single move (out of all of them, not the chosen 60) will end the game, I'll take it immediately.

To score a board, I give each piece a base value. It's then modified by the piece's mobility, how many (and which) pieces it threatens, and how many pieces threaten it.

Of course, mobile kings are not necessarily good in the early game, so I special case the values for them a bit.

This runs fairly quickly, and can finish a game with the current crop in 3-4 seconds. It looks like there's room to bump it up a couple moves if need be.

**update:**

* adding scoring for "control the center" in early game
* special case king scores
* fixed a double-scoring bug in move simulation

```
package player;

import java.util.*;
import pieces.*;
import controller.*;

public class ThreeMoveMonte extends Player{
    final static int TOSSES = 60;
    Random rand = new Random();

    @Override
    public Move getMove(Board board, Player them){
        List<Move> moves = getMoves(board, getTeam(), 0);
        for(Move move : moves)
            if(gameOver(apply(board, move)))
                return move;

        moves = getMoves(board, getTeam(), TOSSES);
        int highest = Integer.MIN_VALUE;
        Move best = moves.get(0);
        for(Move move : moves){
            Board applied = apply(board, move);
            Move oBest = getBestMove(applied, getOpponent(getTeam()), 0);
            applied = apply(applied, oBest);
            if(!gameOver(applied)){
                Move lBest = getBestMove(applied, getTeam(), TOSSES);
                Board lApplied = apply(applied, lBest);
                int score = eval(lApplied, getTeam());
                if(score > highest){
                    best = move;
                    highest = score;
                }
            }
        }
        return best;
    }

    boolean gameOver(Board board){
        Field[][] fields = board.getFields();
        int kings = 0;
        for(int x=0;x<fields.length;x++)
            for(int y=0;y<fields[x].length;y++){
                Piece p = fields[x][y].getPiece();
                if(p!=null&&p.getType().equals(PieceType.KING))
                    kings++;
            }
        return kings==2?false:true;
    }

    Move getBestMove(Board board, Color color, int breadth){
        int highest = Integer.MIN_VALUE;
        Move best = null;
        List<Move> moves = getMoves(board, color, breadth);
        for(Move move : moves){
            Board applied = apply(board, move);
            int score = eval(applied, color);
            if(score > highest){
                best = move;
                highest = score;
            }
        }
        return best;
    }

    List<Move> getMoves(Board board, Color color, int breadth){
        List<Move> moves = new ArrayList<Move>();
        Set<Piece> pieces = getPiecesOfColor(board, color);
        for(Piece piece : pieces){
            Set<Point> points = piece.getValidDestinationSet(board);
            for(Point point : points){
                moves.add(new Move(piece, point));
            }
        }
        Collections.shuffle(moves);
        if(breadth > 0)
            while(moves.size()>breadth)
                moves.remove(moves.size()-1);
        return moves;
    }

    Board apply(Board board, Move move){
        Board copy = board.copy();
        Piece piece = move.getPiece().copy();
        Point src = piece.getPos();
        Point dest = move.getDestination();
        if(piece.getType().equals(PieceType.PAWN)){
            if(piece.getTeam().equals(Color.WHITE)&&dest.getY()==7 ||
                    piece.getTeam().equals(Color.BLACK)&&dest.getY()==0)
                piece = new Queen(piece.getTeam(), piece.getPos());
        }
        piece.setPos(dest);
        copy.getFields()[src.getX()][src.getY()].setPiece(null);
        copy.getFields()[dest.getX()][dest.getY()].setPiece(piece);
        return copy;
    }

    int eval(Board board, Color color){
        int score = 0;
        List<Piece> mine = getPieces(board);
        Field[][] fields = board.getFields();
        for(Piece piece : mine){
            int value = getValueModified(board, piece);

            Set<Point> moves = piece.getValidDestinationSet(board);
            for(Point move : moves){
                int x = move.getX(),y=move.getY();
                if(fields[x][y].hasPiece()){
                    Piece other = fields[x][y].getPiece();
                    if(!other.getTeam().equals(getTeam()))
                        value += getValue(other) / (other.getType()==PieceType.KING ? 1 : 30);
                }
                if(mine.size()>10)
                    value += (int)(8 - (Math.abs(3.5-x) + Math.abs(3.5-y)));
            }

            int attackerCount = getAttackers(board, piece, false).size();
            if(piece.getType()==PieceType.KING){
                if(attackerCount > 0)
                    value = -value;
            } else {
                for(int i=0;i<attackerCount;i++)
                    value = (value * 90) / 100;
            }
            score += value;
        }

        return score;
    }

    Set<Piece> getPiecesOfColor(Board board, Color color){
        Field[][] fields = board.getFields();
        Set<Piece> out = new HashSet<Piece>();
        for(int x=0;x<fields.length;x++){
            for(int y=0;y<fields[x].length;y++){
                Piece p = fields[x][y].getPiece();
                if(p!=null&&p.getTeam().equals(color))
                        out.add(p);
            }
        }
        return out;
    }

    Set<Piece> getAttackers(Board board, Piece piece, boolean all){
        Set<Piece> out = new HashSet<Piece>();
        Color color = piece.getTeam();
        Set<Piece> others = getPiecesOfColor(board, getOpponent(color));
        if(all)
            others.addAll(getPiecesOfColor(board, color));
        for(Piece other : others){
            if(other.getValidDestinationSet(board).contains(piece.getPos()))
                out.add(other);
        }
        return out;
    }

    Color getOpponent(Color color){
        return color.equals(Color.BLACK)?Color.WHITE:Color.BLACK;
    }

    int[] pieceValues = {100, 500, 300, 320, 880, 1500};
    int getValue(Piece piece){
        return pieceValues[piece.getType().ordinal()];
    }

    int[] maxMoves = {3, 14, 8, 13, 27, 8};
    int getValueModified(Board board, Piece piece){
        int moves = piece.getValidDestinationSet(board).size();
        double value = getValue(piece)*.9;
        double mod = getValue(piece)*.1*((double)moves/maxMoves[piece.getType().ordinal()]);
        if(piece.getType()==PieceType.KING)
            if(getPieces(board).size()>10)
                mod = -mod;

        return (int)(value + mod);
    }
}

```
> 8 votes

# Answer
# Not an answer, but a simulation to help

I added a new class: GamePanel and edited Game and Controller

~~It isn't very pretty...yet.~~ Did you know Unicode had chess characters!?!? (totally awesome!)
By the way, you need UTF-8 for these characters to show. It worked for me, but not sure how it will work on other operating systems.

Fixed end of games bug (thanks to tim for pointing that out).

GamePanel:

```
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GamePanel extends JPanel{
    private static final long serialVersionUID = 1L;
    JFrame container;
    Board currentBoard;
    Game currentGame;
    ArrayList<Game> games;
    public GamePanel(ArrayList<Game> Games){
        games = Games;
        currentGame = games.get(0);
        currentBoard = currentGame.allBoards.get(0);
        container = new JFrame();
        container.setSize(new Dimension(500,500));
        container.setMinimumSize(new Dimension(150,150));
        this.setMinimumSize(new Dimension(150,150));
        JButton skipButton = new JButton("skip game");
        skipButton.addMouseListener(new MouseListener(){
            @Override
            public void mouseClicked(MouseEvent arg0) {
                nextGame();
            }
            @Override
            public void mouseEntered(MouseEvent arg0) {
                // TODO Auto-generated method stub

            }
            @Override
            public void mouseExited(MouseEvent arg0) {
                // TODO Auto-generated method stub

            }
            @Override
            public void mousePressed(MouseEvent arg0) {
                // TODO Auto-generated method stub

            }
            @Override
            public void mouseReleased(MouseEvent arg0) {
                // TODO Auto-generated method stub

            }

        });
        JButton undoButton = new JButton("go back");
        undoButton.addMouseListener(new MouseListener(){
            @Override
            public void mouseClicked(MouseEvent e) {
                unStep();
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                // TODO Auto-generated method stub

            }
            @Override
            public void mouseExited(MouseEvent e) {
                // TODO Auto-generated method stub

            }
            @Override
            public void mousePressed(MouseEvent e) {
                // TODO Auto-generated method stub

            }
            @Override
            public void mouseReleased(MouseEvent e) {
                // TODO Auto-generated method stub

            }

        });
        JButton continueButton = new JButton("continue");
        undoButton.setSize(40,40);
        skipButton.setSize(40,40);
        continueButton.setSize(40,40);
        continueButton.addMouseListener(new MouseListener(){
            @Override
            public void mouseClicked(MouseEvent arg0) {
                step();
            }
            @Override
            public void mouseEntered(MouseEvent arg0) {
            }
            @Override
            public void mouseExited(MouseEvent arg0) {
            }
            @Override
            public void mousePressed(MouseEvent arg0) {
            }
            @Override
            public void mouseReleased(MouseEvent arg0) {
            }
        });
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout());
        buttonPanel.add(continueButton);
        buttonPanel.add(undoButton);
        buttonPanel.add(skipButton);
        container.setLayout(new BorderLayout());
        container.getContentPane().add(this,BorderLayout.CENTER);
        container.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        container.getContentPane().add(buttonPanel,BorderLayout.NORTH);
        container.setTitle("White: " + currentGame.players[0].getClass().getSimpleName()
                + " vs "+ "Black: " + currentGame.players[1].getClass().getSimpleName());
        container.setVisible(true);
        container.invalidate();
        container.repaint();
    }
    private void unStep(){
        if(currentBoard!=currentGame.allBoards.get(0)){
            currentBoard=currentGame.allBoards.get(currentGame.allBoards.indexOf(currentBoard)-1);
        }
        container.invalidate();
        container.repaint();
    }
    private void unGame(){
        if(currentGame != games.get(0)){
            currentGame = games.get(games.indexOf(currentGame)-1);
            currentBoard = currentGame.allBoards.get(0);
        }
        container.invalidate();
        container.repaint();
    }
    private void step(){
        if(currentGame.allBoards.indexOf(currentBoard)==currentGame.allBoards.size()-1){
            nextGame();
        }
        else{
            currentBoard = currentGame.allBoards.get(currentGame.allBoards.indexOf(currentBoard)+1);
        }
        container.invalidate();
        container.repaint();
    }
    private void nextGame(){
        container.setTitle("White: " + currentGame.players[0].getClass().getSimpleName()
                + " vs "+ "Black: " + currentGame.players[1].getClass().getSimpleName());
        if(currentGame != games.get(games.size()-1)){
            currentGame = games.get(games.indexOf(currentGame)+1);
        }
        else{
            //games complete
            container.dispose();
        }
        currentBoard = currentGame.allBoards.get(0);
        container.invalidate();
        container.repaint();
    }
    @Override
    public void paintComponent(Graphics g){
        if(getWidth()>150 && getHeight() > 150){
        int leftBounds,topBounds,width,height;
        topBounds = 50;
        leftBounds = 50;
        if(getWidth() > getHeight()){
            width = (int) (getHeight()-100);
            height = (int) (getHeight()-100);
        }
        else{
            width = (int) (getWidth()-100);
            height = (int) (getWidth()-100);
        }
        //draw grid
        java.awt.Color dark = new java.awt.Color(128, 78, 41);
        java.awt.Color light = new java.awt.Color(250, 223, 173);
        Field[][] feilds = currentBoard.getFields();
        for(int x = leftBounds; x < leftBounds+width-width/8; x+=width/8){
            for(int y = topBounds; y < topBounds+height-height/8; y+=height/8){
                int xPos = (int)Math.round(((double)(x-leftBounds)/(double)width)*8);
                int yPos = (int)Math.round(((double)(y-topBounds)/(double)height)*8);
                String piece = "";
                java.awt.Color stringColor = java.awt.Color.black;
                if(feilds[xPos][yPos].hasPiece()){
                    piece = getPiece(feilds[xPos][yPos].getPiece());
                    if(feilds[xPos][yPos].getPiece().getTeam()==Color.WHITE){stringColor = java.awt.Color.WHITE;}
                }
                if(yPos % 2 == 1){
                    if(xPos % 2 == 1){
                        g.setColor(dark);
                        g.fillRect(x, y, width/8, height/8);
                    }
                    else{
                        g.setColor(light);
                        g.fillRect(x, y, width/8, height/8);
                    }
                }
                else{
                    if(xPos % 2 == 1){
                        g.setColor(light);
                        g.fillRect(x, y, width/8, height/8);
                    }
                    else{
                        g.setColor(dark);
                        g.fillRect(x, y, width/8, height/8);
                    }
                }
                g.setColor(java.awt.Color.black);
                g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, width/8));
                g.drawString(piece, x, y+width/8);
            }
        }
        }

    }
    public String getPiece(Piece p){
        if(p.getTeam() == Color.WHITE){
            if(p.getType() == PieceType.BISHOP){return "\u2657";}
            if(p.getType() == PieceType.PAWN){return "\u2659";}
            if(p.getType() == PieceType.KING){return "\u2654";}
            if(p.getType() == PieceType.QUEEN){return "\u2655";}
            if(p.getType() == PieceType.ROOK){return "\u2656";}
            if(p.getType() == PieceType.KNIGHT){return "\u2658";}
        }
        else{
            if(p.getType() == PieceType.BISHOP){return "\u265D";}
            if(p.getType() == PieceType.PAWN){return "\u265F";}
            if(p.getType() == PieceType.KING){return "\u265A";}
            if(p.getType() == PieceType.QUEEN){return "\u265B";}
            if(p.getType() == PieceType.ROOK){return "\u265C";}
            if(p.getType() == PieceType.KNIGHT){return "\u265E";}
        }
        return p.toString();
    }

}

```

Game:

```
import java.util.ArrayList;

public class Game {
    private static final int MAX_TURNS_WITHOUT_CAPTURES = 100; //=50, counts for both teams
    private static final int MAX_MILLISECONDS = 2000;
    private Board board;
    Player[] players = new Player[2];
    private int turnsWithoutCaptures = 0;
    private boolean draw = false;
    ArrayList<Board> allBoards = new ArrayList<Board>();

    public Game(Player player1, Player player2) {
        board = new Board();
        board.initialize();
        players[0] = player1;
        players[0].setTeam(Color.WHITE);
        players[1] = player2;
        players[1].setTeam(Color.BLACK);
        allBoards.add(board.copy());
    }
    int run() {
        int i = 0;
        while (!gameOver()) {
            if (!turnAvailable(players[i])) {
                draw = true;
            } else {
                makeTurn(players[i], players[(i+1) % 2]);
                i = (i + 1) % 2;
            }
        }
        if (loses(players[0]) && !loses(players[1])) {
            return Controller.LOSE_POINTS;
        } else if (loses(players[1]) && !loses(players[0])) {
            return Controller.WIN_POINTS;
        } else {
            return Controller.DRAW_POINTS;
        }
    }

    private boolean loses(Player player) {
        if (player.isDisqualified() || board.getKing(player) == null) {
            return true;
        }
        return false;
    }

    // player can make a turn
    private boolean turnAvailable(Player player) {
        for (Piece piece : player.getPieces(board)) {
            if (piece.getValidDestinationSet(board).size() > 0) {
                return true;
            }
        }
        return false;
    }

    private void makeTurn(Player player, Player enemy) {
        player.setCheck(board.isCheck(player, enemy));
        enemy.setCheck(board.isCheck(enemy, player));
        try {
            long start = System.currentTimeMillis();

            Move move = player.getMove(board.copy(), enemy);
            if ((System.currentTimeMillis() - start) > MAX_MILLISECONDS) {
                player.setDisqualified();
            }
            if (move.isValid(board, player)) {
                if (board.movePiece(move) || move.getPiece().getType() == PieceType.PAWN) {
                    turnsWithoutCaptures = 0;
                } else {
                    turnsWithoutCaptures++;
                }
            } else {
                player.setDisqualified(); //invalid move
            }
        } catch (Exception e) {
            player.setDisqualified();
            e.printStackTrace();
            System.out.println("Exception while moving " + player);
        }
        allBoards.add(board.copy());
    }
    public boolean gameOver() {
        for (Player player : players) {
            if (player.isDisqualified() || board.getKing(player) == null
                    || turnsWithoutCaptures >= MAX_TURNS_WITHOUT_CAPTURES || draw) {
                return true;
            }
        }
        return false;
    }
}

```

Controller:

```
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import players.*;

public class Controller {
    public static final int WIN_POINTS = 3;
    public static final int DRAW_POINTS = 1;
    public static final int LOSE_POINTS = 0;
    private static final int GAMES_PER_PAIR = 10;
    private final Class[] classes = {StretchPlayer.class,TestPlayer.class};
    private final Map<Class<? extends Player>, Integer> scores = new HashMap<Class<? extends Player>, Integer>();

    public static void main(String... args) {
        new Controller().generateResult();
    }

    public Controller() {
        for (Class player : classes) {
            scores.put(player, 0);
        }
    }
    ArrayList<Game> games = new ArrayList<Game>();
    private void generateResult() {

        for (int i = 0; i < classes.length - 1; i++) {
            for (int j = i + 1; j < classes.length; j++) {
                for (int k = 0; k < GAMES_PER_PAIR; k++) {
                    runGame(classes[i], classes[j], k>=GAMES_PER_PAIR);
                }
            }
        }
        GamePanel panel = new GamePanel(games);
        printScores();
    }

    private void runGame(Class class1, Class class2, boolean switchSides) {
        if (switchSides) { //switch sides
            Class tempClass = class2;
            class2 = class1;
            class1 = tempClass;
        }
        try {
            Player player1 = (Player) class1.newInstance();
            Player player2 = (Player) class2.newInstance();
            Game game = new Game(player1, player2);
            games.add(game);
            int result = game.run();
            addResult(class1, result, false);
            addResult(class2, result, true);
        } catch (Exception e) {
            System.out.println("Error in game between " + class1 + " and " + class2);
        }
    }

    private void addResult(Class player, int result, boolean reverse) {
        if (reverse) {
            if (result == WIN_POINTS) {
                result = LOSE_POINTS;
            } else if (result == LOSE_POINTS) {
                result = WIN_POINTS;
            }
        }
        int newScore = scores.get(player) + result;
        scores.put(player, newScore);
    }

    private void printScores() {
        int bestScore = 0;
        Class currPlayer = null;
        int place = 1;

        while (scores.size() > 0) {
            bestScore = 0;
            currPlayer = null;
            for (Class player : scores.keySet()) {
                int playerScore = scores.get(player);
                if (scores.get(player) >= bestScore) {
                    bestScore = playerScore;
                    currPlayer = player;
                }
            }
            System.out.println(String.format("%02d", place++) + ") " + currPlayer + ": " + bestScore);
            scores.remove(currPlayer);
        }
    }
}

```
> 5 votes

# Answer
## AlphaBeta

Sorry, for having only morphed and fused code from other internet sources into this JAVA code. But it beats all other opponents (including PieceMaker) ... so far.

* No move ordering.
* No quiescence search.
* No position evaluation.
* Just raw brute force of alpha beta search.
* Uses iterative deepening only for time management.

And sorry, for playing so machine boring.

```
package player;

import java.util.Random;
import controller.*;

public class AlphaBeta extends Player {
    private static final int INFINITY = Integer.MAX_VALUE;
    private static final int MAXTIME = 1800; // max time for evaluation
    private static final Random random=new Random();
    private static int seed=1;

    private long time; // time taken this turn
    private int iterativeDepth;
    private Player myOpponent;
    private int best, candidate;

    @Override
    public Move getMove(Board root, Player min) {
        time=System.currentTimeMillis();
        seed++; myOpponent=min; best=0;
        iterative_deepening(root);
        return allMoves(root, this)[best];
    }

    private void iterative_deepening(Board root) {
        try {
            for (iterativeDepth = 2;; iterativeDepth++) {
                alphaBeta(root, -INFINITY, +INFINITY, iterativeDepth, this, myOpponent);
                best=candidate;
            }
        } catch (InterruptedException e) {}
    }

    //http://chessprogramming.wikispaces.com/Alpha-Beta
    private int alphaBeta(Board root, int alpha, int beta, int d, Player max, Player min) throws InterruptedException {
        if ((System.currentTimeMillis() - time) > MAXTIME)  throw new InterruptedException();
        if (d==0 || root.getKing(max) == null) return evaluate(root, d);
        Move[] allMoves = allMoves(root, max);
        Move move;
        for (int m=0; (move = allMoves[m])!=null; m++) {
            Board board = root.copy();
            board.movePiece(move);
            int score = -alphaBeta(board, -beta, -alpha, d - 1, min, max);
            if (score >= beta)
                return beta; // fail hard beta-cutoff
            if (score > alpha) {
                alpha = score; // alpha acts like max in MiniMax
                if (d == iterativeDepth) candidate = m;
            }
        }
        return alpha;
    }

    private int evaluate(Board board, int d) {
        int minmax=2*((iterativeDepth-d)&1)-1;
        int value = 0, king=0;
        Field[][] field = board.getFields();
        for (int x = 0; x < 8; x++) {
            for (int y = 0; y < 8; y++) {
                Piece piece = field[x][y].getPiece();
                if (piece==null) continue;

                int sign=(piece.getTeam()==getTeam())?-minmax:minmax;
                switch (piece.getType()) {
                case PAWN:      value += 1*sign; break;
                case KNIGHT:    value += 3*sign; break;
                case BISHOP:    value += 3*sign; break;
                case ROOK:      value += 5*sign; break;
                case QUEEN:     value += 9*sign; break;
                case KING:      king  += (100-(iterativeDepth-d))*sign; break;
                default: // value += 0;
                }
            }
        }
        return king==0?value:king;
    }

    private Move[] allMoves(Board board, Player player) {
        random.setSeed(seed);
        Move[] move = new Move[200];
        int m=0;
        for (Piece piece : player.getPieces(board)) {
            for (Point point: piece.getValidDestinationSet(board)) {
                // shuffle
                int r=random.nextInt(++m);
                move[m-1]=move[r];
                move[r]=new Move(piece.copy(), point);
            }
        }
        return move;
    }
}

```
> 5 votes

# Answer
## DontThinkAhead

This 'AI' doesn't like thinking ahead. If it sees that it can catch an enemy piece, it will do so immediately. If it cannot, it will just move a piece at random.

It is slightly better than `SimplePlayer` and `TestPlayer` and I mainly wrote it to get a feel for the controller code and have something to test against.

```
package player;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Random;

import controller.*;
/**
 * Thinking ahead is hard, so lets not do it.
 */
public class DontThinkAhead extends Player {

    @Override
    public Move getMove(Board board, Player enemy) {
        List<Move> moves = new ArrayList<>();
        List<Piece> pieces = this.getPieces(board);
        for (Piece piece : pieces) {
            Point[] destinations = piece.getValidDestinations(board);
            for (Point point : destinations) {
                moves.add(new Move(piece, point));
            }
        }

        List<Node> ratedMoves = new ArrayList<>();
        for (Move move : moves) {
            Point dest = move.getDestination();
            Field destField = board.getFields()[dest.getX()][dest.getY()];

            if (destField.hasPiece()) {
                int rating = 0;
                PieceType type = destField.getPiece().getType();
                switch (type) {
                case PAWN:
                    rating = 1;
                    break;
                case KNIGHT:
                    rating = 3;
                    break;
                case BISHOP:
                    rating = 3;
                    break;
                case ROOK:
                    rating = 5;
                    break;
                case QUEEN:
                    rating = 9;
                    break;
                case KING:
                    rating = 9999;
                    break;
                default:
                    rating = 0;
                }
                ratedMoves.add(new Node(move, rating));
            }
        }

        if (!ratedMoves.isEmpty()) {
            Collections.sort(ratedMoves, new ComparatorNode());
            return ratedMoves.get(0).getMove();
        } else {
            // no good move possible, return random move
            return moves.get(new Random().nextInt(moves.size()));
        }
    }

    private class Node {
        private Move move;
        private int rating;

        public Node(Move move, int rating) {
            this.move = move;
            this.rating = rating;
        }

        public int getRating() {
            return rating;
        }

        public Move getMove() {
            return move;
        }
    }

    private class ComparatorNode implements Comparator<Node> {

        @Override
        public int compare(Node t, Node t1) {
            return t1.getRating() - t.getRating();
        }
    }
}

```
> 4 votes

# Answer
# SimplePlayer

This player just makes sure he uses valid moves, but otherwise is pretty dumb.

```
package player;

import java.util.List;
import controller.*;

public class SimplePlayer extends Player {

    @Override
    public Move getMove(Board board, Player enemy) {
        //get all pieces of this player
        List<Piece> pieces = this.getPieces(board);
        for (Piece piece : pieces) {
            Point[] destinations = piece.getValidDestinations(board);
            if (destinations.length > 0) {
                return new Move(piece, destinations[0]);
            }
        }

        //should never happen, because the game is over then
        return null;
    }

}

```
> 2 votes

# Answer
# Cheese

Yes, you read it right. A block of cheese, playing chess.

## Algorithm

The cheese checks all possible moves and scores them accordingly. He (the cheese, and yes it's a male) uses the following guide to scoring his choices :

### Eating

* King = **OVER 9000!!!!!!!!!!**
* Queen = 18
* Rook = 10
* Bishop = 6
* Knight = 6
* Pawn = 2

### Risk of getting eaten

* King = **UNDER -9000!!!!!!!!!!!**
* Queen = -16
* Rook = -8
* Bishop = -5
* Knight = -5
* Pawn = 0

### Chance of eating next turn

* King = 5
* Queen = 3
* Rook = 2
* Bishop = 1
* Knight = 1
* Pawn = 0

## Pending Improvements

* NOT ENOUGH SWAG (going to check on this possibility soon)
* I checked my time and it seems that I run in 0-1 milliseconds. I think I can be more aggressive with my algorithms then.

## Bugs fixed

* When checking for scores for possible targets to eat, I counted my own units. Now, I'm only scoring if I can eat an **enemy piece**.

```
package player;

import pieces.Queen;
import controller.*;

public class Cheese extends Player {
    private final int[] eatingPriorities = { 9999, 18, 10, 6, 6, 2, 0 };
    private final int[] gettingEatenPriorities = { -9000, -16, -8, -5, -5, 0, 0 };
    private final int[] chanceToEatPriorities = {5,3,2,1,1,0,0};

    @Override
    public Move getMove(Board board, Player enemy) {
        int maxScore = -10000;
        Move bestMove = null;

        int score = 0;

        Field[][] field = board.getFields();
        Field fieldDest;

        // get best move
        for (Piece myPiece : this.getPieces(board)) {
            for (Point possibleDest : myPiece.getValidDestinationSet(board)) {
                score=0;
                fieldDest = field[possibleDest.getX()][possibleDest.getY()];

                //if you're eating an enemy piece, SCORE!
                if(fieldDest.hasPiece() && fieldDest.getPiece().getTeam()!=this.getTeam()){
                    score += eatingPriorities[getPriorityIndex(fieldDest.getPiece().getType())];
                }
                score+=getAftermoveRisk(board, enemy, new Move(myPiece, possibleDest));
                if (maxScore < score) {
                    maxScore = score;
                    bestMove = new Move(myPiece,possibleDest);
                }
            }
        }

        return bestMove;
    }

    private int getAftermoveRisk(Board board, Player enemy, Move move){
        int gettingEatenRisk=0, chanceToEatScore=0;
        Field[][] simField;
        Field field;
        Board simBoard = board.copy();

        simField = simBoard.getFields();
        this.simulateMovePiece(simField, move);

        //gettingEaten risk
        for (Piece enemyPiece : enemy.getPieces(simBoard)) {
            for (Point possibleDest : enemyPiece.getValidDestinationSet(simBoard)) {
                field = simField[possibleDest.getX()][possibleDest.getY()];

                //if it's my piece that's in the line of fire, increase gettingEatenRisk
                if(field.hasPiece() && field.getPiece().getTeam()==this.getTeam()){
                    gettingEatenRisk += gettingEatenPriorities[getPriorityIndex(field.getPiece().getType())];
                }
            }
        }

        //chanceToEat score
        for (Piece myPiece : this.getPieces(simBoard)) {
            for (Point possibleDest : myPiece.getValidDestinationSet(simBoard)) {
                field = simField[possibleDest.getX()][possibleDest.getY()];

                //if it's their piece that's in the line of fire, increase chanceToEatScore
                if(field.hasPiece() && field.getPiece().getTeam()!=this.getTeam()){
                    chanceToEatScore += chanceToEatPriorities[getPriorityIndex(field.getPiece().getType())];
                }
            }
        }

        return gettingEatenRisk + chanceToEatScore;
    }

    // Copied and edited from Board.movePiece
    public void simulateMovePiece(Field[][] fields, Move move) {
        Piece piece = move.getPiece();
        Point dest = move.getDestination();
        if (!dest.isOutside()) {
            // upgrade pawn
            if (piece.getType() == PieceType.PAWN && (dest.getY() == 0 || dest.getY() == 7)) {
                fields[dest.getX()][dest.getY()].setPiece(new Queen(piece.getTeam(), dest));
            } else {
                fields[dest.getX()][dest.getY()].setPiece(piece);
            }
            //remove piece on old field
            fields[piece.getPos().getX()][piece.getPos().getY()].setPiece(null);
        }
    }

    private int getPriorityIndex(PieceType type) {
        int index = 0;
        switch (type) {
        case KING:
            index = 0;
            break;
        case QUEEN:
            index = 1;
            break;
        case ROOK:
            index = 2;
            break;
        case BISHOP:
            index = 3;
            break;
        case KNIGHT:
            index = 4;
            break;
        case PAWN:
            index = 5;
            break;
        default:
            index = 6;
        }
        return index;
    }

}

```
> 2 votes

---
Tags: king-of-the-hill, chess, java
---


title: Tetrahedron Surface Area

text:
# Question
Title: Tetrahedron Surface Area
## The challenge

This challenge is very straightforward. Given four 3-dimensional points, calculate the surface area of the tetrahedron that they form. This is , so shortest code wins. Standard loopholes apply, with the added stipulation that any built-in function to do this task given four points is prohibited.

You can assume all four points will be distinct, and will be given via STDIN, 1 point per line. Each point will consist of three 16-bit unsigned integers. The exact format of each point can be modified if it makes things easier, such as three space separated integers. Having each point on a separate line is mandatory however. Output should be through STDOUT, to at least 2 decimal places.

For those of you who do not know, a tetrahedron is a 3-d solid, formed by 4 triangular faces.

### Example

```
# input (format is up to you, see clarification above)
[23822, 47484, 57901]
[3305, 23847, 42159]
[19804, 11366, 14013]
[52278, 28626, 52757]

# output
2932496435.95

```

Please leave a note if you notice my math is wrong.

# Answer
## Python, 198 178 161 chars

```
V=eval('input(),'*4)
A=0
for i in range(4):F=V[:i]+V[i+1:];a,b,c=map(lambda e:sum((a-b)**2for a,b in zip(*e)),zip(F,F[1:]+F));A+=(4*a*b-(a+b-c)**2)**.5
print A/4

```

The input format is as given in the question.

It calculates the length of the edges adjacent to each of the faces and then uses Heron's formula.
> 5 votes

# Answer
## APL, 59

```
f←{+.×⍨⊃1 2-.⌽(⊂⍵)×1 2⌽¨⊂⍺}
.5×.5+.*⍨(f/2-/x),2f/4⍴x←⎕⎕⎕-⊂⎕

```

Works by calculating cross products

**Explanation**
The first line defines a function that takes two arguments (implicity named  and ), implicitly expects them to be numerical arrays of length 3, treat them as 3d vectors, and calculates the **squared** magnitude of their cross product.

```
                        ⊂⍺   # Wrap the argument in a scalar
                   1 2⌽¨     # Create an array of 2 arrays, by rotating `⊂⍺` by 1 and 2 places
             (⊂⍵)×           # Coordinate-wise multiply each of them with the other argument
        1 2-.⌽               # This is a shorthand for:
        1 2  ⌽               #   Rotate the first array item by 1 and the second by 2
           -.                #   Then subtract the second from the first, coordinate-wise
       ⊃                     # Unwrap the resulting scalar to get the (sorta) cross product
   +.×                       # Calculate the dot product of that...
      ⍨                      # ...with itself
f←{+.×⍨⊃1 2-.⌽(⊂⍵)×1 2⌽¨⊂⍺} # Assign function to `f`

```

The second line does the rest.

```
                         ⎕⎕⎕-⊂⎕ # Take 4 array inputs, create an array of arrays by subtracting one of them from the other 3
                       x←        # Assign that to x
                     4⍴          # Duplicate the first item and append to the end
                  2f/            # Apply f to each consecutive pair
            2-/x                 # Apply subtraction to consecutive pairs in x
          f/                     # Apply f to the 2 resulting arrays
         (f/2-/x),2f/4⍴x←⎕⎕⎕-⊂⎕ # Concatenate to an array of 4 squared cross products
   .5+.*⍨                        # Again a shorthand for:
   .5  *⍨                        #   Take square root of each element (by raising to 0.5)
     +.                          #   And sum the results
.5×                              # Finally, divide by 2 to get the answer

```
> 5 votes

# Answer
# Matlab/Octave 103

I assume the values to be stored in the variable `c`. This uses the fact that the area of a triangle is the half length of the cross product of two of its side vectors.

```
%input
[23822, 47484, 57901;
3305, 23847, 42159;
19804, 11366, 14013;
52278, 28626, 52757]

%actual code
c=input('');
a=0;
for i=1:4;
    d=c;d(i,:)=[];
    d=d(1:2,:)-[1 1]'*d(3,:);
    a=a+norm(cross(d(1,:),d(2,:)))/2;
end
a

```
> 4 votes

# Answer
# Python 3, ~~308 298 292 279 258~~ 254

```
from itertools import*
def a(t,u,v):w=(t+u+v)/2;return(w*(w-t)*(w-u)*(w-v))**.5
z,x,c,v,b,n=((lambda i,j:(sum((i[x]-j[x])**2for x in[0,1,2]))**.5)(x[0],x[1])for*x,in combinations([eval(input())for i in">"*4],2))
print(a(z,x,v)+a(z,c,b)+a(b,v,n)+a(x,c,n))

```

This uses:

* The Pythagorean Theorem (in 3D) to work out the length of each line
* Heron's Formula to work out the area of each triangle
> 3 votes

# Answer
# Mathematica ~~168~~ 154

This finds the lengths of the edges of the tetrahedron and uses Heron's formula to determine the areas of the faces.

```
t = Subsets; p = Table[Input[], {4}];
f@{a_, b_, c_} := Module[{s = (a + b + c)/2}, N[Sqrt[s (s - #) (s - #2) (s -#3)] &[a, b, c], 25]]
  Tr[f /@ (EuclideanDistance @@@ t[#, {2}] & /@ t[p, {3}])]

```

---

There is a more direct route that requires only **60 chars**, but it violates the rules insofar as it computes the area of each face with a built-in function, `Area`:

```
p = Table[Input[], {4}];
N[Tr[Area /@ Polygon /@ Subsets[p, {3}]], 25]

```
> 2 votes

# Answer
## Sage – 103

```
print sum((x*x*y*y-x*y*x*y)^.5for x,y in map(differences,Combinations(eval('vector(input()),'*4),3)))/2

```

The input-reading part is adapted from Keith Randall’s answer.
> 1 votes

# Answer
## Python - 260

I'm not sure what the etiquette on posting answers to your own questions is, but her is my solution, which I used to verify my example, golfed:

```
import copy,math
P=[input()for i in"1234"]
def e(a, b):return math.sqrt(sum([(b[i]-a[i])**2 for i in range(3)]))
o=0
for j in range(4):p=copy.copy(P);p.pop(j);a,b,c=[e(p[i],p[(i+1)%3])for i in range(3)];s=(a+b+c)/2;A=math.sqrt(s*(s-a)*(s-b)*(s-c));o+=A
print o

```

It uses the same procedure as laurencevs.
> 0 votes

# Answer
# C, 303

Excluding unnecessary whitespace. However, there's still a lot of golfing to be done here (I will try to come back and do it later.) It's the first time I've declared a `for` loop in a `#define`. I've always found ways to minmalise the number of loops before.

I had to change from `float` to `double` to get the same answer as the OP for the test case. Before that, it was a round 300.

`scanf` works the same whether you separate your input with spaces or newlines, so you can format it into as many or as few lines as you like.

```
#define F ;for(i=0;i<12;i++)
#define D(k) (q[i]-q[(i+k)%12])
double q[12],r[12],s[4],p,n;

main(i){
  F scanf("%lf",&q[i])
  F r[i/3*3]+=D(3)*D(3),r[i/3*3+1]+=D(6)*D(6)
  F r[i]=sqrt(r[i])
  F i%3||(s[i/3]=r[(i+3)%12]/2),s[i/3]+=r[i]/2
  F i%3||(p=s[i/3]-r[(i+3)%12]),p*=s[i/3]-r[i],n+=(i%3>1)*sqrt(p)
  ;printf("%lf",n);
}

```
> 0 votes

---
Tags: code-golf, math, 3d
---


title: The Reaction Time Game

text:
# Question
Title: The Reaction Time Game
# Game

The game is simple. Test the user's response time by asking them to enter the correct value that is displayed on the screen in the shortest time possible. Each round of the game will be as follows:

> Show Value ----\> Get Response ----\> Check Response ----\> Report Response Time

# Example

```
ROUND ONE
---------
COMPUTER : G
USER     : G
CORRECT INPUT, TIME = 0.26 SECONDS

```

# Code

* You may use any language or program.
* Do not use third party libraries, except GUI libraries.
(as suggested by marinus)
* You may choose between CLI and GUI.

# Points

* +12 for the shortest code
* -2 for every byte after the 1024th byte
* +8 for GUI
* +8 for showing questions (eg: 4 + 2 = ?)
(rather than static values shown in the example above. There must be at least 10 questions.)
* +2 for random intervals between each round
* +4 for reporting average response time (in a set of 10 rounds)
* +4 for quickly vanishing questions/values
(questions/values stays on screen only for a short interval of time.
The vanish time must be less than or equal to 1 seconds.)

> You must, in your answer, calculate the total points you have scored. eg (+12 (-2x3) +4 = 10)

The answer with the most points wins.

# Answer
## JavaScript, ES6 ~~352 340~~ 335 bytes, Potential score : 2 + 8 + 12 + 4 + 4 + 8 = 38

```
<script>r=Math.random,s=setTimeout;T=N=0;a=_=>(S=s(_=>(C=eval(G.innerHTML=((k=~~(r()*5))+~~(r()*5))+'-'+k),t=new Date,R=s(_=>C=G.innerHTML=a(clearTimeout(S)),r()*1e3)),r()*2e3+1e3),'');document.onkeyup=E=>{clearTimeout(R);E.key==C&&++N&&(T+=(X=new Date-t))&&alert([X,N%10?'':T/10]);C=G.innerHTML=a(N%10||(T=0))};a()</script><a id='G'/>

```

or try this JSFiddle on latest Firefox.

Working:

1. Shows a random question in form of `X-Y` after a random interval of \[2,4\] seconds.
2. Waits for a keypress till a random time in an interval of \[1,2\] seconds, after which, clears the input and moves to step 1.
3. If correct number is pressed, alerts the time in *milliseconds*.
4. If this is the tenth (or rather every tenth) correct answer, show the average time in milliseconds for the last 10 correct answers after a comma.
5. Empties the input area, goes to Step 1 again.

Please comment if something is incorrect or if you have any doubts.
> 2 votes

# Answer
# JavaScript (E6) 305 bytes. Score 8+8+2+4=22

Rusty GUI, but GUI it is. Try in FireFox/FireBug console.
At the time shortest code, but I don't claim the 12 points. Waiting for some more answer.

```
(Q=i=>(
  i&&(t=r=x=y=0,msg=''),
  w=~new Date(),
  v=prompt(msg+'\nRound '+ ++r+': '+(a=1+t%9)+'+'+(b=1+(t>>4)%9)+'=?'),
  u=~new Date(),
  v-a-b?(++x,msg='Wrong'):(++y,msg='OK Time '+(p=w-u)/1000+' sec'),
  t+=p,
  r<10?setTimeout(Q,u%2000)
  :confirm('Wrong '+x+', OK '+y+' in Avg time '+(t/y/1000)+' sec\nRepeat?')&&Q(1)
))(1)

```
> 2 votes

# Answer
**Ruby (237)**

```
def measure_time(v)
  t = Time.now
  puts "Enter the value: #{v}"
  result = gets.chomp
  if result == v
    puts "CORRECT INPUT, TIME = #{(Time.now - t).to_f(2)} SECONDS"
  else
    puts "Incorrect"
  end
end

```
> 2 votes

# Answer
**WIP, Python, 366 bytes, Potential score : 8 + 4 = 12**

```
import msvcrt as x
import random as r
import time,os
t=0
while t<11:
    time.sleep(1)
    n=r.randint(1,4)
    m=r.randint(1,4)
    print(str(n)+"+"+str(m)+"?")
    time.sleep(.1)
    t1=time.clock()
    os.system('cls')
    c=x.getch()
    if int(c)==n+m:
        print("Rct time:"+str(time.clock()-t1))
    else:
        print("Wrong char")
    time.sleep(1)
    t+=1

```
> 1 votes

# Answer
# Kivy Application 983 bytes, 26 points (8+8+2+4+4)

I used Python's application framework, Kivy, to create a GUI, just under the 1024 byte penalty.

The game starts with a textbox. Once you click it, a question of the form `A+B` or `A*B`, where A,B are between 1 and 10, is shown. To have quick input the user's answer is read as soon as the length of text in the textbox is the same length as the length of the correct answer. For example, if `7*4` is shown, the user's input will be read as an answer once they have entered at least two characters. If the user enters the correct value their response time in milliseconds is shown, otherwise "W" is displayed. The user's input and the question will immediately be hidden, followed by the next question displayed after a random interval of time between 0 and 1 seconds. Every time the user inputs 10 correct responses their average response time is shown for those ten responses.

To run this code you will need a Python interpreter with the Kivy library, and you will want to place both the python file and the kv file in the same directory and name the kv file g.kv. Then you can run the python file as usual.

**Python File**

```
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.clock import Clock as K
from random import randint as R, random as Q
import time

class GApp(App):
    def build(s):
        g=G()
        K.schedule_interval(g.P, 0.01)
        return g

class G(Widget):
    def __init__(s):
        super(G, s).__init__()
        s.c=0
        s.t=10*[0]
        s.o=['+','*']

    def on_touch_up(s,t):
        s.U(0)

    def U(s,J):
        s.q.text=str(R(1,10))+s.o[R(0,1)]+str(R(1,10))
        s.i=int(round(time.time()*1000))

    def P(s,J):
        A=s.r
        B=s.q
        C=s.u
        if s.c==10:
            A.text+=";"+str(sum(s.t)/10)
            s.c=0
        try:
            S=str(eval(B.text))
        except:
            return

        if C.text!=S and len(C.text)>=len(S):
            A.text="W"
            B.text=""
            C.text=""
            K.schedule_once(s.U, Q())

        if C.text==str(S):
            s.t[s.c]=int(round(time.time()*1000))-s.i
            A.text=str(s.t[s.c])
            s.c+=1
            C.text=""
            B.text=""
            K.schedule_once(s.U,Q())
GApp().run()

```

**Kv File**

```
#:kivy 1.0.9
<G>:
    u:u
    r:r
    q:q
    Label:
        center:100,400
        text: "A"
    Label:
        center:100,300
        text: "Q"
    Label:
        id: q
        center:200,300
    TextInput:
        id: u
        center:200,400
    Label:
        id: r
        center:100,200

```
> 1 votes

# Answer
# JAVA: (8+8+2+4+4) = 26

Not going for shortest, just grabbing all bonus points first:

Code: (999 Bytes)

```
import java.awt.*;
import java.util.*;
import java.util.concurrent.*;
import javax.swing.*;

class Q
{
    public static void main( String[] z ) throws Exception
    {
        Random r = new Random();

        int v = 0;
        String x = "FIRST ROUND";

        ScheduledExecutorService e = Executors.newScheduledThreadPool( 1 );
        for( int i = 0; i < 10; ++i )
        {
            int a = r.nextInt( 10 );
            int b = r.nextInt( 10 );
            long s = System.currentTimeMillis();
            ScheduledFuture< ? > f = e.schedule( ( ) -> Window.getWindows()[ 0 ].dispose(), 3, TimeUnit.SECONDS );
            String c = JOptionPane.showInputDialog( x + "\n" + a + "+" + b + "=" );
            if( ( a + b + "" ).equals( c ) )
            {
                long t = System.currentTimeMillis() - s;
                x = "CORRECT :" + t + "ms";
                v += t / 10;
            }
            else
            {
                x = "WRONG";
                v += 300;
            }
            f.cancel( true );
            Thread.sleep( r.nextInt( 1000 ) );
        }
        e.shutdown();
        JOptionPane.showMessageDialog( null, "Average: " + v + "ms" );
    }
}

```
> 1 votes

# Answer
## APL(72), Score: 12+2+8=22

```
{a←?9⋄c←?9⋄b←⎕TS⋄⎕←a,'+',c⋄d←(⎕TS-b)×⎕=a+c⋄⎕←(5⌷d×60)+d[6]+7⌷d÷999⋄⎕DL(?⌊*9)÷*8}¨⍳⌊*9

```

Gets two random numbers between 1 and 9. Adds them together and asks the user the answer. If the answer is correct, it prints the reaction time in seconds. Else it prints 0. Repeats e^9=8103.08... times. Breaks when given a vector, a command or a variable name. But you could feed it ⌊\*1 (floor(e^1))and it would happily interpret it as 2. Gives a negative score if the answer is not given within the same hour because of the dumb system of APL timestamps.
> 0 votes

---
Tags: code-challenge
---


title: Get Out of the Turing Tarpit - EasyFlow

text:
# Question
Title: Get Out of the Turing Tarpit - EasyFlow
I've created a new language called "EasyFlow." Your task is to simplify writing BrainFlow programs by compiling EasyFlow to BrainFlow. That is, you take an EasyFlow program and output a BrainFlow program which does the same thing. EasyFlow is defined as follows:

* The program starts out with a list of variables. A variable is anything that matches `[a-zA-Z][a-zA-Z0-9]*`. The variables are separated by commas and the list is followed by a semicolon.
* The program then has zero or more statements. All statements are followed by a `;`. Each statement consists of
    + A print statement `print(<variable>);`
    + An input statement, which copies the next input byte into the variable: `input(<variable>);`.
    + An assignment: `<variable> = <expression>;`. An expression consists of an `<integer>` from 0 to 255 inclusive (but see bonuses for more).
    + An increment `<variable> += <expression>` or decrement `<variable> -= <expression>`.
    + Control statements
        - `if(<variable>) { <statement>*; };` An if statement, which has a body of one or more if statements. Notice the semicolon at the end of the if statement.
        - `while(<variable>) { <statement>*; };` A while statement.

Comments are denoted with `//` and, you must ignore everything for the rest of the line. Spaces can be put anywhere except between variables (so `a b` is invalid and not equivalent to `ab`), between integers, and between `input`s and `print`s. Invalid syntax/statements, however, is undefined behavior.

**Input**: Input can be taken from anywhere (file, HTML `<textarea>` element etc.) Example input (doubles the char code of the input and outputs it as a character):

```
// Define variables
inputNumber, total;
// Get input
input(inputNumber);
// Set total to inputNumber * 2
// Reduce inputNumber and add 2 to total until inputNumber is 0
while (inputNumber) {
    inputNumber -= 1;
    total += 2;
};
print(total);

```

**Output**: The output should be a valid BrainFlow program which does the same thing as the input program. However, you can use a shorthand notation `<command><number>` which indicates `<command>` repeated `<number>` times. This can only be applied to `+ - > <` commands. Note that this version of BrainFlow overflows numbers at 256, which is also the length of the tape. You do not have to worry about too many slots being taken up, the program is guaranteed to have less than or equal to 100 bytes as variables. In addition, there won't be anything extreme like `a[a[a[a ... repeat 50 times ]]]] = 6`.

```
[ The variable inputNumber is at location 0
    and the variable total is at location 1 ]
, Get input for inputNumber
[
        - Subtract 1
        > Move to location of total
        +2 Add two
        < Move to location of inputNumber
]
>. Print the number

```

**Bonuses**: There are a wide variety of bonuses you can earn. Your final score is your character count multiplied by all the bonuses that you earn. The bonuses are:

* *0.9*: Instead of invalid syntax/statements being undefined behavior, fail to compile, printing the line number of the invalid syntax. This means your program should fail to compile on `a b = 5;` or `c = 3 5;` or `prin t(a);`. (The error message can read `E:<line>`
* *0.9*: Allow declarations of arrays as `<variable>[<integer]`. All arrays must have a fixed length. Allow access from arrays using `<variable>[<expression>]`. Assigning `<variable> = <expression>` is an invalid statement if `<variable>` is an array. In addition `LEN(<variable>)` should return the (constant) length of `<variable>`.
* *0.7*: Allow `<expression>` to also be a `<variable>`. That is, the following should correctly compile: `a = b;`, `a[a[0]] = c;`, `b[a[a[b]]] = c;` and so on. (Of course, the array part only applies if you took that bonus).
    + These bonuses are obtainable after getting the previous bonus.
    + *0.7*: Allow `<expression>` to be addition and subtraction. That is, we have `<expression> + <expression>` or `<expression> - <expression>`.
    + *0.7*: Allow `<expression>` to include `==, !, &&, ||` operators
    + *0.6*: Allow `<expression>` to include `<, <=, >, >=` operators
    + *0.5*: Allow multiplication. This must follow the order of operations e.g. `<epxression> + <expression> * <expression>`.
* *0.00000000000001*: Compile C to BrainFlow. (Please don't actually do this)

Example with a few bonuses:

**Input**: (Calculates the last one-based index of a given number in the string "141592" or 0 if it doesn't exist).

```
pi[6], inputNumber, index, finalIndex; // An array with 6 slots and input number
pi[0] = 1;
pi[1] = 4;
pi[2] = 1;
pi[3] = 5;
pi[4] = 9;
pi[5] = 2;
input(inputNumber);
inputNumber -= 48; // Get inputNumber as a digit
index = LEN(pi); // evaluates to index = 6
while (index) {
    index -= 1;
    if (inputNumber == pi[index]) {
        finalIndex = index + 1;
        index = 0; // break the loop
    };
};
finalIndex += 48; // Hack to convert to character if finalIndex < 10
print(finalIndex);

```

You can find an interpreter for brainflow written in coffeescript here (along with the compiled version of the above program).

This is code golf. The answer with the lowest score wins.

Here is my attempt in ES6 javascript function at a whopping 561 characters if white space and comments are removed and with no bonuses:

```
// Defines a function called `compile`
compile = a => {
    h = a => {
        for (; a;) {
            // Create a copy of the input string
            var c = a;
            // Replace print statements with "."
            a = a[R](l, (a, d) => {
                e(d);
                b += ".";
                return ""
            })[R](m, (a, d) => { // Replace input statements with ","
                e(d);
                b += ",";
                return ""
            })[R](n, (a, d, c, g) => { // Replace equal to, increment, and decrements
                e(d);
                b += (c || "[-]+") + g;
                return ""
            })[R](p, (a, c, f, g) => { // Replace if and while loops
                e(f);
                b += "[";
                h(g);
                "if" == c ? b += "[>]^" : e(f);
                b += "]";
                return ""
            });
            // If the copy is the same as the input string
            // i.e. no changes were made in replacing, we've reached the end, break
            if (c == a) break
        }
    };
    // A function which moves to the variable location
    e = a => {
        // Go to zeroth position
        b += "[>]^";
        // f[a] is where the variable is located, move there
        b += ">" + f[a]
    };
    var b = "",
        R = "replace";
    // Remove comments and whitespace
    a = a[R](/\/\/.*?\n/g, "")[R](/[\s\n\t]+|/g, "");
    // Regexes
    var l = /^print\((.*?)\);/, // Print statements
        m = /^input\((.*?)\);/, // Input statements
        n = /^([a-zA-Z0-9]+)([\+\-]?)=(\d+);/, // Assignments
        p = // If and while statements
        /(if|while)\((.*?)\)\{(.*?)\};/,
        k = a.split(";")[0].split(","); // Get the variables
    a = a.slice(a.indexOf(";") + 1); // Strip variables from program
    // Assign each variable a unique index
    for (var f = {}, c = 0; c < k.length; ++c) f[k[c]] = c;
    // Compile
    h(a);
    return b // Return
};

```

I'm sure many people can do better!

# Answer
# Javascript ES6 - 366 bytes

Minified:

```
C=a=>(R="replace",e=a=>"[>]^>"+C[a],h=a=>a[R](/(if|while)\((.*?)\)\{(.*?)\};/g,(a,c,f,g)=>e(f)+"["+h(g)+(c[2]?e(f):"[>]^")+"]")[R](/print\((.*?)\);/g,(a,d)=>e(d)+".")[R](/input\((.*?)\);/g,(a,d)=>e(d)+",")[R](/([a-z\d]+)(\W?)=(\d+);/ig,(a,d,c,g)=>e(d)+(c||"[-]+")+g),[,k,a]=/(.*?);(.*)/.exec(a[R](/\/\/.*?\n/g,'')[R](/\s+/g,'')),k.split(",").map((a,b)=>C[a]=b),h(a))

```

Expanded:

```
C = a => (
    R = "replace",
    e = a => "[>]^>" + C[a],

    h = a =>
        a[R]( /(if|while)\((.*?)\)\{(.*?)\};/g,
            (a, c, f, g) => e(f) + "[" + h(g) + (c[2] ? e(f) : "[>]^") + "]" )

         [R]( /print\((.*?)\);/g,
            (a, d) => e(d) + "." )

         [R]( /input\((.*?)\);/g,
            (a, d) => e(d) + "," )

         [R]( /([a-z\d]+)(\W?)=(\d+);/ig,
            (a, d, c, g) => e(d) + (c || "[-]+") + g ),

    [,k,a] = /(.*?);(.*)/.exec( a[R]( /\/\/.*?\n/g, '' )[R]( /\s+/g, '' ) ),

    k.split(",").map( (a,b) => C[a] = b ),
    h(a)
)

```

This is simply a tweaked, refactored, and re-golfed version of the reference implementation in the OP. Most of the saved bytes occur through regex optimizations, elimination of loops, and switching from a push (i.e. `b += ...`) architecture to an inline architecture.

My apologies for the lack of creativity, but it's all I had time for. Hopefully it will inspire a few more intrepid souls to take the plunge. ;)
> 3 votes

---
Tags: code-golf
---


title: Print the Retro Rocket

text:
# Question
Title: Print the Retro Rocket
*(inspired by this SO question)*

You are given as input a single positive integer *n*.

In as few characters as possible, output a rocket in ASCII art with a head, a tail, and a body composed of *n* segments. There should be no trailing spaces or newlines.

The head and the tail of the rocket are always the same for any value of *n*. The body consists of two different types of segments which alternate. The examples should make the structure of the rocket clear.

Output for *n* = 1:

```
     /**\
    //**\\
   ///**\\\
  ////**\\\\
 /////**\\\\\
+=*=*=*=*=*=*+
|\/\/\/\/\/\/|
|.\/\/..\/\/.|
|..\/....\/..|
|../\..../\..|
|./\/\../\/\.|
|/\/\/\/\/\/\|
+=*=*=*=*=*=*+
     /**\
    //**\\
   ///**\\\
  ////**\\\\
 /////**\\\\\

```

Output for *n* = 2:

```
     /**\
    //**\\
   ///**\\\
  ////**\\\\
 /////**\\\\\
+=*=*=*=*=*=*+
|../\..../\..|
|./\/\../\/\.|
|/\/\/\/\/\/\|
|\/\/\/\/\/\/|
|.\/\/..\/\/.|
|..\/....\/..|
+=*=*=*=*=*=*+
|\/\/\/\/\/\/|
|.\/\/..\/\/.|
|..\/....\/..|
|../\..../\..|
|./\/\../\/\.|
|/\/\/\/\/\/\|
+=*=*=*=*=*=*+
     /**\
    //**\\
   ///**\\\
  ////**\\\\
 /////**\\\\\

```

Output for *n* = 3:

```
     /**\
    //**\\
   ///**\\\
  ////**\\\\
 /////**\\\\\
+=*=*=*=*=*=*+
|\/\/\/\/\/\/|
|.\/\/..\/\/.|
|..\/....\/..|
|../\..../\..|
|./\/\../\/\.|
|/\/\/\/\/\/\|
+=*=*=*=*=*=*+
|../\..../\..|
|./\/\../\/\.|
|/\/\/\/\/\/\|
|\/\/\/\/\/\/|
|.\/\/..\/\/.|
|..\/....\/..|
+=*=*=*=*=*=*+
|\/\/\/\/\/\/|
|.\/\/..\/\/.|
|..\/....\/..|
|../\..../\..|
|./\/\../\/\.|
|/\/\/\/\/\/\|
+=*=*=*=*=*=*+
     /**\
    //**\\
   ///**\\\
  ////**\\\\
 /////**\\\\\

```

# Answer
# CJam, ~~67~~ 63 characters

```
"дȈ鰚㒄å摒四ㄺ뎞椉ᖛⲠ줥葌⌁掗⦠춻锦䎷겲铣굛쮂먲꿡㦺좒轃汁̕뎕갴瓖邻吟㭰戔蟏㳵回㡚钦״脮烮鋉둎邫"6e4b127b:c~

```

This should work in the online interpreter.

### How it works

After pushing the Unicode string, the snippet

```
6e4b127b:c~

```

converts the string from base 60000 to base 127, casts to string and evaluates the result.

The code that get executed is the following:

```
"..."          " A binary string of length 42.                                            ";
122b7b         " Convert from base 122 to base 7.                                         ";
"\n *./\|"f=   " Replace each digits with the corresponding character.                    ";
60/~           " Split into chunks of length 60 and dump the resulting array.             ";
               " The stack now contains the rocket's head and a body half.                ";
[_W%[\]_W%]    " Push an array of the body half and the reversed body half, a reversed    ";
               " copy of that array and collect both array into another one.              ";
Nf*Nf+         " Join each array of body halves separating by LFs and append LFs.         ";
ri:I*           " Repeat the resulting array I := int(input()) times.                     ";
I<W%           " Keep the first I bodies and reverse their order.                         ";
\a_@\++        " Prepend and append the rocket head/tail.                                 ";
'+"=*"6*'+N+++ " Push S := '+=*=*=*=*=*=*+\n'.                                            ";
*              " Join the array of parts, separating by S.                                ";

```
> 6 votes

# Answer
## CJam, 121 bytes

```
5,{_5\-S*\)_'/*"**"@'\*N}%:A['+"+
"]"=*"6**:Lri:M{M(:M;2,{M+2%:J;3,{:I'|J@2\-'.*I'.*?_J"/\\""\/"?JI)3I-?*\++_+'|N}%}%L}*A

```

Try it online

Takes the input *n* via STDIN.

I'll add an explanation at some point later. Basically it's all just a bunch of loops in a very naive way. To alternate between the two different body parts, I've got a nested loop over the part and a loop over `0` and `1`. Then I just add the outer iterator and the inner one, and use their parity to decide between upwards or downwards pointing triangle.
> 10 votes

# Answer
# Ruby, 203

```
n,q=$*[0].to_i,"\\/"
h,r,m=1.upto(5).map{|i|(?/*i+"**"+?\\*i).center 14},?++"=*"*6+?+,3.times.map{|i|?|+?.*i+q*(3-i)+?.*(2*i)+q*(3-i)+?.*i+?|}*"\n"
p=m.reverse.tr q,"/\\"
puts h,([r,m,p,r,p,m]*n)[0,3*n],r,h

```

## Ungolfed

I think in this case it's beneficial to have an non-golfed version.

```
n      = $*[0].to_i
head   = 1.upto(5).map { |i| ("/"*i + "**" + "\\"*i).center 14 }
ridge  = "+" + "=*"*6 + "+"
middle = 3.times.map { |i| "|" + "."*i + "\\/"*(3-i) + "."*(2*i) + "\\/"*(3-i) + "."*i + "|" }.join "\n"
piddle = middle.reverse.tr "\\/", "/\\"

puts head
puts ([ridge,middle,piddle,ridge,piddle,middle]*n)[0,3*n]
puts ridge, head

```

## Explanation

I doubt this is anywhere near efficient, but it was fun nonetheless.

* Input is taken from `ARGV`.
* `h` contains the "head" and "tail" of the rocket, `r` contains the "ridges" that separate the different parts of the rocket and `m` and `p` are the top and bottom parts of the "body" of the rocket.
* The body is constructed by cycling through the `Array` `["ridge", "top of body", "bottom of body", "ridge", "bottom of body", "top of body"]` and taking the first `3*n` elements.
* `puts` makes sure everything gets its own line.
> 5 votes

# Answer
# Python, 120 + 77 + 1 = 198 characters

This ended up being the wrong approach, but I had already finished when Martin posted his answer.

```
H,L,T,B=open("R","rb").read().decode('zip').split("X")
n=input()
for p in[H]+([B,T,L,T,B,L]*n)[:3*n][::-1]+[L,H]:print p

```

Requires a file `R` (+1 for filename) of 77 bytes, which you can generate as follows:

```
>>> open('R','wb').write('eJxNjMENwDAIA/+ZIm8i4Qm6Bw+PwvDFQRUFydwJwd5VMOO6ILqIRjE+LsEI4zw2fSKJ6Vzpmt4p\ndVlnRikoVWqrK+8s/X1ivozIJuo=\n'.decode('base64'))

```
> 3 votes

# Answer
# JavaScript (E6) 252 ~~257~~

Overuse of string.repeat

```
F=p=>{
  R=(n,s='.',a='')=>a+s.repeat(n)+a;
  for(i=f=o=m=n='';++i<6;)
    o+=f+R(6-i,' ')+R(i,u='/')+'**'+R(i,t='\\'),
    f='\n',
    i<4?m+=f+R(2,R(4-i,t+u,R(i-1)),'|',n+=f+R(2,R(i,u+t,R(3-i)),'|')):0;
  s=f+R(6,'=*','+'),
  console.log(o+s+R(p&1,q=m+n+s)+R(p/2,n+m+s+q)+f+o)
}

```
> 3 votes

# Answer
## JS, WIP, 252b or 173 chars

It's not a function, so you have to set the value of n at the beginning (3 here), then execute it in the console or in nodeJS.

Here's the 252b version:

```
n=3;r=a="     /**01    //**001   ///**0001  ////**00001 /////**00000";b="1+=*=*=*=*=*=*+1";for(c=[d="|0/0/0/0/0/0/|1|.0/0/..0/0/.|1|..0/....0/..|",d.split("").reverse().join("")];n--;)r+=b+c[n%2]+1+c[1-n%2];(r+b+a).replace(/0/g,"\\").replace(/1/g,"\n")

```

And here's the 173 chars version (using http://xem.github.io/obfuscatweet/)

```
n=3;eval(unescape(escape('').replace(/uD./g,'')))

```
> 3 votes

# Answer
# Javascript (ES3): 243 ~~219~~ bytes

```
R=function(n){for(a='',i=5;i--;t=a+=s+'\n')for(s='**',j=6;j--;b=['|../\\..|./\\/\\.|/\\/\\/\\','|\\/\\/\\/|.\\/\\/.|..\\/..'])s=i<j?'/'+s+'\\':' '+s+' ';for(;a+='+=*=*=*=*=*=*+\n',n;)a+=(b[n&1]+b[--n&1]).replace(/[^|]+/g,'$&$&|\n');return a+t}

```
> 3 votes

---
Tags: code-golf, ascii-art, kolmogorov-complexity
---


title: Shubbles and Smoles - Part I

text:
# Question
Title: Shubbles and Smoles - Part I
# The Setup

Consider an oddly-shaped box containing 29 numbered cells as shown in Fig. 1 below.

Inside this 2D box are two species of square-shaped animals: shubbles and smoles. Fig. 1 (a) shows some shubbles in blue, and some smoles in red. Each creature occupies exactly one grid cell. The box may contain anywhere between 0 and 26 shubbles, but will always contain exactly two smoles.

Being subject to gravity, shubbles and smoles sit on the bottom of the box, stacking on top of anything below them. Both species are exceptionally lazy and remain perpetually motionless.

The box also contains a stot, depicted as a black square, that occupies exactly one grid cell. The stot is *not* subject to gravity.

The box has one opening located at the bottom of cell 28, as depicted in the figure.

To represent the configuration of shubbles, smoles, and the stot in the box textually, we use a 29-character string, one character per grid cell, in the enumerated order, with `.` representing an empty cell, `o` representing a shubble, `x` representing a smole, and `@` representing the stot. For example, the configuration of Fig. 1 (a) is represented by the string `.........@...o....ooo..xox...`.

# Manipulations

The box can be **rotated** by any multiple of 90°. While the box is being rotated, the shubbles and smoles remain stationary within their grid cells. As soon as a rotation is complete, they fall directly downward until either *i*) they are blocked by a wall below, *ii*) they are blocked by a shubble, smole, or stot below, or *iii*) they fall through the hole in cell 28 and exit the box. The stot does not fall; it stays fixed in its current cell, even if creatures rest on top of it.

The box cannot be rotated again until the creatures are done falling and have reached a new stable configuration.

Textually, box rotations are denoted by `+` for a 90° clockwise rotation, `|` for a 180° rotation, and `-` for a 90° counterclockwise rotation.

Additionally, the stot can be **moved** in the four compass directions in increments of one grid cell. A move may not: *i*) cause a collision between the stot and a creature (i.e. the destination grid cell must be empty), *ii*) cause a collision between the stot and a wall, nor *iii*) cause the stot to exit the box through the hole in cell 28.

Also, the stot *may not move* if it has any creatures resting on top of it (with respect to current gravity).

Textually, stot moves are denoted by `<` for left, `>` for right, `^` for up, and `v` for down. Stot moves are always specified *with respect to the "standard" (non-rotated) frame* depicted in the figures. That is, if the stot is in cell 10, the move `^` will always move it to cell 5, and the move `>` will always move it to cell 11. The orientation of the box does not affect the direction of the move.

Sequences of manipulations are encoded using left-to-right character strings. For example, the string `+<<^-` indicates the box is rotated clockwise 90°, then the stot is moved left twice and up once (with respect to the standard frame), then the box is rotated 90° counterclockwise back into its original orientation.

# The Challenge

For perfectly good reasons (that I cannot disclose), we wish to extricate all shubbles from the box *without* extricating a single smole. To accomplish this, we can use the manipulations specifically described above.

Before solving this problem, it behooves us to simulate how our various manipulations will affect the contents of the box, which is the focus of this challenge.

You must write a program that accepts two arguments from `stdin` (or equivalent):

* a string describing the initial state of the box
* a sequence of manipulations

You may assume that both arguments are syntactically valid, that the box starts in the standard orientation, and that the initial state of the box is stable and legal.

The program must output to `stdout` (or equivalent) either:

* (**case 1**) the final state of the box, expressed as a string, if the sequence of moves is legal (it does not violate the stot move rules) and does not cause any smoles to exit the box. The final orientation of the box is unimportant.
* (**case 2**) a single exclamation mark, `!`, if the sequence of moves is illegal or causes any smoles to exit the box

# Scoring

The winning program is the **shortest program by byte count**, subject to some extremely lucrative bonus multipliers:

* claim a **multiplier of 0.65** if instead of printing the encoded output for case 1, the program outputs an ASCII picture of the box in its final state and orientation, using the spec characters for shubbles, smoles, stots, and empty cells, and placing a `*` in the cell just outside the hole in cell 28. Leading and trailing whitespace is ignored.

For example, if Fig. 1 (a) is rotated 90°, the output would be

```
   .  .
  .....
  .o...
  xo.@.
 *ooo..
  x  .

```
* claim a **multiplier of 0.22** if instead of printing encoded output for case 1, the program outputs an image file or displays a GUI window with a picture of the box in its final state and orientation. The picture should be in the style of Fig. 1 (a), showing the grid cells, walls, and creatures/stot using coloured boxes.
* claim a **multiplier of 0.15** if instead of printing encoded output for case 1, the program outputs an animated .gif or animated GUI window showing all intermediate states in the simulation at 1 sec intervals. The same picture rules as for the 0.22 multiplier apply. The first frame of the animation should depict the initial state of the simulation. Additionally, the animation should show "hidden" intermediate states, which are

+ the shubbles/smoles falling into a stable configuration by one cell per animation frame after a rotation
    + the intermediate 90°-rotated state of the box in a 180° rotation
* claim a **multiplier of 0.12** if the program produces an animated .gif or animated GUI window of the above style, but runs at 20 fps and shows

+ smooth, continuous animations of the box rotating
    + smooth, continuous animations of the stot moving, and of the shubbles/smoles falling into a stable configuration

Shubbles falling through the hole in cell 28 should be shown exiting the box, and should disappear once totally outside. You may choose your own timing for the animation so long as no more than 1 manipulation/sec is performed.

Total score is `floor( base score * multiplier )`. **Only one multiplier may be claimed.**

It's a smole world after all. ;)

# Answer
> 2 votes
# MATLAB, as yet ungolfed * 0.15

It would be great if someone could hazard a guess as to whether this works right.

```
n = @()input('', 's');
E = @()fprintf('!');
M = zeros(7,9);
G = M;
I = [9:7:44 17:7:52 18:7:46 12:7:47 20:7:55];
M0 = M;
M0(I) = 1;
M([I 49]) = 1;
G(I) = n()-46;
trot = 0;
Xtr = [0 1-10i 11-7i 8+i];
X0 ='c66++66++oozzoozzn'-i*'YYNNAA--  ++88LLYY'-22+22i;
for a = [97 n()]
    a = find('-|+a^<v>'==a);
    if a<5
        R = @(m) rot90(m, a);
        G = R(G);
        [nr,nc] = size(G);
        M = R(M);
        M0 = R(M0);
        trot = mod(trot+a,4);
        X = exp(i*pi*trot/2)*X0 + 11*Xtr(trot+1);
    else
        z = find(G==18);
        J = z + [-nr,1]*[0,-1;1,0]^(trot+a)*[1;0];
        if ~M0(J) | G(J) | G(z+1)
            E();return
        end
        G(z) = 0;
        G(J) = 18;
    end
    fall = 1;
    while fall
        clf
        plot(X/11,'k','LineW',3);
        for x = 2:nc; for y = 2:nr
             ch = G(y,x);
             if M0(y,x)
                 rectangle('Po',[x,-y,1,1],'F',~ch|ch==[74 1 65]);
             end
        end;end
        pause(1);
        G2 = G;
        for r = nr-1:-1:2
            s = G2 > 30;
            f = G2(r,:) .* (s(r,:) & ~s(r+1,:) & M(r+1,:) & G(r+1,:)~=18);
            if r==size(G,1)-1 & any(f==74)
                E();return
            end
            G2(r:r+1,:) = G2(r:r+1,:) + [-f;f];
        end
        G2 = G2 .* M0;
        fall = any(any(G2 ~= G));
        G = G2;
    end
end

```

Sample end result for some random moves:

```
.........@...o....ooo..xox...
+>|<-v+^+

```

---
Tags: code-golf, ascii-art, graphical-output
---