@Override
    public List<Move> getMoves(ChessBoard board) {
        Position tem;
        Coin c;
        boolean prev = false;
        LinkedList<Move> p = new LinkedList<Move>();
        int temp = (getColor() == CoinColor.WHITE) ? 1 : -1;
        if (readyForPromote()) {
            tem = Position.getPosition(getRank() + temp, getFile());
            if (board.getCoinAt(tem) == Empty) {
                p.add(new Promote(board, getPosition(), tem, Promote.QUEEN, getColor()));
                p.add(new Promote(board, getPosition(), tem, Promote.ROOK, getColor()));
                p.add(new Promote(board, getPosition(), tem, Promote.BISHOP, getColor()));
                p.add(new Promote(board, getPosition(), tem, Promote.KNIGHT, getColor()));
            }
            tem = Position.getPosition(getRank() + temp, getFile() + 1);
            c = board.getCoinAt(tem);
            if (c != Empty && c != null && c.getColor() != getColor()) {
                p.add(new Promote(board, getPosition(), tem, Promote.QUEEN, getColor()));
                p.add(new Promote(board, getPosition(), tem, Promote.ROOK, getColor()));
                p.add(new Promote(board, getPosition(), tem, Promote.BISHOP, getColor()));
                p.add(new Promote(board, getPosition(), tem, Promote.KNIGHT, getColor()));
            }
            tem = Position.getPosition(getRank() + temp, getFile() - 1);
            c = board.getCoinAt(tem);
            if (c != Empty && c != null && c.getColor() != getColor()) {
                p.add(new Promote(board, getPosition(), tem, Promote.QUEEN, getColor()));
                p.add(new Promote(board, getPosition(), tem, Promote.ROOK, getColor()));
                p.add(new Promote(board, getPosition(), tem, Promote.BISHOP, getColor()));
                p.add(new Promote(board, getPosition(), tem, Promote.KNIGHT, getColor()));
            }
        } else {
            tem = Position.getPosition(getRank() + temp, getFile());
            if (board.getCoinAt(tem) == Empty) {
                p.add(new StandardMove(board, getPosition(), tem));
                prev = true;
            }
            tem = Position.getPosition(getRank() + temp, getFile() + 1);
            c = board.getCoinAt(tem);
            if (c != Empty && c != null && c.getColor() != getColor()) {
                p.add(new StandardMove(board, getPosition(), tem));
            }
            tem = Position.getPosition(getRank() + temp, getFile() - 1);
            c = board.getCoinAt(tem);
            if (c != Empty && c != null && c.getColor() != getColor()) {
                p.add(new StandardMove(board, getPosition(), tem));
            }
            if (prev && isNotYetMoved()) {
                tem = Position.getPosition(getRank() + temp + temp, getFile());
                if (board.getCoinAt(tem) == Empty) {
                    p.add(new StandardMove(board, getPosition(), tem));
                }
            } else if (canEnpassent()) {
                prev = false;
                tem = Position.getPosition(getRank(), getFile() - 1);
                c = board.getCoinAt(tem);
                if (c != null && c != Empty && c.getColor() != getColor()) {
                    if (board.getMoveAt(board.moveSize() - 1).equals(new StandardMove(board, Position.getPosition(getRank() + temp + temp, getFile() - 1), tem))) {
                        p.add(new Enpassant(board, getPosition(), Position.getPosition(getRank() + temp, getFile() - 1)));
                        prev = true;
                    }
                }
                tem = Position.getPosition(getRank(), getFile() + 1);
                c = board.getCoinAt(tem);
                if (c != null && c != Empty && c.getColor() != getColor() && (!prev)) {
                    if (board.getMoveAt(board.moveSize() - 1).equals(new StandardMove(board, Position.getPosition(getRank() + temp + temp, getFile() + 1), tem))) {
                        p.add(new Enpassant(board, getPosition(), Position.getPosition(getRank() + temp, getFile() + 1)));
                        prev = true;
                    }
                }
            }

        }
        return p;
    }