This was a pain to debug but I finally got it right. There’s a little bit of trickery with outputting the result as well so watch out for that!
import java.io.PrintWriter;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.StringTokenizer;
/**
*
* @author Sanchit M. Bhatnagar
* @see http://uhunt.felix-halim.net/id/74004
*
*/
public class P162 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
PrintWriter out = new PrintWriter(System.out);
while (sc.hasNextLine()) {
String line = sc.nextLine().trim();
while (line.equals(""))
line = sc.nextLine();
if (line.equals("#"))
break;
gameOver = false;
Player[] players = new Player[2];
for (int i = 0; i < players.length; i++) {
players[i] = new Player();
}
Card[] deck = new Card[52];
StringTokenizer st = new StringTokenizer(line);
for (int i = 0; i < 13; i++) {
deck[i] = new Card(st.nextToken());
}
for (int i = 13; i < 52; i++) {
deck[i] = new Card(sc.next());
}
for (int j = 0; j < players.length; j++) {
for (int i = 0; i < 26; i++) {
players[j].deck.add(deck[i * 2 + j]);
}
Collections.reverse(players[j].deck);
}
// players[0] = non-dealer
// players[1] = dealer
int idx = 0;
LinkedList<Card> stack = new LinkedList<>();
while ((players[0].deck.size() > 0 || players[1].deck.size() > 0) && !gameOver) {
Card played = players[idx].deck.poll();
if (played == null)
break;
stack.add(played);
if (played.isFaceCard()) {
idx = doThing(stack, players, idx);
}
idx = 1 - idx;
}
if (players[0].deck.isEmpty()) {
out.println("1 " + String.format("%2d", players[1].deck.size()));
} else {
out.println("2 " + String.format("%2d", players[0].deck.size()));
}
}
out.close();
sc.close();
}
private static boolean gameOver = false;
private static int doThing(LinkedList<Card> stack, Player[] players, int idx) {
boolean good = true;
idx = 1 - idx;
int val = getGameCardVal(stack.peekLast());
for (int i = 0; i < val; i++) {
Card played = players[idx].deck.poll();
if (played == null) {
gameOver = true;
good = false;
break;
} else {
stack.add(played);
if (played.isFaceCard()) {
return doThing(stack, players, idx);
}
}
}
if (good)
while (!stack.isEmpty()) {
players[1 - idx].deck.add(stack.poll());
}
return idx;
}
private static int getGameCardVal(Card c) {
switch (c.card.charAt(1)) {
case 'A':
return 4;
case 'K':
return 3;
case 'Q':
return 2;
case 'J':
return 1;
}
return 0;
}
private static class Card {
String card;
public Card(String card) {
int test1 = getSuitIdx(card.charAt(0));
if (test1 == -1)
return;
int test2 = getNumIdx(card.charAt(1));
if (test2 == -1)
return;
this.card = card;
}
public boolean isFaceCard() {
int val = getCardValue();
return (val == 1 || val == 11 || val == 12 || val == 13);
}
public int getCardValue() {
return getNumIdx(card.charAt(1));
}
private int getSuitIdx(char suit) {
switch (suit) {
case 'H':
return 0;
case 'S':
return 1;
case 'D':
return 2;
case 'C':
return 3;
}
return -1;
}
private int getNumIdx(char num) {
switch (num) {
case 'A':
return 1;
case 'T':
return 10;
case 'J':
return 11;
case 'Q':
return 12;
case 'K':
return 13;
default:
try {
int val = Integer.parseInt(num + "");
if (val > 1 && val < 10)
return val;
return -1;
} catch (Exception e) {
return -1;
}
}
}
@Override
public String toString() {
return this.card;
}
}
private static class Player {
private LinkedList<Card> deck;
public Player() {
deck = new LinkedList<>();
}
@Override
public String toString() {
return this.deck.toString();
}
}
}