package algorithms;
import general.Card;
import general.Config;
import general.Range;
import general.Symbol;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import utils.CardUtils;
import utils.Log;
public abstract class DealingAlgorithm {
protected Card[] deck;
protected Card[][] allHands; // hands: north east south west each hand will
// hold all the cards
protected Range[] pointsLimits;
protected Range[][] cardLimits;
protected int num;
protected char[][][] answers;
private static int[] typeAmount = new int[4];
private static final String FILE_NAME = "ranges.ser";
public DealingAlgorithm(int num) {
this(num, CardUtils.createAll());
}
public DealingAlgorithm(int num,Card[] deck) {
this.num = num;
this.answers = new char[this.num][][];
this.deck = deck;
this.allHands = new Card[4][13];
this.loadConfig();
}
public void setNum(int num)
{
if (num > this.answers.length)
this.answers = new char[num][][];
this.num = num;
}
public abstract void extraConfig(String configLine);
public abstract void deal(Card[] deck);
public void printResults()
{
int printamount = 0;
System.out.println("<html>" +
"<style>@media print { table {page-break-after:always;} } td {font-size: 9px;}</style><body><table>");
for (int i = 0; i < num;) {
ArrayList<char[][]> list = new ArrayList<char[][]>();
int cols = Config.getInstance().getColsNumber();
int limit = 0;
//System.err.print("Joined: ");
while (limit < cols && i < num)
{
//System.err.print(i+" ");
list.add(answers[i]);
limit++;
i++;
}
//System.err.println("");
char[][] ans = merge(list);
this.printMatrix(ans);
/*for (int x=0;x<ans.length;x++)
{
im.add(new String(ans[x]));
}*/
printamount+=cols;
if (printamount == 4 * cols)
{
printamount = 0;
//System.err.println("page-break");
System.out.println("</table><table>");
for (int x=0; x<4;x++)
System.out.println();
}
}
System.out.println("</table></body></html>");
//im.write();
}
protected char[][] merge(ArrayList<char[][]> matrices) {
char[][] ans = new char[matrices.get(0).length][];
int pos = 0;
for (int i = 0; i < ans.length; i++) {
String s = "";
for (int x = 0; x < matrices.size(); x++) {
s += new String(matrices.get(x)[i]).trim();
}
ans[pos] = s.toCharArray();
pos++;
// System.err.println(s);
}
return ans;
}
public boolean isLegal(boolean end, int pos0, int pos1, int pos2, int pos3) {
if (end) {
if (pos0 != 13 || pos1 != 13 || pos2 != 13 || pos3 != 13)
return false;
}
for (int i = 0; i < allHands.length; i++) {
int sum = 0;
// int[] typeAmount = new int[4];
for (int x = 0; x < 4; x++)
typeAmount[x] = 0;
Card[] player = allHands[i];
int pos = this.getPos(i, pos0, pos1, pos2, pos3);
for (int j = 0; j < pos; j++) {
sum += player[j].getLetter().getScore();
typeAmount[player[j].getSymbol().getLocation()]++;
}
if (sum > this.pointsLimits[i].getMax()) // points are more then the
// max allowed
return false;
if (end) // check also minimums
{
if (sum < this.pointsLimits[i].getMin()) // points are more then
// the max allowed
return false;
}
for (int x = 0; x < 4; x++) {
if (typeAmount[x] > this.cardLimits[i][x].getMax()) {
return false;
}
if (end) {
if (typeAmount[x] < this.cardLimits[i][x].getMin()) {
return false;
}
}
}
}
return true;
}
protected final int getPos(int i,int pos0,int pos1,int pos2,int pos3)
{
int pos = pos0;
if (i == 1)
pos = pos1;
else if (i == 2)
pos = pos2;
else if (i == 3)
pos = pos3;
return pos;
}
public boolean isScoreLegal(boolean end, int pos0, int pos1, int pos2, int pos3) {
for (int i = 0; i < allHands.length; i++) {
int sum = 0;
Card[] player = allHands[i];
int pos = getPos(i, pos0, pos1, pos2, pos3);
for (int j = 0; j < pos; j++) {
sum += player[j].getLetter().getScore();
}
if (sum > this.pointsLimits[i].getMax()) // points are more then the
// max allowed
return false;
if (end) // check also minimums
{
if (sum < this.pointsLimits[i].getMin()) // points are more then
// the max allowed
return false;
}
}
return true;
}
public char[][] putInMatrix(Card[][] unSorted) {
Card[][] cards = CardUtils.sort(unSorted);
char[][] matrix = new char[16][60];
for (int j = 0; j < matrix.length; j++) {
for (int i = 0; i < matrix[j].length; i++) {
if (i == 0)
matrix[j][i] = '|';
else
matrix[j][i] = ' ';
}
}
int[] rows = new int[] { 1, 6, 11, 6 };
int[] cols = new int[] { 10, 19, 10, 1 };
int maxCol = 0;
for (int p = 0; p < 4; p++) {
Card[][] player = split(cards[p]);
int row = rows[p];
int col = cols[p];
for (Symbol symb : Symbol.values()) {
matrix[row][col] = symb.getUnicode();
col = col + 1;
for (int pos = 0; pos < player[symb.getLocation()].length; pos++) {
char[] chars = player[symb.getLocation()][pos].getLetter()
.getValue().toCharArray();
for (int curChar = 0; curChar < chars.length; curChar++) {
matrix[row][col] = chars[curChar];
col++;
}
//col++;
}
row++;
if (col > maxCol)
maxCol = col;
col = cols[p];
}
}
for (int i = 0; i < matrix.length; i++) {
matrix[i][maxCol] = '|';
}
for (int j = 1; j <= maxCol; j++) {
matrix[matrix.length - 1][j] = '-';
matrix[0][j] = '-';
}
return matrix;
}
public void printMatrix(char[][] matrix) {
for (int j = 0; j < matrix.length; j++) {
System.out.print("<tr>");
for (int x=0;x<matrix[j].length;x++)
{
System.out.print("<td>"+Symbol.toHTML(matrix[j][x])+"</td>");
}
//System.out.println(new String(matrix[j]));
System.out.println("</tr>");
}
}
private static final ArrayList<ArrayList<Card>> temp = new ArrayList<ArrayList<Card>>();
protected Card[][] split(Card[] cards) {
Card[][] ans = new Card[4][];
temp.clear();
for (int i = 0; i < 4; i++)
temp.add(i, new ArrayList<Card>());
for (int pos = 0; pos < cards.length; pos++) {
temp.get(cards[pos].getSymbol().getLocation()).add(cards[pos]);
}
for (int i = 0; i < 4; i++) {
ans[i] = new Card[temp.get(i).size()];
temp.get(i).toArray(ans[i]);
}
return ans;
}
public void addPointLimit(int player, int min, int max) {
this.pointsLimits[player].set(min, max);
}
public Range getPointlimit(int player)
{
return this.pointsLimits[player];
}
public void addCardLimit(int player, int type, int min, int max) {
this.cardLimits[player][type].set(min, max);
}
public Range getCardLimit(int player,int symbol)
{
return this.cardLimits[player][symbol];
}
public void saveConfig()
{
try {
Log.write("Saving data to ranges.ser ...");
FileOutputStream fileOut = new FileOutputStream(FILE_NAME,false);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(this.cardLimits);
out.writeObject(this.pointsLimits);
out.close();
Log.write("Saving completed");
} catch (Exception e) {
Log.write("Loading failed, file error");
}
}
public void loadConfig()
{
try
{
Log.write("Loading data from ranges.ser ...");
FileInputStream fileIn = new FileInputStream(FILE_NAME);
ObjectInputStream in = new ObjectInputStream(fileIn);
this.cardLimits = (Range[][])in.readObject();
this.pointsLimits = (Range[])in.readObject();
in.close();
fileIn.close();
Log.write("Loading completed");
}
catch (Exception e){
Log.write("Loading failed, file doesn't exist - creating new ranges");
this.pointsLimits = new Range[4];
this.cardLimits = new Range[4][4];
for (int t = 0; t < 4; t++) {
this.pointsLimits[t] = new Range(0, 40);
for (int s = 0; s < 4; s++) {
this.cardLimits[t][s] = new Range(0, 13);
}
}
}
}
}