int minimaxNoAlphaBeta(state s, playerNum p, int depth) { num_nodes_searched++; playerNum trickLeader = (getP1LeadTrick(s)) ? PLAYER_ONE : PLAYER_TWO; playerNum actingPlayer = (getPLastMoves(s, trickLeader)) ? 1-trickLeader : trickLeader; moveGroup mg = generateAllMoves(s, actingPlayer); unsigned int mg_size = sizeOfMoveGroup(mg); int moveScores[mg_size]; for(int i=0; i < (int) mg_size; i++) { state sMinimax = s; move m = getNextMoveFromMoveGroup(&mg); sMinimax = setNextMove(sMinimax, actingPlayer, m); if(getDealEnded(sMinimax)) { int pointsYouGained = ((int) getPCurrGamePoints(sMinimax, p)) - ((int) getPCurrGamePoints(s, p)); int pointsOppGained = ((int) getPCurrGamePoints(sMinimax, 1-p)) - ((int) getPCurrGamePoints(s, 1-p)); moveScores[i] = pointsYouGained - pointsOppGained; continue; } moveScores[i] = minimaxNoAlphaBeta(sMinimax, p, depth+1); } if(p == actingPlayer) { //maximise int maxScore = -4; for(int i=0; i < mg_size; i++) { if(moveScores[i] > maxScore) { maxScore = moveScores[i]; } } return maxScore; } else { //minimise int minScore = 4; for(int i=0; i < mg_size; i++) { if(moveScores[i] < minScore) { minScore = moveScores[i]; } } return minScore; } fail("Didn't return correctly from minimax() in Agents module\n"); return -1; }
bool checkResult(board& b) { if (b.fiftyMoves > 100) { printf("1/2-1/2 {fifty move rule (claimed by PENIQLIOTUV)}"); return true; } if (threeFoldRep(b) >= 2) { printf("1/2-1/2 {3-fold repetition (claimed by PENIQLIOTUV)}"); return true; } if (drawMaterial(b) == true) { printf("1/2-1/2 {insufficient material (claimed by PENIQLIOTUV)}"); return true; } moveList* list = new moveList; generateAllMoves(b,list); int found = 0; for(int i = 0; i < list->count; ++i) { if (!makeMove(b,list->ml_getMove(i))) { continue; } found++; takeMove(b); break; } if(found != 0) { return false; } bool inCheck = sqAttacked(b.kingSquare[b.side],b.side^1,b); if(inCheck == true) { if(b.side == WHITE) { printf("0-1 {black mates (claimed by PENIQLIOTUV)}"); return true; } else { printf("0-1 {white mates (claimed by PENIQLIOTUV)}"); return true; } } else { printf("\n1/2-1/2 {stalemate (claimed by PENIQLIOTUV)}"); return true; } delete list; return false; }
move askMinimaxAction(state s, playerNum p, int *extraArgs) { moveGroup mg = generateAllMoves(s, p); unsigned int numUnseenCards = numCardsLeft(getAllUnseenCards(s, p)); unsigned int numIters = 10; int **allMinimaxScores = malloc(numIters*sizeof(int *)); for(unsigned int i=0; i < numIters; i++) { allMinimaxScores[i] = malloc(sizeOfMoveGroup(mg)*sizeof(int)); } switch((minimaxType) extraArgs[0]) { case RANDOM: startMinimaxRandom(s, mg, allMinimaxScores, numIters, numUnseenCards, p); break; case NUM_MINIMAX_TYPES: startMinimaxRandomNoAlphaBeta(s, mg, allMinimaxScores, numIters, numUnseenCards, p); break; default: break; } move chosenMove = 0; return chosenMove; }
int minimax(state s, playerNum p, int depth, int alpha, int beta) { num_nodes_searched++; playerNum trickLeader = (getP1LeadTrick(s)) ? PLAYER_ONE : PLAYER_TWO; playerNum actingPlayer = (getPLastMoves(s, trickLeader)) ? 1-trickLeader : trickLeader; moveGroup mg = generateAllMoves(s, actingPlayer); unsigned int mg_size = sizeOfMoveGroup(mg); int moveScores[mg_size]; if(p == actingPlayer) { for(int i=0; i < (int) mg_size; i++) { state sMinimax = s; move m = getNextMoveFromMoveGroup(&mg); sMinimax = setNextMove(sMinimax, actingPlayer, m); if(getDealEnded(sMinimax)) { int pointsYouGained = ((int) getPCurrGamePoints(sMinimax, p)) - ((int) getPCurrGamePoints(s, p)); int pointsOppGained = ((int) getPCurrGamePoints(sMinimax, 1-p)) - ((int) getPCurrGamePoints(s, 1-p)); moveScores[i] = pointsYouGained - pointsOppGained; alpha = (moveScores[i] > alpha) ? moveScores[i] : alpha; if(alpha >= beta) { fprintf(f, "%d,%d,%d,%d\n", depth, getTalonClosed(sMinimax), i+1, mg_size); return alpha; } continue; } moveScores[i] = minimax(sMinimax, p, depth+1, alpha, beta); alpha = (moveScores[i] > alpha) ? moveScores[i] : alpha; if(alpha >= beta) { fprintf(f, "%d,%d,%d,%d\n", depth, getTalonClosed(sMinimax), i+1, mg_size); return alpha; } } return alpha; } else { for(int i=0; i < (int) mg_size; i++) { state sMinimax = s; move m = getNextMoveFromMoveGroup(&mg); sMinimax = setNextMove(sMinimax, actingPlayer, m); if(getDealEnded(sMinimax)) { int pointsYouGained = ((int) getPCurrGamePoints(sMinimax, p)) - ((int) getPCurrGamePoints(s, p)); int pointsOppGained = ((int) getPCurrGamePoints(sMinimax, 1-p)) - ((int) getPCurrGamePoints(s, 1-p)); moveScores[i] = pointsYouGained - pointsOppGained; beta = (moveScores[i] < beta) ? moveScores[i] : beta; if(beta <= alpha) { fprintf(f, "%d,%d,%d,%d\n", depth, getTalonClosed(sMinimax), i+1, mg_size); return beta; } continue; } moveScores[i] = minimax(sMinimax, p, depth+1, alpha, beta); beta = (moveScores[i] < beta) ? moveScores[i] : beta; if(beta <= alpha) { fprintf(f, "%d,%d,%d,%d\n", depth, getTalonClosed(sMinimax), i+1, mg_size); return beta; } } return beta; } fail("Didn't return correctly from minimax() in Agents module\n"); return -1; }
int BOARD::alphabeta(int depth,int alpha,int beta,bool donull) { if(depth==0) { //info.nodes++; return quiescence(alpha,beta); //return evaluate(); } if((info.nodes & 2047) == 0) check(); info.nodes++; if((repeat() || fifty >=100) & ply) return 0; if(ply >MAXDEPTH -1) return evaluate(); bool kingsafe; int pos=(int)log2(board[side+4] & -board[side+4]); kingsafe=isSafe(pos,side); if(!kingsafe) depth++; int score = -INFINITE; /* if(donull && ply && kingsafe && depth >4 && bigPiece[side] >0) { makeNullMove(); score=-alphabeta(depth-4,-beta,-beta+1,false); unmakeNullMove(); if(info.stopped) return 0; if(score>=beta) return beta; }*/ int legal=0; int oldalpha=alpha; int bestmove=NOMOVE; score=-INFINITE; MOVE_LIST moveList; moveList.count=0; generateAllMoves(moveList); int pvMove=getPvMove(); if(pvMove != NOMOVE) { for(int i=0;i<moveList.count;i++) { if(moveList.l[i].move == pvMove) { moveList.l[i].score=2000000; break; } } } std::sort(moveList.l,moveList.l+moveList.count,so); for(int i=0;i<moveList.count;i++) { //pickBest(i,moveList); if(!makeMove(moveList.l[i].move)) continue; legal++; score=-alphabeta(depth-1,-beta,-alpha,donull); unmakeMove(); if(info.stopped) return 0; if(score >alpha) { if(score >=beta) { if(legal==1) info.fhf++; info.fh++; if(CAP(moveList.l[i].move) == EMPTY) { searchKillers[1][depth]=searchKillers[0][depth]; searchKillers[0][depth]=moveList.l[i].move; } return beta; //beta - cutoff } alpha=score; bestmove=moveList.l[i].move; if(CAP(moveList.l[i].move) == EMPTY) searchHistory[cboard[FROM(bestmove)]][TO(bestmove)]+=depth; } } if(legal == 0) { if(!kingsafe) return -MATE + ply; else return 0; } if(alpha != oldalpha) storePv(bestmove); return alpha; }
void testGetMoves() { testMoveGroup(); unsigned char pTypes = ((unsigned char) HUMAN) + (((unsigned char) HUMAN) << 4); state s = newStartingState(pTypes); pile p1Hand = newCardRankSuit(KING, SPADES) | newCardRankSuit(ACE, CLUBS) | newCardRankSuit(JACK, HEARTS) | newCardRankSuit(QUEEN, HEARTS) | newCardRankSuit(KING, HEARTS); pile p2Hand = newCardRankSuit(TEN, SPADES) | newCardRankSuit(TEN, CLUBS) | newCardRankSuit(JACK, DIAMONDS) | newCardRankSuit(QUEEN, DIAMONDS) | newCardRankSuit(KING, DIAMONDS); s.pHands = (((unsigned long long) p2Hand) << 32) + (unsigned long long) p1Hand; s.trumpCard = newCardRankSuit(TEN, HEARTS); s = setP1LeadTrick(s, true); moveGroup mg1 = newEmptyMoveGroup(s, PLAYER_ONE); if(numCardsLeft(mg1.groups[5] & DECK) != 0) {fail("newEmptyMoveGroup() failed in GetMoves module\n");} mg1 = addAllMarriageMoves_NOCLOSE(s, getPHand(s, PLAYER_ONE), mg1); if(numCardsLeft(mg1.groups[5] & DECK) != 2) {fail("addAllMarriageMoves_NOCLOSE() failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[0] & DECK) != 0) {fail("newEmptyMoveGroup() failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[1] & DECK) != 0) {fail("newEmptyMoveGroup() failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[4] & DECK) != 0) {fail("newEmptyMoveGroup() failed in GetMoves module\n");} mg1 = addTrumpSwapMoves_NOCLOSE(s, getPHand(s, PLAYER_ONE), mg1); if(numCardsLeft(mg1.groups[0] & DECK) != 2) {fail("addTrumpSwapMoves_NOCLOSE() 1failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[1] & DECK) != 0) {fail("addTrumpSwapMoves_NOCLOSE() 2failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[4] & DECK) != 5) {fail("addTrumpSwapMoves_NOCLOSE() 3failed in GetMoves module\n");} if(!contains(mg1.groups[4] & DECK, newCardRankSuit(KING, SPADES))) {fail("addTrumpSwapMoves_NOCLOSE() 1failed in GetMoves module\n");} if(!contains(mg1.groups[4] & DECK, newCardRankSuit(ACE, CLUBS))) {fail("addTrumpSwapMoves_NOCLOSE() 2failed in GetMoves module\n");} if(!contains(mg1.groups[4] & DECK, newCardRankSuit(QUEEN, HEARTS))) {fail("addTrumpSwapMoves_NOCLOSE() 3failed in GetMoves module\n");} if(!contains(mg1.groups[4] & DECK, newCardRankSuit(KING, HEARTS))) {fail("addTrumpSwapMoves_NOCLOSE() 4failed in GetMoves module\n");} if(!contains(mg1.groups[4] & DECK, newCardRankSuit(TEN, HEARTS))) {fail("addTrumpSwapMoves_NOCLOSE() 5failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[9] & DECK) != 0) {fail("newEmptyMoveGroup() failed in GetMoves module\n");} mg1 = addAllCardMovesNoOptions_NOCLOSE(s, getPHand(s, PLAYER_ONE), mg1); if(numCardsLeft(mg1.groups[9] & DECK) != 5) {fail("addAllCardMovesNoOptions_NOCLOSE() failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(KING, SPADES))) {fail("addAllCardMovesNoOptions_NOCLOSE() 1failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(ACE, CLUBS))) {fail("addAllCardMovesNoOptions_NOCLOSE() 2failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(QUEEN, HEARTS))) {fail("addAllCardMovesNoOptions_NOCLOSE() 3failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(KING, HEARTS))) {fail("addAllCardMovesNoOptions_NOCLOSE() 4failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(JACK, HEARTS))) {fail("addAllCardMovesNoOptions_NOCLOSE() 5failed in GetMoves module\n");} for(unsigned int i=0; i < 12; i++) { mg1.n += numCardsLeft(mg1.groups[i] & DECK); } if(sizeOfMoveGroup(mg1) != 14) {fail("sizeOfMoveGroup() failed in GetMoves module\n");} mg1 = addCloseTalonMoves_NOCLOSE(mg1); mg1.n = 0; for(unsigned int i=0; i < 12; i++) { mg1.n += numCardsLeft(mg1.groups[i] & DECK); } if(sizeOfMoveGroup(mg1) != 28) {fail("sizeOfMoveGroup() failed in GetMoves module\n");} mg1 = newEmptyMoveGroup(s, PLAYER_ONE); mg1 = generateAllLeadMoves_NOCLOSE(s, PLAYER_ONE); if(sizeOfMoveGroup(mg1) != 28) {fail("generateAllLeadMoves_NOCLOSE() failed in GetMoves module\n");} mg1 = newEmptyMoveGroup(s, PLAYER_ONE); mg1 = generateAllLeadMoves_CLOSE(s, PLAYER_ONE); if(sizeOfMoveGroup(mg1) != 28) {fail("generateAllLeadMoves_CLOSE() failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[9] & DECK) != 2) {fail("generateAllLeadMoves_CLOSE() failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[6] & DECK) != 2) {fail("generateAllLeadMoves_CLOSE() failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[3] & DECK) != 2) {fail("generateAllLeadMoves_CLOSE() failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[0] & DECK) != 2) {fail("generateAllLeadMoves_CLOSE() failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(KING, HEARTS))) {fail("addTrumpSwapMoves_NOCLOSE() 1failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(QUEEN, HEARTS))) {fail("addTrumpSwapMoves_NOCLOSE() 2failed in GetMoves module\n");} if(!contains(mg1.groups[6] & DECK, newCardRankSuit(KING, HEARTS))) {fail("addTrumpSwapMoves_NOCLOSE() 1failed in GetMoves module\n");} if(!contains(mg1.groups[6] & DECK, newCardRankSuit(QUEEN, HEARTS))) {fail("addTrumpSwapMoves_NOCLOSE() 2failed in GetMoves module\n");} if(!contains(mg1.groups[3] & DECK, newCardRankSuit(KING, HEARTS))) {fail("addTrumpSwapMoves_NOCLOSE() 1failed in GetMoves module\n");} if(!contains(mg1.groups[3] & DECK, newCardRankSuit(QUEEN, HEARTS))) {fail("addTrumpSwapMoves_NOCLOSE() 2failed in GetMoves module\n");} if(!contains(mg1.groups[0] & DECK, newCardRankSuit(KING, HEARTS))) {fail("addTrumpSwapMoves_NOCLOSE() 1failed in GetMoves module\n");} if(!contains(mg1.groups[0] & DECK, newCardRankSuit(QUEEN, HEARTS))) {fail("addTrumpSwapMoves_NOCLOSE() 2failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[2] & DECK) != 5) {fail("generateAllLeadMoves_CLOSE() failed in GetMoves module\n");} if(!contains(mg1.groups[2] & DECK, newCardRankSuit(KING, SPADES))) {fail("generateAllLeadMoves_CLOSE() 1failed in GetMoves module\n");} if(!contains(mg1.groups[2] & DECK, newCardRankSuit(ACE, CLUBS))) {fail("generateAllLeadMoves_CLOSE() 2failed in GetMoves module\n");} if(!contains(mg1.groups[2] & DECK, newCardRankSuit(QUEEN, HEARTS))) {fail("generateAllLeadMoves_CLOSE() 3failed in GetMoves module\n");} if(!contains(mg1.groups[2] & DECK, newCardRankSuit(KING, HEARTS))) {fail("generateAllLeadMoves_CLOSE() 4failed in GetMoves module\n");} if(!contains(mg1.groups[2] & DECK, newCardRankSuit(TEN, HEARTS))) {fail("generateAllLeadMoves_CLOSE() 5failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[11] & DECK) != 5) {fail("generateAllLeadMoves_CLOSE() failed in GetMoves module\n");} if(!contains(mg1.groups[11] & DECK, newCardRankSuit(KING, SPADES))) {fail("generateAllLeadMoves_CLOSE() 1failed in GetMoves module\n");} if(!contains(mg1.groups[11] & DECK, newCardRankSuit(ACE, CLUBS))) {fail("generateAllLeadMoves_CLOSE() 2failed in GetMoves module\n");} if(!contains(mg1.groups[11] & DECK, newCardRankSuit(QUEEN, HEARTS))) {fail("generateAllLeadMoves_CLOSE() 3failed in GetMoves module\n");} if(!contains(mg1.groups[11] & DECK, newCardRankSuit(KING, HEARTS))) {fail("generateAllLeadMoves_CLOSE() 4failed in GetMoves module\n");} if(!contains(mg1.groups[11] & DECK, newCardRankSuit(JACK, HEARTS))) {fail("generateAllLeadMoves_CLOSE() 5failed in GetMoves module\n");} mg1 = newEmptyMoveGroup(s, PLAYER_ONE); mg1 = generateAllMoves(s, PLAYER_ONE); if(sizeOfMoveGroup(mg1) != 28) {fail("generateAllMoves() 0failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[0] & DECK) != 2) {fail("generateAllMoves() 1failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[1] & DECK) != 0) {fail("generateAllMoves() 2failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[4] & DECK) != 5) {fail("generateAllMoves() 3failed in GetMoves module\n");} if(!contains(mg1.groups[4] & DECK, newCardRankSuit(KING, SPADES))) {fail("generateAllMoves() 1failed in GetMoves module\n");} if(!contains(mg1.groups[4] & DECK, newCardRankSuit(ACE, CLUBS))) {fail("generateAllMoves() 2failed in GetMoves module\n");} if(!contains(mg1.groups[4] & DECK, newCardRankSuit(QUEEN, HEARTS))) {fail("generateAllMoves() 3failed in GetMoves module\n");} if(!contains(mg1.groups[4] & DECK, newCardRankSuit(KING, HEARTS))) {fail("generateAllMoves() 4failed in GetMoves module\n");} if(!contains(mg1.groups[4] & DECK, newCardRankSuit(TEN, HEARTS))) {fail("generateAllMoves() 5failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[9] & DECK) != 5) {fail("generateAllMoves() failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(KING, SPADES))) {fail("generateAllMoves() 1failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(ACE, CLUBS))) {fail("generateAllMoves() 2failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(QUEEN, HEARTS))) {fail("generateAllMoves() 3failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(KING, HEARTS))) {fail("generateAllMoves() 4failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(JACK, HEARTS))) {fail("generateAllMoves() 5failed in GetMoves module\n");} s.pLastMoves |= newCardRankSuit(KING, SPADES); s = removePHandCard(s, PLAYER_ONE, newCardRankSuit(KING, SPADES)); moveGroup mg2 = generateAllMoves(s, PLAYER_TWO); if(sizeOfMoveGroup(mg2) != 5) {fail("generateAllMoves() 0failed in GetMoves module\n");} if(numCardsLeft(mg2.groups[9] & DECK) != 5) {fail("generateAllMoves() failed in GetMoves module\n");} if(!contains(mg2.groups[9] & DECK, newCardRankSuit(TEN, SPADES))) {fail("generateAllMoves() 1failed in GetMoves module\n");} if(!contains(mg2.groups[9] & DECK, newCardRankSuit(TEN, CLUBS))) {fail("generateAllMoves() 2failed in GetMoves module\n");} if(!contains(mg2.groups[9] & DECK, newCardRankSuit(JACK, DIAMONDS))) {fail("generateAllMoves() 3failed in GetMoves module\n");} if(!contains(mg2.groups[9] & DECK, newCardRankSuit(QUEEN, DIAMONDS))) {fail("generateAllMoves() 4failed in GetMoves module\n");} if(!contains(mg2.groups[9] & DECK, newCardRankSuit(KING, DIAMONDS))) {fail("generateAllMoves() 5failed in GetMoves module\n");} s = setP1LeadTrick(s, false); mg2 = generateAllMoves(s, PLAYER_TWO); if(sizeOfMoveGroup(mg2) != 14) {fail("generateAllMoves() 0failed in GetMoves module\n");} s = setPLastMovesNull(s); s = setPClosedTalon(s, PLAYER_ONE); mg2 = generateAllMoves(s, PLAYER_TWO); if(sizeOfMoveGroup(mg2) != 7) {fail("generateAllMoves() 0failed in GetMoves module\n");} if(numCardsLeft(mg2.groups[9] & DECK) != 5) {fail("generateAllMoves() failed in GetMoves module\n");} if(!contains(mg2.groups[9] & DECK, newCardRankSuit(TEN, SPADES))) {fail("generateAllMoves() 1failed in GetMoves module\n");} if(!contains(mg2.groups[9] & DECK, newCardRankSuit(TEN, CLUBS))) {fail("generateAllMoves() 2failed in GetMoves module\n");} if(!contains(mg2.groups[9] & DECK, newCardRankSuit(JACK, DIAMONDS))) {fail("generateAllMoves() 3failed in GetMoves module\n");} if(!contains(mg2.groups[9] & DECK, newCardRankSuit(QUEEN, DIAMONDS))) {fail("generateAllMoves() 4failed in GetMoves module\n");} if(!contains(mg2.groups[9] & DECK, newCardRankSuit(KING, DIAMONDS))) {fail("generateAllMoves() 5failed in GetMoves module\n");} if(numCardsLeft(mg2.groups[6] & DECK) != 2) {fail("generateAllMoves() failed in GetMoves module\n");} if(!contains(mg2.groups[6] & DECK, newCardRankSuit(QUEEN, DIAMONDS))) {fail("generateAllMoves() 4failed in GetMoves module\n");} if(!contains(mg2.groups[6] & DECK, newCardRankSuit(KING, DIAMONDS))) {fail("generateAllMoves() 5failed in GetMoves module\n");} s.pLastMoves |= ((unsigned long long) newCardRankSuit(JACK, DIAMONDS)) << 32; s = removePHandCard(s, PLAYER_TWO, newCardRankSuit(JACK, DIAMONDS)); mg1 = generateAllMoves(s, PLAYER_ONE); if(sizeOfMoveGroup(mg1) != 3) {fail("generateAllMoves() failed in GetMoves module\n");} if(numCardsLeft(mg1.groups[9] & DECK) != 3) {fail("generateAllMoves() failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(QUEEN, HEARTS))) {fail("generateAllMoves() 3failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(KING, HEARTS))) {fail("generateAllMoves() 4failed in GetMoves module\n");} if(!contains(mg1.groups[9] & DECK, newCardRankSuit(JACK, HEARTS))) {fail("generateAllMoves() 5failed in GetMoves module\n");} // Trump: // 100, TS // Hand: // 1000, KD // 800, QD // 20, JS // 4, KH // 1, JH // 500000 // 301800 // d00000 // b01800 // 101905 // 400000 // 201800 // c00000 // a01800 // 1825 // 901905 // 801825 puts("GetMoves Module OK\n"); }