import acm.program.*;

public class SimpleSet extends ConsoleProgram {

    // Number of suits in the card deck
    private static final int NUM_SUITS = 3;

    // Number of values per suit in the card deck
    private static final int NUM_VALUES = 3;

    public void run() {
        println("Welcome to Simple Set!");
        GeneralCardDeck deck = new GeneralCardDeck(NUM_VALUES, NUM_SUITS);
        deck.shuffle();

        while (!deck.isEmpty()) {

            // 1. draw three cards from the deck
            String[] cards = drawThreeCards(deck);

            // 2. show the three cards to the user
            for (String card : cards) {
                println(card);
            }

            /* 3. ask the user to answer, in boolean form, whether or not
             * the three cards make a Set.
             */
            boolean userAnswer = readBoolean("Is this a set? ");

            /* 4. verify if the user was correct.  If they were correct,
             * print "good job!".  If they were not correct, tell them
             * the right answer.
             */
            boolean isSet = isSet(cards);
            if (userAnswer == isSet) {
                println("Good job!");
            } else if (isSet) {
                println("It is a set");
            } else {
                println("It is not a set");
            }
        }
    }

    // Returns the top three cards from the given deck.
    private String[] drawThreeCards(GeneralCardDeck deck) {
        String[] cards = new String[3];
        for (int i = 0; i < 3; i++) {
            cards[i] = deck.getNextCard();
        }

        return cards;
    }

    /* Returns whether or not the cards in the list are a set.
     * The cards make a set if:
     * 1) All three values are different OR all three values are the same
     * 2) All three suits are different OR all three suits are the same
     */
    private boolean isSet(String[] cards) {
        // Count up the frequencies of each suit and value in the cards
        int[] suitsCount = new int[NUM_SUITS];
        int[] valuesCount = new int[NUM_VALUES];

        for (String card : cards) {
            char value = card.charAt(0);
            char suit = card.charAt(1);

            int valueIndex = value - '1';
            int suitIndex = suit - 'A';
            suitsCount[suitIndex]++;
            valuesCount[valueIndex]++;
        }

        /* If we see any value or suit appear twice, it's
         * not a set (because that means a suit or value appeared some
         * number of times other than ALL of them (3) or ONE of them (1).
         */
        for (int i = 0; i < NUM_SUITS; i++) {
            if (suitsCount[i] == 2) return false;
        }

        for (int i = 0; i < NUM_VALUES; i++) {
            if (valuesCount[i] == 2) return false;
        }

        return true;
    }
}
