Newer
Older
hanabi / src / game / AbstractGame.java
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("");
		}
	}*/
}