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

#define N 52
#define TIMES 100     // 遊戲戰績儲存次數上限常數 
#define BUF_SIZE 3

/* run this program using the console pauser or add your own getch, system("pause") or input loop */


const char flower_table[4] = { '\5' , '\4' , '\3' , '\6'};  // ascii code， \5 \4 \3 \6 分別代表梅花、方塊、紅心、黑桃
const char number_table[13][BUF_SIZE] = {
      " A" , " 2" , " 3" , " 4" , " 5" , " 6" ,
	  " 7" , " 8" , " 9" , "10" , " J" , " Q" ," K" , " "};
	  
	/*  ※花色與數字的決定方法 
	for (i = 0; i!=52; ++i){
    flower = i % 4; // 花色, 0~3
    number = i / 4; // 數字, 0~12
    }
    */
    
typedef struct handle Handle;
struct handle{
	Handle *node ;
	int card ;     // 牌值 
	int flower;    // 計算牌的花色 
	int number;    // 計算牌的點數 
	float point;   // 這一局的點數 
	float fnumber; // 這張牌的點數 
	int cardnum;   // 手牌數量 
};
    
    
typedef struct player Player;    
struct player{
	char record[TIMES] ;  // 戰績 
	int record_flag ;     // 戰績陣列索引 
	Handle hand;          // struct 手牌 
	int Case;             // Case 1: 玩家要牌 遊戲結束 
};



  // SWAP 交換
  
  void Swap(int *a , int *b){
  	
  	// printf("*****  Function  Swap  Begin  *****\n\n");
  	
  	int temp;
  	
  	temp = *a ;
  	*a = *b ;
  	*b = temp ;
  	
  	return;
  	
  	// printf("*****  Function  Swap  End  *****\n\n");
  	
  }

  // Shuttle 洗牌  
  void Shuttle(int *array ){
  	
  	// printf("*****  Function  Shttle  Begin  *****\n\n");
  	
  	BLACK_RED;
  	printf("Creat New Deck And Shuttle !\n\n");
  	BLACK_WHITE;
  	
  	int i , pos ;
  	srand((unsigned)time(NULL));
  	rand(); // 先抽一次亂數 打亂亂數序 
  	
  	
  	for(i=0;i<52;i++){
  		
  		array[i] = i+1 ;
  		
	  }
  	
  	
  	for(i=0;i!=N;++i){
  		// 取出第pos張牌
		  pos = (int) (N*(double)rand()/RAND_MAX);
		// 交換第i張與第pos張牌
		  Swap(&array[i],&array[pos]); 
	  }
  	
  	// printf("*****  Function  Shttle  End  *****\n\n");
  	
  	return;
  	
  } 
  
  
    void Deal(int *array , Player *a , int *flag){
  	
  	BLACK_RED;
  	printf("Deal !\n\n");
  	BLACK_WHITE;
  	a->hand.card = array[*flag];
	++*flag;
	a->hand.flower = a->hand.card % 4 ;
	a->hand.number = a->hand.card / 4 ;
	a->hand.fnumber = a->hand.number ;
	
	// printf("test card number : %d \n\n",a->hand.card);
	
	// printf("Your card is %c%s \n\n",flower_table[flower],number_table[number]);

  	
  } 
  
  
  // Cardnum 算手牌數量
  
  void Cardnum(int *cardnum){

	*cardnum = *cardnum + 1 ;

  }  
  
  
  // Point 算手牌點數
  
  void Point(float *fnumber,float *sumpoint){
  	
  	if(*fnumber <10.0 && *fnumber >0.0){
  		*fnumber = *fnumber + 1.0 ;
  		*sumpoint = *sumpoint + *fnumber ;
	  }
	else if (*fnumber == 0.0){
		*fnumber = 1.0 ;
		*sumpoint = *sumpoint + *fnumber ;
	}
	else if (*fnumber >=10.0 && *fnumber <= 12.0){
		*fnumber = 0.5 ;
		*sumpoint = *sumpoint + *fnumber ;
	}
  	
  } 
  
  // Watchdeal  得牌顯示
  
  void Watchdeal(Player *a){
  	
  	BLACK_CYAN;
	printf("Your card is %c%s \n\n",flower_table[a->hand.flower],number_table[a->hand.number]);
	Point(&a->hand.fnumber,&a->hand.point);
	printf("POINT Now: %.1f\n\n",a->hand.point);
	Cardnum(&a->hand.cardnum);
	printf("Card Num Now: %d\n\n\n\n",a->hand.cardnum);
	BLACK_WHITE;
  	
  } 
  
  
  // Win Lose  輸贏 
  
  void Lose(Player *A,Player *B){
  	
  	A->record[A->record_flag] = 'L' ;
  	A->record_flag ++ ;
  	B->record[B->record_flag] = 'W' ;
  	B->record_flag ++ ;
  	
  } 
  
  void Win(Player *A,Player *B){
  	
  	B->record[A->record_flag] = 'L' ;
  	B->record_flag ++ ;
  	A->record[B->record_flag] = 'W' ;
  	A->record_flag ++ ;
  	
  }
  
  
  void Getcard(Player *A,Player *B,int card[],int *flag){
  	
  	char temp = '\0';
  	printf("%p\n",&A->Case);
  	
  	while(1){
  	
	  // 詢問是否要牌	
  	BLACK_YELLOW;
	printf("Do you want to get card ?  ( max card is 5 )\n\n");
	BLACK_YELLOW;
	printf("Type 1 for YES , 2 for NO .\n\n");
	BLACK_WHITE;
	
	scanf("%s",&temp);
	
	 // 防呆機制  
	if(temp != '1' && temp != '2'){

		BLACK_RED;
		printf("Your Type is wrong ! Retype Please.\n");
		BLACK_WHITE;
		scanf("%c",&temp);
		printf("\n");
		
	}
	
	// 不要牌 
	if(temp == '2'){
		BLACK_YELLOW;
	    printf("You Do Not Get Card Anymore !\n");  
	    BLACK_CYAN;
	    printf("Your End Point : %.1f\n\n\n\n",A->hand.point);
	    BLACK_WHITE;
	    return;
	}

	
	if(temp == '1'){
	Deal(card,A,flag);
	Watchdeal(A);
	if(A->hand.point >10.5){
		BLACK_RED;
		printf("BOOM ! YOU LOSE !\n\n");
		BLACK_WHITE;
		Lose(A,B);
		A->Case = 1 ;
		return;
	}
	if(A->hand.cardnum == 5){
		BLACK_RED;
		printf("FIVE CARD ! YOU WIN !\n\n");
		BLACK_WHITE;
		Win(A,B);
		A->Case = 1 ;
		return;
	}
	if(A->hand.point == 10.5){
		BLACK_RED;
		printf("10.5 ! YOU WIN !\n\n");
		BLACK_WHITE;
		Win(A,B);
		A->Case = 1 ;
		return;
	}
	}
	
    }
  	
  	} 
  	
   void Cgetcard(Player *A,Player *B,int card[],int *flag){
  	
  	BLACK_PURPLE;
  	printf("Computer's First Card is %c%s\n\n",flower_table[B->hand.flower],number_table[B->hand.number]);
  	printf("Coumputer's Point : %.1f\n\n",B->hand.point); 
  	
  }
  
  
  
  void Display(){
  	
  	BLACK_YELLOW;
  	printf("\nGame Start !\n\n");
  	BLACK_WHITE;
  	
  	// 建立牌組 
  	int card[52] = {} ;
	int flag = 0 ;  // 牌組堆疊用旗標 
	
	// 洗牌 
  	Shuttle(card);
  	
  	// 建立Player 
  	Player A ;
  	A.hand.cardnum = 0 ;
  	A.hand.fnumber = 0.0 ;
  	A.hand.point = 0.0 ;
  	A.record_flag = 0 ;
  	A.Case = 0 ;
  	
  	int i = 0 ;
  	for(i=0;i<TIMES;i++){
  		A.record[i] = '\0' ;
	  }
  	
	Player B ;
	B.hand.cardnum = 0 ;
	B.hand.fnumber = 0.0 ;
	B.hand.point = 0.0 ;
	B.record_flag = 0;
	B.Case = 0 ;
	
	for(i=0;i<TIMES;i++){
  		B.record[i] = '\0' ;
	  }
	  
	  
	// 第一次發牌 (玩家) 
	BLACK_YELLOW;
	printf("You Get First.\n\n");
	BLACK_WHITE;
	
	Deal(card,&A,&flag); 
	
	BLACK_CYAN;
	printf("Your card is %c%s \n\n",flower_table[A.hand.flower],number_table[A.hand.number]);
	Point(&A.hand.fnumber,&A.hand.point);
	printf("POINT: %.1f\n\n",A.hand.point);
	Cardnum(&A.hand.cardnum);
	printf("Card Num Now: %d\n\n",A.hand.cardnum);
	BLACK_WHITE;
	
	// 第一次發牌 (電腦)
	BLACK_YELLOW;
	printf("Computer Get Now.\n\n");
	BLACK_WHITE;
	
	Deal(card,&B,&flag);
	Cardnum(&B.hand.cardnum);
	printf("\n\n");
	
	// printf("Computer's card is %5c%s\n\n",flower_table[B.hand.flower],number_table[B.hand.number]); // 電腦的點數(按遊戲規則不顯示) 
	Point(&B.hand.fnumber,&B.hand.point);
	
	// 要牌(玩家) 
	Getcard(&A,&B,card,&flag);
	 printf("%p\n",&A.Case);
	if (A.Case == 1) return ;  // 玩家點數爆 & 過五關 & 10半 結束遊戲 
	
	// 要牌(電腦) 
	Cgetcard(&A,&B,card,&flag);
	
  	
  }




int main(int argc, char *argv[]) {
	
	char p = 0 ;
	BLACK_BLUE;
	printf("Program Start !\n\n");
	BLACK_WHITE;
	do{
		Display();
		BLACK_YELLOW;
		printf("Do you want to play again ?\n(1 for YES 2 for NO.)\n\n");
		BLACK_WHITE;
		scanf("%s",&p);
		while(p != '1' && p!='2'){
			BLACK_YELLOW;
			printf("Type Wrong ! Retype !\n\n");
			BLACK_WHITE;
			scanf("%s",&p);
		}
	}while(p == '1');
	
	if(p=='2'){
		BLACK_BLUE;
		printf("\nProgram End.\n\n");
		BLACK_WHITE;
	}
	
	return 0;
}