U E D R , A S I H C RSS

Poker Hands/문보창

소감

2005/03/02 Accepted 0:00.000 64
가까스로 버그를 잡았지만 난잡한 소스가 그다지 맘에 들지 않는다. 어떻게 하면 보다 효율적으로 포커패의 족보를 검사해 낼 수 있을까?

코드

~cpp 
// no10315 - Poker Hands 
#include <iostream>   
#include <cstdlib>   
using namespace std; 

enum {HighCard, OnePair, TwoPairs, ThreeCard, Straight, Flush, FullHouse, FourCard, StraightFlush};   
const int NONE = 0;   
const int TIED = 2;   
const int BLACK = -1;   
const int WHITE = 1;   

struct Poker   
{   
	int value[5];   
	int rank[6];   
};   

inline int comp(const void *i,const void *j) { return *(int *)i-*(int *)j; };    
int compare(Poker & b, Poker & w);   
void interpret(bool b, bool w, int & result);   
void rankCompare(Poker & b, Poker & w, int & result);   
void showResult(int & result);   
bool straightFlush(Poker & po);   
bool fourCard(Poker & po);   
bool fullHouse(Poker & po);   
bool flush(Poker & po);   
bool straight(Poker & po);   
bool threeCard(Poker & po);   
bool twoPair(Poker & po);   
bool onePair(Poker & po);   
bool highCard(Poker & po);   

int main()   
{   
	Poker black, white;   
	
	// 입력   
	char values[] = "23456789TJQKA";   
	char str[30], suit;   
	int count, i, j;   
	while(cin.getline(str, 30, '\n'))   
	{   
		for (i=0; i<6; i++)   
			black.rank[i] = white.rank[i] = 0;   
		count = 0;   
		suit = str[1];   
		black.rank[0] = white.rank[0] = Flush;   
		for (i=0; i<15; i+=2)   
		{   
			for (j=0; j<13; j++)   
			{   
				if (str[i] == values[j])   
				{   
					black.value[count++] = j;   
					i++;   
					break;   
				}   
			}   
			if (suit != str[i])   
				black.rank[0] = HighCard;   
		}   
		count = 0;   
		suit = str[16];   
		for (i=15; i<30; i+=2)   
		{   
			for (j=0; j<13; j++)   
			{   
				if (str[i] == values[j])   
				{   
					white.value[count++] = j;   
					i++;   
					break;   
				}   
			}   
			if (suit != str[i])   
				white.rank[0] = HighCard;   
		}   
        // 소트   
        qsort(black.value, 5, sizeof(int), comp);   
        qsort(white.value, 5, sizeof(int), comp);   
        // 처리   
        int result = compare(black, white);   
        showResult(result);   
	}   
	return 0;   
}   

int compare(Poker & b, Poker & w)   
{   
	int result = false;   
	if (!result)  
		interpret(straightFlush(b), straightFlush(w), result);   
	if (!result)   
		interpret(fourCard(b), fourCard(w), result);   
	if (!result)   
		interpret(fullHouse(b), fullHouse(w), result);   
	if (!result)   
		interpret(flush(b), flush(w), result);    
	if (!result)   
		interpret(straight(b), straight(w), result);   
	if (!result)   
		interpret(threeCard(b), threeCard(w), result);   
	if (!result)   
		interpret(twoPair(b), twoPair(w), result);   
	if (!result)   
		interpret(onePair(b), onePair(w), result);   
	if (!result)   
		interpret(highCard(b), highCard(w), result);   
	if (result == BLACK || result == WHITE)   
		return result;   
	else   
		rankCompare(b, w, result);   
	return result;   
}   

void interpret(bool b, bool w, int & result)   
{   
	if (b && w)   
		result = TIED;   
	else if (b && !w)   
		result = BLACK;   
	else if (!b && w)   
		result = WHITE;   
	else   
		result = NONE;   
}   

void rankCompare(Poker & b, Poker & w, int & result)   
{   
	result = NONE;  
	for (int i=0; i<6; i++)   
	{   
		if (b.rank[i] > w.rank[i])   
		{   
			result = BLACK;   
			break;   
		}   
		else if (b.rank[i] < w.rank[i])   
		{   
			result = WHITE;   
			break;   
		}   
	}   
	if (result != BLACK && result != WHITE)   
		result = TIED;   
}   

bool straightFlush(Poker & po)   
{   
	if (flush(po) && straight(po))   
	{   
		po.rank[0] = StraightFlush;   
		po.rank[1] = po.value[4];  
		po.rank[2] = po.value[3];  
		po.rank[3] = po.rank[4] = po.rank[5] = 0;
		return true;   
	}   
	return false;   
}   

bool fourCard(Poker & po)   
{   
	int count = 1;   
	for (int i=0; i<4; i++)   
	{   
		if (po.value[i] == po.value[i+1])   
			count++;   
		else    
			count = 1;   
		if (count == 4)   
			break;   
	}   
	if (count == 4)   
	{   
		po.rank[0] = FourCard;   
		if (po.value[0] =! po.value[1])   
		{   
			po.rank[1] = po.value[1];   
			po.rank[2] = po.value[0];   
		}   
		else   
		{   
			po.rank[1] = po.value[0];   
			po.rank[2] = po.value[4];   
		}   
		po.rank[3] = po.rank[4] = po.rank[5] = 0;
		return true;   
	}   
	return false;   
}   

bool fullHouse(Poker & po)   
{   
	int kind = 1;   
	for (int i=0; i<4; i++)   
	{   
		if (po.value[i] != po.value[i+1])   
			kind++;   
	}   
	if (kind == 2)   
	{   
		po.rank[0] = FullHouse;   
		if (po.value[1] != po.value[2])   
		{   
			po.rank[1] = po.value[2];   
			po.rank[2] = po.value[1];   
		}   
		else if (po.value[0] != po.value[1])  
		{  
			po.rank[1] = po.value[1];  
			po.rank[2] = po.value[0];  
		}  
		else   
		{   
			po.rank[1] = po.value[1];   
			po.rank[2] = po.value[4];   
		}
		po.rank[3] = po.rank[4] = po.rank[5] = 0;
		return true;   
	}   
	return false;   
}   

bool threeCard(Poker & po)   
{   
	int count = 1;   
	int i;   
	for (i=0; i<4; i++)   
	{   
		if (po.value[i] == po.value[i+1])   
			count++;   
		else    
			count = 1;   
		if (count == 3)   
			break;   
	}   
	if (count == 3)   
	{   
		po.rank[0] = ThreeCard;   
		if (i == 3)   
		{   
			po.rank[1] = po.value[2];   
			po.rank[2] = po.value[1];   
			po.rank[3] = po.value[0];   
		}   
		else if (i == 2)   
		{   
			po.rank[1] = po.value[1];   
			po.rank[2] = po.value[4];   
			po.rank[3] = po.value[0];   
		}   
		else if (i == 1)   
		{   
			po.rank[1] = po.value[0];   
			po.rank[2] = po.value[4];   
			po.rank[3] = po.value[3];   
		}   
		po.rank[4] = po.rank[5] = 0;
		return true;   
	}   
	return false;   
}   

bool twoPair(Poker & po)   
{   
	int kind = 0;   
	int stickCount = 0;   
	int stick[2];   
	for (int i=0; i<4; i++)   
	{   
		if (po.value[i] != po.value[i+1])   
		{   
			stick[stickCount++] = i;   
			kind++;   
		}   
	}   
	if (kind == 2)   
	{   
		po.rank[0] = TwoPairs;   
		if (stick[0] == 1 && stick[1] == 2)   
		{   
			po.rank[1] = po.value[4];   
			po.rank[2] = po.value[0];   
			po.rank[3] = po.value[2];   
		}   
		else if (stick[0] == 0 && stick[1] == 2)   
		{   
			po.rank[1] = po.value[4];   
			po.rank[2] = po.value[1];   
			po.rank[3] = po.value[0];   
		}   
		else   
		{   
			po.rank[1] = po.value[2];   
			po.rank[2] = po.value[0];   
			po.rank[3] = po.value[4];   
		}   
		po.rank[4] = po.rank[5] = 0;
		return true;   
	}   
	return false;   
}   

bool straight(Poker & po)   
{   
	int count = 0;   
	for (int i=0; i<4; i++)   
	{   
		if (po.value[i] + 1 == po.value[i+1])   
			count++;   
	}   
	if (count == 4 || (count == 3 && po.value[4] == 12 && po.value[0] == 0))   
	{   
		po.rank[0] = Straight;   
		po.rank[1] = po.value[4];   
		po.rank[2] = po.value[3];  
		po.rank[3] = po.rank[4] = po.rank[5] = 0;
		return true;   
	}   
	return false;   
}   

bool flush(Poker & po)   
{   
	if (po.rank[0] == Flush)   
	{   
		for (int i=0; i<5; i++)   
			po.rank[i+1] = po.value[4-i];   
		return true;   
	}   
	return false;   
}   

bool onePair(Poker & po)   
{   
	int kind = 0;   
	int i;   
	for (i=0; i<4; i++)   
	{   
		if (po.value[i] == po.value[i+1])   
		{   
			kind++;   
			break;   
		}   
	}   
	if (kind == 1)   
	{   
		po.rank[0] = OnePair;   
		switch (i)   
		{   
		case 0:   
			po.rank[1] = po.value[0];   
			po.rank[2] = po.value[4];   
			po.rank[3] = po.value[3];   
			po.rank[4] = po.value[2];   
			break;   
		case 1:   
			po.rank[1] = po.value[1];   
			po.rank[2] = po.value[4];   
			po.rank[3] = po.value[3];   
			po.rank[4] = po.value[0];   
			break;   
		case 2:   
			po.rank[1] = po.value[2];   
			po.rank[2] = po.value[4];   
			po.rank[3] = po.value[1];   
			po.rank[4] = po.value[0];   
			break;   
		case 3:   
			po.rank[1] = po.value[4];   
			po.rank[2] = po.value[2];   
			po.rank[3] = po.value[1];   
			po.rank[4] = po.value[0];   
			break;   
		}   
		po.rank[5] = 0;
		return true;   
	}   
	return false;   
}   

bool highCard(Poker & po)   
{   
	po.rank[0] = HighCard;   
	for (int i=0; i<5; i++)   
	{   
		po.rank[i+1] = po.value[4-i];   
	}   
	return true;   
}   

void showResult(int & result)   
{   
	switch (result)   
	{   
	case BLACK:   
		cout << "Black wins.\n";   
		break;   
	case WHITE:   
		cout << "White wins.\n";   
		break;   
	case TIED:   
		cout << "Tie.\n";   
		break;   
	}   
} 
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:24:00
Processing time 0.0212 sec