bool Poker::getBiggestCards() { std::vector<std::vector<CCard> > allcards; std::vector<CardType> allcardtypes; if (mVecCommonCards.size() != 5) { return false; } for (size_t i = 0; i < mVecCommonCards.size()-2; ++i) { for (size_t j = i+1; j < mVecCommonCards.size()-1; ++j) { std::vector<CCard> cvec; cvec.push_back(mVecCards[0]); cvec.push_back(mVecCards[1]); cvec.push_back(mVecCommonCards[i]); cvec.push_back(mVecCommonCards[j]); cvec.push_back(mVecCommonCards[j+1]); sortPlayerCards(cvec); allcards.push_back(cvec); } } for (size_t i = 0; i < allcards.size(); ++i) { CardType ct; getCardType(allcards[i], ct); allcardtypes.push_back(ct); } sort(allcardtypes.begin(), allcardtypes.end(), typeCompare()); m_ctype = allcardtypes[0]; return true; }
QString CardInfo::getMainCardType() const { QString result = getCardType(); /* Legendary Artifact Creature - Golem Instant // Instant */ int pos; if ((pos = result.indexOf('-')) != -1) result.remove(pos, result.length()); if ((pos = result.indexOf("—")) != -1) result.remove(pos, result.length()); if ((pos = result.indexOf("//")) != -1) result.remove(pos, result.length()); result = result.simplified(); /* Legendary Artifact Creature Instant */ if ((pos = result.lastIndexOf(' ')) != -1) result = result.mid(pos + 1); /* Creature Instant */ return result; }
QList<int> CardUtil::getOvercome(QList<CardItem *> myCards,QList<CardItem *> prevCards, CardType prevCardType,bool isteam){ QList<int> result; // 默认情况:上家和自己想出的牌都符合规则 qSort(prevCards.begin(),prevCards.end(),lessThan); qSort(myCards.begin(),myCards.end(),lessThan); // 上一首牌的个数 int prevSize = prevCards.size(); int mySize = myCards.size(); // 我先出牌,上家没有牌 if (prevSize == 0 && mySize != 0) { result.append(myCards.size()-1); return result; } //如果对方为王炸,不能出牌。 if (prevCardType == WANG_ZHA) { qDebug("上家王炸,肯定不能出。"); return result; } ////如果我有王炸,可以出牌。 //if (mySize >= 2) { // QList<CardItem *> cards; // cards.append(myCards.at(0)); // cards.append(myCards.at(1)); // if (isDuiWang(cards)) { // return result; // } //} //// 集中判断对方不是炸弹,我出炸弹的情况 //if (prevCardType != ZHA_DAN) { // if (mySize < 4) { // return result; // } else { // for (int i = 0; i < mySize - 3; i++) { // int grade0 = myCards.at(i)->CardNum; // int grade1 = myCards.at(i + 1)->CardNum; // int grade2 = myCards.at(i + 2)->CardNum; // int grade3 = myCards.at(i + 3)->CardNum; // if (grade1 == grade0 && grade2 == grade0 // && grade3 == grade0) { // return result; // } // } // } //} int prevGrade = prevCards.at(0)->CardNum; // 比较2家的牌,主要有2种情况,1.我出和上家一种类型的牌,即对子管对子; // 2.我出炸弹,此时,和上家的牌的类型可能不同 // 王炸的情况已经排除 // 上家出单 if (prevCardType == DAN) { if(mySize >= prevSize){ // 一张牌可以大过上家的牌 for (int i = mySize - 1; i >= 0; i--) { int grade = myCards.at(i)->CardNum; if (grade > prevGrade) { result.append(i); // 只要有1张牌可以大过上家,则返回 break; } } } } // 上家出对子 else if (prevCardType == DUI_ZI) { if(mySize >= prevSize){ // 2张牌可以大过上家的牌 for (int i = mySize - 1; i >= 1; i--) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i - 1)->CardNum; if (grade0 == grade1) { if (grade0 > prevGrade) { result.append(i); result.append(i-1); // 只要有1对牌可以大过上家,则返回 break; } } } } } // 上家出3不带 else if (prevCardType == SAN_BU_DAI) { if(mySize >= prevSize){ // 3张牌可以大过上家的牌 for (int i = mySize - 1; i >= 2; i--) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i - 1)->CardNum; int grade2 = myCards.at(i - 2)->CardNum; if (grade0 == grade1 && grade0 == grade2) { if (grade0 > prevGrade) { result.append(i); result.append(i-1); result.append(i-2); // 只要3张牌可以大过上家,则返回 break; } } } } } // 上家出3带1 else if (prevCardType == SAN_DAI_YI) { if(mySize >= prevSize){ bool flag = false; int a = -1; // 3张牌可以大过上家的牌 for (int i = mySize - 1; i >= 2; i--) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i - 1)->CardNum; int grade2 = myCards.at(i - 2)->CardNum; if (grade0 == grade1 && grade0 == grade2) { if (grade0 > prevGrade) { // 只要3张牌可以大过上家,则返回true a = i; flag = true; result.append(i); result.append(i-1); result.append(i-2); break; } } } //如果三张已经找到,找最小的单张。 if(flag){ for (int i = mySize - 1; i >= 0; i--) { if(i != a && i != a-1 && i != a-2){ result.append(i); break; } } } } } // 上家出炸弹 else if (prevCardType == ZHA_DAN) { if(mySize >= prevSize){ // 4张牌可以大过上家的牌 for (int i = mySize - 1; i >= 3; i--) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i - 1)->CardNum; int grade2 = myCards.at(i - 2)->CardNum; int grade3 = myCards.at(i - 3)->CardNum; if (grade0 == grade1 && grade0 == grade2 && grade0 == grade3) { if (grade0 > prevGrade) { result.append(i); result.append(i-1); result.append(i-2); result.append(i-3); break; } } } } } // 上家出4带2 else if (prevCardType == SI_DAI_ER) { if(mySize >= prevSize){ bool flag = false; int a = -1; // 4张牌可以大过上家的牌 for (int i = mySize - 1; i >= 3; i--) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i - 1)->CardNum; int grade2 = myCards.at(i - 2)->CardNum; int grade3 = myCards.at(i - 3)->CardNum; if (grade0 == grade1 && grade0 == grade2 && grade0 == grade3) { if (grade0 > prevGrade) { result.append(i); result.append(i-1); result.append(i-2); result.append(i-3); flag = true; a = i; break; } } } //如果三张已经找到,找最小的两张。 if(flag){ for (int i = mySize - 1; i >= 0; i--) { if(result.size()>=6){ break; } if(i != a && i != a-1 && i != a-2 && i != a-3){ result.append(i); } } } } } // 上家出顺子 else if (prevCardType == SHUN_ZI) { //???????????????? if (mySize >= prevSize) { for (int i = mySize - 1; i >= prevSize - 1; i--) { QList<CardItem *> cards; for (int j = 0; j < prevSize; j++) { cards.append(myCards.at(i - j)); } CardType myCardType = getCardType(cards); if (myCardType == SHUN_ZI) { int myGrade2 = cards.at(cards.size()-1)->CardNum;// 最大的牌在最后 int prevGrade2 = prevCards.at(prevSize - 1)->CardNum;// 最大的牌在最后 if (myGrade2 > prevGrade2) { //return result; } } } } } // 上家出连对 else if (prevCardType == LIAN_DUI) { //???????????????? if (mySize >= prevSize) { for (int i = mySize - 1; i >= prevSize - 1; i--) { QList<CardItem *> cards; for (int j = 0; j < prevSize; j++) { cards.append(myCards.at(i - j)); } CardType myCardType = getCardType(cards); if (myCardType == LIAN_DUI) { int myGrade2 = cards.at(cards.size()-1)->CardNum;// 最大的牌在最后,getCardType会对列表排序 int prevGrade2 = prevCards.at(prevSize - 1)->CardNum;// 最大的牌在最后 if (myGrade2 > prevGrade2) { /*return result;*/ } } } } }else if (prevCardType == FEI_JI) { // 上家出飞机 //???????????????? if (mySize >= prevSize) { for (int i = mySize - 1; i >= prevSize - 1; i--) { QList<CardItem *> cards; for (int j = 0; j < prevSize; j++) { cards.append(myCards.at(i - j)); } CardType myCardType = getCardType(cards); if (myCardType == FEI_JI) { int myGrade4 = cards.at(4)->CardNum; // int prevGrade4 = prevCards.at(4)->CardNum;// if (myGrade4 > prevGrade4) { //return result; } } } } } //如果没有匹配的,出炸弹 if(result.size() <= 0){ if(mySize >= 4){ // 4张牌可以大过上家的牌 for (int i = mySize - 1; i >= 3; i--) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i - 1)->CardNum; int grade2 = myCards.at(i - 2)->CardNum; int grade3 = myCards.at(i - 3)->CardNum; if (grade0 == grade1 && grade0 == grade2 && grade0 == grade3) { if (grade0 > prevGrade) { result.append(i); result.append(i-1); result.append(i-2); result.append(i-3); break; } } } }else if(mySize >= 2){ QList<CardItem *> cards; cards.append(myCards.at(0)); cards.append(myCards.at(1)); if (isDuiWang(cards)) { result.append(0); result.append(1); } } } return result; }
/** * 判断我所有的牌中,是否存在能够管住上家的牌,决定出牌按钮是否显示 * @param myCards 我所有的牌 * * @param prevCards 上家的牌 * @param prevCardType 上家牌的类型 * @return 可以出牌,返回true;否则,返回false。 */ bool CardUtil::isOvercomePrev(QList<CardItem *> myCards, QList<CardItem *> prevCards, CardType prevCardType) { // 默认情况:上家和自己想出的牌都符合规则 qSort(prevCards.begin(),prevCards.end(),lessThan); qSort(myCards.begin(),myCards.end(),lessThan); // 上一首牌的个数 int prevSize = prevCards.size(); int mySize = myCards.size(); // 我先出牌,上家没有牌 if (prevSize == 0 && mySize != 0) { return true; } //如果对方为王炸,不能出牌。 if (prevCardType == WANG_ZHA) { qDebug("上家王炸,肯定不能出。"); return false; } //如果我有王炸,可以出牌。 if (mySize >= 2) { QList<CardItem *> cards; cards.append(myCards.at(0)); cards.append(myCards.at(1)); if (isDuiWang(cards)) { return true; } } // 集中判断对方不是炸弹,我出炸弹的情况 if (prevCardType != ZHA_DAN) { if (mySize < 4) { return false; } else { for (int i = 0; i < mySize - 3; i++) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i + 1)->CardNum; int grade2 = myCards.at(i + 2)->CardNum; int grade3 = myCards.at(i + 3)->CardNum; if (grade1 == grade0 && grade2 == grade0 && grade3 == grade0) { return true; } } } } int prevGrade = prevCards.at(0)->CardNum; // 比较2家的牌,主要有2种情况,1.我出和上家一种类型的牌,即对子管对子; // 2.我出炸弹,此时,和上家的牌的类型可能不同 // 王炸的情况已经排除 // 上家出单 if (prevCardType == DAN) { // 一张牌可以大过上家的牌 for (int i = mySize - 1; i >= 0; i--) { int grade = myCards.at(i)->CardNum; if (grade > prevGrade) { // 只要有1张牌可以大过上家,则返回true return true; } } } // 上家出对子 else if (prevCardType == DUI_ZI) { // 2张牌可以大过上家的牌 for (int i = mySize - 1; i >= 1; i--) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i - 1)->CardNum; if (grade0 == grade1) { if (grade0 > prevGrade) { // 只要有1对牌可以大过上家,则返回true return true; } } } } // 上家出3不带 else if (prevCardType == SAN_BU_DAI) { // 3张牌可以大过上家的牌 for (int i = mySize - 1; i >= 2; i--) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i - 1)->CardNum; int grade2 = myCards.at(i - 2)->CardNum; if (grade0 == grade1 && grade0 == grade2) { if (grade0 > prevGrade) { // 只要3张牌可以大过上家,则返回true return true; } } } } // 上家出3带1 else if (prevCardType == SAN_DAI_YI) { // 3带1 3不带 比较只多了一个判断条件 if (mySize < 4) { return false; } // 3张牌可以大过上家的牌 for (int i = mySize - 1; i >= 2; i--) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i - 1)->CardNum; int grade2 = myCards.at(i - 2)->CardNum; if (grade0 == grade1 && grade0 == grade2) { if (grade0 > prevGrade) { // 只要3张牌可以大过上家,则返回true return true; } } } } // 上家出炸弹 else if (prevCardType == ZHA_DAN) { // 4张牌可以大过上家的牌 for (int i = mySize - 1; i >= 3; i--) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i - 1)->CardNum; int grade2 = myCards.at(i - 2)->CardNum; int grade3 = myCards.at(i - 3)->CardNum; if (grade0 == grade1 && grade0 == grade2 && grade0 == grade3) { if (grade0 > prevGrade) { // 只要有4张牌可以大过上家,则返回true return true; } } } } // 上家出4带2 else if (prevCardType == SI_DAI_ER) { // 4张牌可以大过上家的牌 for (int i = mySize - 1; i >= 3; i--) { int grade0 = myCards.at(i)->CardNum; int grade1 = myCards.at(i - 1)->CardNum; int grade2 = myCards.at(i - 2)->CardNum; int grade3 = myCards.at(i - 3)->CardNum; if (grade0 == grade1 && grade0 == grade2 && grade0 == grade3) { // 只要有炸弹,则返回true return true; } } } // 上家出顺子 else if (prevCardType == SHUN_ZI) { if (mySize < prevSize) { return false; } else { for (int i = mySize - 1; i >= prevSize - 1; i--) { QList<CardItem *> cards; for (int j = 0; j < prevSize; j++) { cards.append(myCards.at(i - j)); } CardType myCardType = getCardType(cards); if (myCardType == SHUN_ZI) { int myGrade2 = cards.at(cards.size()-1)->CardNum;// 最大的牌在最后 int prevGrade2 = prevCards.at(prevSize - 1)->CardNum;// 最大的牌在最后 if (myGrade2 > prevGrade2) { return true; } } } } } // 上家出连对 else if (prevCardType == LIAN_DUI) { if (mySize < prevSize) { return false; } else { for (int i = mySize - 1; i >= prevSize - 1; i--) { QList<CardItem *> cards; for (int j = 0; j < prevSize; j++) { cards.append(myCards.at(i - j)); } CardType myCardType = getCardType(cards); if (myCardType == LIAN_DUI) { int myGrade2 = cards.at(cards.size()-1)->CardNum;// 最大的牌在最后,getCardType会对列表排序 int prevGrade2 = prevCards.at(prevSize - 1)->CardNum;// 最大的牌在最后 if (myGrade2 > prevGrade2) { return true; } } } } } // 上家出飞机 else if (prevCardType == FEI_JI) { if (mySize < prevSize) { return false; } else { for (int i = mySize - 1; i >= prevSize - 1; i--) { QList<CardItem *> cards; for (int j = 0; j < prevSize; j++) { cards.append(myCards.at(i - j)); } CardType myCardType = getCardType(cards); if (myCardType == FEI_JI) { int myGrade4 = cards.at(4)->CardNum; // int prevGrade4 = prevCards.at(4)->CardNum;// if (myGrade4 > prevGrade4) { return true; } } } } } // 默认不能出牌 return false; }
bool GameMain::init() { if(!Layer::init()){return false;} createBackground(); createLabel(); createCards(); createBoards(); createMenuButton(); settingStart(); auto listener=EventListenerTouchOneByOne::create(); //ドラッグ開始 listener->onTouchBegan=[this](Touch* touch,Event* event){ //// if(!_moveCards.empty()){ if(_moveCards.front()->getNumberOfRunningActions()){//ダブルタッチアニメーション中 auto card=_moveCards.front(); card->stopAllActions();//アニメーションをキャンセル this->dragTouchEnded(_homeCellLayer->getHomeCellTalonPosition(card->getCardType()));//CallFuncの処理を実行 } } //// auto position=touch->getLocation(); if(_gameState==GameState::TOUCH_WAITING){ _moveCards.clear(); if(TALON_AREA_RECT.containsPoint(position)){ _moveCards=_talonLayer->dragCards(position); this->setDragLayer(_talonLayer); }else if(BOARD_CARD_AREA_RECT.containsPoint(position)){ _moveCards=_boardCardLayer->dragCards(position); this->setDragLayer(_boardCardLayer); }else if(HOME_CELL_AREA_RECT.containsPoint(position)){ _moveCards=_homeCellLayer->dragCards(position); this->setDragLayer(_homeCellLayer); } if(!_moveCards.empty()){//カードがドラッグできれば auto cardPosition=Vec2(0,-CARD_SIZE.height/4); int z=1; for(auto card:_moveCards){ card->setPosition(cardPosition); _moveLayer->addChild(card,z); cardPosition+=TALON_DIFF; z++; } _moveLayer->setPosition(position); _gameState=GameState::DRAG; //ダブルタップ処理 _doubleTouchFlag=false; if(_dragLayer==_talonLayer || _dragLayer==_boardCardLayer){//山札あるいは場札からのドロップ if(_homeCellLayer->checkDropCard(_moveCards)){//ホームセルに置けるカードである _doubleTouchFlag=true;//ダブルタップ処理フラグをtrue _oneTouch=false;//一回タップされたかのフラグをfalse _touchTime=0;//タップ時間の初期化 } } }else{ this->setDragLayer(nullptr); } } return true; }; //ドロップ、山札の切り替え listener->onTouchEnded=[this](Touch* touch,Event* event){ auto position=touch->getLocation(); if(_gameState==GameState::TOUCH_WAITING){ if(TALON_AREA_RECT.containsPoint(position)){ if(_talonLayer->touchTalonCard(position)){ //山札が一巡 if(_talonLayer->getPullCount()==3){ //引くカードが3枚ずつの場合-20 this->updateScore(-20); }else if(_talonLayer->getPullCount()==1){ //引くカードが1枚ずつの場合-100 this->updateScore(-100); }else{ log("Talon::_pullCoount neither 1 nor 3."); } } } }else if(_gameState==GameState::DRAG){ if(_doubleTouchFlag){//ダブルタップを行う可能性がある if(_oneTouch){//既に一度タップされている if(_touchTime<TOUCH_TIME_PERIOD){//ダブルタップ受付時間以内 this->unschedule(DRAG_SCHEDULE); auto card=_moveCards.front(); //this->dragTouchEnded(_homeCellLayer->getHomeCellTalonPosition(card->getCardType())); _doubleTouchFlag=false; //// //カードを移すホームセルの位置 auto homeCellPosition=_homeCellLayer->getHomeCellTalonPosition(card->getCardType()); //_moveLayerとGameMainレイヤーは基準座標が違うためconvertする card->runAction(Sequence::create(MoveTo::create(0.3,_moveLayer->convertToNodeSpace(homeCellPosition)) ,CallFunc::create([this,homeCellPosition](){ this->dragTouchEnded(homeCellPosition); }) ,NULL)); //// } }else{ if(_touchTime<TOUCH_TIME_PERIOD){//ダブルタップ受付時間以内 _oneTouch=true; //ダブルタップされなかったときのためにスケジュールを設定 this->scheduleOnce([this,position](float dt){ this->dragTouchEnded(position); _doubleTouchFlag=false; },TOUCH_TIME_PERIOD-_touchTime+0.1,DRAG_SCHEDULE); }else{ this->dragTouchEnded(position); _doubleTouchFlag=false; } } }else{ this->dragTouchEnded(position); } } }; //ドロップ中の移動 listener->onTouchMoved=[this](Touch* touch,Event* event){ auto position=touch->getLocation(); if(_gameState==GameState::DRAG){ _moveLayer->setPosition(position); } }; //キャンセル listener->onTouchCancelled=[this](Touch* touch,Event* event){ if(_gameState==GameState::DRAG){ _moveLayer->removeAllChildren(); _dragLayer->cancelCards(_moveCards); _gameState=GameState::TOUCH_WAITING; } }; //test Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener,this); return true; }