Last active
December 11, 2015 01:48
-
-
Save elsewhat/4525762 to your computer and use it in GitHub Desktop.
Ingress Pontifax code testing
Output can be found here: https://docs.google.com/document/d/1Z2Baw94tlcoRODV_g89nOy2FgI6Dvx-vy6eV8Wpwpus/edit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SolitaireCipher.java | |
// Copyright (C) 1999 Jeff Gold | |
// This program is free software; you can redistribute it and/or | |
// modify it under the terms of the GNU General Public License as | |
// published by the Free Software Foundation; either version 2 of the | |
// License, or (at your option) any later version. | |
// This program is distributed in the hope that it will be useful, | |
// but WITHOUT ANY WARRANTY; without even the implied warranty of | |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
// GNU General Public License for more details. | |
// You should have received a copy of the GNU General Public License | |
// along with this program (see License.txt); if not, see | |
// http://www.gnu.org | |
// or write to the Free Software Foundation, Inc., 59 Temple Place, | |
// Suite 330, Boston, MA 02111-1307 USA | |
// NOTE: the Solitaire encryption algorithm is strong cryptography. | |
// That means the security it affords is based on the secrecy of the | |
// key rather than secrecy of the algorithm itself. That also means | |
// that this program and programs derived from it may be treated as | |
// a munition for the purpose of export regulation in the United States | |
// and other countries. You are encouraged to seek competent legal | |
// counsel before distributing copies of this program. | |
// | |
// This package contains a Java implementation of the Solitaire | |
// encryption algorithm, as designed by Bruce Schneier and described at: | |
// http://www.counterpane.com/solitaire.html | |
// as well as in Neil Stephenson's novel Cryptonomicon. | |
// Solitaire is a cryptographically strong stream cipher that can | |
// be implemented using a deck of playing cards. This implementation | |
// is not designed for high performance -- this is a Java program, after | |
// all. Instead it is intended to be clean, portable, and easy to | |
// understand. | |
import java.lang.*; | |
import java.util.ArrayList; | |
import java.util.Iterator; | |
import java.util.Random; | |
import java.io.Serializable; | |
public final class | |
SolitaireCipher | |
implements Serializable, Cloneable | |
{ | |
/** | |
* All ingress code logic handled inside main methode | |
* Rest is from schneier's pontifax code | |
* http://www.schneier.com/solitaire.html | |
*/ | |
public static void main(String args[]) { | |
String ingressCipher = "YPEJOZLPHRZMKAPLVUMAIHXDSFOXMHPPGHCJKEMQAVSTJ"; | |
System.out.println("Start - Attempting various variants of the incomplete keyphrase and checking if deck after keying 3S 7S 10S ..."); | |
String keyPhraseLine1="DEALTWITH"; | |
String[] keyPhraseLine2Alt={ | |
"BYDISCRET", | |
"BYDISCRETE", | |
"BYDISCREET", | |
"BYDISCREDITS", | |
"BYDISCRETELY", | |
"BYDISCREETER", | |
"BYDISCRETION", | |
"BYDISCREETLY", | |
"BYDISCREPANT", | |
"BYDISCREDITED", | |
"BYDISCREETEST", | |
"BYDISCREPANCY", | |
"BYDISCRETIONS" | |
}; | |
String[] keyPhraseLine3Alt={ | |
"MACHINATING", | |
"MACHES", | |
"MACHOS", | |
"MACHETE", | |
"MACHREE", | |
"MACHZOR", | |
"MACHINE", | |
"MACHETES", | |
"MACHINED", | |
"MACHINES", | |
"MACHISMO", | |
"MACHOISM", | |
"MACHREES", | |
"MACHZORS", | |
"MACHINATE", | |
"MACHINERY", | |
"MACHINING", | |
"MACHINIST", | |
"MACHISMOS", | |
"MACHOISMS", | |
"MACHZORIM", | |
"MACHINABLE", | |
"MACHINATED", | |
"MACHINATES", | |
"MACHINATOR", | |
"MACHINISTS", | |
"MACHINATING", | |
"MACHINATION", | |
"MACHINATORS", | |
"MACHINEABLE", | |
"MACHINELIKE", | |
"MACHINERIES" | |
}; | |
ArrayList potentialCorrectKeyphrases= new ArrayList(); | |
int combinations=0; | |
for (int line2 = 0; line2 < keyPhraseLine2Alt.length; line2++) { | |
for (int line3 = 0; line3 < keyPhraseLine3Alt.length; line3++) { | |
combinations++; | |
String keyPhrase = keyPhraseLine1+keyPhraseLine2Alt[line2]+ keyPhraseLine3Alt[line3]; | |
//System.out.println(keyPhrase); | |
SolitaireCipher sc = new SolitaireCipher(keyPhrase); | |
Deck deckAfterKeying = sc.keyDeck; | |
byte topCard = deckAfterKeying.peekTop(0); | |
byte secondCard =deckAfterKeying.peekTop(1); | |
byte thirdCard = deckAfterKeying.peekTop(2); | |
//System.out.println(keyPhrase + " top card "+Deck.cardString(topCard) + " second card "+Deck.cardString(secondCard)); | |
if(Deck.isSpade(topCard) && Deck.isThree(topCard) | |
&& Deck.isSpade(secondCard) && Deck.isSeven(secondCard) | |
&& Deck.isSpade(thirdCard) && Deck.isTen(thirdCard)){ | |
potentialCorrectKeyphrases.add(keyPhrase); | |
} | |
//not needed, as we only do it for the candidates | |
String outputtext = sc.decrypt(ingressCipher); | |
} | |
} | |
System.out.println("Tried "+ combinations + " for the key phrasse"); | |
if(potentialCorrectKeyphrases.size()==0) { | |
System.out.println("No suitable candidates found (ie. last card three of spades"); | |
}else { | |
for (Iterator iterator = potentialCorrectKeyphrases.iterator(); iterator | |
.hasNext();) { | |
String keyPhrase = (String) iterator.next(); | |
System.out.println("Suitable candidates found " +keyPhrase); | |
SolitaireCipher sc = new SolitaireCipher(keyPhrase); | |
Deck deckAfterKeying = (Deck) sc.keyDeck.clone(); | |
System.out.println("Deck after keying (should match photo)\n" + deckAfterKeying); | |
String outputtext = sc.decrypt(ingressCipher); | |
System.out.println("Decrypted value\n" + outputtext); | |
} | |
} | |
/* | |
* DEALTWITHBYDISCRETEMACHINERY | |
String keyPhrase = "DEALTWITHBYDISCRETEMACHINERY"; | |
SolitaireCipher sc = new SolitaireCipher(keyPhrase); | |
Deck deck = sc.keyDeck; | |
System.out.println("DEALTWITHBYDISCRETEMACHINERY Deck before \n" + deck); | |
String outputtext = sc.decrypt(ingressCipher); | |
System.out.println("Decrypted value\n" + outputtext); | |
System.out.println("DEALTWITHBYDISCRETEMACHINERY Deck after \n" + deck); | |
*/ | |
} // main(String[]) | |
// Representation Data | |
// =================== | |
public Deck keyDeck; | |
// Constructors | |
// ============ | |
public SolitaireCipher(Deck keyDeck) { | |
// Effect: creates a cipher with a key based on the | |
// order of the cards in the specified deck. | |
if (keyDeck != null) { | |
this.keyDeck = (Deck)keyDeck.clone(); | |
} else this.keyDeck = new Deck(true); | |
} // SolitaireCipher(Deck) | |
public SolitaireCipher(String keyPhrase) { | |
// Effect: creates a cipher with a key based on the | |
// specified string. | |
keyDeck = new Deck(true); | |
// Shuffle deck according to key phrase. | |
for (int i = 0; i < keyPhrase.length(); i++) { | |
int cut_size = getCharValue(keyPhrase.charAt(i)); | |
if (cut_size > 0) { | |
nextKeyStream(); | |
keyDeck.tripleCut(1, keyDeck.count() - cut_size); | |
keyDeck.cutTop(1); | |
} // if (cut_size > 0) | |
} // for i | |
} // SolitaireCipher(String) | |
// Generic Methods | |
// =============== | |
public Object clone() { | |
return new SolitaireCipher(keyDeck); | |
} // clone() | |
public String toString() { | |
// Effect: return a string that represents the state of | |
// this cipher. | |
return keyDeck.toString(); | |
} // toString() | |
// Deck Methods | |
// ============ | |
public Deck getDeck() { | |
// Effect: return a copy of the current key deck. | |
return (Deck)keyDeck.clone(); | |
} // getDeck() | |
// Utility Methods | |
// =============== | |
protected static int getCardValue(byte card) { | |
// Effect: returns a numeric value for the specified card. | |
if (Deck.isJoker(card)) { | |
return 53; | |
} else if (Deck.isClub(card)) { | |
return Deck.getFaceValue(card); | |
} else if (Deck.isDiamond(card)) { | |
return 13 + Deck.getFaceValue(card); | |
} else if (Deck.isHeart(card)) { | |
return 26 + Deck.getFaceValue(card); | |
} else if (Deck.isSpade(card)) { | |
return 39 + Deck.getFaceValue(card); | |
} else { | |
return 0; // Something bad happened. | |
} // if card | |
} // getCardValue(byte) | |
protected static int getCharValue(char c) { | |
// Effect: return the position of the specified character in | |
// the alphabet regardless of case, or zero if the character | |
// is not in the Latin alphabet. | |
if (c >= 'A' && c <= 'Z') { | |
return (int)c - 'A' + 1; | |
} else if (c >= 'a' && c <= 'z') { | |
return (int)c - 'a' + 1; | |
} else { | |
return 0; | |
} // if c | |
} // getCharValue(char) | |
protected static char getValueChar(int v) { | |
// Effect: return the position of the specified character in | |
// the alphabet regardless of case, or zero if the character | |
// is not in the Latin alphabet. | |
if (v >= 1 && v <= 26) { | |
return (char)((v - 1) + (int)'A'); | |
} else { | |
return '*'; | |
} // if c | |
} // getCharValue(char) | |
// Cryptographic Methods | |
// ===================== | |
protected int nextKeyStream() { | |
// Effect: performs the basic stream encryption operation | |
// and returns the next element of the key stream. | |
byte jokerA = (byte)(Deck.JOKER | Deck.JOKER_A); | |
byte jokerB = (byte)(Deck.JOKER | Deck.JOKER_B); | |
// Step one: Move Joker A one card down. | |
keyDeck.moveDown(keyDeck.findTop(jokerA), 1); | |
// Step two: Move Joker B two cards down. | |
keyDeck.moveDown(keyDeck.findTop(jokerB), 2); | |
// Step three: Perform a triple cut. | |
int at_jokerA = keyDeck.findBottom(jokerA); | |
int at_jokerB = keyDeck.findBottom(jokerB); | |
keyDeck.tripleCut(Math.min(at_jokerA, at_jokerB), | |
Math.max(at_jokerA, at_jokerB) + 1); | |
// Step four: Perform a count cut. | |
byte count = keyDeck.peekBottom(0); | |
keyDeck.tripleCut(1, keyDeck.count() - getCardValue(count)); | |
keyDeck.cutTop(1); | |
// Step five: Find the output card. | |
byte output = keyDeck.peekTop(getCardValue(keyDeck.peekTop(0))); | |
// Step six: Convert output card to a number. | |
int result = getCardValue(output); | |
if (result == 53) return nextKeyStream(); | |
else if (result > 26) result = result - 26; | |
return result; | |
} // nextKeyStream() | |
public String decrypt(String ciphertext) { | |
// Effect: returns the ciphertext corresponding to the specified | |
// plaintext, according to the current key deck ordering. | |
StringBuffer buffer = new StringBuffer(); | |
for (int i = 0; i < ciphertext.length(); i++) { | |
int plain = getCharValue(ciphertext.charAt(i)); | |
if (plain > 0) { | |
plain -= nextKeyStream(); | |
if (plain < 1) plain += 26; | |
buffer.append(getValueChar(plain)); | |
} // if (plain > 0) | |
} // for i | |
return buffer.toString(); | |
} // decrypt(String) | |
public String encrypt(String plaintext) { | |
// Effect: returns the ciphertext corresponding to the specified | |
// plaintext, according to the current key deck ordering. Any | |
// string with a length that is not a multiple of five will be | |
// padded with the character 'X'. | |
return encrypt(plaintext, true); | |
} // encrypt(String) | |
public String encrypt(String plaintext, boolean padded) { | |
// Effect: returns the ciphertext corresponding to the specified | |
// plaintext, according to the current key deck ordering. | |
StringBuffer buffer = new StringBuffer(); | |
for (int i = 0; i < plaintext.length(); i++) { | |
int cipher = getCharValue(plaintext.charAt(i)); | |
if (cipher > 0) { | |
cipher += nextKeyStream(); | |
if (cipher > 26) cipher -= 26; | |
buffer.append(getValueChar(cipher)); | |
} // if (cipher > 0) | |
} // for i | |
if (padded) { | |
while (buffer.length() % 5 != 0) { | |
buffer.append(encrypt("X", false)); | |
} // while buffer | |
} // if (padded) | |
return buffer.toString(); | |
} // encrypt(String, boolean) | |
} // class SolitaireCipher | |
class Deck | |
implements Serializable, Cloneable | |
{ | |
// Constants | |
// ========= | |
// Card Masking Constants | |
protected static final byte MASK_SUIT = (byte)0xF0; | |
protected static final byte MASK_VALUE = (byte)0x0F; | |
protected static final byte MASK_BLACK = (byte)0x20; | |
protected static final byte MASK_RED = (byte)0x40; | |
protected static final byte MASK_JOKER = (byte)0x80; | |
// Card Suit Constants | |
public static final byte CLUBS = (byte)0x20; | |
public static final byte DIAMONDS = (byte)0x40; | |
public static final byte HEARTS = (byte)0x50; | |
public static final byte SPADES = (byte)0x30; | |
public static final byte JOKER = (byte)0x90; | |
// Card Value Constants | |
public static final byte ACE = (byte)0x01; | |
public static final byte DEUCE = (byte)0x02; | |
public static final byte THREE = (byte)0x03; | |
public static final byte FOUR = (byte)0x04; | |
public static final byte FIVE = (byte)0x05; | |
public static final byte SIX = (byte)0x06; | |
public static final byte SEVEN = (byte)0x07; | |
public static final byte EIGHT = (byte)0x08; | |
public static final byte NINE = (byte)0x09; | |
public static final byte TEN = (byte)0x0A; | |
public static final byte JACK = (byte)0x0B; | |
public static final byte QUEEN = (byte)0x0C; | |
public static final byte KING = (byte)0x0D; | |
public static final byte JOKER_A = (byte)0x0E; | |
public static final byte JOKER_B = (byte)0x0F; | |
// Representation Data | |
// =================== | |
protected byte cards[]; // The contents of the deck. | |
protected int marker; // Indicates the top. | |
// Constructors | |
// ============ | |
public Deck() { | |
// Effect: create a deck of cards in bridge sorted order | |
// with jokers at the end. | |
this(true); | |
} // Deck() | |
public Deck(boolean useJokers) { | |
// Effect: create a deck of cards in bridge sorted order. | |
// Jokers will be included only if useJokers is true. | |
marker = useJokers? 54 : 52; | |
cards = new byte[54]; | |
// Place the cards in order. | |
for (int i = 0; i < 4; i++) { | |
// Determine suit (using bridge ordering). | |
byte suit = JOKER; | |
switch (i) { | |
case 0: suit = CLUBS; break; | |
case 1: suit = DIAMONDS; break; | |
case 2: suit = HEARTS; break; | |
case 3: suit = SPADES; break; | |
default: | |
// This should not happen. | |
break; | |
} | |
for (int j = 0; j < 13; j++) { | |
cards[(marker - 1) - ((13 * i) + j)] = | |
(byte)(suit | (j+1)); | |
} // for j | |
} // for i | |
// Place the jokers | |
cards[useJokers ? 1 : marker + 1] = JOKER | JOKER_A; | |
cards[useJokers ? 0 : marker] = JOKER | JOKER_B; | |
} // Deck() | |
public Deck(byte cards[]) { | |
// Effect: create a deck of cards with the order and | |
// content specified by the cards array. | |
marker = cards.length; | |
this.cards = new byte[marker]; | |
for (int i = 0; i < cards.length; i++) { | |
this.cards[i] = cards[i]; | |
} // for i | |
} | |
protected Deck(Deck d) { | |
// Effect: create a deck of cards identical to the | |
// specified deck. | |
marker = d.marker; | |
cards = new byte[d.cards.length]; | |
for (int i = 0; i < 54; i++) { | |
cards[i] = d.cards[i]; | |
} // for i | |
} // Deck(Deck) | |
// Generic Methods | |
// =============== | |
public Object clone() { | |
// Effect: returns a deck that is identical to this one. | |
return new Deck(this); | |
} // clone() | |
public String toString() { | |
// Effect: returns a string that represents the cards in | |
// this deck, included from the bottom of the deck to | |
// the top. This is meant to correspond to how a | |
// person might look through an actual deck of cards | |
// after turning it over. | |
StringBuffer buffer = new StringBuffer(); | |
for (int i = 0; i < marker; i++) { | |
buffer.append(cardString(cards[i])); | |
// Add line breaks after every thirteen cards. | |
if (i % 13 == 12) | |
buffer.append("\n"); | |
else buffer.append(" "); | |
} // for i | |
// Add a final linefeed if necessary. | |
if (marker % 13 != 0) | |
buffer.append("\n"); | |
return buffer.toString(); | |
} // toString() | |
// Deck Manipulation Methods (Mutators) | |
// ========================= | |
public void shuffle() { | |
// Effect: changes the order of the cards to a random | |
// pattern. | |
shuffle(new Random()); | |
} // shuffle() | |
public void shuffle(Random rand) { | |
// Effect: changes the order of the cards to a random | |
// pattern using the specified random number generator. | |
for (int i = 0; i < marker; i++) { | |
int swap = Math.abs(rand.nextInt() % marker); | |
byte buffer = cards[i]; | |
cards[i] = cards[swap]; | |
cards[swap] = buffer; | |
} // for i | |
} // shuffle(Random) | |
public byte deal() { | |
// Effect: return the top card and remove it from the deck | |
// if any cards are left in the deck. Otherwise return zero. | |
return (marker > 0) ? cards[--marker] : (byte)0; | |
} // deal() | |
public void collect() { | |
// Effect: restore cards that have been dealt to the deck. | |
marker = cards.length; | |
} // collect() | |
protected void basicCut(int size, int limit) { | |
// Effect: switch cards below the specified position with | |
// the cards above, up to the specified limit. | |
// A size of zero or limit will not change the deck. | |
if (size > 0 && size < limit) { | |
byte buffer[] = new byte[limit]; | |
// First move the lower cards up. | |
for (int i = 0; i < size; i++) { | |
buffer[i + (limit - size)] = cards[i]; | |
} // for i | |
// Then move the upper cards down. | |
for (int i = size; i < limit; i++) { | |
buffer[i - size] = cards[i]; | |
} // for i | |
// Then replace the original deck. | |
for (int i = 0; i < limit; i++) { | |
cards[i] = buffer[i]; | |
} // for i | |
} // if position | |
} // basicCut(int, int) | |
public void cutTop(int size) { | |
// Effect: switch cards below the specified position with the | |
// cards above. | |
// A size of zero or marker will not change the deck. | |
basicCut(marker - size, marker); | |
} // cutTop(int) | |
public void cutBottom(int size) { | |
// Effect: switch cards below the specified position with the | |
// cards above. | |
// A size of zero or marker will not change the deck. | |
basicCut(size, marker); | |
} // cutBottom(int) | |
public void tripleCut(int low, int high) { | |
// Requires: 0 < low < high < this.count() | |
// Effect: swaps the cards above the highest of the | |
// specified positions with cards below the lowest. | |
if ((0 <= low) && (low <= high) && (high <= marker)) { | |
basicCut(low, high); | |
basicCut(high, marker); | |
} // if low && high | |
} // tripleCut(); | |
public void moveDown(int position) { | |
// Effect: swaps the card at the specified position with | |
// the card below it, wrapping around the end of the | |
// deck. | |
moveDown(position, 1); | |
} // moveDown(int) | |
public void moveDown(int position, int count) { | |
// Effect: swaps the card at the specified position with | |
// the card below it, wrapping around the end of the | |
// deck. If count is greater than zero then this | |
// operation is repeated that many times. | |
int index = (marker - 1) - position; | |
while (count > 0) { | |
if (index > 0 && index < marker) { | |
byte buffer = cards[index]; | |
cards[index] = cards[index - 1]; | |
cards[index - 1] = buffer; | |
index--; | |
} else if (index == 0) { | |
byte buffer; | |
for (int i = 0; i < marker - 2; i++) { | |
buffer = cards[i]; | |
cards[i] = cards[i + 1]; | |
cards[i + 1] = buffer; | |
index++; | |
} // for i | |
} // if position | |
count--; | |
} // while (count > 0) | |
} // moveDown(int) | |
// Deck Inspection Methods (Non-Mutators) | |
// ======================= | |
public int count() { | |
// Effect: return the number of cards in this deck. | |
return marker; | |
} // count() | |
public byte peekTop(int position) { | |
// Effect: return the card at the specified position, but do | |
// not remove it from the deck. The top card has position | |
// zero, the next card position one, and so on. | |
if (position >= 0 && position < marker) { | |
return cards[(marker - 1) - position]; | |
} else return (byte)0; | |
} // peekTop(int) | |
public byte peekBottom(int position) { | |
// Effect: return the card at the specified position, but do | |
// not remove it from the deck. The top card has position | |
// zero, the next card position one, and so on. | |
if (position >= 0 && position < marker) { | |
return cards[position]; | |
} else return (byte)0; | |
} // peekBottom(int) | |
public int findTop(byte card) { | |
// Effect: return the position of the specified card if it can | |
// be found in the deck. Otherwise return a negative number. | |
int i = 0; | |
while (i < marker) { | |
if (cards[i] == card) { | |
return (marker - 1) - i; | |
} // if (cards[i] == card) | |
i++; | |
} // while (i < marker) | |
return -1; | |
} // findTop(byte) | |
public int findBottom(byte card) { | |
// Effect: return the position of the specified card if it can | |
// be found in the deck. Otherwise return a negative number. | |
int i = 0; | |
while (i < marker) { | |
if (cards[i] == card) { | |
return i; | |
} // if (cards[i] == card) | |
i++; | |
} // while (i < marker) | |
return -1; | |
} // findBottom(byte) | |
// Card Methods | |
// ============ | |
public static String | |
cardString(byte card) { | |
// Effect: return a string that represenets the specified | |
// card. | |
StringBuffer buffer = new StringBuffer(); | |
// Mark the card value. | |
switch (card & MASK_VALUE) { | |
case ACE: | |
buffer.append("A"); | |
break; | |
case DEUCE: | |
buffer.append("2"); | |
break; | |
case THREE: | |
buffer.append("3"); | |
break; | |
case FOUR: | |
buffer.append("4"); | |
break; | |
case FIVE: | |
buffer.append("5"); | |
break; | |
case SIX: | |
buffer.append("6"); | |
break; | |
case SEVEN: | |
buffer.append("7"); | |
break; | |
case EIGHT: | |
buffer.append("8"); | |
break; | |
case NINE: | |
buffer.append("9"); | |
break; | |
case TEN: | |
buffer.append("0"); | |
break; | |
case JACK: | |
buffer.append("J"); | |
break; | |
case QUEEN: | |
buffer.append("Q"); | |
break; | |
case KING: | |
buffer.append("K"); | |
break; | |
case JOKER_A: | |
buffer.append("A"); | |
break; | |
case JOKER_B: | |
buffer.append("B"); | |
break; | |
default: | |
// This should not happen. | |
break; | |
} // switch (card & MASK_VALUE) | |
// Mark the card suit. | |
switch (card & MASK_SUIT) { | |
case CLUBS: | |
buffer.append("C"); | |
break; | |
case DIAMONDS: | |
buffer.append("D"); | |
break; | |
case HEARTS: | |
buffer.append("H"); | |
break; | |
case SPADES: | |
buffer.append("S"); | |
break; | |
case JOKER: | |
buffer.append("J"); | |
break; | |
default: | |
break; | |
} // switch (card & MASK_SUIT) | |
return buffer.toString(); | |
} // cardString(byte) | |
// Suit Methods | |
public static boolean | |
isClub(byte card) { return (card & MASK_SUIT) == CLUBS; } | |
public static boolean | |
isDiamond(byte card) { return (card & MASK_SUIT) == DIAMONDS; } | |
public static boolean | |
isHeart(byte card) { return (card & MASK_SUIT) == HEARTS; } | |
public static boolean | |
isSpade(byte card) { return (card & MASK_SUIT) == SPADES; } | |
// Type Methods | |
public static boolean | |
isBlack(byte card) { return (card & MASK_BLACK) != (byte)0; } | |
public static boolean | |
isRed(byte card) { return (card & MASK_RED) != (byte)0; } | |
public static boolean | |
isJoker(byte card) { return (card & MASK_JOKER) != (byte)0; } | |
// Joker Methods | |
public static boolean | |
isJokerA(byte card) { return card == (JOKER | JOKER_A); } | |
public static boolean | |
isJokerB(byte card) { return card == (JOKER | JOKER_B); } | |
// Value Methods | |
public static boolean | |
isAce(byte card) { return (card & MASK_VALUE) == ACE; } | |
public static boolean | |
isDuece(byte card) { return (card & MASK_VALUE) == DEUCE; } | |
public static boolean | |
isTwo(byte card) { return isDuece(card); } | |
public static boolean | |
isThree(byte card) { return (card & MASK_VALUE) == THREE; } | |
public static boolean | |
isFour(byte card) { return (card & MASK_VALUE) == FOUR; } | |
public static boolean | |
isFive(byte card) { return (card & MASK_VALUE) == FIVE; } | |
public static boolean | |
isSix(byte card) { return (card & MASK_VALUE) == SIX; } | |
public static boolean | |
isSeven(byte card) { return (card & MASK_VALUE) == SEVEN; } | |
public static boolean | |
isEight(byte card) { return (card & MASK_VALUE) == EIGHT; } | |
public static boolean | |
isNine(byte card) { return (card & MASK_VALUE) == NINE; } | |
public static boolean | |
isTen(byte card) { return (card & MASK_VALUE) == TEN; } | |
public static boolean | |
isJack(byte card) { return (card & MASK_VALUE) == JACK; } | |
public static boolean | |
isQueen(byte card) { return (card & MASK_VALUE) == QUEEN; } | |
public static boolean | |
isKing(byte card) { return (card & MASK_VALUE) == KING; } | |
public static int | |
getFaceValue(byte card) {return (int)(card & MASK_VALUE); } | |
// Module Test Method | |
// ================== | |
// /public static void main(String args[]) { | |
// // Effect: executes a test of this module. | |
// Deck d = new Deck(false); | |
// System.out.println("Default Deck:"); | |
// System.out.println(d.toString()); | |
// System.out.println(); // */ | |
// | |
// d.shuffle(); | |
// System.out.println("Shuffled Deck:"); | |
// System.out.println(d.toString()); | |
// System.out.println(); // */ | |
// } // main(String[])*/ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment