in hanabi-learning-environment/hanabi_lib/hanabi_state.cc [169:222]
bool HanabiState::MoveIsLegal(HanabiMove move) const {
switch (move.MoveType()) {
case HanabiMove::kDeal:
if (cur_player_ != kChancePlayerId) {
return false;
}
if (deck_.CardCount(move.Color(), move.Rank()) == 0) {
return false;
}
break;
case HanabiMove::kDiscard:
if (InformationTokens() >= ParentGame()->MaxInformationTokens()) {
return false;
}
if (move.CardIndex() >= hands_[cur_player_].Cards().size()) {
return false;
}
break;
case HanabiMove::kPlay:
if (move.CardIndex() >= hands_[cur_player_].Cards().size()) {
return false;
}
break;
case HanabiMove::kRevealColor: {
if (!HintingIsLegal(move)) {
return false;
}
const auto& cards = HandByOffset(move.TargetOffset()).Cards();
if (!std::any_of(cards.begin(), cards.end(),
[move](const HanabiCard& card) {
return card.Color() == move.Color();
})) {
return false;
}
break;
}
case HanabiMove::kRevealRank: {
if (!HintingIsLegal(move)) {
return false;
}
const auto& cards = HandByOffset(move.TargetOffset()).Cards();
if (!std::any_of(cards.begin(), cards.end(),
[move](const HanabiCard& card) {
return card.Rank() == move.Rank();
})) {
return false;
}
break;
}
default:
return false;
}
return true;
}