Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*.prefs
*.project
*.classpath
target/
*/target/*
*/target/**
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
Deck-o-Cards
=========

## Description

Following the principle of least surprise, this project represents a simple poker-style playing cards which has made reasonable decisions regarding implementation, in the possibility that it would become a foundational part of an application in the future.

This implementation will randomly traverse and reorder all cards in deck using an in memory technique over a single pass of the deck. A card will be randomly selected and inserted at random at the end of the deck.

## Installation
Then you can download this repository with the following command:

git clone https://github.com/amadib/deck-o-cards.git

## MainClass
The main class of this project is `Dealer` and can be found in Dealer.java.

## Dependencies
This project has dependencies on log4j and can be built and ran using [Maven](http://maven.apache.org/download.cgi).

The project may be built and executed with maven by running the following command:

mvn install exec:java -Dmaven.test.skip=true

Importing the project as an *Existing Maven Project* within eclipse with the [M2eclipse](https://www.eclipse.org/m2e/) plugin installed and running the following goal:

install exec:java -Dmaven.test.skip=true

*Note: log4j logging has been turned off by default.*

###Version

1.0

### Deprecated
Parts of the **com.appian.cards.Card** class have been deprecated in favor of a *"better"* solution.
41 changes: 38 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,46 @@
<artifactId>cards</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Deck of Cards</name>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>default-cli</id>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>com.appian.players.Dealer</mainClass>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
<exclusions>
<exclusion>
<groupId>com.sun.jmx</groupId>
<artifactId>jmxri</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.jdmk</groupId>
<artifactId>jmxtools</artifactId>
</exclusion>
<exclusion>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
</exclusion>
</exclusions>
</dependency>

</dependencies>
</project>
14 changes: 11 additions & 3 deletions src/main/java/com/appian/cards/Card.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,22 @@ public Card(Suit suit, Face face, Card previous, Card next) {
}
@Override
public String toString(){
if (face.ordinal() == 0 || face.ordinal() >= 10 ){
return face.name() + " of " + suit.name();
} else {
return (face.ordinal()+1) + " of " + suit.name();
}
}

public String printFaceFirst(){
return Utils.padRight(face.name(), 5) + " " + suit.name();
}
public String toStringBackwards() {
public String printSuitFirst() {
return Utils.padRight(suit.name(), 8) + " " + face.name();
}

/*
* Deprecated methods
/**
* Deprecated methods
*/
@Deprecated
private Card next = null;
Expand Down
52 changes: 39 additions & 13 deletions src/main/java/com/appian/cards/utils/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,55 @@
import java.math.BigInteger;
import java.util.Random;

import org.apache.log4j.Logger;

public class Utils {

private static final Logger logger = Logger.getLogger(Utils.class);

/**
* Returns true or false at random.
*
* @return true or false randomly
*/
public static boolean rightOrLeft(){
// int d = (int) (Math.random() * 100);
// System.out.println("random number is: " + d);
return ( (int) (Math.random() * 100) % 2 == 0 ) ? true : false;
int d = (int) (Math.random() * 100);
logger.debug("random number is: " + d);
return ( d % 2 == 0 ) ? true : false;
}

private static int BITLENGTH = 17;
static Random rnd = new Random();
static int previous = (int)Math.random() ;
public static int randomPostionBtw(int max){
/**
* Returns a random number between a range; bounded by 0 and {@code max}.
*
* Randomly selects a number between 0-100, and uses the number to get a large prime number.
* Multiplies the prime number and the random number, takes the absolute
* value of the product and modulo {@code max}.
*
* @param max - the ceiling of randomly
* @return 0 if the maximum number is 0;
*/
public static int randomPostionBtwn(int max){
if (max == 0 ){
logger.debug("randomPostionBtwn 0-" + padLeft(max + "", 2) +" => " + 0);
return 0;
}
int e = ( BigInteger.probablePrime(BITLENGTH, rnd)).intValue() ;
int d = ( (int) (Math.random() *(100)) * e % max);
previous = d;
// System.out.println("random number is: " + d );
return d;
Random rnd = new Random();
int randomNumber = (int) (Math.random() *(100)) ;
int BITLENGTH = randomNumber + 2;
int prime = (BigInteger.probablePrime(BITLENGTH, rnd)).intValue() ;
int randomPositionBtwn = Math.abs((randomNumber * prime) % max);
logger.debug("random number is: " + padLeft(randomNumber +"" , 2)
+ ", the prime number:" + padLeft(prime+"", 7)
+ ", randomPostionBtwn 0-" + padLeft(max + "", 2) +" => " + padLeft(randomPositionBtwn + "", 2));
return Math.abs(randomPositionBtwn);
}


public static String padRight(String s, int n) {
return String.format("%1$-" + n + "s", s);
}

public static String padLeft(String s, int n) {
return String.format("%1$" + n + "s", s);
}

}
69 changes: 53 additions & 16 deletions src/main/java/com/appian/decks/DeckArrayList.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@
import java.util.Arrays;
import java.util.List;

import org.apache.log4j.Logger;

import com.appian.cards.Card;
import com.appian.cards.Face;
import com.appian.cards.Suit;
import com.appian.cards.utils.Utils;

public class DeckArrayList implements IDeck{

private static final Logger logger = Logger.getLogger(DeckArrayList.class);
private List<Card> deck;
static Card[] deckOfCards = new Card[52];
static {
Expand All @@ -32,51 +35,85 @@ private DeckArrayList(){
deck = new ArrayList<Card>(Arrays.asList(deckOfCards));
}

/**
* Randomly reorders cards in deck using in memory technique over a single pass.
*
* Each card will be randomly selected and inserted at random at the end of the deck.
*/
public void shuffle() {
if (deck.size() == 0){
logger.warn("Deck is empty.");
return;
}
boolean first = true;
for (int numberOfCards = deck.size()+1; numberOfCards >= 0; numberOfCards--){
Card c = deck.remove(Utils.randomPostionBtw(numberOfCards));
if (first){
deck.add(c);
for (int numberOfCards = deck.size()-1; numberOfCards >= 0; numberOfCards--)
{
Card c = deck.remove(Utils.randomPostionBtwn(numberOfCards));
if (first) {
deck.add(c);
first = false;
} else {
int i = Utils.randomPostionBtw((deck.size())-numberOfCards);
deck.add((numberOfCards - 1) + i, c);
}
else {
int index = -1;
index = (numberOfCards - 1) + Utils.randomPostionBtwn((deck.size()) - numberOfCards);
if(index < 0){
index *= index;
}
deck.add(index, c);
}
}
}

/**
* Returns one card from deck
*
* @return the topmost card; null if the deck is empty
*/
public Card dealOneCard() {
if(deck.size() > 0){
return deck.remove(0);
}
else {
System.err.println("Deck has no more cards.");
logger.warn("Deck has no more cards.");
return null;
}
}

@Override
public String toString(){
if (deck.size() == 0 ){
logger.warn("Deck is empty.");
return "Deck is empty.";
}
StringBuilder sb = new StringBuilder();
int count = 1;
for(Card c : deck){
sb.append(c.toString() + ((count < deck.size()) ? ", " : ""));
count++;
}
return sb.toString();
}

public void printSuitFirst() {
for(Card c : deck){
System.out.println(c.toStringBackwards());
System.out.println(c.printSuitFirst());
}
}

public void printSuitFirstBackwards() {
public void printBackwardsSuitFirst() {
for(int i = deck.size(); i >= 0; i--){
System.out.println(deck.get(i).toStringBackwards());
System.out.println(deck.get(i).printSuitFirst());
}
}

public void printBackwards() {
public void printBackwardsFaceFirst() {
for(int i = deck.size(); i >= 0; i--){
System.out.println(deck.get(i).toString());
System.out.println(deck.get(i).printFaceFirst());
}
}

public void print() {
public void printFaceFirst() {
for(Card c : deck){
System.out.println(c.toString());
System.out.println(c.printFaceFirst());
}
}
}
6 changes: 3 additions & 3 deletions src/main/java/com/appian/decks/IDeck.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ public interface IDeck {
public Card dealOneCard();

public void printSuitFirst();
public void printSuitFirstBackwards();
public void printBackwardsSuitFirst();

public void printBackwards();
public void printFaceFirst();
public void printBackwardsFaceFirst();

public void print();
}
32 changes: 26 additions & 6 deletions src/main/java/com/appian/players/Dealer.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,42 @@
package com.appian.players;

import org.apache.log4j.Logger;

import com.appian.cards.Card;
import com.appian.decks.DeckArrayList;
import com.appian.decks.IDeck;

/**
* Main class of Deck-o-Cards
*
* Dealer will get a deck of cards and proceed to shuffle twice
* before dealing out the entire deck.
*
*/
public class Dealer {
static IDeck deck = DeckArrayList.getNewDeck();
private static final Logger logger = Logger.getLogger(Dealer.class);

public static void main(String[]args){
deck.print();
System.out.println("============Shuffle==============");
IDeck deck = DeckArrayList.getNewDeck();
deck.printFaceFirst();
System.out.println("============First Shuffle===============");
deck.shuffle();
deck.printSuitFirst();
System.out.println("============Second Shuffle==============");
deck.shuffle();
System.out.println(deck);
System.out.println("============Empty The Deck==============");
int i = 54;
while(i-- != 0){
Card card = deck.dealOneCard();
System.out.println("Drew " + card);
if (card == null){
System.out.println("No Jokers here!");
} else {
System.out.println("Drew " + card);
}
}
System.out.println(deck);
System.out.println("========Shuffle an Empty Deck========");
deck.shuffle();
System.out.println(deck);
}
}
17 changes: 17 additions & 0 deletions src/main/resources/log4j.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%5p] [%t %d{hh:mm:ss}] (%F:%M:%L) %m%n" />
</layout>
</appender>
<logger name="com.appian">
<level value="OFF" />
</logger>
<root>
<priority value="WARN" />
<appender-ref ref="console" />
</root>
</log4j:configuration>