Exemple #1
0
void Manager::handleDiscardRequest(ValueEvent<DiscardRequestMsg>* e)
{
    Seat* s = seat(e->value().seat());
    std::vector<Card> cards;
    for (auto c : e->value().card()) {
        cards.push_back(c);
    }
    if (mStatus != DiscardWait) {
        notifyDiscardFail(s, cards, ErrorCode::StatusError);
        return;
    }
    if (mPerformer != s) {
        notifyDiscardFail(s, cards, ErrorCode::PerformerError);
        return;
    }
    CardContainer res;
    bool isMax = false;
    try {
        isMax = mChecker->discard(mRes, s, cards, res);
    } catch (Exception& excp) {
        if (excp.code() == ErrorCode::ThrowFail) {
            mStatus = ThrowFail;
            mRes.putThrowFail(s->id(), res);
        }
        notifyDiscardFail(s, cards, excp.code());
        return;
    }
    DiscardActionMsg m;
    m.set_seat(s->seat());
    m.set_max(isMax);
    m.set_reason(DiscardActionMsg::Normal);
    m.set_order(mRes.resNumber());
    m.set_score(0);
    mRes.put(s->seat(), res, isMax);
    if (mRes.resNumber() == 0) {
        mPerformer = seat(mRes.lastCircle().max()->seat);
        if ((mPerformer->id() & 1) != (mDealer & 1)) {
            int score = mRes.lastCircle().score();
            if (score > 0) {
                mRes.addScore(score);
                m.set_score(score);
            }
        }
    } else {
        mPerformer = mPerformer->next();
    }
    m << cards;
    notifyDiscardAction(m);
    if (mRes.resCnt() == 100) {
        mStatus = DiscardFinish;
        std::vector<Card> b;
        mGen.getBottom(b);
        Seat* s = seat(mRes.lastCircle().max()->seat);
        int score = 0;
        int factor = 0;
        if ((s->id() & 1) != (mDealer & 1)) {
            const CardContainer& cc = mRes.lastCircle().max()->cards;
            if (mOpt.slaveCanCatchBottom ||
                cc.mask().hasOnlySuit() == CardMask::Master) {
                for (auto& i : b) {
                    score += i.score();
                }
                factor = cc.factor();
                if (mOpt.doubleBottomScore) {
                    factor <<= 1;
                }
                mRes.addScore(score * factor);
            }
        }
        mPerformer = NULL;
        notifyDiscardFinish(mRes, score, factor);
    } else {
        mStatus = DiscardNotify;
    }
}