UVA 162 – Beggar My Neighbour

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();
    }
  }

}

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.