in simple_game/two_suited_bridge.h [87:143]
void step(int action) override {
// Any input action has to be legal action.
assert(!terminated());
if (card1_ < 0) {
// [TODO]: HACK here.
// If seqEnumerate is true (e.g. in evaluation mode),
// then the environment would alter the nature action to enumerate all
// possible
// situations (different card1_) and see whether they works.
if (commOptions_.seqEnumerate) {
action = numGameFinished_;
}
// 0 .. N
card1_ = action % (commOptions_.N + 1);
card2_ = action / (commOptions_.N + 1);
return;
}
// Check if bidding is valid.
if (publicActions_.size() >= 1) {
if (action > kPass && lastBid_ >= action) {
// illegal action.
throw std::runtime_error("action " + std::to_string(action) +
" is not a legal action!");
} else if (action == kPass) {
// 1 pass, not initial and we end the game.
terminated_ = true;
if (lastBid_ == kPass) {
// no contract.
reward_ = 0;
} else {
int finalContractLevel = (lastBid_ + 1) / 2;
int finalContractSuit = lastBid_ % 2;
int contractReward = 1;
for (int i = 0; i < finalContractLevel - 1; i++) {
contractReward <<= 1;
}
bool contractMake = false;
if (((finalContractSuit == 1) && (commOptions_.N + finalContractLevel <= card1_ + card2_)) ||
((finalContractSuit == 0) && (commOptions_.N + finalContractLevel <= 2 * commOptions_.N - card1_ - card2_))) {
contractMake = true;
}
if (contractMake) {
reward_ = contractReward;
} else {
// Failed the contract.
reward_ = -1;
}
}
}
}
publicActions_.push_back(action);
if (action != kPass) {
lastBid_ = action;
}
}