docs: Optional<PlayerKilled> move(Player player) {
          Move move = player.getMoves().poll();
          if (move != null) {
              Tile from = tiles[move.getFrom()];
              boolean armyBigEnough = from.getArmySize() > 1;
              boolean tileAndPlayerMatching = from.isOwnedBy(player.getPlayerIndex());
              boolean oneStepAway = Stream.of(getTileAbove(from), getTileBelow(from), getTileLeftOf(from), getTileRightOf(from))
                      .filter(Optional::isPresent).map(Optional::get)
                      .map(Tile::getTileIndex)
                      .anyMatch(neighbourIndex -> neighbourIndex == move.getTo());
              if (armyBigEnough && tileAndPlayerMatching && oneStepAway) {
                  int armySize = from.moveFrom(move.half());
                  return tiles[move.getTo()]
                          .moveTo(armySize, from.getOwnerPlayerIndex().get(), tiles)
                          .map(this::transfer);
              } else {
                  return move(player);
              }
          }
          return Optional.empty();
      }