Crazy

Poker

Mar 29th, 2018
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 19.13 KB | None | 0 0
  1. import java.util.*;
  2. import java.util.concurrent.Semaphore;
  3.  
  4. public class Poker {
  5.  
  6.  
  7.     static Semaphore slobodniMesta;
  8.     static Semaphore mozeDaigraat;
  9.     static int igraci;
  10.     static Semaphore lockIgraci;
  11.  
  12.  
  13.     public static void init() {
  14.  
  15.         slobodniMesta = new Semaphore(6);
  16.         igraci=0;
  17.         lockIgraci = new Semaphore(1);
  18.         mozeDaigraat = new Semaphore(0);
  19.  
  20.  
  21.  
  22.     }
  23.  
  24.     public static class Player extends TemplateThread {
  25.  
  26.         public Player(int numRuns) {
  27.             super(numRuns);
  28.         }
  29.  
  30.         @Override
  31.         public void execute() throws InterruptedException {
  32.  
  33.             slobodniMesta.acquire();
  34.             state.playerSeat();
  35.  
  36.             lockIgraci.acquire();
  37.             igraci++;
  38.  
  39.             if (igraci==6){
  40.                 state.dealCards();
  41.                 mozeDaigraat.release(6);
  42.  
  43.             }
  44.  
  45.             lockIgraci.release();
  46.  
  47.             mozeDaigraat.acquire();
  48.  
  49.             state.play();
  50.  
  51.             lockIgraci.acquire();
  52.             igraci--;
  53.             if (igraci==0){
  54.                 state.endRound();
  55.                 slobodniMesta.release(6);
  56.             }
  57.             lockIgraci.release();
  58.  
  59.  
  60.         }
  61.  
  62.     }
  63.  
  64.     public static void main(String[] args) {
  65.  
  66.         run();
  67.  
  68.     }
  69.  
  70.     static PokerState state = new PokerState();
  71.  
  72.     public static void run() {
  73.         try {
  74.             int numRuns = 1;
  75.             int numIterations = 1200;
  76.  
  77.             HashSet<Thread> threads = new HashSet<Thread>();
  78.  
  79.             for (int i = 0; i < numIterations; i++) {
  80.                 Player c = new Player(numRuns);
  81.                 threads.add(c);
  82.             }
  83.  
  84.             init();
  85.  
  86.             ProblemExecution.start(threads, state);
  87.         } catch (Exception ex) {
  88.             ex.printStackTrace();
  89.         }
  90.     }
  91. }
  92.  
  93. class PokerState extends AbstractState {
  94.  
  95.     private static final int PREVIOUS_ROUND_NOT_FINISHED_POINTS = 7;
  96.     private static final String PREVIOUS_ROUND_NOT_FINISHED = "Prethodnata grupa nema zavrseno so igrata.";
  97.     private static final int NO_6_FINISHED_PLAYERS_POINTS = 7;
  98.     private static final String NO_6_FINISHED_PLAYERS = "Nema 6 igraci koi zavrsile so igranje";
  99.  
  100.     private static final int PLAYERS_STIL_PLAYING_POINTS = 7;
  101.     private static final String PLAYERS_STIL_PLAYING = "Ima uste igraci koi ne zavrsile so igranje";
  102.  
  103.     private static final int PLAYING_NOT_PARALLEL_POINTS = 7;
  104.     private static final String PLAYING_NOT_PARALLEL = "ne e paralelno igranjeto";
  105.  
  106.     private static final int CARDS_NOT_DEALED_POINTS = 7;
  107.     private static final String CARDS_NOT_DEALED = "Ne moze da igra koga kartite ne se podeleni";
  108.  
  109.     private static final int MAXIMUM_6_CUSTOMERS_POINTS = 7;
  110.     private static final String MAXIMUM_6_CUSTOMERS = "Poveke od 6 igraci probuvaat da sednat istovremeno";
  111.  
  112.     private static final int NOT_ENOUGH_PLAYERS_POINTS = 7;
  113.     private static final String NOT_ENOUGH_PLAYERS = "nema dovolno igraci za da se sostavi grupa";
  114.  
  115.     private BoundCounterWithRaceConditionCheck playersAtTable;
  116.     private BoundCounterWithRaceConditionCheck peoplePlaying;
  117.     private BoundCounterWithRaceConditionCheck peopleFinishedPlaying;
  118.     private boolean emptyTable = true;
  119.     private boolean cardsDealed = false;
  120.  
  121.     public PokerState() {
  122.         playersAtTable = new BoundCounterWithRaceConditionCheck(0, 6,
  123.                 MAXIMUM_6_CUSTOMERS_POINTS, MAXIMUM_6_CUSTOMERS, null, 0, null);
  124.  
  125.         peoplePlaying = new BoundCounterWithRaceConditionCheck(0);
  126.         peopleFinishedPlaying = new BoundCounterWithRaceConditionCheck(0);
  127.     }
  128.  
  129.     /*
  130.      * Igracot sednuva na masata
  131.      */
  132.     public void playerSeat() {
  133.         synchronized (PokerState.class) {
  134.             if (emptyTable) {
  135.                 emptyTable = false;
  136.                 playersAtTable.assertEquals(0,
  137.                         PREVIOUS_ROUND_NOT_FINISHED_POINTS,
  138.                         PREVIOUS_ROUND_NOT_FINISHED);
  139.             }
  140.         }
  141.         log(playersAtTable.incrementWithMax(false), "Igrac sednuva");
  142.         Switcher.forceSwitch(5);
  143.     }
  144.  
  145.     /*
  146.      * Dilerot deli karti
  147.      */
  148.     public void dealCards() {
  149.         log(playersAtTable.assertEquals(6, NOT_ENOUGH_PLAYERS_POINTS,
  150.                 NOT_ENOUGH_PLAYERS), null);
  151.         synchronized (PokerState.class) {
  152.             cardsDealed = true;
  153.         }
  154.         Switcher.forceSwitch(5);
  155.     }
  156.  
  157.     /*
  158.      * Igracot zapocnuva so igrata
  159.      */
  160.     public void play() {
  161.         synchronized (PokerState.class) {
  162.             if (!cardsDealed) {
  163.                 log(new PointsException(CARDS_NOT_DEALED_POINTS,
  164.                         CARDS_NOT_DEALED), null);
  165.             }
  166.         }
  167.         log(peoplePlaying.incrementWithMax(false), "Igracot igra poker");
  168.         Switcher.forceSwitch(10);
  169.         log(peoplePlaying.decrementWithMin(false), null);
  170.         peopleFinishedPlaying.incrementWithMax(false);
  171.     }
  172.  
  173.     /*
  174.      * Site igraci zavrsile so igranjeto, moze da vleze nova grupa
  175.      */
  176.     public void endRound() {
  177.         peopleFinishedPlaying.assertEquals(6, NO_6_FINISHED_PLAYERS_POINTS,
  178.                 NO_6_FINISHED_PLAYERS);
  179.         log(peoplePlaying.assertEquals(0, PLAYERS_STIL_PLAYING_POINTS,
  180.                 PLAYERS_STIL_PLAYING), "Site igraci zavrsija so igranje.");
  181.  
  182.         synchronized (PokerState.class) {
  183.             // reset scenario
  184.             emptyTable = true;
  185.             cardsDealed = false;
  186.             playersAtTable.setValue(0);
  187.             peopleFinishedPlaying.setValue(0);
  188.         }
  189.         Switcher.forceSwitch(3);
  190.     }
  191.  
  192.     @Override
  193.     public void finalize() {
  194.         if (peoplePlaying.getMax() == 1) {
  195.             logException(new PointsException(PLAYING_NOT_PARALLEL_POINTS,
  196.                     PLAYING_NOT_PARALLEL));
  197.         }
  198.  
  199.     }
  200.  
  201. }
  202.  
  203. abstract class AbstractState {
  204.  
  205.     /**
  206.      * Method called after threads ended their execution to validate the
  207.      * correctness of the scenario
  208.      */
  209.     public abstract void finalize();
  210.  
  211.     /**
  212.      * List of logged actions
  213.      */
  214.     private List<String> actions = new ArrayList<String>();
  215.  
  216.     /**
  217.      *
  218.      * @return if the current thread is instance of TemplateThread it is
  219.      *         returned, and otherwise null is returned
  220.      */
  221.     protected TemplateThread getThread() {
  222.         Thread current = Thread.currentThread();
  223.         if (current instanceof TemplateThread) {
  224.             TemplateThread t = (TemplateThread) current;
  225.             return t;
  226.         } else {
  227.             return null;
  228.         }
  229.     }
  230.  
  231.     /**
  232.      * Log this exception or action
  233.      *
  234.      * @param e
  235.      *            occurred exception (null if no exception)
  236.      * @param action
  237.      *            Description of the occurring action
  238.      */
  239.     public synchronized void log(PointsException e, String action) {
  240.         TemplateThread t = (TemplateThread) Thread.currentThread();
  241.         if (e != null) {
  242.             t.setException(e);
  243.             actions.add(t.toString() + "\t(e): " + e.getMessage());
  244.             throw e;
  245.         } else if (action != null) {
  246.             actions.add(t.toString() + "\t(a): " + action);
  247.         }
  248.     }
  249.  
  250.     /**
  251.      * Logging exceptions
  252.      *
  253.      * @param e
  254.      */
  255.     protected synchronized void logException(PointsException e) {
  256.         Thread t = Thread.currentThread();
  257.         if (e != null) {
  258.             if (t instanceof TemplateThread) {
  259.                 ((TemplateThread) t).setException(e);
  260.             }
  261.             TemplateThread.hasException = true;
  262.             actions.add("\t(e): " + e.getMessage());
  263.             throw e;
  264.         }
  265.     }
  266.  
  267.     /**
  268.      * Printing of the actions and exceptions that has occurred
  269.      */
  270.     public synchronized void printLog() {
  271.         System.out
  272.                 .println("Poradi konkurentnosta za pristap za pecatenje, mozno e nekoja od porakite da ne e na soodvetnoto mesto.");
  273.         System.out.println("Log na izvrsuvanje na akciite:");
  274.         System.out.println("=========================");
  275.         System.out.println("tip\tid\titer\takcija/error");
  276.         System.out.println("=========================");
  277.         for (String l : actions) {
  278.             System.out.println(l);
  279.         }
  280.     }
  281.  
  282.     /**
  283.      * Prints the status of the execution, with the exceptions that has occur
  284.      */
  285.     public void printStatus() {
  286.         try {
  287.             finalize();
  288.         } catch (Exception e) {
  289.             e.printStackTrace();
  290.         }
  291.         if (!TemplateThread.hasException) {
  292.             int poeni = 25;
  293.             if (PointsException.getTotalPoints() == 0) {
  294.                 System.out
  295.                         .println("Procesot e uspesno sinhroniziran. Osvoeni 25 poeni.");
  296.             } else {
  297.                 poeni -= PointsException.getTotalPoints();
  298.                 PointsException.printErrors();
  299.                 System.out.println("Maksimalni osvoeni poeni: " + poeni);
  300.             }
  301.  
  302.         } else {
  303.             System.out
  304.                     .println("Procesot ne e sinhroniziran spored uslovite na zadacata");
  305.             printLog();
  306.             System.out
  307.                     .println("====================================================");
  308.             PointsException.printErrors();
  309.             int total = (25 - PointsException.getTotalPoints());
  310.             if (total < 0) {
  311.                 total = 0;
  312.             }
  313.             System.out.println("Maksimum Poeni: " + total);
  314.         }
  315.  
  316.     }
  317. }
  318.  
  319. class PointsException extends RuntimeException {
  320.  
  321.     private static HashMap<String, PointsException> exceptions = new HashMap<String, PointsException>();
  322.     private int points;
  323.  
  324.     public PointsException(int points, String message) {
  325.         super(message);
  326.         this.points = points;
  327.         exceptions.put(message, this);
  328.     }
  329.  
  330.     public static int getTotalPoints() {
  331.         int sum = 0;
  332.         for (PointsException e : exceptions.values()) {
  333.             sum += e.getPoints();
  334.         }
  335.         return sum;
  336.     }
  337.  
  338.     public static void printErrors() {
  339.         if (!exceptions.isEmpty()) {
  340.             System.out.println("Gi imate slednite greski: ");
  341.             for (Map.Entry<String, PointsException> e : exceptions.entrySet()) {
  342.                 System.out.println(String.format("[%s] : (-%d)", e.getKey(), e
  343.                         .getValue().getPoints()));
  344.             }
  345.         }
  346.     }
  347.  
  348.     public int getPoints() {
  349.         return points;
  350.     }
  351. }
  352.  
  353. class Switcher {
  354.     private static final Random RANDOM = new Random();
  355.  
  356.     /*
  357.      * This method pauses the current thread i.e. changes its state to be
  358.      * Blocked. This should force thread switch if there are threads waiting
  359.      */
  360.     public static void forceSwitch(int range) {
  361.         try {
  362.             Thread.sleep(RANDOM.nextInt(range));
  363.         } catch (InterruptedException e) {
  364.         }
  365.     }
  366. }
  367.  
  368. abstract class TemplateThread extends Thread {
  369.  
  370.     static boolean hasException = false;
  371.     public int iteration = 0;
  372.     protected Exception exception = null;
  373.     int numRuns = 1;
  374.  
  375.     public TemplateThread(int numRuns) {
  376.         this.numRuns = numRuns;
  377.     }
  378.  
  379.     public abstract void execute() throws InterruptedException;
  380.  
  381.     @Override
  382.     public void run() {
  383.         try {
  384.             for (int i = 0; i < numRuns&&!hasException; i++) {
  385.                 execute();
  386.                 iteration++;
  387.  
  388.             }
  389.         } catch (InterruptedException e) {
  390.             // Do nothing
  391.         } catch (Exception e) {
  392.             exception = e;
  393.             e.printStackTrace();
  394.             hasException = true;
  395.         }
  396.     }
  397.  
  398.     public void setException(Exception exception) {
  399.         this.exception = exception;
  400.         hasException = true;
  401.     }
  402.  
  403.     @Override
  404.     public String toString() {
  405.         Thread current = Thread.currentThread();
  406.         if (numRuns > 1) {
  407.             return String.format("[%d]%s\t%d\t%d", new Date().getTime(), ""
  408.                             + current.getClass().getSimpleName().charAt(0), getId(),
  409.                     iteration);
  410.         } else {
  411.             return String.format("[%d]%s\t%d\t", new Date().getTime(), ""
  412.                     + current.getClass().getSimpleName().charAt(0), getId());
  413.         }
  414.     }
  415. }
  416.  
  417. class BoundCounterWithRaceConditionCheck {
  418.  
  419.     private static final int RACE_CONDITION_POINTS = 25;
  420.     private static final String RACE_CONDITION_MESSAGE = "Race condition occured";
  421.  
  422.     private int value;
  423.     private Integer maxAllowed;
  424.     private Integer minAllowed;
  425.     private int maxErrorPoints;
  426.     private int minErrorPoints;
  427.     private String maxErrorMessage;
  428.     private String minErrorMessage;
  429.  
  430.     public static int raceConditionDefaultTime = 3;
  431.  
  432.     private int max;
  433.  
  434.     /**
  435.      *
  436.      * @param value
  437.      */
  438.     public BoundCounterWithRaceConditionCheck(int value) {
  439.         super();
  440.         this.value = value;
  441.         this.max = value;
  442.     }
  443.  
  444.     /**
  445.      *
  446.      * @param value
  447.      *            initial value
  448.      * @param maxAllowed
  449.      *            upper bound of the value
  450.      * @param maxErrorPoints
  451.      *            how many points are lost with the max value constraint
  452.      *            violation
  453.      * @param maxErrorMessage
  454.      *            message shown when the upper bound constrain is violated
  455.      * @param minAllowed
  456.      *            lower bound of the value
  457.      * @param minErrorPoints
  458.      *            how many points are lost with the min value constraint
  459.      *            violation
  460.      * @param minErrorMessage
  461.      *            message shown when the lower bound constrain is violated
  462.      */
  463.     public BoundCounterWithRaceConditionCheck(int value, Integer maxAllowed,
  464.                                               int maxErrorPoints, String maxErrorMessage, Integer minAllowed,
  465.                                               int minErrorPoints, String minErrorMessage) {
  466.         super();
  467.         this.value = value;
  468.         this.max = value;
  469.         this.maxAllowed = maxAllowed;
  470.         this.minAllowed = minAllowed;
  471.         this.maxErrorPoints = maxErrorPoints;
  472.         this.minErrorPoints = minErrorPoints;
  473.         this.maxErrorMessage = maxErrorMessage;
  474.         this.minErrorMessage = minErrorMessage;
  475.     }
  476.  
  477.     /**
  478.      *
  479.      * @return the maximum value of the integer variable that occurred at some
  480.      *         point of the execution
  481.      */
  482.     public int getMax() {
  483.         return max;
  484.     }
  485.  
  486.     /**
  487.      *
  488.      * @return the current value
  489.      */
  490.     public synchronized int getValue() {
  491.         return value;
  492.     }
  493.  
  494.     public synchronized void setValue(int value) {
  495.         this.value = value;
  496.     }
  497.  
  498.     /**
  499.      * Throws exception when the val is different than the value of the counter.
  500.      *
  501.      * @param val
  502.      * @param points
  503.      * @param errorMessage
  504.      * @return
  505.      */
  506.     public synchronized PointsException assertEquals(int val, int points,
  507.                                                      String errorMessage) {
  508.         if (this.value != val) {
  509.             PointsException e = new PointsException(points, errorMessage);
  510.             return e;
  511.         } else {
  512.             return null;
  513.         }
  514.     }
  515.  
  516.     public synchronized PointsException assertNotEquals(int val, int points,
  517.                                                         String errorMessage) {
  518.         if (this.value == val) {
  519.             PointsException e = new PointsException(points, errorMessage);
  520.             return e;
  521.         } else {
  522.             return null;
  523.         }
  524.     }
  525.  
  526.     /**
  527.      * Testing for race condition. NOTE: there are no guarantees that the race
  528.      * condition will be detected
  529.      *
  530.      * @return
  531.      */
  532.     public PointsException checkRaceCondition() {
  533.         return checkRaceCondition(raceConditionDefaultTime,
  534.                 RACE_CONDITION_MESSAGE);
  535.     }
  536.  
  537.     /**
  538.      * Testing for race condition. NOTE: there are no guarantees that the race
  539.      * condition will be detected, but higher the time argument is, the
  540.      * probability for race condition occurrence is higher
  541.      *
  542.      * @return
  543.      */
  544.     public PointsException checkRaceCondition(int time, String message) {
  545.         int val;
  546.  
  547.         synchronized (this) {
  548.             val = value;
  549.         }
  550.         Switcher.forceSwitch(time);
  551.         if (val != value) {
  552.             PointsException e = new PointsException(RACE_CONDITION_POINTS,
  553.                     message);
  554.             return e;
  555.         }
  556.         return null;
  557.  
  558.     }
  559.  
  560.     public PointsException incrementWithMax() {
  561.         return incrementWithMax(true);
  562.     }
  563.  
  564.     public PointsException incrementWithMax(boolean checkRaceCondition) {
  565.         if (checkRaceCondition) {
  566.             PointsException raceCondition = checkRaceCondition();
  567.             if (raceCondition != null) {
  568.                 return raceCondition;
  569.             }
  570.         }
  571.         synchronized (this) {
  572.             value++;
  573.  
  574.             if (value > max) {
  575.                 max = value;
  576.             }
  577.             if (maxAllowed != null) {
  578.                 if (value > maxAllowed) {
  579.                     PointsException e = new PointsException(maxErrorPoints,
  580.                             maxErrorMessage);
  581.                     return e;
  582.                 }
  583.             }
  584.         }
  585.  
  586.         return null;
  587.     }
  588.  
  589.     public PointsException decrementWithMin() {
  590.         return decrementWithMin(true);
  591.     }
  592.  
  593.     public PointsException decrementWithMin(boolean checkRaceCondition) {
  594.         if (checkRaceCondition) {
  595.             PointsException raceCondition = checkRaceCondition();
  596.             if (raceCondition != null) {
  597.                 return raceCondition;
  598.             }
  599.         }
  600.  
  601.         synchronized (this) {
  602.             value--;
  603.             if (minAllowed != null) {
  604.                 if (value < minAllowed) {
  605.                     PointsException e = new PointsException(minErrorPoints,
  606.                             minErrorMessage);
  607.                     return e;
  608.                 }
  609.             }
  610.         }
  611.         return null;
  612.     }
  613.  
  614. }
  615.  
  616. abstract class ProblemExecution {
  617.  
  618.     public static void start(HashSet<Thread> threads, AbstractState state)
  619.             throws Exception {
  620.  
  621.         startWithoutDeadlock(threads, state);
  622.  
  623.         checkDeadlock(threads, state);
  624.     }
  625.  
  626.     public static void startWithoutDeadlock(HashSet<Thread> threads,
  627.                                             AbstractState state) throws Exception {
  628.  
  629.         // start the threads
  630.         for (Thread t : threads) {
  631.             t.start();
  632.         }
  633.  
  634.         // wait threads to finish
  635.         for (Thread t : threads) {
  636.             t.join(1000);
  637.         }
  638.  
  639.     }
  640.  
  641.     private static void checkDeadlock(HashSet<Thread> threads,
  642.                                       AbstractState state) {
  643.         // check for deadlock
  644.         for (Thread t : threads) {
  645.             if (t.isAlive()) {
  646.                 t.interrupt();
  647.                 if (t instanceof TemplateThread) {
  648.                     TemplateThread tt = (TemplateThread) t;
  649.                     tt.setException(new PointsException(25, "DEADLOCK"));
  650.                 }
  651.             }
  652.         }
  653.  
  654.         // print the status
  655.         state.printStatus();
  656.     }
  657.  
  658. }
Advertisement
Add Comment
Please, Sign In to add comment