diff --git a/Cribbage/.idea/vcs.xml b/Cribbage/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6c0b8635858dc7ad44b93df54b762707ce49eefc
--- /dev/null
+++ b/Cribbage/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/.." vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/Cribbage/cribbage.log b/Cribbage/cribbage.log
index 9c8820efcf7e505da73e32b9ae4615520f98595a..bbca90486b9cbda7dfd8c71c2596fddc88b571b5 100644
--- a/Cribbage/cribbage.log
+++ b/Cribbage/cribbage.log
@@ -6,3 +6,19 @@ deal,P1,[AD,AH,TD,JS,QH,KC]
 discard,P0,[2C,QC]
 discard,P1,[JS,KC]
 starter,8H
+
+
+show,P0,8H+[2H,7C,QD,KH]
+score,P0,2,2,fifteen,[7C,8H]
+show,P1,8H+[AD,AH,TD,QH]
+score,P1,2,2,pair2,[AD,AH]
+show,P1,8H+[2C,JS,QC,KC]
+score,P1,5,3,run3,[JS,QC,KC]
+
+
+show,P0,8H+[2H,7C,QD,KH]
+score,P0,2,2,fifteen,[7C,8H]
+show,P1,8H+[AD,AH,TD,QH]
+score,P1,7,2,pair2,[AD,AH]
+show,P1,8H+[2C,JS,QC,KC]
+score,P1,10,3,run3,[JS,QC,KC]
diff --git a/Cribbage/cribbage.properties b/Cribbage/cribbage.properties
index c9e8635a9c9831d8bfbd97036796b354a1f698ab..07cd098a1569820f205ce904b49647c4169e77ce 100644
--- a/Cribbage/cribbage.properties
+++ b/Cribbage/cribbage.properties
@@ -3,7 +3,7 @@ Seed=55510
 #Seed=1248
 #Seed=30006
 #Animate=true
-#Animate=false
+Animate=false
 #Player0=cribbage.HumanPlayer
 Player0=cribbage.RandomPlayer
 #Player1=cribbage.HumanPlayer
diff --git a/Cribbage/out/production/Cribbage/cribbage/Cribbage$1.class b/Cribbage/out/production/Cribbage/cribbage/Cribbage$1.class
index a147958a39f3d8d4f821a8a9067d4cd3a3a31377..c7ababb458a852037976b699ea4af0f7e672e206 100644
Binary files a/Cribbage/out/production/Cribbage/cribbage/Cribbage$1.class and b/Cribbage/out/production/Cribbage/cribbage/Cribbage$1.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/Cribbage$MyCardValues.class b/Cribbage/out/production/Cribbage/cribbage/Cribbage$MyCardValues.class
index fd620cdab36aae8688b2641dad70484ff1e0caa1..ad673df763de4d13b8c8801558a189860e3510ef 100644
Binary files a/Cribbage/out/production/Cribbage/cribbage/Cribbage$MyCardValues.class and b/Cribbage/out/production/Cribbage/cribbage/Cribbage$MyCardValues.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/Cribbage$Rank.class b/Cribbage/out/production/Cribbage/cribbage/Cribbage$Rank.class
index 9b0414c05acf17d1611d7f441ef9cd299f7afef0..b6c942a0d758ef09d80b5c925ed00c14e8393576 100644
Binary files a/Cribbage/out/production/Cribbage/cribbage/Cribbage$Rank.class and b/Cribbage/out/production/Cribbage/cribbage/Cribbage$Rank.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/Cribbage$Segment.class b/Cribbage/out/production/Cribbage/cribbage/Cribbage$Segment.class
index 15eaecc4b144ba1962aff3b0f0d9eb0db13d2b88..f41e54cfa506cd10ebc9ff5f807d5070ec43c975 100644
Binary files a/Cribbage/out/production/Cribbage/cribbage/Cribbage$Segment.class and b/Cribbage/out/production/Cribbage/cribbage/Cribbage$Segment.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/Cribbage$Suit.class b/Cribbage/out/production/Cribbage/cribbage/Cribbage$Suit.class
index e6a85e089e9a8805170c3ac5f5cb24ea0c0b61f3..95cf7eff903ab318d9ee38ef640294946369d21d 100644
Binary files a/Cribbage/out/production/Cribbage/cribbage/Cribbage$Suit.class and b/Cribbage/out/production/Cribbage/cribbage/Cribbage$Suit.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/Cribbage.class b/Cribbage/out/production/Cribbage/cribbage/Cribbage.class
index e2ceda0a8d6876c7363284db3c0881cf5e589609..8cecbea403ee3f3cb6c9e6a242f396b09e7cd981 100644
Binary files a/Cribbage/out/production/Cribbage/cribbage/Cribbage.class and b/Cribbage/out/production/Cribbage/cribbage/Cribbage.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/CribbageHandCards.class b/Cribbage/out/production/Cribbage/cribbage/CribbageHandCards.class
new file mode 100644
index 0000000000000000000000000000000000000000..26e29fc6065d3e179572e4dcf322f321f479036d
Binary files /dev/null and b/Cribbage/out/production/Cribbage/cribbage/CribbageHandCards.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/Fifteens.class b/Cribbage/out/production/Cribbage/cribbage/Fifteens.class
new file mode 100644
index 0000000000000000000000000000000000000000..dc654828575dfd346092433ff70c2b8058cf86b5
Binary files /dev/null and b/Cribbage/out/production/Cribbage/cribbage/Fifteens.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/Flush.class b/Cribbage/out/production/Cribbage/cribbage/Flush.class
new file mode 100644
index 0000000000000000000000000000000000000000..f94ad1b49f6bbbf5a1b422e3a1dc7f7fcff16793
Binary files /dev/null and b/Cribbage/out/production/Cribbage/cribbage/Flush.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/HandCards.class b/Cribbage/out/production/Cribbage/cribbage/HandCards.class
new file mode 100644
index 0000000000000000000000000000000000000000..5cbf91854a3e1cbf19341e8987edf611c35daa00
Binary files /dev/null and b/Cribbage/out/production/Cribbage/cribbage/HandCards.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/IPlayer.class b/Cribbage/out/production/Cribbage/cribbage/IPlayer.class
index 0333e8d97086a0e9f30cbe899a0e3119540e16ea..5bf30b3e1009af0db7502e9bd2428d1574558ba9 100644
Binary files a/Cribbage/out/production/Cribbage/cribbage/IPlayer.class and b/Cribbage/out/production/Cribbage/cribbage/IPlayer.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/Jack.class b/Cribbage/out/production/Cribbage/cribbage/Jack.class
new file mode 100644
index 0000000000000000000000000000000000000000..abe4dad483fb43696ebb2227a7304174a698edab
Binary files /dev/null and b/Cribbage/out/production/Cribbage/cribbage/Jack.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/LogGenerator.class b/Cribbage/out/production/Cribbage/cribbage/LogGenerator.class
index cc7d45b71d7f8103957aa6174f635d01805be96e..fd9aa818ead1769b63a2f8f5aaf12b5156dd4389 100644
Binary files a/Cribbage/out/production/Cribbage/cribbage/LogGenerator.class and b/Cribbage/out/production/Cribbage/cribbage/LogGenerator.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/Pairs.class b/Cribbage/out/production/Cribbage/cribbage/Pairs.class
new file mode 100644
index 0000000000000000000000000000000000000000..ac63c6a5a98e123e9be0b2e588ac15b23c4d70dc
Binary files /dev/null and b/Cribbage/out/production/Cribbage/cribbage/Pairs.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/Rule.class b/Cribbage/out/production/Cribbage/cribbage/Rule.class
new file mode 100644
index 0000000000000000000000000000000000000000..2b5ad62c54a6cb39677de9f54535ddc50493be74
Binary files /dev/null and b/Cribbage/out/production/Cribbage/cribbage/Rule.class differ
diff --git a/Cribbage/out/production/Cribbage/cribbage/Runs.class b/Cribbage/out/production/Cribbage/cribbage/Runs.class
new file mode 100644
index 0000000000000000000000000000000000000000..1a0733a9f6dfc7184a93b5e90f3937cd2001d164
Binary files /dev/null and b/Cribbage/out/production/Cribbage/cribbage/Runs.class differ
diff --git a/Cribbage/src/cribbage/Cribbage.java b/Cribbage/src/cribbage/Cribbage.java
index 874ec0d1a717e9ff24e2a0ffa58a6e7d6a8966aa..bc3d9cd54f21da60a704fd6d6530a08bff741ba1 100644
--- a/Cribbage/src/cribbage/Cribbage.java
+++ b/Cribbage/src/cribbage/Cribbage.java
@@ -4,7 +4,6 @@ package cribbage;
 
 import ch.aplu.jcardgame.*;
 import ch.aplu.jgamegrid.*;
-import observer.*;
 
 import java.awt.Color;
 import java.awt.Font;
@@ -129,17 +128,20 @@ public class Cribbage extends CardGame {
   private Hand starter;
   private Hand crib;
 
+  private Hand[] handsCopy = {new Hand(deck), new Hand(deck)};
+
   public static void setStatus(String string) { cribbage.setStatusText(string); }
 
 static private final IPlayer[] players = new IPlayer[nPlayers];
 private final int[] scores = new int[nPlayers];
 
-static private final LogGenerator logGenerator = new LogGenerator();
+static LogGenerator log = LogGenerator.getLog();
 private final String[] playerName = {"P0", "P1"};
 
 final Font normalFont = new Font("Serif", Font.BOLD, 24);
 final Font bigFont = new Font("Serif", Font.BOLD, 36);
 
+
 private void initScore() {
 	 for (int i = 0; i < nPlayers; i++) {
 		 scores[i] = 0;
@@ -178,8 +180,8 @@ private void deal(Hand pack, Hand[] hands) {
 	}
 	layouts[0].setStepDelay(0);
 	//log
-	logGenerator.writeLog("deal,P0," + canonical(players[0].hand));
-	logGenerator.writeLog("deal,P1," + canonical(players[1].hand));
+	log.writeLog("deal,P0," + canonical(players[0].hand));
+	log.writeLog("deal,P1," + canonical(players[1].hand));
 }
 
 private void discardToCrib() {
@@ -189,6 +191,7 @@ private void discardToCrib() {
 	crib.setView(this, layout);
 	// crib.setTargetArea(cribTarget);
 	crib.draw();
+
 	Hand dPlayer = new Hand(deck); //discarded cards.
 	for (IPlayer player: players) {
 		for (int i = 0; i < nDiscards; i++) {
@@ -198,10 +201,18 @@ private void discardToCrib() {
 		dPlayer.insert(crib.get(crib.getNumberOfCards()-2), false);
 		dPlayer.sort(Hand.SortType.POINTPRIORITY, false);
 		crib.sort(Hand.SortType.POINTPRIORITY, true);
+
 		//log
-		logGenerator.writeLog("discard," + playerName[player.id] + "," + canonical(dPlayer));
+		log.writeLog("discard," + playerName[player.id] + "," + canonical(dPlayer));
 		dPlayer.removeAll(false);
 	}
+
+	for (Card c : hands[0].getCardList()){
+		handsCopy[0].insert(c.clone(), false);
+	}
+	for (Card c : hands[1].getCardList()){
+		handsCopy[1].insert(c.clone(), false);
+	}
 }
 
 private void starter(Hand pack) {
@@ -212,7 +223,7 @@ private void starter(Hand pack) {
 	starter.draw();
 	Card dealt = randomCard(pack);
 	dealt.setVerso(false);
-	logGenerator.writeLog("starter," + canonical(dealt));
+	log.writeLog("starter," + canonical(dealt));
 	transfer(dealt, starter);
 }
 
@@ -238,9 +249,9 @@ class Segment {
 		}
 }
 
+
 private void play() {
 	final int thirtyone = 31;
-	final int fifteen = 15;
 	List<Hand> segments = new ArrayList<>();
 	int currentPlayer = 0; // Player 1 is dealer
 	Segment s = new Segment();
@@ -252,8 +263,6 @@ private void play() {
 			if (s.go) {
 				// Another "go" after previous one with no intervening cards
 				// lastPlayer gets 1 point for a "go"
-				scores[s.lastPlayer] += 1;
-				updateScore(s.lastPlayer);
 				s.newSegment = true;
 			} else {
 				// currentPlayer says "go"
@@ -263,23 +272,12 @@ private void play() {
 		} else {
 			s.lastPlayer = currentPlayer; // last Player to play a card in this segment
 			transfer(nextCard, s.segment);
-			// lastPlayer gets 1 point for place the last card.
-			if ((players[0].emptyHand() && players[1].emptyHand())){
-				scores[s.lastPlayer] += 1;
-				updateScore(s.lastPlayer);
-			}
 			if (total(s.segment) == thirtyone) {
 				// lastPlayer gets 2 points for a 31
-				scores[s.lastPlayer] += 2;
-				updateScore(s.lastPlayer);
 				s.newSegment = true;
 				currentPlayer = (currentPlayer+1) % 2;
 			} else {
 				// if total(segment) == 15, lastPlayer gets 2 points for a 15
-				if (total(s.segment) == fifteen){
-					scores[s.lastPlayer] += 2;
-					updateScore(s.lastPlayer);
-				}
 				if (!s.go) { // if it is "go" then same player gets another turn
 					currentPlayer = (currentPlayer+1) % 2;
 				}
@@ -294,21 +292,24 @@ private void play() {
 
 void showHandsCrib() {
 	// score player 0 (non dealer)
+	log.writeLog(String.format("show,P0,%s+%s", canonical(starter.getLast()), canonical(handsCopy[0])));
 	HandCards p0HandCards = new CribbageHandCards();
+	p0HandCards.setPlayer(0);
 	modifySubject(p0HandCards);
-	p0HandCards.sendHandCards(players[0].hand, starter);
+	p0HandCards.sendHandCards(handsCopy[0], starter);
 	scores[0] += p0HandCards.scoreHandCards();
 	updateScore(0);
 	// score player 1 (dealer)
+	log.writeLog(String.format("show,P1,%s+%s", canonical(starter.getLast()), canonical(handsCopy[1])));
 	HandCards p1HandCards = new CribbageHandCards();
+	p1HandCards.setPlayer(1);
 	modifySubject(p1HandCards);
-	p1HandCards.sendHandCards(players[1].hand, starter);
-	scores[1] += p1HandCards.scoreHandCards();
+	p1HandCards.sendHandCards(handsCopy[1], starter);
+	p1HandCards.scoreHandCards();
 	// score crib (for dealer)
-	HandCards cribHandCards = new CribbageHandCards();
-	modifySubject(cribHandCards);
-	cribHandCards.sendHandCards(crib, starter);
-	scores[1] += cribHandCards.scoreHandCards();
+	log.writeLog(String.format("show,P1,%s+%s", canonical(starter.getLast()), canonical(crib)));
+	p1HandCards.sendHandCards(crib, starter);
+	scores[1] += p1HandCards.scoreHandCards();
 	updateScore(1);
 }
 
@@ -395,10 +396,9 @@ public Cribbage()
 	  // End properties
 
 	  //log
-	  logGenerator.generateLogFile();
-	  logGenerator.writeLog("seed," + SEED);
-	  logGenerator.writeLog(cribbageProperties.getProperty("Player0") + ",P0");
-	  logGenerator.writeLog(cribbageProperties.getProperty("Player1") + ",P1");
+	  log.writeLog("seed," + SEED);
+	  log.writeLog(cribbageProperties.getProperty("Player0") + ",P0");
+	  log.writeLog(cribbageProperties.getProperty("Player1") + ",P1");
 
 	  new Cribbage();
   }
diff --git a/Cribbage/src/cribbage/CribbageHandCards.java b/Cribbage/src/cribbage/CribbageHandCards.java
new file mode 100644
index 0000000000000000000000000000000000000000..e8e6301fa7d16dfa6e6ec9539fbecbaf0c3017be
--- /dev/null
+++ b/Cribbage/src/cribbage/CribbageHandCards.java
@@ -0,0 +1,45 @@
+package cribbage;
+
+import ch.aplu.jcardgame.Hand;
+
+import java.util.ArrayList;
+
+public class CribbageHandCards implements HandCards{
+
+    private ArrayList<Rule> rules;
+
+    int player;
+    int score = 0;
+
+    public CribbageHandCards(){
+        rules = new ArrayList<Rule>();
+    }
+
+    @Override
+    public void addRule(Rule rule){
+        rules.add(rule);
+    }
+
+    @Override
+    public void removeRule(Rule rule){
+        rules.remove(rule);
+    }
+
+    @Override
+    public void sendHandCards(Hand hand, Hand starter){
+        rules.forEach((rule) -> rule.receiveHandCards(hand, starter));
+    }
+
+    @Override
+    public void setPlayer(int player){
+        this.player = player;
+    }
+
+    @Override
+    public int scoreHandCards() {
+        for(Rule r : rules){
+            score += r.calculateScore(player, score);
+        }
+        return score;
+    }
+}
diff --git a/Cribbage/src/cribbage/Fifteens.java b/Cribbage/src/cribbage/Fifteens.java
new file mode 100644
index 0000000000000000000000000000000000000000..3efe55ca05ddbd744d9c90f3f9eeec0e59f86a1c
--- /dev/null
+++ b/Cribbage/src/cribbage/Fifteens.java
@@ -0,0 +1,52 @@
+package cribbage;
+
+import ch.aplu.jcardgame.Card;
+import ch.aplu.jcardgame.Hand;
+
+import java.util.ArrayList;
+
+public class Fifteens implements Rule{
+
+    Hand hand;
+
+    public Fifteens(){}
+
+    @Override
+    public void receiveHandCards(Hand hand, Hand starter){
+        this.hand = hand;
+        this.hand.insert(starter, false);
+    }
+
+
+    @Override
+    public int calculateScore(int playerId, int currentScore){
+        int score;
+        ArrayList<Integer> cardValues = new ArrayList<>(); //An array list that contains all card values.
+        //Add values to the array list.
+        for (Card c: hand.getCardList()){
+            cardValues.add(((Cribbage.Rank) c.getRank()).value);
+        }
+        //Choose N numbers from a list, the sum of them should be 15.
+        score = search(cardValues, playerId, currentScore);
+        return score;
+    }
+
+    private int search(ArrayList<Integer> cardValues, int playerId, int currentScore){
+        int len = cardValues.size(), bit = 1 << len, score = 0, goal = 15;
+        for(int i=1; i<bit; i++){
+            int sum = 0;
+            Hand fifteen = new Hand(hand.getFirst().getDeck());
+            for (int j=0; j < len; j++){
+                if((i & 1 << j) != 0){
+                    fifteen.insert(hand.get(j).getCardNumber(), false);
+                    sum += cardValues.get(j);
+                }
+            }
+            if (sum == goal){
+                log.writeLog(String.format("score,P%d,%d,%d,fifteen,%s", playerId, currentScore + 2, 2, Cribbage.cribbage.canonical(fifteen)));
+                score += 2;
+            }
+        }
+        return score;
+    }
+}
diff --git a/Cribbage/src/cribbage/Flush.java b/Cribbage/src/cribbage/Flush.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e764c0f2f69d17694644965e35e5af146ec6fbe
--- /dev/null
+++ b/Cribbage/src/cribbage/Flush.java
@@ -0,0 +1,36 @@
+package cribbage;
+
+import ch.aplu.jcardgame.Card;
+import ch.aplu.jcardgame.Hand;
+
+public class Flush implements Rule{
+
+    Hand hand;
+    Card starter;
+
+    public Flush(){}
+
+    @Override
+    public void receiveHandCards(Hand hand, Hand starter){
+        this.hand = hand;
+        this.starter = starter.get(0);
+    }
+
+
+
+    public int calculateScore(int playerId, int currentScore){
+        int score = 0;
+        for (Cribbage.Suit suit : Cribbage.Suit.values()){
+            int nSuit = hand.getNumberOfCardsWithSuit(suit);
+            if (nSuit == 4){
+                score += 4;
+                if (starter.getSuit() == suit){
+                    score += 1;
+                    break;
+                }
+                log.writeLog(String.format("score,P%d,%d,%d,flush%d,%s", playerId, currentScore + score, score, score, Cribbage.cribbage.canonical(hand)));
+            }
+        }
+        return score;
+    }
+}
diff --git a/Cribbage/src/cribbage/HandCards.java b/Cribbage/src/cribbage/HandCards.java
new file mode 100644
index 0000000000000000000000000000000000000000..31360d387a07900521c3ec7fe56b12e6c2fd6e36
--- /dev/null
+++ b/Cribbage/src/cribbage/HandCards.java
@@ -0,0 +1,16 @@
+package cribbage;
+
+import ch.aplu.jcardgame.Hand;
+
+public interface HandCards {
+
+    void addRule(Rule rule);
+
+    void removeRule(Rule rule);
+
+    void sendHandCards(Hand hand, Hand starter);
+
+    void setPlayer(int player);
+
+    int scoreHandCards();
+}
diff --git a/Cribbage/src/cribbage/IPlayer.java b/Cribbage/src/cribbage/IPlayer.java
index 05eb568068f0a4daf255d9bcbcce047bf15636c0..765aba210e41ae9b8360b3f0c5e5fb82bff75be5 100644
--- a/Cribbage/src/cribbage/IPlayer.java
+++ b/Cribbage/src/cribbage/IPlayer.java
@@ -8,10 +8,14 @@ public abstract class IPlayer {
     int id;
     Deck deck; // Need this since can't get from hand to deck
     Hand hand;
+    int score;
 
     void setId(int id)  {
         this.id = id;
     }
+    public int getId(){return id;}
+    public void setScore(int score){this.score = score;}
+    public int getScore(){return score;}
     void startSegment(Deck deck, Hand hand) {this.deck = deck; this.hand = hand;}
     abstract Card discard();
     boolean emptyHand() {return hand.isEmpty();}
diff --git a/Cribbage/src/cribbage/Jack.java b/Cribbage/src/cribbage/Jack.java
new file mode 100644
index 0000000000000000000000000000000000000000..d088bed4c31d065ebd971d5432295c89816ed22e
--- /dev/null
+++ b/Cribbage/src/cribbage/Jack.java
@@ -0,0 +1,34 @@
+package cribbage;
+
+import ch.aplu.jcardgame.Card;
+import ch.aplu.jcardgame.Hand;
+
+public class Jack implements Rule{
+
+    Hand hand;
+    Card starter;
+
+
+    public Jack(){}
+
+    @Override
+    public void receiveHandCards(Hand hand, Hand starter){
+        this.hand = hand;
+
+        this.starter = starter.get(0);
+    }
+
+    @Override
+    public int calculateScore(int playerId, int currentScore){
+        int score = 0;
+        for (Card c : hand.getCardList()){
+            if (((Cribbage.Rank) c.getRank()).order == 11){
+                if (c.getSuitId() == starter.getSuitId()){
+                    score += 1;
+                    log.writeLog(String.format("score,P%d,%d,%d,jack,%s", playerId, currentScore + score, score, Cribbage.cribbage.canonical(c)));
+                }
+            }
+        }
+        return score;
+    }
+}
diff --git a/Cribbage/src/cribbage/LogGenerator.java b/Cribbage/src/cribbage/LogGenerator.java
index be03ef43f6d99cf66385d996afedc3416bbe5586..34229d30547aba58ae39224ec22105be27dbc569 100644
--- a/Cribbage/src/cribbage/LogGenerator.java
+++ b/Cribbage/src/cribbage/LogGenerator.java
@@ -1,32 +1,29 @@
 package cribbage;
 
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
 
 public class LogGenerator {
 
-    String pathName = "cribbage.log";
+    private static final LogGenerator log = new LogGenerator();
+    private final Path file_name = Path.of("cribbage.log");
 
-    public void generateLogFile(){
+    private LogGenerator(){
         try {
-            File file = new File(pathName);
-            if (file.exists()){
-                file.delete();
-            } else {
-                file.createNewFile();
-            }
-        }catch (Exception e){e.printStackTrace();}
+            Files.deleteIfExists(file_name);
+        }catch (IOException e){System.err.println(e);}
+    }
+
+    public static LogGenerator getLog(){
+        return log;
     }
 
     public void writeLog(String str){
+        String s = str + "\n";
         try {
-            FileWriter fileWriter = new FileWriter(pathName, true);
-            BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
-            bufferedWriter.write(str);
-            bufferedWriter.newLine();
-            bufferedWriter.close();
-        }catch (IOException e){e.printStackTrace();}
+            Files.write(file_name, s.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.APPEND);
+        }catch (IOException e){System.err.println(e);}
     }
 }
diff --git a/Cribbage/src/cribbage/Pairs.java b/Cribbage/src/cribbage/Pairs.java
new file mode 100644
index 0000000000000000000000000000000000000000..c27727b4d6865e585644a244bc3e546ae8b47d32
--- /dev/null
+++ b/Cribbage/src/cribbage/Pairs.java
@@ -0,0 +1,40 @@
+package cribbage;
+
+import ch.aplu.jcardgame.Hand;
+
+
+public class Pairs implements Rule{
+
+    Hand hand;
+
+    public Pairs(){}
+
+    @Override
+    public void receiveHandCards(Hand hand, Hand starter){
+        this.hand = hand;
+        this.hand.insert(starter, false);
+    }
+
+    @Override
+    public int calculateScore(int playerId, int currentScore){
+        int score = 0;
+        Hand[] pairs = hand.extractPairs();
+        for (Hand pair : pairs){
+            score += 2;
+            log.writeLog(String.format("score,P%d,%d,%d,pair2,%s", playerId, currentScore + score, score, Cribbage.cribbage.canonical(pair)));
+        }
+
+        Hand[] trips = hand.extractTrips();
+        for (Hand trip : trips) {
+            score += 6;
+            log.writeLog(String.format("score,P%d,%d,%d,pair3,%s", playerId, currentScore + score, score, Cribbage.cribbage.canonical(trip)));
+        }
+
+        Hand[] quads = hand.extractQuads();
+        for (Hand quad : quads) {
+            score += 12;
+            log.writeLog(String.format("score,P%d,%d,%d,pair4,%s", playerId, currentScore + score, score, Cribbage.cribbage.canonical(quad)));
+        }
+        return score;
+    }
+}
diff --git a/Cribbage/src/cribbage/Rule.java b/Cribbage/src/cribbage/Rule.java
new file mode 100644
index 0000000000000000000000000000000000000000..e6dffca7e9993a6b7f0dde707e8013018b04e36a
--- /dev/null
+++ b/Cribbage/src/cribbage/Rule.java
@@ -0,0 +1,13 @@
+package cribbage;
+
+import ch.aplu.jcardgame.Hand;
+import cribbage.IPlayer;
+import cribbage.LogGenerator;
+
+public interface Rule {
+
+    LogGenerator log = LogGenerator.getLog();
+
+    void receiveHandCards(Hand hand, Hand starter);
+    int calculateScore(int playerId, int currentScore);
+}
diff --git a/Cribbage/src/cribbage/Runs.java b/Cribbage/src/cribbage/Runs.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8d3efd647c45a7ccaabb79930a7d5e6a9ce8847
--- /dev/null
+++ b/Cribbage/src/cribbage/Runs.java
@@ -0,0 +1,31 @@
+package cribbage;
+
+import ch.aplu.jcardgame.Hand;
+
+public class Runs implements Rule{
+
+    Hand hand;
+
+    public Runs(){}
+
+    @Override
+    public void receiveHandCards(Hand hand, Hand starter){
+        this.hand = hand;
+        this.hand.insert(starter, false);
+    }
+
+    @Override
+    public int calculateScore(int playerId, int currentScore){
+        int score = 0;
+        for (int i=3; i<6; i++){
+            Hand[] runs = hand.extractSequences(i);
+            if (runs.length>0){
+                for (Hand run : runs){
+                    score += i;
+                    log.writeLog(String.format("score,P%d,%d,%d,run%d,%s", playerId, currentScore + score, score, i, Cribbage.cribbage.canonical(run)));
+                }
+            }
+        }
+        return score;
+    }
+}