2014年5月7日 星期三

大老二


#include <stdio.h>
#include <stdlib.h>

int const cardsPerSuit = 13, haveCards = 13;
int tempCountArray[haveCards+1] = {0}; //紀錄1~13各點數出現次數

/** return card numbers:
From one to thirteen */
inline int cardNum(int card){
return card%cardsPerSuit+1;
}

//Initializing CountArray once
inline void setTempCountArray(int cards[]){
static bool isSetTempCountArray = false;
if(!isSetTempCountArray){
for(int i=0; i<haveCards && cards[i]!=-1; i++){
int cardpoint = cardNum(cards[i]);
tempCountArray[cardpoint]++;
}
isSetTempCountArray = true;
}
}

//Single count
int cardsSingle(int cards[]){
int counts = 0;
while(cards[counts]!=-1 && counts<haveCards){
counts++;
}
return counts;
}

// Pair count
int cardsPair(int cards[]){
int counts = 0;
setTempCountArray(cards);

//等於或大於2者遞增計數
for(int i=1; i<cardsPerSuit+1; i++){
switch(tempCountArray[i]){
case 2: counts+=1; break;
case 3: counts+=3; break;
case 4: counts+=6; break;
default: ;//error or less than 2
}
}

return counts;
}

//Three of a Kind count
int cardsThreeKind(int cards[]){
int counts = 0;
setTempCountArray(cards);

//等於或大於3者遞增計數
for(int i=1; i<cardsPerSuit+1; i++){
switch(tempCountArray[i]){
case 3: counts+=1; break;
case 4: counts+=4; break;
default: ;//error or less than 3
}
}

return counts;
}

//Straight count
int cardsStraight(int cards[]){
int counts = 0;
setTempCountArray(cards);

/** cards pattern order is:
1 2 3 4 5 6 7 8 9 10 11 12 13 1 */
int cardsPattern = 0x0;
for(int i=1; i<cardsPerSuit+1; i++){
if(tempCountArray[i]) //有出現
cardsPattern |= 1; //設為1
cardsPattern<<=1;
}
if(tempCountArray[1]) cardsPattern|=1; //set most right bit
//printf("%0x\n",cardsPattern);
/** cards bound pattern is:
1 2 3 4 5 6 7 8 9 10 11 12 13 1
1 1 1 1 1 0 0 0 0  0  0  0  0 0 */
int boundPattern = 0x3E00;
for(int mapPattern = 0x1F,i=13; mapPattern<=boundPattern; mapPattern<<=1,i--){
if((cardsPattern & mapPattern) == mapPattern){ //有順子存在
int distinctSuitCount = 1;
for(int j=i; j>i-5; j--){ //順子也分花色
distinctSuitCount *= tempCountArray[j%13+1]; //取得對映的不同花色順子數量
}
counts+=distinctSuitCount;
}
}

return counts;
}

//Full House count
int cardsFullHouse(int cards[]){
int counts = 0;
setTempCountArray(cards);

int justPair=0;
int pairsFromThree = 0;
int pairsFromFour = 0;
int threeKind=0;
for(int i=1; i<cardsPerSuit+1; i++){
switch(tempCountArray[i]){
case 2: justPair++; break;
case 3: threeKind+=1;
   pairsFromThree++; break;
case 4: threeKind+=4;
pairsFromFour++; break;
default: ;//error or less than 2
}
}
//printf("threeKind:%d\n",threeKind);
//printf("pairsFromThree:%d\n",pairsFromThree);
//printf("pairsFromFour:%d\n",pairsFromFour);

counts = justPair * threeKind; //三條一對組合
if(pairsFromThree>1) //三條三條組合
counts += (pairsFromThree-1)*3 * threeKind;
if(pairsFromFour>1) //三條四條組合
counts += (pairsFromFour-1)*6 * threeKind;

return counts;
}

//Four of a Kind count
int cardsFourKind(int cards[]){
int counts = 0;
setTempCountArray(cards);

int fourKind=0;
for(int i=1; i<cardsPerSuit+1; i++){
switch(tempCountArray[i]){
case 4: fourKind+=1; break;
default: ;//error or less than 4
}
}
counts = (haveCards-4)*fourKind;

return counts;
}

// Insertion sort
inline void InsertionSort(int a[], int n){
int i,j,up;
for(i=1; i<=n-1; i++){
up = a[i];
j = i;
while(a[j-1]>up && j>=1){
a[j] = a[j-1];
j--;
}
a[j] = up;
}
}

//
int checkLast(int cards[], int i){
if(cards[i]%cardsPerSuit==cardsPerSuit-1){
for(int j=i; j>=0; j--){
if(cards[j]==cards[i]-cardsPerSuit+1){
return 1;
}
}
}
return 0;
}

//Straight Flush count
int straightFlush(int cards[]){
int counts = 0;
//13張牌排序
InsertionSort(cards,haveCards);

int sequenceNumber; //need initialization
sequenceNumber = 1;
for(int i=0; i<haveCards; i++){
if(cards[i]==-1){
continue;
}

if(i<haveCards-1 && cards[i]+1==cards[i+1] && cards[i]/13==cards[i+1]/13){
sequenceNumber++;
//printf("squence:%d\n",sequenceNumber);
}//i==haveCards-1 時一定會進入
else{
//連續數字產生同花順數量
if(sequenceNumber>=4){
sequenceNumber-=4;
counts+=sequenceNumber;
counts+=checkLast(cards, i);
}
sequenceNumber = 1; //重新初始化
}
}
return counts;
}

//Total cards type count
int totalCardsType(int cards[]){
setTempCountArray(cards);
return cardsSingle(cards) + cardsPair(cards) + cardsThreeKind(cards) +
cardsStraight(cards) + cardsFullHouse(cards) + cardsFourKind(cards)+
straightFlush(cards);
}

int main(int argc, char* argv[]){

//假設不足張數可以設定為-1作default
int cards[haveCards] = {8, 9 ,10 ,11 ,12 ,13 ,14 ,15, 16 ,17 ,18 ,19 ,20};

//單張
printf("%s%d\n","Single:",cardsSingle(cards));
//一對
printf("%s%d\n","Pair:",cardsPair(cards));
//三條
printf("%s%d\n","Three of a Kind:",cardsThreeKind(cards));
//順子
printf("%s%d\n","Straight:",cardsStraight(cards));
//葫蘆
printf("%s%d\n","Full House:",cardsFullHouse(cards));
//鐵枝
printf("%s%d\n","Four of a Kind:",cardsFourKind(cards));
//同花順
printf("%s%d\n","Straight Flush:",straightFlush(cards));
//所有組合
printf("%s%d\n","Sample Output:",totalCardsType(cards));

//問題:順子會包含同花順,不知是否該重複計算
system("PAUSE");
return 0;
}

沒有留言:

張貼留言