Package algorithms

Source Code of algorithms.DivAlgorithm

package algorithms;

import general.Card;
import general.Range;
import general.Symbol;

import java.util.Random;

import utils.CardUtils;

public class DivAlgorithm extends DealingAlgorithm {

  private Card[] royalDeck;
  private Card[] nonRoyal;

  public DivAlgorithm(int num) {
    super(num);
    royalDeck = new Card[16];
    nonRoyal = new Card[36];
    int pos = 0;
    int nonPos = 0;
    for (int i = 0; i < deck.length; i++) {
      if (deck[i].getLetter().isRoyal()) {
        royalDeck[pos] = deck[i];
        pos++;
      } else {
        nonRoyal[nonPos] = deck[i];
        nonPos++;
      }
    }
  }

  public static int[] playersOrder = new int[] { 0, 1, 2, 3 };

  public void deal(Card[] cards) {
    // deck = new Card[cards.length];
    // System.arraycopy(cards, 0, deck, 0, cards.length);

    deck = royalDeck;
    for (int i = 0; i < num; i++) {
      CardUtils.shuffle(deck);

      int ans = deal(0, num - 1, 0, 0, 0, 0);
      if (ans >= 0)
        answers[i] = answers[num - 1];
      else
        i--; // retry
      // answers[i+num/2] = answers[num -2];
      //System.err.println(i);
    }

    printResults();
  }

  public int deal(int pos, int amount, int pos0, int pos1, int pos2, int pos3) {
    CardUtils.shuffle(playersOrder);
    // for each card there are 4 options: N,W,S,E
    if (pos == this.royalDeck.length && amount < num) // on the last on
    {
      if (isScoreLegal(true, pos0, pos1, pos2, pos3)) {
        System.out.println("Here");
        return this.completeHands(allHands, this.nonRoyal, pos0, pos1,
            pos2, pos3, amount);
      }
      return amount;
    } else {
      int tempAmount = amount;
      int player;
      for (int i = 0; i < 4; i++) {
        player = DivAlgorithm.playersOrder[i];
        if (player == 0) {
          if (pos0 < 13) // no more then 13 cards
          {

            allHands[0][pos0] = deck[pos];

            if (isScoreLegal(false, pos0 + 1, pos1, pos2, pos3)) {
              tempAmount = deal(pos + 1, tempAmount, pos0 + 1,
                  pos1, pos2, pos3);
            }

            if (tempAmount >= num)
              return tempAmount;
          }
        } else if (player == 1) {
          if (pos1 < 13) // no more then 13 cards
          {
            allHands[1][pos1] = deck[pos];

            if (isScoreLegal(false, pos0, pos1 + 1, pos2, pos3)) {
              tempAmount = deal(pos + 1, tempAmount, pos0,
                  pos1 + 1, pos2, pos3);
            }

            if (tempAmount >= num)
              return tempAmount;
          }
        } else if (player == 2) {
          if (pos2 < 13) // no more then 13 cards
          {

            allHands[2][pos2] = deck[pos];

            if (isScoreLegal(false, pos0, pos1, pos2 + 1, pos3)) {
              tempAmount = deal(pos + 1, tempAmount, pos0, pos1,
                  pos2 + 1, pos3);
            }

            if (tempAmount >= num)
              return tempAmount;
          }
        } else {
          if (pos3 < 13) // no more then 13 cards
          {

            allHands[3][pos3] = deck[pos];

            if (isScoreLegal(false, pos0, pos1, pos2, pos3 + 1)) {
              tempAmount = deal(pos + 1, tempAmount, pos0, pos1,
                  pos2, pos3 + 1);
            }

            if (tempAmount >= num)
              return tempAmount;
          }
        }
      }
      return tempAmount;
    }
  }

  private void count(int pos, Card[] royalHands, int[] amounts) {
    for (int i = 0; i < pos; i++) {
      amounts[royalHands[i].getSymbol().getLocation()]++;
    }
  }

  private static final int[] randomForplayers = new int[] { 0, 1, 2, 3 };
  private static final int[] randomForSuites = new int[] { 0, 1, 2, 3 };

  private int completeHands(Card[][] royalHands, Card[] rest, int pos0,
      int pos1, int pos2, int pos3, int amount) {
    Card[][] splited = split(rest);
    for (int i = 0; i < 4; i++) {
      CardUtils.shuffle(splited[i]);
    }
    int[][] amounts = new int[4][4];
    count(pos0, royalHands[0], amounts[0]);
    count(pos1, royalHands[1], amounts[1]);
    count(pos2, royalHands[2], amounts[2]);
    count(pos3, royalHands[3], amounts[3]);

    // check that all the players can have the minimum range of cards
    Range[][] newRanges = new Range[4][4];
    for (int i = 0; i < 4; i++) {
      int cardsNeeded = 0;
      for (Symbol symb : Symbol.values()) {
        newRanges[i][symb.getLocation()] = new Range(
            this.cardLimits[i][symb.getLocation()].getMin()
                - amounts[i][symb.getLocation()],
            this.cardLimits[i][symb.getLocation()].getMax()
                - amounts[i][symb.getLocation()]);
        if (newRanges[i][symb.getLocation()].getMax() < 0) // has more
                                  // then the
                                  // maximum
                                  // card
          return amount;
        cardsNeeded += newRanges[i][symb.getLocation()].getMin();
      }
      // check that the number of minimum cards required from each player
      // is bigger then the card he has

      if (cardsNeeded + this.getPos(i, pos0, pos1, pos2, pos3) > 13)
        return amount;
    }
    // check that all the minimum criterion are reachable per suite
    for (Symbol symb : Symbol.values()) {
      int neededFromSuite = 0;
      for (int i = 0; i < 4; i++) {
        neededFromSuite += newRanges[i][symb.getLocation()].getMin();
      }
      if (neededFromSuite > 9) // more then non-royal cards still needed
                    // by the players
        return amount;
    }

    // if we arrived here than all we need to do is to deal each player the
    // minimum from each suite then deal the rest
    int[] positions = new int[] { pos0, pos1, pos2, pos3 };
    int[] restPositions = new int[] { 0, 0, 0, 0 };
    for (int s = 0; s < 4; s++) {
      for (int p = 0; p < 4; p++) {
        if (newRanges[p][s].getMin() > 0) {
          System.arraycopy(splited[s], restPositions[s],
              royalHands[p], positions[p], newRanges[p][s]
                  .getMin());
          restPositions[s] += newRanges[p][s].getMin();
          positions[p] += newRanges[p][s].getMin();
          newRanges[p][s].reduce(newRanges[p][s].getMin());
        }
      }
    }

    int playersIndex = randomForplayers.length;
    int suitesIndex = randomForSuites.length;
    Random rand = new Random(System.currentTimeMillis());
    while (playersIndex > 0 || suitesIndex > 0) {
      int playerInd = rand.nextInt(playersIndex);
      int player = randomForplayers[playerInd];
      int suiteInd = rand.nextInt(suitesIndex);
      int suite = randomForSuites[suiteInd];
      if (newRanges[player][suite].getMax() > 0) {
        royalHands[player][positions[player]] = splited[suite][restPositions[suite]];
        restPositions[suite]++;
        positions[player]++;
        newRanges[player][suite].reduce(1);

        if (positions[player] == 13) // player is full
        {
          int temp = randomForplayers[playerInd];
          playersIndex--;
          randomForplayers[playerInd] = randomForplayers[playersIndex];
          randomForplayers[playersIndex] = temp;
        }
        if (restPositions[suite] == splited[suite].length) // Suite is
                                  // full
        {
          int temp = randomForSuites[suiteInd];
          suitesIndex--;
          randomForSuites[suiteInd] = randomForSuites[suitesIndex];
          randomForSuites[suitesIndex] = temp;
        }
      }
    }
    this.answers[amount] = this.putInMatrix(royalHands);
    // this.printMatrix(this.answers[amount]);
    return amount + 1;
  }

  @Override
  public void extraConfig(String configLine) {
    // TODO Auto-generated method stub

  }
}
TOP

Related Classes of algorithms.DivAlgorithm

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.