class Player {

	public short bestMove() {
		stopThreads();
		final short move = book.nextMove(board);
		if (move != NO_POINT) {
			return move;
		}
		if (cleanupMode) {
			if (!findCleanupMoves()) {
				return PASS;
			}
		} else if (board.getPasses() == 1 && coupDeGrace) {
			if (canWinByPassing()) {
				return PASS;
			}
			findCleanupMoves();
		}
		if (!timeLeftWasSent) {
			// No time left signal was received
			startThreads();
			try {
				Thread.sleep(msecPerMove);
			} catch (final InterruptedException e) {
				e.printStackTrace();
				System.exit(1);
			}
			stopThreads();
		} else {
			// Time left signal was received
			timeManager.startNewTurn();
			msecPerMove = timeManager.getMsec();
			log("Allocating " + msecPerMove + " msec");
			do {
				startThreads();
				try {
					Thread.sleep(msecPerMove);
				} catch (final InterruptedException e) {
					e.printStackTrace();
					System.exit(1);
				}
				stopThreads();
				msecPerMove = timeManager.getMsec();
			} while (msecPerMove > 0);
		}
		long playouts = 0;
		for (McRunnable runnable : runnables) {
			playouts += runnable.getPlayoutsCompleted();
		}
		Logging.log("Turn : " + board.getTurn() + " Playouts : " + playouts);
		return descender.bestPlayMove();
	}

	public  Player(int threads, CopiableStructure stuff);

}