#include #include #include #include #include #include using namespace std; const int TIME_MOVE_R = 500; const int TIME_MOVE_L = 700; const int TIME_OPEN = 300; const int TIME_RETURN = 500; const int INF = 1<<29; string nums = "23456789XJQKA"; string suits = "CDHS"; struct Card { int num; int suit; Card() : num(-256), suit(-256) {} Card(int n, int s) : num(n), suit(s) {} bool isValid() const { return num >= 0; } bool isAdj(const Card& b) const { int diff = (num - b.num + 13) % 13; return diff == 1 || diff == 12; } bool operator <(const Card& b) const { if(num != b.num) return num < b.num; return suit < b.suit; } friend istream& operator >>(istream& s, Card& c) { string w; s >> w; c.num = nums.find(w[1]); c.suit = suits.find(w[0]); return s; } friend ostream& operator <<(ostream& s, const Card& c) { if(!c.isValid()) return s << " "; return s << suits[c.suit] << nums[c.num]; } }; Card pile[2]; struct Player { int id; vector deck; vector field; int wait_time; int mv_card; int mv_target; Card last; Player(int i) : id(i) {} void load(istream& cin, int card_num) { #ifdef PRINT cout << card_num; #endif for(int i = 0; i < card_num; ++i) { Card c; cin >> c; deck.push_back(c); #ifdef PRINT cout << " " << c; #endif } #ifdef PRINT cout << endl; #endif reverse(deck.begin(), deck.end()); wait_time = 0; mv_card = mv_target = -1; for(int i = 0; i < 4; ++i) { if(!deck.empty()) { field.push_back(deck.back()); deck.pop_back(); } } } bool canPut() const { return wait_time == 0 && mv_card >= 0; } void open() { assert(wait_time > INF/2); assert(mv_card < 0); if(!deck.empty()) { pile[id] = deck.back(); deck.pop_back(); } else { assert(!field.empty()); pile[id] = field[0]; field.erase(field.begin()); if(field.empty()) last = pile[id]; } wait_time = 0; } void prepare() { if(wait_time == 0 && mv_card < 0) { prepareTarget(id); if(mv_card < 0) prepareTarget(!id); if(mv_card >= 0) wait_time = (mv_target == id) ? TIME_MOVE_R : TIME_MOVE_L; else wait_time = INF; } } void prepareTarget(int target) { for(int i = 0; i < (int)field.size(); ++i) { if(pile[target].isAdj(field[i])) if(mv_card < 0 || field[i] < field[mv_card]) { mv_card = i; mv_target = target; } } } void done() { if(mv_card >= 0) { pile[mv_target] = field[mv_card]; if(!deck.empty()) { field[mv_card] = deck.back(); deck.pop_back(); wait_time = TIME_OPEN; } else { field.erase(field.begin() + mv_card); if(field.empty()) last = pile[mv_target]; } mv_card = mv_target = -1; } } void interrupt() { if(mv_card >= 0) { mv_card = mv_target = -1; wait_time = TIME_RETURN; } else if(wait_time > INF/2) { wait_time = 0; } } void print() { cout << "P" << id << ": "; for(int i = 0; i < (int)field.size(); ++i) { if(i == mv_card) cout << "[" << field[i] << "] "; else cout << field[i] << " "; } cout << mv_target << " " << wait_time << endl; } }; int main() { ifstream cin("D.txt"); int a_num, b_num; while(cin >> a_num && a_num) { pile[0] = pile[1] = Card(); Player a(0), b(1); Player* p[2] = { &a, &b }; a.load(cin, a_num); cin >> b_num; b.load(cin, b_num); int time = 0; while(!a.last.isValid() && !b.last.isValid()) { a.prepare(); b.prepare(); #ifdef PRINT cout << pile[0] << " " << pile[1] << " @" << time << endl; a.print(); b.print(); #endif int dt = min(a.wait_time, b.wait_time); if(dt > INF/2) { a.open(); b.open(); time += TIME_MOVE_R; continue; } time += dt; a.wait_time -= dt; b.wait_time -= dt; if(a.mv_target == b.mv_target || a.wait_time > INF/2 || b.wait_time > INF/2) { if(a.canPut()) { if(b.canPut()) p[a.mv_target]->interrupt(); else b.interrupt(); } else if(b.canPut()) a.interrupt(); } if(a.canPut()) a.done(); if(b.canPut()) b.done(); } if(b.last < a.last) cout << "A wins." << endl; else cout << "B wins." << endl; } }