private List<Move> possibleMoves() {
        final boolean mustAttack = state.mustAttack();
        final List<Move> result = new ArrayList<>();

        if (!mustAttack) {
            result.add(Move.PASS);
        }
        for (byte from = 0; from < Move.N_BOARD_LOCATIONS; from++) {
            if (state.getOwner(from) != state.getPlayerToMove()) {
                continue;
            }
            for (final BoardLocation to : toLocations(from)) {
                /* attack? */
                final byte toB = Move.fromBoardLocation(to);
                final boolean canAttack =
                        (state.getOwner(toB) == state.getPlayerToMove().opponent()) &&
                                (state.getHeight(from) >= state.getHeight(toB));

                if (canAttack) {
                    result.add(Move.attack(from, toB));
                }

                final boolean canStrengthen =
                        (state.getOwner(toB) == state.getPlayerToMove()) && !mustAttack;
                if (canStrengthen) {
                    result.add(Move.strengthen(from, toB));
                }
            }
        }
        return result;
    }