package game;
import player.AbstractPlayer;
import java.awt.Font;
import java.awt.Point;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.ArrayList;
import org.json.*;
import card.Card;
public abstract class AbstractGame {
/*
* COLORS:
* GREEN
* RED
* YELLOW
* WHITE
* BLUE
* (COLORED)
*/
final static int GREEN = 0;
final static int RED = 1;
final static int YELLOW = 2;
final static int WHITE = 3;
final static int BLUE = 4;
final static int COLORS = 5;
int NR_PLAYERS = 2;
static int CARDS_PER_PLAYER;
final static int NR_OF_CARDS = 50;
static int CARDS_IN_DECK;
final static int MAX_HINTS = 8;
final static int MAX_THUNDERS = 3;
int hints;
int thunders;
ArrayList<Card> cards;
Card[][] deck;
int[] deckCounter;
ArrayList<Card> trash;
AbstractPlayer[] players;
int currentPlayer;
int selectedPlayer;
int selectedCards;
int chosenColor;
int chosenValue;
boolean useColor;
boolean useValue;
boolean placeCard;
boolean trashCard;
boolean won;
boolean lost;
Font font;
//Options stuff
final File options = new File("options.json");
JSONObject root;
int difficulty;
int fontSize;
/*public static void main(String[] args) {
AbstractGame game = new AbstractGame();
game.getPlayer(game.currentPlayer).deactiveCards();
System.out.println("Player " + game.currentPlayer + "'s turn");
}*/
public AbstractGame(){
init();
}
protected void init(){
loadOptions();
loadFont();
CARDS_PER_PLAYER = (NR_PLAYERS < 3) ? 5 : 4;
hints = MAX_HINTS;
thunders = 0;
createPlayers();
currentPlayer = 0;
resetMoveValues();
addCards();
CARDS_IN_DECK = cards.size();
createUI();
dealCards();
}
protected void loadOptions(){
try {
JSONTokener tokener = new JSONTokener(options.toURI().toURL().openStream());
root = new JSONObject(tokener);
difficulty = root.getInt("difficulty");
fontSize = root.getInt("fontSize");
if(difficulty < 0) difficulty = 0;
if(fontSize <= 0) fontSize = 20;
System.out.println("FontSize: " + fontSize);
System.out.println("Difficulty: " + difficulty);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void resetMoveValues(){
selectedPlayer = -1;
chosenColor = -1;
chosenValue = -1;
selectedCards = 0;
useColor = useValue = trashCard = placeCard = false;
}
protected void createPlayers(){
players = new AbstractPlayer[NR_PLAYERS];
/*for(int i=0; i<NR_PLAYERS; ++i){
players[i] = new AbstractPlayer(CARDS_PER_PLAYER, this, i);
}*/
}
private void addCards(){
cards = new ArrayList<>();
deck = new Card[COLORS][5];
deckCounter = new int[5];
trash = new ArrayList<>();
int[] dist = new int[]{3, 2, 2, 2, 1};
int[][] tmp_cards = new int[][]{
dist.clone(),
dist.clone(),
dist.clone(),
dist.clone(),
dist.clone()
};
for(int i=0; i<NR_OF_CARDS; ++i){
Point p = null;
do{
p = randomPosition();
} while(tmp_cards[p.x][p.y] == 0);
tmp_cards[p.x][p.y]--;
cards.add(new Card(p.x, (p.y + 1), -1, this));
}
}
boolean checkValidMove(){
if(selectedCards == 0) return false;
if(!hintAvailable() && (useColor || useValue)) return false;
if((trashCard || placeCard) && selectedCards == 1) return true;
int countCards = 0;
for(int i=0; i<CARDS_PER_PLAYER; ++i){
AbstractPlayer p = players[selectedPlayer];
if(useColor){
if(p.getCard(i).getColorInt() == chosenColor) countCards++;
} else if(useValue){
if(p.getCard(i).getValue() == chosenValue) countCards++;
}
}
return (countCards == selectedCards);
}
protected abstract void createUI();
void moveCardToTrash(int index){
trash.add(players[currentPlayer].getCard(index));
updateCards(index);
}
void updateCards(int index){
dealCard(index, currentPlayer);
players[currentPlayer].setCardInfo(index, "");
Card c = players[currentPlayer].getCard(index);
//JLabel card = ((SwingPlayer) players[currentPlayer]).getUiCard(index);
if(c.getValue() == -1){ //dummy card, no more cards
setNoCard(index);
}
}
protected abstract void setNoCard(int index);
private void dealCard(int cardID, int playerID){
Card card;
if(CARDS_IN_DECK > 0){
int index = random(CARDS_IN_DECK--);
card = cards.remove(index);
} else {
card = new Card(3, -1, playerID, this);
}
players[playerID].setCard(cardID, card);
}
protected void dealCards(){
int dealtCards = 0;
for(; dealtCards < CARDS_PER_PLAYER; ++dealtCards){
for(int i=0; i<NR_PLAYERS; ++i){
int index = random(CARDS_IN_DECK--);
Card card = cards.remove(index);
players[i].setCard(dealtCards, card);
}
}
}
boolean hintAvailable(){
return (hints > 0);
}
void setWonOrLost(){
won = true;
lost = false;
for(int i=0; i<COLORS; ++i){
System.out.println("Deck " + i + ": " + deckCounter[i]);
if(deckCounter[i] != 5){
won = false;
break;
}
}
if(thunders == MAX_THUNDERS){
lost = true;
won = false;
}
if(won) printMessage("YOU WON!", 1);
if(lost) printMessage("YOU LOST...", 1);
}
private Point randomPosition(){
Point p = new Point();
p.x = random(5);
p.y = random(5);
return p;
}
private int random(int max){
return (int) (Math.random() * max);
}
public void setSelectedPlayer(int selectedPlayer){
this.selectedPlayer = selectedPlayer;
}
public int getSelectedPlayer(){
return selectedPlayer;
}
public AbstractPlayer getPlayer(int index){
return players[index];
}
public int getCurrentPlayerIndex(){
return currentPlayer;
}
public boolean isTrashCard(){
return trashCard;
}
public boolean isPlaceCard(){
return placeCard;
}
public boolean isUseColor(){
return useColor;
}
public boolean isUseValue(){
return useValue;
}
public int getChosenColor(){
return chosenColor;
}
public void setChosenColor(int chosenColor){
this.chosenColor = chosenColor;
}
public int getChosenValue(){
return chosenValue;
}
public void setChosenValue(int chosenValue){
this.chosenValue = chosenValue;
}
public int getSelectedCards(){
return selectedCards;
}
public void addSelectedCards(){
selectedCards++;
}
public void removeSelectedCards(){
selectedCards--;
}
public int getDifficulty(){
return difficulty;
}
public abstract void loadFont();
public int getFontSize(){
return fontSize;
}
public Font getFont(){
return font;
}
public abstract void printMessage(String msg, int type);
/*private void printArray(int[][] arr){
for(int j=0; j<arr.length; ++j){
for(int k=0; k<arr[0].length; ++k){
System.out.print(arr[j][k] + ", ");
}
System.out.println("");
}
}*/
}