in csrc/HanabiServer.cc [476:539]
void Server::pleasePlay(int index)
{
assert(0 <= activePlayer_ && activePlayer_ < hands_.size());
assert(players_.size() == hands_.size());
HANABI_SERVER_ASSERT(movesFromActivePlayer_ < 1, "bot attempted to move twice");
HANABI_SERVER_ASSERT(movesFromActivePlayer_ == 0, "called pleasePlay() from the wrong observer");
HANABI_SERVER_ASSERT(0 <= index && index <= hands_[activePlayer_].size(), "invalid card index");
Card selectedCard = hands_[activePlayer_][index];
activeCard_ = selectedCard;
activeCardIsObservable_ = true;
/* Notify all the players of the attempted play (before it happens). */
movesFromActivePlayer_ = -1;
int oldObservingPlayer = observingPlayer_;
for (int i=0; i < players_.size(); ++i) {
observingPlayer_ = i;
players_[i]->pleaseObserveBeforePlay(*this, activePlayer_, index);
}
observingPlayer_ = oldObservingPlayer;
activeCardIsObservable_ = false;
/* Examine the selected card. */
Pile &pile = piles_[(int)selectedCard.color];
if (pile.nextValueIs(selectedCard.value)) {
if (log_) {
(*log_) << "Player " << activePlayer_
<< " played his " << nth(index, hands_[activePlayer_].size())
<< " card (" << selectedCard.toString() << ").\n";
}
pile.increment_();
if (selectedCard.value == 5) {
/* Successfully playing a 5 regains a hint stone. */
regainHintStoneIfPossible_();
}
} else {
/* The card was unplayable! */
if (log_) {
(*log_) << "Player " << activePlayer_
<< " tried to play his " << nth(index, hands_[activePlayer_].size())
<< " card (" << selectedCard.toString() << ")"
<< " but failed.\n";
}
discards_.push_back(selectedCard);
loseMulligan_();
}
/* Shift the old cards down, and draw a replacement if possible. */
hands_[activePlayer_].erase(hands_[activePlayer_].begin() + index);
if (mulligansRemaining_ > 0 && !deck_.empty()) {
Card replacementCard = this->draw_();
hands_[activePlayer_].push_back(replacementCard);
if (log_) {
(*log_) << "Player " << activePlayer_
<< " drew a replacement (" << replacementCard.toString() << ").\n";
}
}
this->logPiles_();
movesFromActivePlayer_ = 1;
}