public void giveHint(String target, String hint)
		throws HanabiException
	{
		if (hintsLeft <= 0) {
			throw new HanabiException("No hints left; discard or play a card instead");
		}

		int seatNumber = Integer.parseInt(target);
		if (seatNumber < 0 || seatNumber >= seats.size()) {
			throw new HanabiException("Invalid target for hint");
		}
		Seat targetSeat = seats.get(seatNumber);

		Hint h = new Hint();
		h.from = activeSeat;
		h.to = seatNumber;
		h.whenGiven = turn;

		if (h.from == h.to) {
			throw new HanabiException("Invalid target for hint");
		}

		if (hint.matches("^(\\d+)$")) {
			int rank = Integer.parseInt(hint);
			h.type = HintType.RANK;
			h.hintData = rank;
		}
		else {
			h.type = HintType.SUIT;
			h.hintData = -1;
			for (int i = 0; i < SUIT_NAMES.length; i++) {
				if (hint.equals(SUIT_NAMES[i])) {
					h.hintData = i;
					break;
				}
			}
			if (h.hintData == -1) {
				throw new HanabiException("Invalid hint '"+hint+"'");
			}
		}

		hints.add(h);
		hintsLeft--;

		HintEvent evt = new HintEvent();
		evt.actor = activeSeat;
		evt.actorSeat = getActiveSeat();
		evt.target = h.to;
		evt.hintType = h.type;
		evt.hint = h.getHintString();
		evt.applies = new boolean[targetSeat.hand.size()];
		for (int i = 0; i < targetSeat.hand.size(); i++) {
			evt.applies[i] = h.affirms(targetSeat.hand.get(i));
		}
		events.push(evt);

		nextTurn();
	}