diff --git a/.gitignore b/.gitignore index a56aa49..b1a9353 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .classpath .project bin/ +*.log diff --git a/options.json b/options.json index e9c9c78..dbb07f5 100644 --- a/options.json +++ b/options.json @@ -1,4 +1,5 @@ { "difficulty": 1, - "fontSize": 20 + "fontSize": 20, + "host":false } diff --git a/src/card/Card.java b/src/card/Card.java new file mode 100644 index 0000000..f35f9bc --- /dev/null +++ b/src/card/Card.java @@ -0,0 +1,166 @@ +package card; +import game.BaseGame; +import game.BaseGame.MSG_TYPES; + +import java.awt.Color; + +/* + * COLORS: + * GREEN + * RED + * YELLOW + * WHITE + * BLUE + * (COLORED) + */ +public class Card implements Cloneable { + protected int color; + protected int value; + protected int playerId; + protected boolean isSelected; + protected BaseGame g; + + public Card(int color, int value, int playerId, BaseGame g){ + this.color = color; + this.value = value; + this.playerId = playerId; + this.g = g; + isSelected = false; + } + + public Card clone(){ + Card card = new Card(color, value, playerId, g); + return card; + } + + protected void onCardClick(){ + if(isSelected){ + g.removeSelectedCards(); + isSelected = false; + if(g.getSelectedCards() == 0){ + g.resetMoveValues(); + } + } + if(!g.isUseColor() && !g.isUseValue() && !g.isTrashCard() && !g.isPlaceCard()){ + g.printMessage("Please choose move type first", MSG_TYPES.ERROR); + return; + } + if(playerId == g.getCurrentPlayerIndex()){ + if(g.isUseColor() || g.isUseValue()){ + g.printMessage("Please don't select your own cards!", MSG_TYPES.ERROR); + return; + } else if((g.isTrashCard() || g.isPlaceCard()) && g.getSelectedCards() == 1){ + g.printMessage("You already selected a card!", MSG_TYPES.ERROR); + return; + } + } else if(playerId != g.getCurrentPlayerIndex() && (g.isTrashCard() || g.isPlaceCard())){ + g.printMessage("Please select your own cards", MSG_TYPES.ERROR); + return; + } + if(g.getSelectedPlayer() == -1){ + g.setSelectedPlayer(playerId); + g.setChosenColor(color); + g.setChosenValue(value); + g.addSelectedCards(); + isSelected = true; + return; + } + if(g.getSelectedPlayer() != playerId){ + g.printMessage("Please choose a card of the selected player or unselect all cards and choose another player.", MSG_TYPES.ERROR); + return; + } + if(g.getChosenColor() == -1){ + g.setChosenColor(color); + } + if(g.getChosenValue() == -1){ + g.setChosenValue(value); + } + if(!isSelected){ + if(g.isUseColor()){ + if(g.getChosenColor() == color){ + if(!isSelected){ + g.addSelectedCards(); + isSelected = true; + } + } + } else if(g.isUseValue()){ + if(g.getChosenValue() == value){ + if(!isSelected){ + g.addSelectedCards(); + isSelected = true; + } + } + } + } + } + + @Override + public String toString(){ + return "Color: " + intColorToText(color) + ", Value: " + value; + } + + public Color getColor(){ + Color c = null; + switch(color){ + case 0: + c = Color.green; + break; + case 1: + c = Color.red; + break; + case 2: + c = Color.yellow; + break; + case 3: + c = Color.white; + break; + case 4: + c = Color.blue; + break; + } + return c; + } + + public static String intColorToText(int id){ + String color = ""; + switch(id){ + 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; + } + return color; + } + + public boolean isSelected(){ + return isSelected; + } + + public void setSelected(boolean set){ + isSelected = set; + } + + public int getColorInt(){ + return color; + } + + public int getValue(){ + return value; + } + + public void setProps(Card c){ + this.value = c.getValue(); + this.color = c.getColorInt(); + } +} \ No newline at end of file diff --git a/src/card/SwingCard.java b/src/card/SwingCard.java new file mode 100644 index 0000000..379224b --- /dev/null +++ b/src/card/SwingCard.java @@ -0,0 +1,72 @@ +package card; + +import game.SwingGame; + +import java.awt.Color; +import java.awt.Font; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; + +public class SwingCard extends Card { + JLabel face; + + public SwingCard(int color, int value, int playerId, SwingGame swingGame) { + super(color, value, playerId, swingGame); + } + + public void setFace(JLabel face){ + this.face = face; + face.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + face.setFont(((Font) g.getFont()).deriveFont(g.getFontSize()*2)); + addMouseListener(); + } + + public JLabel getFace(){ + return face; + } + + private void addMouseListener(){ + face.addMouseListener(new MouseListener() { + @Override + public void mouseReleased(MouseEvent e) { + onCardClick(); + } + + @Override + public void mousePressed(MouseEvent e) { + } + + @Override + public void mouseExited(MouseEvent e) { + } + + @Override + public void mouseEntered(MouseEvent e) { + } + + @Override + public void mouseClicked(MouseEvent e) { + } + }); + } + + @Override + protected void onCardClick(){ + super.onCardClick(); + if(isSelected){ + face.setBackground(Color.pink); + } else { + face.setBackground(Color.black); + } + } + + @Override + public void setSelected(boolean set){ + super.setSelected(set); + if(isSelected) face.setBackground(Color.pink); + else face.setBackground(Color.black); + } +} diff --git a/src/game/BaseGame.java b/src/game/BaseGame.java new file mode 100644 index 0000000..9b5e0bd --- /dev/null +++ b/src/game/BaseGame.java @@ -0,0 +1,473 @@ +package game; +import player.AbstractPlayer; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.ArrayList; + +import org.json.*; + +import card.Card; + +public abstract class BaseGame { + /* + * COLORS: + * GREEN + * RED + * YELLOW + * WHITE + * BLUE + * (COLORED) + */ + + public enum MSG_TYPES {ERROR, WARNING, INFORMATION, QUESTION}; + + 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 COLORED = 5; + final static int COLORS = 5; + int N_PLAYERS = 2; + static int CARDS_PER_PLAYER; + final static int N_CARDS = 50; + int CARDS_IN_DECK; + final static int MAX_HINTS = 8; + final static int MAX_THUNDERS = 3; + int hints; + int thunders; + ArrayList cards; + Card[][] deck; + int[] deckCounter; + ArrayList trash; + AbstractPlayer[] players; + int currentPlayer; + int roundsLeft; + + int selectedPlayer; + int selectedCards; + int chosenColor; + int chosenValue; + boolean useColor; + boolean useValue; + boolean placeCard; + boolean trashCard; + boolean won; + boolean lost; + + //Options stuff + final File options = new File("options.json"); + JSONObject root; + int difficulty; + int fontSize; + + //Network stuff + ServerSocket server; + Socket s; + boolean isHost; + + public BaseGame(){ + init(); + } + + protected void init(){ + loadOptions(); + loadFont(); + //establishConnection(); + CARDS_PER_PLAYER = (N_PLAYERS <= 3) ? 5 : 4; + hints = MAX_HINTS; + thunders = 0; + roundsLeft = -1; + 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"); + isHost = root.getBoolean("host"); + if(difficulty < 0) difficulty = 0; + if(fontSize <= 0) fontSize = 20; + } catch (JSONException e) { + e.printStackTrace(); + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + protected void establishConnection(){ + try { + if(isHost){ + server = new ServerSocket(8765); + printMessage("Your server is running on port 8765", MSG_TYPES.INFORMATION); + s = server.accept(); + DataInputStream inStream = new DataInputStream(s.getInputStream()); + String str = inStream.readUTF(); + System.out.println("Message: " + str); + s.close(); + server.close(); + } else { + s = new Socket("localhost", 8765); + DataOutputStream outStream = new DataOutputStream(s.getOutputStream()); + outStream.writeUTF("Hello"); + outStream.flush(); + outStream.close(); + s.close(); + } + } catch(UnknownHostException uhe){ + printMessage("Unknown host '???'", MSG_TYPES.ERROR); + } catch (IOException e) { + printMessage(e.getLocalizedMessage(), MSG_TYPES.ERROR); + System.exit(0); //TODO status code + } + + } + + public void resetMoveValues(){ + selectedPlayer = -1; + chosenColor = -1; + chosenValue = -1; + selectedCards = 0; + useColor = useValue = trashCard = placeCard = false; + } + + protected void createPlayers(){ + players = new AbstractPlayer[N_PLAYERS]; + } + + 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 0){ + int index = random(CARDS_IN_DECK--); + card = cards.remove(index); + } else { + if(roundsLeft == -1) roundsLeft = N_PLAYERS; + 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 0); + } + + void setWonOrLost(){ + won = true; + lost = false; + for(int i=0; i MAX_HINTS) hints = MAX_HINTS; + } + } + + protected void addThunder(){ + thunders++; + } + + protected void placeCard(Card c, int color, int value){ + deckCounter[color]++; + deck[color][value] = c; + if(value == 5) addHint(); + } + + protected void onNext(){ + if(!checkValidMove()){ + printMessage("Please select all cards of the selected color/value", MSG_TYPES.ERROR); + return; + } + if(roundsLeft >= 0) roundsLeft--; + int selCardIndex = 0; + for(int i=0; i 0){ + printMessage("Please deselect all cards first", MSG_TYPES.ERROR); + return; + } + useColor = true; + useValue = false; + placeCard = false; + trashCard = false;} + protected void onValue(){ + if(!hintAvailable()){ + printMessage("No hints left!", MSG_TYPES.ERROR); + return; + } + if(selectedCards > 0){ + printMessage("Please deselect all cards first", MSG_TYPES.ERROR); + return; + } + useValue = true; + useColor = false; + placeCard = false; + trashCard = false; + } + protected void onTrash(){ + if(selectedCards > 0){ + printMessage("Please deselect all cards first", MSG_TYPES.ERROR); + return; + } + useColor = false; + useValue = false; + placeCard = false; + trashCard = true; + } + protected void onPlace(){ + if(selectedCards > 0){ + printMessage("Please deselect all cards first", MSG_TYPES.ERROR); + return; + } + useColor = false; + useValue = false; + placeCard = true; + trashCard = false; + } + protected abstract void showTrash(); +} \ No newline at end of file diff --git a/src/game/Card.java b/src/game/Card.java deleted file mode 100644 index 8fbd3b9..0000000 --- a/src/game/Card.java +++ /dev/null @@ -1,78 +0,0 @@ -package game; -import java.awt.Color; - -/* - * COLORS: - * GREEN - * RED - * YELLOW - * WHITE - * BLUE - * (COLORED) - */ -public class Card { - private int color; - private int value; - - public Card(int color, int value){ - this.color = color; - this.value = value; - } - - @Override - public String toString(){ - return "Color: " + color + "; Value: " + value; - } - - public Color getColor(){ - Color c = null; - switch(color){ - case 0: - c = Color.green; - break; - case 1: - c = Color.red; - break; - case 2: - c = Color.yellow; - break; - case 3: - c = Color.white; - break; - case 4: - c = Color.blue; - break; - } - return c; - } - - public static String intColorToText(int id){ - String color = ""; - switch(id){ - 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; - } - return color; - } - - public int getColorInt(){ - return color; - } - - public int getValue(){ - return value; - } -} \ No newline at end of file diff --git a/src/game/ConsoleGame.java b/src/game/ConsoleGame.java new file mode 100644 index 0000000..da50352 --- /dev/null +++ b/src/game/ConsoleGame.java @@ -0,0 +1,5 @@ +package game; + +public class ConsoleGame { + +} diff --git a/src/game/Game.java b/src/game/Game.java deleted file mode 100644 index 9292b92..0000000 --- a/src/game/Game.java +++ /dev/null @@ -1,651 +0,0 @@ -package game; -import player.AbstractPlayer; -import player.SwingPlayer; -import static game.Card.intColorToText; - -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Font; -import java.awt.GridLayout; -import java.awt.Point; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.io.File; -import java.io.IOException; -import java.net.MalformedURLException; -import java.util.ArrayList; - -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JPanel; - -import org.json.*; - -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; - 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 cards; - Card[][] deck; - int[] deckCounter; - ArrayList 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; - - //UI STUFF - JFrame mainFrame; - JPanel gamePanel; - JPanel hintPanel; - JPanel thunderPanel; - JPanel buttonPanel; - JPanel deckPanel; - JLabel[][] deckUI; - JButton colorButton; - JButton valueButton; - JButton nextMove; - JButton placeCardButton; - JButton trashCardButton; - JLabel[] hintUI; - JLabel[] thunderUI; - JPanel[] playersUI; - Font font; - - //Options stuff - final File options = new File("options.json"); - JSONObject root; - int difficulty; - int fontSize; - - public static void main(String[] args) { - Game game = new Game(); - game.getPlayer(game.currentPlayer).deactiveCards(); - System.out.println("Player " + game.currentPlayer + "'s turn"); - } - - public Game(){ - init(); - } - - private void init(){ - loadOptions(); - font = new Font("Shanghai", Font.PLAIN, fontSize); - 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(); - } - - private void loadOptions(){ - try { - JSONTokener tokener = new JSONTokener(options.toURI().toURL().openStream()); - root = new JSONObject(tokener); - difficulty = root.getInt("difficulty"); - fontSize = root.getInt("fontSize"); - } 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; - } - - private void createPlayers(){ - players = new AbstractPlayer[NR_PLAYERS]; - for(int i=0; i(); - 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 0){ - System.out.println("Please deselect all cards first"); - return; - } - useColor = true; - useValue = false; - placeCard = false; - trashCard = false; - } - @Override - public void mousePressed(MouseEvent e) { - } - @Override - public void mouseExited(MouseEvent e) { - } - @Override - public void mouseEntered(MouseEvent e) { - } - @Override - public void mouseClicked(MouseEvent e) { - } - }); - valueButton.addMouseListener(new MouseListener(){ - @Override - public void mouseReleased(MouseEvent e) { - if(!hintAvailable()){ - System.out.println("No hints left!"); - return; - } - if(selectedCards > 0){ - System.out.println("Please deselect all cards first"); - return; - } - useValue = true; - useColor = false; - placeCard = false; - trashCard = false; - } - @Override - public void mousePressed(MouseEvent e) { - } - @Override - public void mouseExited(MouseEvent e) { - } - @Override - public void mouseEntered(MouseEvent e) { - } - @Override - public void mouseClicked(MouseEvent e) { - } - }); - nextMove.addMouseListener(new MouseListener(){ - @Override - public void mouseReleased(MouseEvent e) { - if(!checkValidMove()){ - System.out.println("Please select all cards of the selected color/value"); - return; - } - int selCardIndex = 0; - for(int i=0; i MAX_HINTS) hints = MAX_HINTS; - } - } else if(placeCard){ - Card c = players[currentPlayer].getCard(selCardIndex); - int color = c.getColorInt(); - int value = c.getValue(); - int deckValue = deckCounter[color] + 1; - if(deckValue == value){ //place card possible - deckCounter[color]++; - deck[color][value-1] = c; - deckUI[color][value-1].setText(value + ""); - deckUI[color][value-1].setForeground(c.getColor()); - setWonOrLost(); - } else { //card too high or too low - thunderUI[thunders++].setText("1"); - moveCardToTrash(selCardIndex); - setWonOrLost(); - if(lost) return; - } - //dealCard(selCardIndex, currentPlayer); - updateCards(selCardIndex); - } - players[currentPlayer].activeCards(); - System.out.println("Player " + currentPlayer + " has finished his move!"); - currentPlayer++; - if(currentPlayer == NR_PLAYERS) currentPlayer = 0; - players[currentPlayer].deactiveCards(); - resetMoveValues(); - System.out.println(CARDS_IN_DECK + " cards left."); - System.out.println(trash.size() + " cards in trash"); - System.out.println("Player " + currentPlayer + "'s turn"); - } - @Override - public void mousePressed(MouseEvent e) { - } - @Override - public void mouseExited(MouseEvent e) { - } - @Override - public void mouseEntered(MouseEvent e) { - } - @Override - public void mouseClicked(MouseEvent e) { - } - }); - trashCardButton.addMouseListener(new MouseListener(){ - @Override - public void mouseReleased(MouseEvent e) { - if(selectedCards > 0){ - System.out.println("Please deselect all cards first"); - return; - } - useColor = false; - useValue = false; - placeCard = false; - trashCard = true; - } - @Override - public void mousePressed(MouseEvent e) { - } - @Override - public void mouseExited(MouseEvent e) { - } - @Override - public void mouseEntered(MouseEvent e) { - } - @Override - public void mouseClicked(MouseEvent e) { - } - }); - placeCardButton.addMouseListener(new MouseListener(){ - @Override - public void mouseReleased(MouseEvent e) { - if(selectedCards > 0){ - System.out.println("Please deselect all cards first"); - return; - } - useColor = false; - useValue = false; - placeCard = true; - trashCard = false; - } - @Override - public void mousePressed(MouseEvent e) { - } - @Override - public void mouseExited(MouseEvent e) { - } - @Override - public void mouseEntered(MouseEvent e) { - } - @Override - public void mouseClicked(MouseEvent e) { - } - }); - } - - private void moveCardToTrash(int index){ - trash.add(players[currentPlayer].getCard(index)); - updateCards(index); - } - - private void updateCards(int index){ - dealCard(index, currentPlayer); - players[currentPlayer].setCardInfo(index, ""); - Card c = players[currentPlayer].getCard(index); - //JLabel card = ((SwingPlayer) players[currentPlayer]).getUiCard(index); - AbstractPlayer card = players[currentPlayer]; - if(c.getValue() == -1){ //dummy card, no more cards - card.setColor(index, 255, 122, 0); - card.setText(index, "No Cards left"); - card.unsetListeners(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); - } - players[playerID].setCard(cardID, card); - } - - private void dealCards(){ - int dealtCards = 0; - for(; dealtCards < CARDS_PER_PLAYER; ++dealtCards){ - for(int i=0; i 0); - } - - private void setWonOrLost(){ - won = true; - lost = false; - for(int i=0; i