// Discards the given card void Role::discardCard(const Card& card) { const CardList legalCards = legalMoves(); // Gets the cards which are legal to play // Determines whether the user is in a situation that they had to discard, if not throws exception if(legalCards.size() != 0) { throw IllegalDiscardException(); } // Removes card from hand, and adds to discard pile const Card* deletedCard = player_->hand_.remove(card); player_->discards_.add(deletedCard); triggerPlayerUpdate(true); }
//Given the cards already played by all players and a player's hand, determines the legal cards which can be played by the player CardList GameLogic::legalMoves(const CardList& table, const CardList& hand) { CardList legalMoves; // used to store legal cards // In the case the table is empty, this means this play has 7 of spades, so he has to be forced to play it if(table.size() == 0) { // finds the 7S card, so we only got one instance of it int index = hand.find(Card(SPADE, SEVEN)); const Card* sevenSpades = hand[index]; legalMoves.add(sevenSpades); return legalMoves; } // loops through hand to determine which ones are legal to play for (int index = 0; index < hand.size(); index++) { const Card * card = hand[index]; // Stores the index of lower rank and higher rank card to determine whether it exists or not int lowerRankIndex = -1; int higherRankIndex = -1; // Determines whether a lower rank or higher rank card exists if (card->getRank() != ACE) { Card lowerRank = Card(card->getSuit(), (Rank) (card->getRank() - 1)); lowerRankIndex = table.find(lowerRank); } if (card->getRank() != KING) { Card higherRank = Card(card->getSuit(), (Rank)(card->getRank() + 1)); higherRankIndex = table.find(higherRank); } // Determines whether the current card is legal to play if (card->getRank() == SEVEN || lowerRankIndex !=-1 || higherRankIndex != -1) { legalMoves.add(card); } } return legalMoves; }
void CellarCard::OnActionPhase( Engine* pEngine ) { Player* pPlayer = pEngine->GetCurrentPlayer(); IAI* pAI = pPlayer->GetAI(); CardList cardsToDiscard; cardsToDiscard = pAI->OnCellar(); if( pPlayer->AreCardsInHand( cardsToDiscard ) ) { pPlayer->DiscardFromHand( cardsToDiscard ); pPlayer->DrawCardsToHand( cardsToDiscard.size() ); } else { // TODO: Add error throw std::wstring( L"Error: CellarCard::OnActionPhase()" ); } }
void GolemCard::OnActionPhase( Engine* pEngine ) { // TODO: Not sure how to implement the Golem playing two cards since it is // not the player playing the cards since the cards in Hand are not // avaliable throw std::wstring( L"GolemCard::OnActionPhase - To be implemented..." ); Player* pPlayer = pEngine->GetCurrentPlayer(); IAI* pAI = pPlayer->GetAI(); CardList revealedCardList; CardList actionCardList; do { Card* pRevealedCard = pPlayer->RevealCardFromDeck(); if( pRevealedCard->IsNullCard() ) { break; } else if( pRevealedCard->IsActionCard() && pRevealedCard->CardId() != CARDID::GOLEM ) { actionCardList.push_back( pRevealedCard ); } else { revealedCardList.push_back( pRevealedCard ); } } while( actionCardList.size() < 2 ); pPlayer->PutCardsInDiscard( revealedCardList ); CardList reorderedCardList = pAI->OnGolem( revealedCardList ); if( Card::CardListsMatch( revealedCardList, reorderedCardList ) ) { CardListIter cardIter; pPlayer->SetGolemFlag( true ); for( cardIter = reorderedCardList.begin(); cardIter != reorderedCardList.end(); cardIter++ ) { Card* pCardToPlay = (Card*)*cardIter; pCardToPlay->OnActionPhase( pEngine ); } pPlayer->SetGolemFlag( false ); pPlayer->PutCardsInPlay( actionCardList ); } else { // TODO: report error throw std::wstring( L"Error: ScoutCard::OnActionPhase" ); } }
/* * aLeftPlayer: next in turn * aRightPlayer: prev in turn * 0, 1th * 1th, 2nd */ Card *AlphaBetaPlayer::makeMove (Card *lMove, Card *rMove, Player *aLeftPlayer, Player *aRightPlayer, bool isPassOut) { qDebug() << type() << "("<< mPlayerNo << ") moves"; card_t hands[3][10]; card_t desk[3]; int crdLeft = 0; int trumpSuit = 0; Player *plst[3]; //again: plst[0] = plst[1] = plst[2] = 0; plst[mPlayerNo-1] = this; plst[aLeftPlayer->number()-1] = aLeftPlayer; plst[aRightPlayer->number()-1] = aRightPlayer; // build hands for (int c = 0; c < 3; c++) { Q_ASSERT(plst[c]); CardList *clst = &(plst[c]->mCards); //for (int f = 0; f < 10; f++) hds[c][f] = hands[c][f] = 0; int pos = 0; for (int f = 0; f < clst->size(); f++) { Card *ct = clst->at(f); if (!ct) continue; hands[c][pos++] = CARD(ct->face(), ct->suit()-1); if (pos > crdLeft) crdLeft = pos; } for (int f = pos; f < 10; f++) hands[c][f] = 0; xsortCards(hands[c], pos); } if (!lMove && !rMove && crdLeft == 10) { return AiPlayer::makeMove(lMove, rMove, aLeftPlayer, aRightPlayer, isPassOut); } // find game const eGameBid bid = m_model->currentGame(); gPassOutOrMisere = (bid == g86 || bid == g86catch || bid == raspass); trumpSuit = bid%10-1;//(bid-(bid/10)*10)-1; /* if (bid == g86catch || bid == g86 || bid == raspass) { return Player::moveSelectCard(lMove, rMove, aLeftPlayer, aRightPlayer); } */ if (bid == g86catch || bid == g86 || bid == raspass) { trumpSuit = 4; } if (trumpSuit < 0) trumpSuit = 4; fprintf(stderr, "po:%s; lm:%s, rm:%s\n", isPassOut?"y":"n", lMove?"y":"n", rMove?"y":"n"); if (isPassOut && rMove && !lMove) { // это распасы, первый или второй круг, первый ход gPassOutSuit = rMove->suit()-1; fprintf(stderr, "pass-out: %i\n", gPassOutSuit); rMove = 0; } else gPassOutSuit = -1; // build desk int turn = 0; if (lMove) { desk[turn++] = CARD(lMove->face(), lMove->suit()-1); if (rMove) desk[turn++] = CARD(rMove->face(), rMove->suit()-1); } else if (rMove) { desk[turn++] = CARD(rMove->face(), rMove->suit()-1); } // build hands for (int f = 0; f < 3; f++) { xHands[f].suitCount[0] = xHands[f].suitCount[1] = xHands[f].suitCount[2] = xHands[f].suitCount[3] = 0; xHands[f].suitStart[0] = xHands[f].suitStart[1] = xHands[f].suitStart[2] = xHands[f].suitStart[3] = 11; xHands[f].tricks = plst[f]->tricksTaken(); int st; for (int z = 0; z < 10; z++) { if (hands[f][z]) { xHands[f].faces[z] = FACE(hands[f][z]); st = xHands[f].suits[z] = SUIT(hands[f][z]); if (xHands[f].suitCount[st]++ == 0) xHands[f].suitStart[st] = z; } else xHands[f].faces[z] = 0; } } // build desk for (int f = 0; f < turn; f++) { xDeskFaces[f] = FACE(desk[f]); xDeskSuits[f] = SUIT(desk[f]); } int a, b, c, move; int me = this->number()-1; xCardsLeft = crdLeft; gTrumpSuit = trumpSuit; gIterations = 0; printf("%shand 0:", this->number()==0?"*":" "); printHand(&(xHands[0])); printf("%shand 1:", this->number()==1?"*":" "); printHand(&(xHands[1])); printf("%shand 2:", this->number()==2?"*":" "); printHand(&(xHands[2])); printDesk(turn); // оптимизации /* if (turn > 0) { // можем вообще взять? if (hands[me].suitCount( } */ stTime = QTime::currentTime(); stTime.start(); abcPrune(turn, me, -666, 666, 666, &a, &b, &c, &move); qDebug() << "face:" << FACE(hands[me][move]) << "suit:" << SUIT(hands[me][move])+1 << "move:" << move << "turn:" << turn << "moves:" << crdLeft << "trump:" << trumpSuit << "iters:" << gIterations << ""; /* for (int h = 0; h < 3; h++) { fprintf(stderr, (h == me)?"*":" "); fprintf(stderr, "hand %i:", h); for (int f = 0; f < 10; f++) { if (hands[h][f]) { fprintf(stderr, " %2i.%i(%3i)", FACE(hands[h][f]), SUIT(hands[h][f]), hands[h][f]); } else { fprintf(stderr, " %2i.%i(%3i)", 0, 0, hands[h][f]); } } fprintf(stderr, "\n"); } fprintf(stderr, "desk:"); for (int f = 0; f < turn; f++) { fprintf(stderr, " %2i.%i(%3i)", FACE(desk[f]), SUIT(desk[f]), desk[f]); } fprintf(stderr, "\n"); */ Q_ASSERT(move >= 0); Card *moveCard = getCard(FACE(hands[me][move]), SUIT(hands[me][move])+1); qDebug() << "move:" << moveCard->toString(); mCards.remove(moveCard); mCardsOut.insert(moveCard); return moveCard; }