import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Game {
/*
* 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;
final static 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;
static ArrayList<Card> cards;
static Card[][] deck;
static int[] deckCounter;
static ArrayList<Card> trash;
static Player[] players;
static int currentPlayer;
static boolean won;
static int selectedPlayer;
static int selectedCards;
static int chosenColor;
static int chosenValue;
static boolean useColor;
static boolean useValue;
//UI STUFF
JFrame mainFrame;
JPanel gamePanel;
JPanel hintPanel;
JPanel thunderPanel;
JLabel[] hintUI;
JLabel[] thunderUI;
static JPanel[] playersUI;
public static void main(String[] args) {
Game game = new Game();
System.out.println("Player " + currentPlayer + "'s turn");
}
public Game(){
init();
}
private void init(){
CARDS_PER_PLAYER = (NR_PLAYERS < 3) ? 5 : 4;
hints = MAX_HINTS;
thunders = 0;
createPlayers();
currentPlayer = 0;
won = false;
resetMoveValues();
addCards();
CARDS_IN_DECK = cards.size();
createUI();
dealCards();
}
private void resetMoveValues(){
selectedPlayer = -1;
chosenColor = -1;
chosenValue = -1;
selectedCards = 0;
useColor = useValue = false;
}
private void createPlayers(){
players = new Player[NR_PLAYERS];
playersUI = new JPanel[NR_PLAYERS];
for(int i=0; i<NR_PLAYERS; ++i){
players[i] = new Player(CARDS_PER_PLAYER);
playersUI[i] = new JPanel();
}
}
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)));
}
}
private boolean checkValidMove(){
int countCards = 0;
for(int i=0; i<CARDS_PER_PLAYER; ++i){
Player 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 && hintAvailable());
}
private void createUI(){
try {
UIManager.setLookAndFeel( "javax.swing.plaf.nimbus.NimbusLookAndFeel" );
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
mainFrame = new JFrame("Hanabi");
mainFrame.setSize(1000, 1000);
mainFrame.setLocation(0, 0);
mainFrame.setLayout(new BorderLayout());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.getContentPane().setBackground(Color.black);
mainFrame.setVisible(true);
gamePanel = new JPanel();
gamePanel.setLayout(new BoxLayout(gamePanel, BoxLayout.Y_AXIS));
hintPanel = new JPanel();
thunderPanel = new JPanel();
mainFrame.add(gamePanel, BorderLayout.CENTER);
gamePanel.add(hintPanel);
gamePanel.add(thunderPanel);
hintUI = new JLabel[MAX_HINTS];
for(int i=0; i<MAX_HINTS; ++i){
JLabel tmp = new JLabel();
tmp.setText("1");
tmp.setBackground(Color.white);
tmp.setName("Hint_" + i);
hintPanel.add(tmp);
hintUI[i] = tmp;
}
thunderUI = new JLabel[MAX_THUNDERS];
for(int i=0;i<MAX_THUNDERS; ++i){
JLabel tmp = new JLabel();
tmp.setText("0");
tmp.setBackground(Color.cyan);
tmp.setName("Thunder_" + i);
thunderPanel.add(tmp);
thunderUI[i] = tmp;
}
mainFrame.addKeyListener(new KeyListener(){
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_SPACE){
//TODO place card
} else if(e.getKeyCode() == KeyEvent.VK_BACK_SPACE){
//TODO card to trash
} else if(e.getKeyCode() == KeyEvent.VK_ENTER){
if(!checkValidMove()){
System.out.println("Please select all cards of the selected color/value");
return;
}
hintUI[hints-1].setText("0");
hints--;
//TODO get cards, reset background, update tooltips
JPanel playerContainer = playersUI[selectedPlayer];
int labels = 0;
for(int i=0; i<playerContainer.getComponentCount(); ++i){
if(playerContainer.getComponent(i).getClass() == JLabel.class){
JLabel card = (JLabel) playerContainer.getComponent(i);
Player p = players[selectedPlayer];
if(card.getBackground() == Color.pink){
card.setBackground(Color.black);
if(useColor){
String color = null;
switch(chosenColor){
case 0:
color = "green";
break;
case 1:
color = "red";
break;
case 2:
color = "yellow";
break;
case 3:
color = "white";
break;
case 4:
color = "blue";
break;
}
p.setCardInfo(labels, p.getCardInfo(labels) + ", " + color);
} else if(useValue){
String value = "is " + chosenValue;
p.setCardInfo(labels, p.getCardInfo(labels) + ", " + value);
}
//TODO else if only one card selected
} else {
if(useColor){
String color = "not ";
switch(chosenColor){
case 0:
color += "green";
break;
case 1:
color += "red";
break;
case 2:
color += "yellow";
break;
case 3:
color += "white";
break;
case 4:
color += "blue";
break;
}
p.setCardInfo(labels, p.getCardInfo(labels) + ", " + color);
} else if(useValue){
String value = "is not " + chosenValue;
p.setCardInfo(labels, p.getCardInfo(labels) + ", " + value);
}
}
card.setToolTipText(p.getCardInfo(labels));
labels++;
}
}
System.out.println("Player " + currentPlayer + " has finished his move!");
currentPlayer++;
if(currentPlayer == NR_PLAYERS) currentPlayer = 0;
resetMoveValues();
System.out.println("Player " + currentPlayer + "'s turn");
}
}
@Override
public void keyPressed(KeyEvent e) {
}
});
}
private 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);
}
}
/*
* PLAYER 0: SOUTH
* PLAYER 1: EAST
* PLAYER 2: NORTH
* PLAYER 3: WEST
*/
for(int i=0; i<NR_PLAYERS; ++i){
JPanel playerContainer = playersUI[i];
playerContainer.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
BoxLayout containerLayout = null;
String playerSide = null;
switch(i){
case 0:
playerSide = BorderLayout.SOUTH;
containerLayout = new BoxLayout(playerContainer, BoxLayout.X_AXIS);
break;
case 1:
playerSide = BorderLayout.EAST;
containerLayout = new BoxLayout(playerContainer, BoxLayout.Y_AXIS);
break;
case 2:
playerSide = BorderLayout.NORTH;
containerLayout = new BoxLayout(playerContainer, BoxLayout.X_AXIS);
break;
case 3:
playerSide = BorderLayout.WEST;
containerLayout = new BoxLayout(playerContainer, BoxLayout.Y_AXIS);
break;
}
playerContainer.setLayout(containerLayout);
playerContainer.setBackground(Color.black);
for(int j=0; j<CARDS_PER_PLAYER; ++j){
Card card = players[i].getCard(j);
JLabel curr = new JLabel("Value: " + card.getValue());
curr.setName(i + "_card" + j);
//curr.setBorder(BorderFactory.createMatteBorder(1, 2, 1, 1, card.getColor()));
curr.setToolTipText(players[i].getCardInfo(j));
curr.setHorizontalAlignment(SwingConstants.CENTER);
curr.setSize(50, 50);
Font f = curr.getFont();
curr.setFont(new Font(f.getFontName(), f.getStyle(), f.getSize()*2));
curr.setForeground(card.getColor());
curr.setBackground(Color.black);
curr.setOpaque(true);
curr.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
if(!hintAvailable()){
System.out.println("No hints left!");
return;
}
JLabel label = (JLabel) e.getComponent();
String name = label.getName();
int clickedPlayer = Integer.parseInt(name.substring(0, 1));
int clickedCard = Integer.parseInt(name.substring(name.length()-1));
Card card = players[clickedPlayer].getCard(clickedCard);
int clickedValue = card.getValue();
int clickedColor = card.getColorInt();
if(selectedPlayer == -1){
selectedPlayer = clickedPlayer;
chosenColor = clickedColor;
chosenValue = clickedValue;
selectedCards++;
System.out.println("Selected player #" + selectedPlayer);
label.setBackground(Color.pink);
//selectedCards.add(clickedCard);
System.out.println("Added card #" + clickedCard + "(" + card.getColorInt() + ", " + card.getValue() + ")");
return;
}
if(selectedPlayer != clickedPlayer){
System.out.println("Please choose a card of the selected player or unselect all cards and choose another player.");
return;
}
if(chosenColor == -1){
chosenColor = clickedColor;
}
if(chosenValue == -1){
chosenValue = clickedValue;
}
if(!useColor && !useValue){
if(chosenValue == clickedValue && chosenColor == clickedColor){
//return; //TODO nothing to do here...
} else if(chosenValue == clickedValue && chosenColor != clickedColor){
//chosenColor = -2;
useValue = true;
//TODO different color => select all 4's
} else if(chosenValue != clickedValue && chosenColor == clickedColor){
//chosenValue = -2;
useColor = true;
//TODO same color => select all reds
}
}
if(label.getBackground() == Color.pink){
selectedCards--;
label.setBackground(Color.black);
System.out.println("Removed card #" + clickedCard + "(" + card.getColorInt() + ", " + card.getValue() + ")");
if(selectedCards == 0){
resetMoveValues();
} else if(selectedCards == 1){
useColor = useValue = false;
}
} else {
if(useColor){
if(chosenColor == clickedColor){
//TODO add card
//selectedCards.add(clickedCard);
if(label.getBackground() != Color.pink){
selectedCards++;
label.setBackground(Color.pink);
System.out.println("Added card #" + clickedCard + "(" + card.getColorInt() + ", " + card.getValue() + ")");
}
}
} else if(useValue){
if(chosenValue == clickedValue){
//TODO add card
//selectedCards.add(clickedCard);
if(label.getBackground() != Color.pink){
selectedCards++;
label.setBackground(Color.pink);
System.out.println("Added card #" + clickedCard + "(" + card.getColorInt() + ", " + card.getValue() + ")");
}
}
}
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
});
playerContainer.add(curr, playerSide);
playerContainer.add(Box.createRigidArea(new Dimension(15,15)));
}
mainFrame.add(playerContainer, playerSide);
}
}
private boolean hintAvailable(){
return (hints > 0);
}
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);
}
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("");
}
}
}