public void run() {

    double budget = 50;

    Optimiser optimiser = new Optimiser(); // Instantiate optimiser class
    ScenarioGenerator scenGen = new ScenarioGenerator(5, 20); // Instantiate ScenarioGenerator class
    OptimisedBidder OptimisedBidder =
        new OptimisedBidder("OptimisedBidder", budget); // Instantiate OptimisedBidder class

    scenGen.createItemAndAuction(); // Create items and auctions
    scenGen.createBidders(); // Create bidders

    scenGen.passAuctionsToBidders(); // Pass list of generated auctions to all simulated bidders
    OptimisedBidder.setAuctions(
        scenGen.getAuctions()); // Pass list of generated auctions to OptimisedBidder
    OptimisedBidder.setOptimiser(optimiser); // Pass optimiser to OptimisedBidder
    OptimisedBidder.setScenarioGenerator(scenGen); // Pass scenGen to OptimisedBidder

    scenGen
        .printItemsUtility(); // Prints a list of all items created by the scenario generator, the
    // current high bid on that item and it's resultant utility

    System.out.println("Simulation started at: " + time());

    try {
      OptimisedBidder.activate(); // Activate OptimisedBidder thread
      for (int i = 0;
          i < scenGen.getBidders().size();
          i++) { // Activate bidder threads (i.e. set them to active, wakeup now and add them to the
        // queue
        Bidder bidder = scenGen.getBidders().get(i);
        bidder.activate();
      }
      Scheduler.startSimulation(); // Start simulation
      hold(50);
      SimulationProcess.mainResume(); // Resume main thread
    } catch (SimulationException e) {
      e.printStackTrace();
    } catch (RestartException e) {
      e.printStackTrace();
    }

    System.out.println("Simulation ended at: " + time());
    printResults(scenGen.getBidders(), scenGen.getAuctions(), OptimisedBidder);
    System.exit(0);
  }
    /* (non-Javadoc)
     * @see java.lang.Runnable#run()
     */
    @Override
    public void run() {
      while (!Thread.interrupted()) {

        // send board notifications to mark the start of the cycle
        //
        LOGGER.info("Board state: {}", boardEvent);
        if (listener != null) listener.boardStateChanged(boardEvent);

        // wait for players moves
        //
        try {
          Thread.sleep(CYCLE_LENGTH);
        } catch (InterruptedException e) {
          return;
        }

        // execute received moves at the end of the cycle
        //
        try {
          boardLock.lock();

          // moves execution
          //
          Arrays.sort(moves, comparator);
          for (Move move : moves) {
            if (move == null) break;

            try {
              state = board.doMove(move);
            } catch (SimulationException e) {
              if (listener != null) listener.onException(e);
              LOGGER.info("Could not execute move {}: {}", move, e.getMessage());
              continue;
            }

            LOGGER.info("Move {} successfully executed. Result: {}", move, state);

            switch (state) {
              case GAME_FINISHED:
                LOGGER.info("GameState: {}", boardEvent);
                if (listener != null) {
                  listener.gameStateChanged(gameEvent);
                  listener.boardStateChanged(boardEvent);
                }

                // finishing the game
                //
                return;
              case SCORE_CHANGED:
                LOGGER.info("GameState: {}", boardEvent);
                if (listener != null) listener.gameStateChanged(gameEvent);
                break;
              default:
            }
          }
        } finally {
          cycle++;
          Arrays.fill(moves, null);
          boardLock.unlock();
        }
      }
    }