UVA 10315 - Poker Hands
Background- This problem has another mathematics based algorithm where hands are ranked in a table and a unique score is generated based on the user hand. So at the end we just need to compare White and Black hands value to decide the winner. I am working on it and soon I will share.
Meanwhile a simple, straight forward implementation could be like this. It is quick enough with timing 0.008 sec over UVA input data set.
C++ Implementation -
After thoughts -
Background- This problem has another mathematics based algorithm where hands are ranked in a table and a unique score is generated based on the user hand. So at the end we just need to compare White and Black hands value to decide the winner. I am working on it and soon I will share.
Meanwhile a simple, straight forward implementation could be like this. It is quick enough with timing 0.008 sec over UVA input data set.
C++ Implementation -
#include <iostream> #include <vector> #include <string> #include <sstream> #include <algorithm> using namespace std; typedef pair<short, char> card; typedef vector<card> hand; typedef pair<short, short> bet; enum { BLACK = 0, WHITE = 1, TIE = 2 }; struct compare { bool operator() (card i, card j) { return (i.first > j.first);} } cmp; stringstream oss(stringstream::in | stringstream::out); string output[] = {"Black wins.","White wins.","Tie."}; void read_hand(hand& h) { for(short i =0; i < 5; i++) { char rank, temp[2]; oss >> temp[0] >> temp[1]; rank = temp[0]; card c; if(temp[1] == 'H' || temp[1] == 'D' || temp[1] == 'C' || temp[1] == 'S') c.second = temp[1]; else continue; if(rank >= '0' && rank <= '9') c.first = rank-48; else if(rank == 'T') c.first = 10; else if(rank == 'J') c.first = 11; else if(rank == 'Q') c.first = 12; else if(rank == 'K') c.first = 13; else if(rank == 'A') c.first = 14; else continue; h.push_back(c); } } void print_hand(const hand& b, const hand& w) { hand::const_iterator it = b.begin(); while(it != b.end()) { cout << it->first << it->second << " "; it++; } it = w.begin(); while(it != w.end()) { cout << it->first << it->second << " "; it++; } cout << endl; } //1 bool high(hand& h, bet& b) { b = bet(1, h.begin()->first); return true; } //2:2, 3:2.2, 4:3, 7:3.2, 8:4 bool same_rank(hand& h, bet& b) { pair<short, short> rank1(0,0); pair<short, short> rank2(0,0); hand::iterator it = h.begin(); rank1.first = it->first; rank1.second++; it++; while(it != h.end()) { if(it->first == rank1.first) rank1.second++; else { if( rank1.second < 2) { rank1.first = it->first; rank2.second = 1; } else { if(rank2.first == it->first) { rank2.second++; } else if(rank2.first == 0){ rank2.first = it->first; rank2.second = 1; } else if (rank2.second < 2) { rank2.first = it->first; rank2.second = 1; } } } it++; } if((rank1.second == rank2.second) && (rank1.second == 2)) { b.first = 3 ; b.second = rank1.first; return true; } else { //swap if(rank1.second < rank2.second) { pair<short, short> temp(0,0); temp = rank1; rank1 = rank2; rank2 = temp; } if(rank1.second == 4) { b.first = 8; b.second = rank1.first; return true; } else if(rank1.second == 3) { if(rank2.second == 2) { b.first = 7; b.second = rank1.first; } else { b.first = 4; b.second = rank1.first; } return true; } else if(rank1.second == 2) { b.first = 2; b.second = rank1.first; return true; } } return false; } //5, 9 bool straight(hand& h, bet& b, bool fls=false) { for(short i =1; i < 5; i++) { if(h[0].first-i != h[i].first) return false; } if(fls == true) b.first = 9; else b.first = 5; b.second = h[0].first; return true; } //6 bool flush(hand& h, bet& b) { hand::iterator it = h.begin(); char color = it->second; it++; while(it != h.end()) { if(it->second != color) return false; it++; } b.first = 6; b.second = h.begin()->first; return true; } bet get_bet(hand& h) { bet b; sort(h.begin(), h.end(), cmp); if(flush(h, b) == true) { straight(h, b, true); return b; } else if(straight(h, b) == true) return b; else if (same_rank(h, b) == true) return b; else { high(h, b); return b; } } short Show(hand& black, hand& white) { bet b_bet = get_bet(black); bet w_bet = get_bet(white); if(b_bet.first == w_bet.first) { if(b_bet.second == w_bet.second) { while(black.empty() == false) { if(black.front().first == white.front().first) { black.erase(black.begin()); white.erase(white.begin()); } else { if(black.front().first > white.front().first) return BLACK; else return WHITE; } } return TIE; } else if(b_bet.second > w_bet.second) { return BLACK; } else { return WHITE; } } else if(b_bet.first > w_bet.first) { return BLACK; } else { return WHITE; } } int main() { hand black; hand white; while(cin.eof() == false) { string line; oss.str(""); cin >> ws; getline(cin, line); if(line.size() < 29) continue; oss << line; black.clear(); white.clear(); read_hand(black); read_hand(white); if((black.size() == white.size()) && (black.size() == 5)) { //print_hand(black, white); short result = Show(black, white); cout << output[result] << endl; } } return 0; }
After thoughts -
1. There is plenty scope to optimize this.
2. There is another way to encode the cards in a way to reveal the rank quickly. I am using the same in different poker and Yahtzee problem.
3. I didn't change this because I want to replace this with math based ranking algorithm.
No comments:
Post a Comment