import java.util.ArrayList;


public class BitwiseFun {

	public static int cardToInt(Card c) {
		return c.getSuit() * 13 + c.getRank();
	}

	public static Card intToCard(int i) {
		return new Card(i % 13, i / 13);
	}
	
	public static long cardsToLong(ArrayList<Card> cards) {
		long l = 0;
		for (Card c : cards)
			l |= (1L << cardToInt(c));
		return l;
	}
	
	public static ArrayList<Card> longToCards(long l) {
		ArrayList<Card> cards = new ArrayList<Card>();
		long mask = 1;
		for (int i = 0; i < 52; i++) {
			if ((l & mask) != 0)
				cards.add(intToCard(i));
			mask <<= 1;
		}
		return cards;
	}
	
	public static void main(String[] args) {
		int i1 = 5;  //    101
		int i2 = 3;  //     11
		int i3 = 42; // 101010
		System.out.println("bitwise and &");
		System.out.println(i1 & i2);
		System.out.println(i1 & i3);
		System.out.println("bitwise or |");
		System.out.println(i1 | i2);
		System.out.println(i1 | i3);
		System.out.println("bitwise exclusive or ^");
		System.out.println(i1 ^ i2);
		System.out.println(i1 ^ i3);
		System.out.println("bitwise complement (not) ~");
		System.out.println(~0);
		System.out.println(~i1);
		System.out.println("left shift <<");
		System.out.println(1 << 1);
		System.out.println(1 << 2);
		System.out.println(1 << 3);
		System.out.println(7 << 1);
		System.out.println("right shift >>");
		System.out.println(42 >> 1);
		System.out.println(42 >> 2);
		System.out.println(-42 >> 1);
		System.out.println("unsigned right shift >>>");
		System.out.println(-42 >>> 1);

		Deck deck = new Deck();
		deck.shuffle();
		ArrayList<Card> cards1 = new ArrayList<Card>();
		for (int i = 0; i < 25; i++)
			cards1.add(deck.draw());
		System.out.println("Cards 1: " + cards1);
		
		deck = new Deck();
		deck.shuffle();
		ArrayList<Card> cards2 = new ArrayList<Card>();
		for (int i = 0; i < 25; i++)
			cards2.add(deck.draw());
		System.out.println("Cards 2: " + cards2);

		long l1 = cardsToLong(cards1);
		System.out.println("Encoded Cards 1: " + l1);

		long l2 = cardsToLong(cards2);
		System.out.println("Encoded Cards 2: " + l2);
		
		System.out.println("Decoded Cards 1: " + longToCards(l1));
		
		System.out.println("Decoded Cards 2: " + longToCards(l2));
		
		System.out.println("Shared Cards: " + longToCards(l1 & l2));
		
		System.out.println("Unshared Cards: " + longToCards(l1 ^ l2));
		
		System.out.println("Combined Cards: " + longToCards(l1 | l2));
		
		System.out.println("Not in Cards 1: " + longToCards(~l1));
		
		System.out.println("Cards 2 not in Cards 1: " + longToCards(l2 & ~l1));

	}

}
