예제 #1
0
// 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);
}
예제 #2
0
//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;
}
예제 #3
0
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()" );
    }
}
예제 #4
0
파일: GolemCard.cpp 프로젝트: npburg/domlib
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" );
    }
}
예제 #5
0
/*
 * 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;
}