private ArrayList<String> sellPropertyItems() {
   ArrayList<String> items =
       BoardSearch.all().filterByOwner(this).filterByMortaged(false).toMenuItems();
   items.add("Give up");
   items.add("Exit this menu");
   return items;
 }
 public Long propertiesWorth() {
   Long total = 0L;
   for (BoardTile tile : BoardSearch.all().filterByOwner(this).getTiles()) {
     total += tile.getValue();
   }
   return total;
 }
 public void payToPlayer(Player payee, Long amount) {
   // if calling giveMoney will be anything but not 0 then all belongings go to payee
   Long owed = this.giveMoney(amount);
   payee.getMoney(amount - owed);
   if (owed > 0) {
     StdOut.println(this.name + " owes to " + payee.name + " " + Bank.moneyEuro(owed));
     if (this == Game.getCurrentPlayer()) {
       // the moment player gave up it will stop recursing
       if (this.playing) {
         // allows player to sell something and then calls itself,
         // so it won't leave till it's paid ot player gave up
         this.sellProperty();
         this.payToPlayer(payee, owed);
       }
     } else {
       for (BoardTile tile : BoardSearch.all().filterByOwner(this).getTiles()) {
         tile.changeOwner(payee);
       }
       // give payee money you got from selling of upgrades
       StdOut.println(
           payee + " got " + Bank.moneyEuro(this.cash) + " from " + this.name + "'s upgrades.");
       this.giveMoney(this.cash);
       this.cash = 0L;
     }
   }
 }
  /**
   * This player will stop playing<br>
   * <br>
   * NOTE:Check before you use giveUp that all properties transfers are made corectly. Because this
   * method will give everything to the bank!!!
   */
  public void giveUp() {
    StdOut.println();
    StdOut.println(this.name + " finished with playing, returning everything back to bank:");
    for (BoardTile tile : BoardSearch.all().filterByOwner(this).getTiles()) {
      // not all necessary but it's neat to clean up after he is done and politely return items back
      // to bank
      tile.downgradeToBasic();

      StdOut.println(this.name + " returns " + tile + " to the bank.");
      tile.setOwned(false);
      tile.setOwner(new Player());
    }
    // not really required, but for neatness
    if (this.cash > 0L) {
      StdOut.println(this.name + " returns " + Bank.moneyEuro(this.cash) + " to the bank.");
      this.cash = 0L;
    }
    this.playing = false;
  }
  public void sellProperty() {
    // TODO test it more
    int option = this.sellPropertyMenu();

    while (option != this.sellPropertyItems().size()) {
      if (option == this.sellPropertyItems().size() - 1) {
        // give up
        if (UI.askNgetBoolean("Do you really want give up?")) {
          this.giveUp();
        }
      } else {
        // sellected property
        BoardTile sellingTile = BoardSearch.all().filterByOwner(this).getTiles().get(option);

        if (UI.askNgetBoolean("Are you sure you want mortage " + sellingTile + "?")) {
          sellingTile.mortageToBank();
        }
      }
    }
  }
  private void playerOptions() {
    int choice = this.displayPlayerMenu();
    while (choice != 0) {
      switch (choice) {

          // player decided to roll dice
        case 1:
          PairDice dice = PairDice.getInstance(Game.getDebugDice());
          UI.diceDisplay(dice);
          Game.getCurrentPlayer().step(dice.total);
          if (dice.same) {
            StdOut.println("\nYou threw a DOUBLE, you are rolling for the second time.");
            UI.pause();

            dice = PairDice.getInstance(Game.getDebugDice());
            UI.diceDisplay(dice);
            Game.getCurrentPlayer().step(dice.total);
            if (dice.same) {
              StdOut.println(
                  "\nYou threw a DOUBLE for the second time, you are rolling the third time.");
              StdOut.println("Note: be careful or you are going to jail.");
              UI.pause();

              dice = PairDice.getInstance(Game.getDebugDice());
              UI.diceDisplay(dice);
              if (dice.same) {
                StdOut.println(
                    "\nYou threw a DOUBLE for the third time, you are going straight to jail.");
                // Game.getCurrentPlayer().jumpTo(Game.getBoard().getJailPosition());
                // will change possition as well
                Game.getCurrentPlayer().setJailTime(3);
              } else {
                Game.getCurrentPlayer().step(dice.total);
              }
            }
          }
          // step is already called in tileActions
          // Game.getBoard().tileActions();
          choice = 0;
          UI.pause();
          break;

          // to see what tiles he owns
        case 2:
          UI.displayMyProperties();
          UI.pause();
          break;

          // to see stats of all players together
        case 3:
          UI.displayChoiceItems(
              "Players", UI.playersToItems(Game.getAllPlayingPlayers()), false, false);
          UI.pause();
          break;

          // Sell properties to other player
        case 4:
          // TODO test it more
          ArrayList<BoardTile> tiles = new ArrayList<BoardTile>();

          for (BoardTile tile :
              BoardSearch.all().filterByOwner(Game.getCurrentPlayer()).getTiles()) {
            if (Game.getBoard()
                .getTile(Game.getCurrentPlayer().getPosition())
                .ownAllofThisColorAreNotUpgraded()) {
              if (tile.getUpgradeLevel() == 0) {
                tiles.add(tile);
              }
            }
          }

          if (tiles.size() > 0) {
            int forSale =
                UI.displayMenuNGetChoice(
                    "Choose tile to sell", BoardSearch.all(tiles).toMenuItems(), false, true);
            //            BoardTile tileForSale = tiles

            Pair<Player, Long> winner =
                Game.getBank().auction("Auction for " + tiles.get(forSale), Game.getOtherPlayers());

            if (winner.first != null) {
              tiles.get(forSale).setOwned(true);
              tiles.get(forSale).setOwner(winner.first);
              winner.first.payToPlayer(Game.getCurrentPlayer(), winner.second);

            } else {
              StdOut.println("Nobody was interested to buy your property.");
            }

          } else {
            StdOut.println(
                "You don't own any properties avaiable for selling. Can't be upgraded and:");
            StdOut.println("To sell property all properties of this colour can't be upgraded!");
          }
          UI.pause();
          break;

          // Downgrade tiles
        case 5:
          // TODO test it more
          UI.displayMyProperties();

          ArrayList<BoardTile> forDowngrade = new ArrayList<BoardTile>();

          for (BoardTile tile :
              BoardSearch.all().filterByOwner(Game.getCurrentPlayer()).getTiles()) {
            if (tile.getUpgradeLevel() > 0) {
              forDowngrade.add(tile);
            }
          }

          if (forDowngrade.size() > 0) {
            if (UI.askNgetBoolean("Are you sure to downgrade some properties?")) {
              int downgradeIndex =
                  UI.displayMenuNGetChoice(
                      "Choose property to downgrade",
                      BoardSearch.all(forDowngrade).toMenuItems(),
                      false,
                      true);

              forDowngrade.get(downgradeIndex).decUpgradeLevel();
            }
          } else {
            StdOut.println("No properties for downgrading");
          }
          UI.pause();
          break;

          // Mortages
        case 6:
          // TODO test it more
          UI.displayMyProperties();

          ArrayList<BoardTile> mortaged =
              BoardSearch.all()
                  .filterByOwner(Game.getCurrentPlayer())
                  .filterByMortaged(true)
                  .getTiles();

          if (mortaged.size() > 0) {
            UI.displayChoiceItems(
                "Mortage properties", BoardSearch.all(mortaged).toMenuItems(), false, true);

            if (UI.askNgetBoolean("Do you want buy some of them back?")) {

              int buyBack =
                  UI.displayMenuNGetChoice(
                      "Mortage properties", BoardSearch.all(mortaged).toMenuItems(), false, true);

              if (mortaged.get(buyBack).mortageBuyOfPrice() <= Game.getCurrentPlayer().getCash()) {

                // you can afford it but still lets confirm it from you
                if (UI.askNgetBoolean(
                    "It will cost "
                        + Bank.roundMoney(mortaged.get(buyBack).mortageBuyOfPrice())
                        + ", do you want it back?")) {
                  mortaged.get(buyBack).mortageFromBank();
                }

              } else {
                StdOut.println(
                    "You cannot affort to pay: "
                        + Bank.roundMoney(mortaged.get(buyBack).mortageBuyOfPrice()));
              }
            }

          } else {
            StdOut.println("You didn't mortaged any properties.");
          }
          UI.pause();

          break;

          // give up on this game
        case 7:
          if (UI.askNgetBoolean("Are you sure to give up?")) Game.getCurrentPlayer().giveUp();
          choice = 0;
          break;

          // save game status and exit the application
        case 8:
          if (UI.askNgetBoolean("Are you sure to suspend the game?")) {
            Game.save();
            Game.stopGame();
            choice = 0;
          }
          break;

        case 9:
          boolean allAgree = true;
          Long max = 0L;

          UI.displayChoiceItems(
              "Players", UI.playersToItems(Game.getAllPlayingPlayers()), false, false);

          // at least empty player, just in case so there will be no NULL
          // pointer issues later
          Player winner = new Player();

          for (Player player : Game.getAllPlayingPlayers()) {
            if (!UI.askNgetBoolean(player + " do you agree with stopping this game?")) {
              allAgree = false;
            }
            // while traversing all players we can also find who is the richest
            // one
            if (player.totalNetWorth() > max) {
              max = player.totalNetWorth();
              winner = player;
            }
          }
          if (allAgree) {
            // we will leave the menu
            choice = 0;

            UI.anounceWinner(winner);
            Game.stopGame();
          } else {
            StdOut.println("Not all players agreed with this request.");
          }
          break;

        case 10:
          debugOptions();
          break;

        case 0:
        default:
          break;
      }
      if (choice != 0) choice = this.displayPlayerMenu();
    }
  }