From 9f55d5bef1dbe027c173b2bba85d3931d303dac7 Mon Sep 17 00:00:00 2001 From: Dajun Date: Mon, 1 May 2017 00:24:35 -0500 Subject: [PATCH 1/2] db --- Project/src/Controller/Connect.java | 43 +++++++++ Project/src/Controller/Controller.java | 42 +++++--- Project/src/Controller/Login.java | 128 +++++++++++++++++++++++++ Project/src/Model/utils/GameUtils.java | 2 +- Project/src/Network/Client.java | 23 +++-- Project/src/Network/Server.java | 59 ++++++++---- Project/src/Tests/ConnectTests.java | 13 +++ Project/src/View/BoardUI.java | 32 ++++--- Project/src/View/PlayerPanel.java | 6 +- Project/src/View/utils/ViewUtils.java | 41 ++++++-- 10 files changed, 323 insertions(+), 66 deletions(-) create mode 100644 Project/src/Controller/Connect.java create mode 100644 Project/src/Controller/Login.java create mode 100644 Project/src/Tests/ConnectTests.java diff --git a/Project/src/Controller/Connect.java b/Project/src/Controller/Connect.java new file mode 100644 index 0000000..5829d3a --- /dev/null +++ b/Project/src/Controller/Connect.java @@ -0,0 +1,43 @@ +package Controller; +import java.sql.*; + +/** + * Created by dajun on 4/30/17. + */ +public class Connect { + + private Connection connection; + + public Connect() throws ClassNotFoundException, SQLException { + + Class.forName("com.mysql.jdbc.Driver"); + connection =DriverManager.getConnection("jdbc:mysql://localhost:3306/splendor","root","1234"); + + } + + public void disconnect() throws SQLException { + connection.close(); + } + + public boolean verify(String usr, String pin) throws SQLException { + + return true; +/* + Statement stmt= connection.createStatement(); + ResultSet rs=stmt.executeQuery("select password from users where username = '" + usr +"'"); + if(rs.first()){ + String password = rs.getString(1); + if(password.equals(pin)) { + return true; + } + } + + return false; + +*/ + } + + +} + + diff --git a/Project/src/Controller/Controller.java b/Project/src/Controller/Controller.java index 6a3a2ef..172592c 100644 --- a/Project/src/Controller/Controller.java +++ b/Project/src/Controller/Controller.java @@ -12,6 +12,7 @@ import java.io.*; import static Model.utils.GameUtils.*; +import static View.utils.ViewUtils.*; /** * Created by boyinzhang on 4/17/17. @@ -21,6 +22,8 @@ public class Controller{ public BoardUI boardUI; private Card selectedCard; private GemInfo currentGemInfo; + + private ObjectOutputStream out; private int id; private String name; @@ -92,12 +95,13 @@ private void newGame() { private void addExitListener() { boardUI.addExitListener(new ActionListener(){ public void actionPerformed(ActionEvent event) { - requestServer("EXIT"); + requestServer("EXIT",null); System.exit(0); } }); } + /** * Add listeners of gems. */ @@ -105,6 +109,7 @@ private void addGemsListener(){ this.boardUI.getGems()[4].addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { + //boardUI.getGems()[4].get currentGemInfo.updateInfo(1,0,0,0,0); } }); @@ -191,6 +196,28 @@ private void addFunctionalListeners(boolean serverMode){ addReserveListener(true); } + + /** + * Reset all buttons + */ + private void resetButtons(){ + + + //reset cards + for(int i = 0; i < NUM_CARD_RANK; i++){ + for(int j = 0; j < NUM_CARD_PER_RANK; j ++) { + boardUI.getCards()[i][j].setSelected(false); + } + } + + //reset gems + for(int i = 0; i < 5; i++) + boardUI.getGems()[i].setSelected(false); + + //clean up gem infos + currentGemInfo.reset(); + } + /** * Add listener to the reset button */ @@ -204,7 +231,7 @@ public void actionPerformed(ActionEvent e) { "Warning", JOptionPane.WARNING_MESSAGE); return; } - currentGemInfo.reset(); + resetButtons(); } }); } @@ -286,7 +313,7 @@ public void actionPerformed(ActionEvent e) { if (checkEnd()) { game.turnToNextPlayer(); - requestServer("VICTORY"); + requestServer("VICTORY",null); return; } game.turnToNextPlayer(); @@ -394,15 +421,6 @@ void setPanelEnabled(JPanel panel, Boolean isEnabled) { * Send text information and the game to server * @param msg text indicator */ - private void requestServer(String msg){ - try { - out.reset(); - out.writeObject(msg); - out.writeObject(game); - } catch (IOException e) { - e.printStackTrace(); - } - } public void requestServer(String msg, String command){ try { diff --git a/Project/src/Controller/Login.java b/Project/src/Controller/Login.java new file mode 100644 index 0000000..8337d13 --- /dev/null +++ b/Project/src/Controller/Login.java @@ -0,0 +1,128 @@ +package Controller; +import java.awt.*; +import java.awt.event.*; +import java.io.*; +import javax.swing.*; +import javax.swing.border.*; + +/** + * Created by dajun on 4/30/17. + */ + + +public class Login extends JDialog { + + private JTextField tfUsername; + private JPasswordField pfPassword; + private JLabel lbUsername; + private JLabel lbPassword; + private JButton btnLogin; + private JButton btnCancel; + private boolean succeeded; + + private ObjectInputStream input; + private ObjectOutputStream output; + + public Login(Frame parent, ObjectInputStream input, ObjectOutputStream output) { + super(parent, "Login", true); + this.input = input; + this.output = output; + // + JPanel panel = new JPanel(new GridBagLayout()); + GridBagConstraints cs = new GridBagConstraints(); + + cs.fill = GridBagConstraints.HORIZONTAL; + + lbUsername = new JLabel("Username: "); + cs.gridx = 0; + cs.gridy = 0; + cs.gridwidth = 1; + panel.add(lbUsername, cs); + + tfUsername = new JTextField(20); + cs.gridx = 1; + cs.gridy = 0; + cs.gridwidth = 2; + panel.add(tfUsername, cs); + + lbPassword = new JLabel("Password: "); + cs.gridx = 0; + cs.gridy = 1; + cs.gridwidth = 1; + panel.add(lbPassword, cs); + + pfPassword = new JPasswordField(20); + cs.gridx = 1; + cs.gridy = 1; + cs.gridwidth = 2; + panel.add(pfPassword, cs); + panel.setBorder(new LineBorder(Color.GRAY)); + + btnLogin = new JButton("Login"); + + btnLogin.addActionListener(new ActionListener() { + + public void actionPerformed(ActionEvent e) { + try { + if (authenticate(getUsername(), getPassword())) { + JOptionPane.showMessageDialog(Login.this, + "Hi " + getUsername() + "! Your game will start soon!", + "Login", + JOptionPane.INFORMATION_MESSAGE); + succeeded = true; + dispose(); + } else { + JOptionPane.showMessageDialog(Login.this, + "Invalid username or password", + "Login", + JOptionPane.ERROR_MESSAGE); + // reset username and password + tfUsername.setText(""); + pfPassword.setText(""); + succeeded = false; + + } + } catch (IOException e1) { + e1.printStackTrace(); + } catch (ClassNotFoundException e2) { + e2.printStackTrace(); + } + } + }); + btnCancel = new JButton("Cancel"); + btnCancel.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); + JPanel bp = new JPanel(); + bp.add(btnLogin); + bp.add(btnCancel); + + getContentPane().add(panel, BorderLayout.CENTER); + getContentPane().add(bp, BorderLayout.PAGE_END); + + pack(); + setResizable(false); + setLocationRelativeTo(parent); + } + + public String getUsername() { + return tfUsername.getText().trim(); + } + + public String getPassword() { + return new String(pfPassword.getPassword()); + } + + public boolean authenticate(String usr, String pin) throws IOException, ClassNotFoundException { + + output.writeObject("VERIFY"); + output.writeObject(usr); + output.writeObject(pin); + + Boolean valid = (Boolean)input.readObject(); + + return valid; + } +} \ No newline at end of file diff --git a/Project/src/Model/utils/GameUtils.java b/Project/src/Model/utils/GameUtils.java index bb9128b..d9d4add 100644 --- a/Project/src/Model/utils/GameUtils.java +++ b/Project/src/Model/utils/GameUtils.java @@ -4,7 +4,7 @@ * Created by boyinzhang on 4/9/17. */ public class GameUtils { - public final static int NUM_PLAYER = 4; + public final static int NUM_PLAYER = 2; public final static int NUM_CARD_RANK = 3; public final static int NUM_CARD_PER_RANK = 4; public final static int INIT_AMOUNT_PER_GEM = 7; diff --git a/Project/src/Network/Client.java b/Project/src/Network/Client.java index 04f4435..462cae0 100644 --- a/Project/src/Network/Client.java +++ b/Project/src/Network/Client.java @@ -1,16 +1,14 @@ package Network; -import Controller.Controller; -import Game.Game; -import Model.*; -import View.*; +import Controller.*; +import Game.*; -import java.lang.management.ManagementFactory; -import java.lang.reflect.Array; +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; import java.net.*; import java.io.*; -import java.util.ArrayList; -import java.util.Scanner; +import java.util.*; /** * Created by boyinzhang on 4/22/17. @@ -44,16 +42,23 @@ public Client(String serverAddress) throws Exception { String msg = (String)flowInput.readObject(); System.out.println(msg); + Login loginDlg = new Login(null,flowInput,flowOutput); + loginDlg.setVisible(true); + + /* //get username from keyboard - keyboardInput =new Scanner(System.in); + keyboardInput = new Scanner(System.in); String name = keyboardInput.nextLine(); //send username back flowOutput.writeObject(name); +*/ + //fetch id and game clientID = (Integer) flowInput.readObject(); Game game = (Game) flowInput.readObject(); + String name = game.players[clientID].getName(); if(name.startsWith("ai")){ ai = true; diff --git a/Project/src/Network/Server.java b/Project/src/Network/Server.java index 50384e0..765eaae 100644 --- a/Project/src/Network/Server.java +++ b/Project/src/Network/Server.java @@ -1,13 +1,13 @@ package Network; -import Controller.Controller; +import Controller.*; import Game.*; import Model.Card; import Model.utils.GemInfo; -import javax.print.DocFlavor; import java.io.*; import java.net.*; +import java.sql.SQLException; import java.util.ArrayList; import static Model.utils.GameUtils.*; @@ -40,20 +40,42 @@ public Server(int port)throws Exception { output[i] = new ObjectOutputStream(server.getOutputStream()); input[i] = new ObjectInputStream(server.getInputStream()); } - } //initialize game after each player sends their game back - private void gameInit() throws IOException, ClassNotFoundException { + private void gameInit() throws IOException, ClassNotFoundException, SQLException { - ArrayList names = new ArrayList(NUM_PLAYER); + Connect connection = new Connect(); + ArrayList names = new ArrayList<>(NUM_PLAYER); for(int i = 0; i < NUM_PLAYER; i++){ - output[i].writeObject("Please specify your username"); - String username = (String)input[i].readObject(); - names.add(username); + output[i].writeObject("Please enter your username/password"); + + //reading username and password + while(true) { + String msg = (String) input[i].readObject(); + //sanity check + if (!msg.equals("VERIFY")){ + System.out.println("Verification interrupted"); + return; + } + + String username = (String) input[i].readObject(); + String password = (String) input[i].readObject(); + + + if (connection.verify(username,password)){ + output[i].writeObject(true); + names.add(username); + break; + } + + output[i].writeObject(false); + } + } + connection.disconnect(); game = new Game(names); System.out.println("new Game"); @@ -238,11 +260,7 @@ else if(vote == NUM_PLAYER){ //splited is the postion of the card, and whether the card is reserved int cardX = Integer.parseInt(splited[0]); int cardY = Integer.parseInt(splited[1]); - boolean isReserved; - if ( Integer.parseInt(splited[2]) == 1) - isReserved = true; - else - isReserved = false; + boolean isReserved = Integer.parseInt(splited[2]) == 1; Card selectedCard; //if it's reserved, then get the card from player section if(isReserved) @@ -255,8 +273,8 @@ else if(vote == NUM_PLAYER){ //if it is not reserved, we need to put a new card back. if(!isReserved) { Card newCard = game.getGameBoard().getNewCard(cardX); - int[] positon = {cardX, cardY}; - game.getGameBoard().setCardOnBoard(newCard, positon); + int[] position = {cardX, cardY}; + game.getGameBoard().setCardOnBoard(newCard, position); } game.getCurrentPlayer().recruitAvailableNobles(); game.turnToNextPlayer(); @@ -274,8 +292,8 @@ else if(vote == NUM_PLAYER){ Card selectedCard = game.gameBoard.getCards()[cardX][cardY]; game.getCurrentPlayer().reserveCard(selectedCard); Card newCard = game.getGameBoard().getNewCard(cardX); - int[] positon = {cardX, cardY}; - game.getGameBoard().setCardOnBoard(newCard, positon); + int[] position = {cardX, cardY}; + game.getGameBoard().setCardOnBoard(newCard, position); game.turnToNextPlayer(); broadcastPlayers(game); currentPlayer = (currentPlayer + 1) % NUM_PLAYER; @@ -292,11 +310,9 @@ else if(vote == NUM_PLAYER){ } - } catch (IOException e) { + } catch (IOException | ClassNotFoundException | SQLException e) { e.printStackTrace(); //break; - } catch (ClassNotFoundException e) { - e.printStackTrace(); } //} System.out.println("Server closed"); @@ -305,6 +321,8 @@ else if(vote == NUM_PLAYER){ public static void main(String [] args) { + + int port = (args.length == 0) ? 8080 : Integer.parseInt(args[1]); Thread t = null; @@ -313,6 +331,7 @@ public static void main(String [] args) { } catch (Exception e) { e.printStackTrace(); } + assert t != null; t.start(); } diff --git a/Project/src/Tests/ConnectTests.java b/Project/src/Tests/ConnectTests.java new file mode 100644 index 0000000..2387d94 --- /dev/null +++ b/Project/src/Tests/ConnectTests.java @@ -0,0 +1,13 @@ +package Tests; + +/** + * Created by dajun on 4/30/17. + */ +public class ConnectTests { + + + public static void main(String [] args) { + + } + +} diff --git a/Project/src/View/BoardUI.java b/Project/src/View/BoardUI.java index dc43093..c78b349 100644 --- a/Project/src/View/BoardUI.java +++ b/Project/src/View/BoardUI.java @@ -33,8 +33,8 @@ public class BoardUI { private JPanel decks[]; private JPanel nobles[]; private JButton gold; - private JButton gems[]; - private JButton cards[][]; + private JToggleButton gems[]; + private JToggleButton cards[][]; private PlayerPanel players[]; private JButton collect, reset, buy, reserve; @@ -99,7 +99,8 @@ public void updateByGame(Game game){ gems[i].setOpaque(false); gems[i].setContentAreaFilled(false); gems[i].setBorderPainted(false); - gems[i].setIcon(plotGemButton(getGemByIndex(5-i), availableGems.getByIndex(5-i), gemImages,GEM_WIDTH)); + gems[i].setIcon(plotGemButton(getGemByIndex(5-i), availableGems.getByIndex(5-i), gemImages,GEM_WIDTH,false)); + gems[i].setSelectedIcon(plotGemButton(getGemByIndex(5-i), availableGems.getByIndex(5-i), gemImages,GEM_WIDTH,true)); } Card[][] currentCards = game.gameBoard.getCards(); @@ -109,7 +110,9 @@ public void updateByGame(Game game){ cards[i][j].setOpaque(false); cards[i][j].setContentAreaFilled(false); cards[i][j].setBorderPainted(false); - cards[i][j].setIcon(plotCardButton(currentCards[i][j],gemImages,cardImages)); + cards[i][j].setIcon(plotCardButton(currentCards[i][j],gemImages,cardImages,false)); + cards[i][j].setSelectedIcon(plotCardButton(currentCards[i][j],gemImages,cardImages,true)); + } } @@ -118,7 +121,9 @@ public void updateByGame(Game game){ gold.setOpaque(false); gold.setContentAreaFilled(false); gold.setBorderPainted(false); - gold.setIcon(plotGoldButton(availableGold,gemImages,GEM_WIDTH)); + gold.setIcon(plotGoldButton(availableGold,gemImages,GEM_WIDTH,false)); + + //gold.setRolloverEnabled(true); Player[] gamePlayers = game.getPlayers(); for (int i=0;i reserved, Hashtable reservedCards[i].setBorderPainted(false); //if there is a reserved card, display the image if(i < reserved.size()) - reservedCards[i].setIcon(plotCardButton(reserved.get(i),gemImages,cardImages)); + reservedCards[i].setIcon(plotCardButton(reserved.get(i),gemImages,cardImages,false)); else reservedCards[i].setIcon(null); reservedCards[i].validate(); diff --git a/Project/src/View/utils/ViewUtils.java b/Project/src/View/utils/ViewUtils.java index 22b928f..ccf4e6f 100644 --- a/Project/src/View/utils/ViewUtils.java +++ b/Project/src/View/utils/ViewUtils.java @@ -32,7 +32,7 @@ public class ViewUtils { public final static int GAME_WIDTH=13*ratio; public final static int GAME_HEIGHT=10*ratio; public final static int PLAYER_WIDTH=3*ratio+3*CARD_WIDTH; - public final static int PLAYER_HEIGHT=10*ratio/NUM_PLAYER; + public final static int PLAYER_HEIGHT=GAME_HEIGHT/NUM_PLAYER; public final static int WINDOW_WIDTH=GAME_WIDTH+PLAYER_WIDTH; public final static int WINDOW_HEIGHT=GAME_HEIGHT; @@ -101,38 +101,60 @@ public static void plotRectWithOutline(Graphics2D g2d, Color fillColor, int x, i } - public static ImageIcon plotGemButton(Gem gem, int left, Hashtable gemImages,int width){ + // + public static void highlightButton(Graphics2D g2d, int w, int h){ + Stroke oldStroke = g2d.getStroke(); + g2d.setStroke(new BasicStroke(5)); + g2d.setColor(Color.orange); + g2d.drawRect(0,0,w,h); + g2d.setStroke(oldStroke); + } + + + // + public static ImageIcon plotGemButton(Gem gem, int left, Hashtable gemImages,int width, boolean selected){ BufferedImage buffered = new BufferedImage(width, width, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = buffered.createGraphics(); int r = width/2; + if(selected){ + g2d.setColor(Color.orange); + g2d.fillOval(0,0,2*r,2*r); + } + //plot gem and resize the image Image gemImg = gemImages.get(gem.getGemName()).getScaledInstance(width,width,Image.SCALE_SMOOTH); g2d.drawImage(gemImg, 0, 0 , null); plotStringWithOutline(g2d,Integer.toString(left),r/2,r*3/2,r*3/4); + return new ImageIcon(buffered); } - - public static ImageIcon plotGoldButton(int left, Hashtable gemImages,int width){ + // + public static ImageIcon plotGoldButton(int left, Hashtable gemImages,int width, boolean selected){ BufferedImage buffered = new BufferedImage(width, width, BufferedImage.TYPE_INT_ARGB); Graphics2D g2d = buffered.createGraphics(); int r = width/2; + if(selected){ + g2d.setColor(Color.orange); + g2d.fillOval(0,0,2*r,2*r); + } + //plot gold and resize the image Image gemImg = gemImages.get("Gold").getScaledInstance(width,width,Image.SCALE_SMOOTH);; g2d.drawImage(gemImg, 0,0, null); + plotStringWithOutline(g2d,Integer.toString(left),r/2,r*3/2,r*3/4); return new ImageIcon(buffered); - } - - public static ImageIcon plotCardButton(Card card, Hashtable gemImages, Hashtable cardImages) { + // + public static ImageIcon plotCardButton(Card card, Hashtable gemImages, Hashtable cardImages, boolean selected) { //extract the card information Gem gem = card.getTargetGem(); @@ -174,6 +196,11 @@ public static ImageIcon plotCardButton(Card card, Hashtable gemIm plotStringWithOutline(g2d,Integer.toString(cost),x+r/2,y+r*3/2,r*3/2); } + if(selected){ + highlightButton(g2d,CARD_WIDTH,CARD_HEIGHT); + } + + return new ImageIcon(buffered); } From 2b81b8d17cba8dd3af5d5026c0c5e71152ebd186 Mon Sep 17 00:00:00 2001 From: Dajun Date: Mon, 1 May 2017 02:18:42 -0500 Subject: [PATCH 2/2] ai+local+dialog --- Project/src/Controller/Connect.java | 6 +- Project/src/Controller/Controller.java | 261 ++++++++++++++----------- Project/src/Controller/Login.java | 4 +- Project/src/Game/Game.java | 2 +- Project/src/Network/Client.java | 37 +++- Project/src/Network/Server.java | 137 +++++++------ Project/src/Tests/ConnectTests.java | 20 +- Project/src/View/utils/ViewUtils.java | 6 +- 8 files changed, 286 insertions(+), 187 deletions(-) diff --git a/Project/src/Controller/Connect.java b/Project/src/Controller/Connect.java index 5829d3a..4e0e52f 100644 --- a/Project/src/Controller/Connect.java +++ b/Project/src/Controller/Connect.java @@ -8,6 +8,7 @@ public class Connect { private Connection connection; + //jdbc library loaded public Connect() throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); @@ -15,14 +16,14 @@ public Connect() throws ClassNotFoundException, SQLException { } + //disconnect from database public void disconnect() throws SQLException { connection.close(); } + //execute query to validate if the username matches with the password public boolean verify(String usr, String pin) throws SQLException { - return true; -/* Statement stmt= connection.createStatement(); ResultSet rs=stmt.executeQuery("select password from users where username = '" + usr +"'"); if(rs.first()){ @@ -34,7 +35,6 @@ public boolean verify(String usr, String pin) throws SQLException { return false; -*/ } diff --git a/Project/src/Controller/Controller.java b/Project/src/Controller/Controller.java index 172592c..5166d27 100644 --- a/Project/src/Controller/Controller.java +++ b/Project/src/Controller/Controller.java @@ -33,10 +33,10 @@ public Controller(){ this.boardUI = new BoardUI(game,"anonymous"); this.currentGemInfo = new GemInfo(0); this.id = 0; - addMenuItemListener(); + addMenuItemListener(false); addGemsListener(); addCardListeners(); - addFunctionalListeners(); + addFunctionalListeners(false); } public Controller(Game game, ObjectOutputStream out, int id, String name){ @@ -46,7 +46,7 @@ public Controller(Game game, ObjectOutputStream out, int id, String name){ this.out = out; this.boardUI = new BoardUI(game,name); this.currentGemInfo = new GemInfo(0); - addMenuItemListener(); + addMenuItemListener(true); addGemsListener(); addCardListeners(); addFunctionalListeners(true); @@ -65,19 +65,22 @@ public Controller(Game game, ObjectOutputStream out, int id, boolean isAi){ /** * Helper function to help initialize the gui */ - private void addMenuItemListener(){ - addNewGameListener(); - addExitListener(); + private void addMenuItemListener(boolean serverMode){ + addNewGameListener(serverMode); + addExitListener(serverMode); } /** * for JMenubar New */ - private void addNewGameListener() { + private void addNewGameListener(boolean serverMode) { boardUI.addNewGameListener(new ActionListener(){ public void actionPerformed(ActionEvent event) { - sendVoteResult("RESTART"); - //newGame(); + + if(serverMode) + sendVoteResult("RESTART"); + else + newGame(); } }); } @@ -92,10 +95,11 @@ private void newGame() { /** * for JMenubar Exit */ - private void addExitListener() { + private void addExitListener(boolean serverMode) { boardUI.addExitListener(new ActionListener(){ public void actionPerformed(ActionEvent event) { - requestServer("EXIT",null); + if(serverMode) + requestServer("EXIT","EXIT"); System.exit(0); } }); @@ -109,8 +113,10 @@ private void addGemsListener(){ this.boardUI.getGems()[4].addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - //boardUI.getGems()[4].get + //double click will not cancel the effect currentGemInfo.updateInfo(1,0,0,0,0); + if(currentGemInfo.diamond >= 2) + boardUI.getGems()[4].setSelected(true); } }); @@ -118,6 +124,8 @@ public void actionPerformed(ActionEvent e) { @Override public void actionPerformed(ActionEvent e) { currentGemInfo.updateInfo(0,1,0,0,0); + if(currentGemInfo.emerald >= 2) + boardUI.getGems()[3].setSelected(true); } }); @@ -125,6 +133,8 @@ public void actionPerformed(ActionEvent e) { @Override public void actionPerformed(ActionEvent e) { currentGemInfo.updateInfo(0,0,1,0,0); + if(currentGemInfo.onyx >= 2) + boardUI.getGems()[2].setSelected(true); } }); @@ -132,6 +142,8 @@ public void actionPerformed(ActionEvent e) { @Override public void actionPerformed(ActionEvent e) { currentGemInfo.updateInfo(0,0,0,1,0); + if(currentGemInfo.ruby >= 2) + boardUI.getGems()[1].setSelected(true); } }); @@ -139,6 +151,8 @@ public void actionPerformed(ActionEvent e) { @Override public void actionPerformed(ActionEvent e) { currentGemInfo.updateInfo(0,0,0,0,1); + if(currentGemInfo.sapphire >= 2) + boardUI.getGems()[0].setSelected(true); } }); } @@ -175,25 +189,15 @@ public void actionPerformed(ActionEvent e) { } } - /** - * Add listeners to the four major operations - */ - private void addFunctionalListeners(){ - addResetLisenter(false); - addCollectListener(false); - addBuyListener(false); - addReserveListener(false); - } - /** * Indicator whether it is used for server mode. * @param serverMode true if it is the server mode */ private void addFunctionalListeners(boolean serverMode){ - addResetLisenter(true); - addCollectListener(true); - addBuyListener(true); - addReserveListener(true); + addResetListener(serverMode); + addCollectListener(serverMode); + addBuyListener(serverMode); + addReserveListener(serverMode); } @@ -202,13 +206,13 @@ private void addFunctionalListeners(boolean serverMode){ */ private void resetButtons(){ - //reset cards for(int i = 0; i < NUM_CARD_RANK; i++){ for(int j = 0; j < NUM_CARD_PER_RANK; j ++) { boardUI.getCards()[i][j].setSelected(false); } } + selectedCard = null; //reset gems for(int i = 0; i < 5; i++) @@ -222,14 +226,16 @@ private void resetButtons(){ * Add listener to the reset button */ - private void addResetLisenter(boolean serverMode){ + private void addResetListener(boolean serverMode){ this.boardUI.getReset().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - if(game.getCurrentPlayer().getPlayerId() != id+1 && serverMode) { - JOptionPane.showMessageDialog(null, "Wait for your opponent's move", - "Warning", JOptionPane.WARNING_MESSAGE); - return; + if(serverMode) { + if (game.getCurrentPlayer().getPlayerId() != id + 1) { + JOptionPane.showMessageDialog(null, "Wait for your opponent's move", + "Warning", JOptionPane.WARNING_MESSAGE); + return; + } } resetButtons(); } @@ -244,30 +250,34 @@ private void addCollectListener(boolean serverMode){ this.boardUI.getCollect().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - if(game.getCurrentPlayer().getPlayerId() != id+1 && serverMode) { - JOptionPane.showMessageDialog(null, "Wait for your opponent's move", - "Warning", JOptionPane.WARNING_MESSAGE); - return; + if(serverMode) { + if (game.getCurrentPlayer().getPlayerId() != id + 1) { + JOptionPane.showMessageDialog(null, "Wait for your opponent's move", + "Warning", JOptionPane.WARNING_MESSAGE); + return; + } } - boolean status = game.getCurrentPlayer().collectGems(currentGemInfo); - if(!status){ - JOptionPane.showMessageDialog(null, "Invalid Collection! Please make another try!", - "Warning", JOptionPane.WARNING_MESSAGE); - currentGemInfo.reset(); - } - else{ - String command = String.valueOf(currentGemInfo.diamond) + ' ' + String.valueOf(currentGemInfo.emerald) + ' ' - + String.valueOf(currentGemInfo.onyx) + ' ' + String.valueOf(currentGemInfo.ruby) + ' ' - + String.valueOf(currentGemInfo.sapphire); - currentGemInfo.reset(); - //if (checkEnd()) return; - //game.turnToNextPlayer(); + boolean status = game.getCurrentPlayer().collectGems(currentGemInfo); + if (!status) { + JOptionPane.showMessageDialog(null, "Invalid Collection! Please make another try!", + "Warning", JOptionPane.WARNING_MESSAGE); + resetButtons(); + } else { + String command = String.valueOf(currentGemInfo.diamond) + ' ' + String.valueOf(currentGemInfo.emerald) + ' ' + + String.valueOf(currentGemInfo.onyx) + ' ' + String.valueOf(currentGemInfo.ruby) + ' ' + + String.valueOf(currentGemInfo.sapphire); + resetButtons(); + if(serverMode) + requestServer("COLLECT", command); + else{ + if (checkEnd(false)) return; + game.turnToNextPlayer(); + boardUI.updateByGame(game); + } + } - requestServer("COLLECT", command); - //boardUI.updateByGame(game); - } } }); @@ -280,11 +290,15 @@ private void addBuyListener(boolean serverMode){ this.boardUI.getBuy().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - if(game.getCurrentPlayer().getPlayerId() != id+1 && serverMode) { - JOptionPane.showMessageDialog(null, "Wait for your opponent's move", - "Warning", JOptionPane.WARNING_MESSAGE); - return; + + if(serverMode) { + if (game.getCurrentPlayer().getPlayerId() != id + 1) { + JOptionPane.showMessageDialog(null, "Wait for your opponent's move", + "Warning", JOptionPane.WARNING_MESSAGE); + return; + } } + if(selectedCard == null){ JOptionPane.showMessageDialog(null, "Must select one card!", "Warning", JOptionPane.WARNING_MESSAGE); @@ -296,30 +310,39 @@ public void actionPerformed(ActionEvent e) { "Warning", JOptionPane.WARNING_MESSAGE); selectedCard = null; } - else{ - String command; - if(selectedCard.isReserved()){ - command = String.valueOf(selectedCard.getPosition()[0]) + ' ' + String.valueOf(selectedCard.getPosition()[1]) - + " 1"; - } - else{ - command = String.valueOf(selectedCard.getPosition()[0]) + ' ' + String.valueOf(selectedCard.getPosition()[1]) - + " 0"; - } - Card newCard = game.getGameBoard().getNewCard(selectedCard.getPosition()[0]); - game.getGameBoard().setCardOnBoard(newCard, selectedCard.getPosition()); - selectedCard = null; - game.getCurrentPlayer().recruitAvailableNobles(); - if (checkEnd()) { - - game.turnToNextPlayer(); - requestServer("VICTORY",null); - return; - } - game.turnToNextPlayer(); - requestServer("PURCHASE", command); + else { + String command; + if (selectedCard.isReserved()) { + command = String.valueOf(selectedCard.getPosition()[0]) + ' ' + String.valueOf(selectedCard.getPosition()[1]) + + " 1"; + } else { + command = String.valueOf(selectedCard.getPosition()[0]) + ' ' + String.valueOf(selectedCard.getPosition()[1]) + + " 0"; + } - //boardUI.updateByGame(game); + Card newCard = game.getGameBoard().getNewCard(selectedCard.getPosition()[0]); + game.getGameBoard().setCardOnBoard(newCard, selectedCard.getPosition()); + resetButtons(); + game.getCurrentPlayer().recruitAvailableNobles(); + if(serverMode) { + if (checkEnd(true)) { + game.turnToNextPlayer(); + try { + out.writeObject("VICTORY"); + out.writeObject(game); + } catch (IOException e1) { + e1.printStackTrace(); + } + return; + } + game.turnToNextPlayer(); + requestServer("PURCHASE", command); + } + else{ + if (checkEnd(false)) return; + game.turnToNextPlayer(); + boardUI.updateByGame(game); + } } } @@ -327,37 +350,37 @@ public void actionPerformed(ActionEvent e) { } - private boolean checkEnd() { + private boolean checkEnd(boolean serverMode) { - /* - if(game.getCurrentPlayer().getPlayerId() == NUM_PLAYER){ - int numberOfWining = game.checkEndofGame(); - if(numberOfWining == 1){ - for(Player player : game.getPlayers()){ - if(player.hasWon()){ - int replyNewGame = JOptionPane.showConfirmDialog(null, - "Player " +player.getPlayerId()+" win! Do you want to start a new game","Yes?",JOptionPane.YES_NO_OPTION); - if(replyNewGame==JOptionPane.YES_OPTION) { - newGame(); - return true; + if(serverMode) { + if (game.currentPlayer.hasWon()) + return true; + } + //local mode + else { + if (game.getCurrentPlayer().getPlayerId() == NUM_PLAYER) { + int numberOfWining = game.checkEndofGame(); + if (numberOfWining == 1) { + for (Player player : game.getPlayers()) { + if (player.hasWon()) { + int replyNewGame = JOptionPane.showConfirmDialog(null, + "Player " + player.getPlayerId() + " win! Do you want to start a new game", "Yes?", JOptionPane.YES_NO_OPTION); + if (replyNewGame == JOptionPane.YES_OPTION) { + newGame(); + return true; + } } } - } - } - else if(numberOfWining >1){ - int replyNewGame = JOptionPane.showConfirmDialog(null, - "Tie! Do you want to start a new game","Yes?",JOptionPane.YES_NO_OPTION); - if(replyNewGame==JOptionPane.YES_OPTION) { - newGame(); - return true; + } else if (numberOfWining > 1) { + int replyNewGame = JOptionPane.showConfirmDialog(null, + "Tie! Do you want to start a new game", "Yes?", JOptionPane.YES_NO_OPTION); + if (replyNewGame == JOptionPane.YES_OPTION) { + newGame(); + return true; + } } } } - */ - if(game.currentPlayer.hasWon()) - return true; - - return false; } @@ -368,12 +391,15 @@ private void addReserveListener(boolean serverMode){ this.boardUI.getReserve().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - System.out.println("Reserve"); - if(game.getCurrentPlayer().getPlayerId() != id+1 && serverMode) { - JOptionPane.showMessageDialog(null, "Wait for your opponent's move", - "Warning", JOptionPane.WARNING_MESSAGE); - return; + //System.out.println("Reserve"); + if(serverMode) { + if (game.getCurrentPlayer().getPlayerId() != id + 1) { + JOptionPane.showMessageDialog(null, "Wait for your opponent's move", + "Warning", JOptionPane.WARNING_MESSAGE); + return; + } } + if(selectedCard == null){ JOptionPane.showMessageDialog(null, "Must select one card!", "Warning", JOptionPane.WARNING_MESSAGE); @@ -387,16 +413,21 @@ public void actionPerformed(ActionEvent e) { } else{ String command = String.valueOf(selectedCard.getPosition()[0]) + ' ' + String.valueOf(selectedCard.getPosition()[1]); + Card newCard = game.getGameBoard().getNewCard(selectedCard.getPosition()[0]); game.getGameBoard().setCardOnBoard(newCard, selectedCard.getPosition()); - selectedCard = null; - //if (checkEnd()) return; + game.turnToNextPlayer(); + resetButtons(); //boardUI.window.setEnabled(false); - requestServer("RESERVE", command); - System.out.println("Reserve request made"); - - //boardUI.updateByGame(game); + if(serverMode) { + requestServer("RESERVE", command); + System.out.println("Reserve request made"); + } + else { + boardUI.updateByGame(game); + if (checkEnd(false)) return; + } } } }); diff --git a/Project/src/Controller/Login.java b/Project/src/Controller/Login.java index 8337d13..fb0ed03 100644 --- a/Project/src/Controller/Login.java +++ b/Project/src/Controller/Login.java @@ -39,7 +39,7 @@ public Login(Frame parent, ObjectInputStream input, ObjectOutputStream output) { cs.gridwidth = 1; panel.add(lbUsername, cs); - tfUsername = new JTextField(20); + tfUsername = new JTextField(10); cs.gridx = 1; cs.gridy = 0; cs.gridwidth = 2; @@ -51,7 +51,7 @@ public Login(Frame parent, ObjectInputStream input, ObjectOutputStream output) { cs.gridwidth = 1; panel.add(lbPassword, cs); - pfPassword = new JPasswordField(20); + pfPassword = new JPasswordField(10); cs.gridx = 1; cs.gridy = 1; cs.gridwidth = 2; diff --git a/Project/src/Game/Game.java b/Project/src/Game/Game.java index 4601103..0e9c062 100644 --- a/Project/src/Game/Game.java +++ b/Project/src/Game/Game.java @@ -29,7 +29,7 @@ public Game(){ this.players = new Player[NUM_PLAYER]; for(int i = 0; i < NUM_PLAYER; i++){ - players[i] = new Player(i+1 , this.gameBoard, null); + players[i] = new Player(i+1 , this.gameBoard, Integer.toString(i+1)); } currentPlayer = players[0]; } diff --git a/Project/src/Network/Client.java b/Project/src/Network/Client.java index 462cae0..fac5ab1 100644 --- a/Project/src/Network/Client.java +++ b/Project/src/Network/Client.java @@ -25,7 +25,6 @@ public class Client { private ObjectOutputStream flowOutput = null; private Controller controller; - private boolean ai; private int clientID; private String username; @@ -151,9 +150,39 @@ else if(response.startsWith("VOTE")){ //main public static void main(String[] args) throws Exception { - String serverAddress = (args.length == 0) ? "localhost" : args[1]; - Client client = new Client(serverAddress); - client.play(); + + Object[] options = {"Yes, help me find the other players! ", "No, I want to start a local game!"}; + int local = JOptionPane.showOptionDialog(null, + "Do you want to connect to the internet?", + "Connection", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, //do not use a custom Icon + options, //the titles of buttons + options[0]); //default button title + + if(local == 1){ + + int localAI = JOptionPane.showOptionDialog(null, + "Do you want to play with AI?", + "AI", + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE, + null, //do not use a custom Icon + options, //the titles of buttons + options[0]); //default button title + if(localAI == 1){ + + } + else { + Controller c = new Controller(); + } + } + else { + String serverAddress = (args.length == 0) ? "localhost" : args[1]; + Client client = new Client(serverAddress); + client.play(); + } } diff --git a/Project/src/Network/Server.java b/Project/src/Network/Server.java index 765eaae..c756c01 100644 --- a/Project/src/Network/Server.java +++ b/Project/src/Network/Server.java @@ -130,6 +130,7 @@ private void announceResult(ArrayList winners) throws IOException { //when someone declares victory, the rest players still have one round to play private void lastRound(int currentPlayer) throws IOException, ClassNotFoundException { + Game updatedGame = (Game) input[currentPlayer].readObject(); broadcastPlayers(updatedGame); @@ -139,11 +140,25 @@ private void lastRound(int currentPlayer) throws IOException, ClassNotFoundExcep for (int nextPlayer = currentPlayer + 1; nextPlayer < NUM_PLAYER; nextPlayer++) { String request = (String) input[nextPlayer].readObject(); - updatedGame = (Game) input[nextPlayer].readObject(); + + // here is receiving the information for collection + if (request.startsWith("COLLECT")) + recvCollect(currentPlayer); + + // here is receiving the information for buying cards + if (request.startsWith("PURCHASE")) + recvBuy(currentPlayer); + + //here is receiving the information for reserving card + if (request.startsWith("RESERVE")) + recvReserve(currentPlayer); + if (request.startsWith("VICTORY")) { winners.add(nextPlayer); } - broadcastPlayers(updatedGame); + + //updatedGame = (Game) input[nextPlayer].readObject(); + //broadcastPlayers(updatedGame); } announceResult(winners); @@ -170,6 +185,60 @@ public void broadcastPlayers(Game updatedGame) throws IOException { } + public void recvCollect(int currentPlayer) throws IOException, ClassNotFoundException { + String command = (String) input[currentPlayer].readObject(); + String[] splited = command.split(" "); + //splited is the number of each gems collected + GemInfo collectedGem = new GemInfo(Integer.parseInt(splited[0]),Integer.parseInt(splited[1]), Integer.parseInt(splited[2]), Integer.parseInt(splited[3]), Integer.parseInt(splited[4])); + game.getCurrentPlayer().collectGems(collectedGem); + game.turnToNextPlayer(); + //send the updated game to all the clients + broadcastPlayers(game); + } + + public void recvBuy(int currentPlayer) throws IOException, ClassNotFoundException { + String command = (String) input[currentPlayer].readObject(); + String[] splited = command.split(" "); + //splited is the postion of the card, and whether the card is reserved + int cardX = Integer.parseInt(splited[0]); + int cardY = Integer.parseInt(splited[1]); + boolean isReserved = Integer.parseInt(splited[2]) == 1; + Card selectedCard; + //if it's reserved, then get the card from player section + if(isReserved) + selectedCard = game.getPlayers()[cardX].getReserves().get(cardY); + //if not, get the card from the game board + else + selectedCard = game.gameBoard.getCards()[cardX][cardY]; + + game.getCurrentPlayer().buyCard(selectedCard,isReserved); + //if it is not reserved, we need to put a new card back. + if(!isReserved) { + Card newCard = game.getGameBoard().getNewCard(cardX); + int[] position = {cardX, cardY}; + game.getGameBoard().setCardOnBoard(newCard, position); + } + game.getCurrentPlayer().recruitAvailableNobles(); + game.turnToNextPlayer(); + broadcastPlayers(game); + + } + + public void recvReserve(int currentPlayer) throws IOException, ClassNotFoundException { + String command = (String) input[currentPlayer].readObject(); + String[] splited = command.split(" "); + // splited is the position of the card + int cardX = Integer.parseInt(splited[0]); + int cardY = Integer.parseInt(splited[1]); + Card selectedCard = game.gameBoard.getCards()[cardX][cardY]; + game.getCurrentPlayer().reserveCard(selectedCard); + Card newCard = game.getGameBoard().getNewCard(cardX); + int[] position = {cardX, cardY}; + game.getGameBoard().setCardOnBoard(newCard, position); + game.turnToNextPlayer(); + broadcastPlayers(game); + } + @Override public void run() { @@ -240,68 +309,20 @@ else if(vote == NUM_PLAYER){ continue; } + // here is receiving the information for collection - if (request.startsWith("COLLECT")){ - String command = (String) input[currentPlayer].readObject(); - String[] splited = command.split(" "); - //splited is the number of each gems collected - GemInfo collectedGem = new GemInfo(Integer.parseInt(splited[0]),Integer.parseInt(splited[1]), Integer.parseInt(splited[2]), Integer.parseInt(splited[3]), Integer.parseInt(splited[4])); - game.getCurrentPlayer().collectGems(collectedGem); - game.turnToNextPlayer(); - //send the updated game to all the clients - broadcastPlayers(game); - currentPlayer = (currentPlayer + 1) % NUM_PLAYER; - } + if (request.startsWith("COLLECT")) + recvCollect(currentPlayer); // here is receiving the information for buying cards - if (request.startsWith("PURCHASE")) { - String command = (String) input[currentPlayer].readObject(); - String[] splited = command.split(" "); - //splited is the postion of the card, and whether the card is reserved - int cardX = Integer.parseInt(splited[0]); - int cardY = Integer.parseInt(splited[1]); - boolean isReserved = Integer.parseInt(splited[2]) == 1; - Card selectedCard; - //if it's reserved, then get the card from player section - if(isReserved) - selectedCard = game.getPlayers()[cardX].getReserves().get(cardY); - //if not, get the card from the game board - else - selectedCard = game.gameBoard.getCards()[cardX][cardY]; - - game.getCurrentPlayer().buyCard(selectedCard,isReserved); - //if it is not reserved, we need to put a new card back. - if(!isReserved) { - Card newCard = game.getGameBoard().getNewCard(cardX); - int[] position = {cardX, cardY}; - game.getGameBoard().setCardOnBoard(newCard, position); - } - game.getCurrentPlayer().recruitAvailableNobles(); - game.turnToNextPlayer(); - broadcastPlayers(game); - currentPlayer = (currentPlayer + 1) % NUM_PLAYER; - } + if (request.startsWith("PURCHASE")) + recvBuy(currentPlayer); //here is receiving the information for reserving card - if (request.startsWith("RESERVE")) { - String command = (String) input[currentPlayer].readObject(); - String[] splited = command.split(" "); - // splited is the position of the card - int cardX = Integer.parseInt(splited[0]); - int cardY = Integer.parseInt(splited[1]); - Card selectedCard = game.gameBoard.getCards()[cardX][cardY]; - game.getCurrentPlayer().reserveCard(selectedCard); - Card newCard = game.getGameBoard().getNewCard(cardX); - int[] position = {cardX, cardY}; - game.getGameBoard().setCardOnBoard(newCard, position); - game.turnToNextPlayer(); - broadcastPlayers(game); - currentPlayer = (currentPlayer + 1) % NUM_PLAYER; - } - - //next one; + if (request.startsWith("RESERVE")) + recvReserve(currentPlayer); - //output[currentPlayer].writeObject("MOVE"); + currentPlayer = (currentPlayer + 1) % NUM_PLAYER; } catch (ClassNotFoundException e) { e.printStackTrace(); diff --git a/Project/src/Tests/ConnectTests.java b/Project/src/Tests/ConnectTests.java index 2387d94..6ea4268 100644 --- a/Project/src/Tests/ConnectTests.java +++ b/Project/src/Tests/ConnectTests.java @@ -1,13 +1,31 @@ package Tests; +import Controller.Connect; +import org.junit.Test; + +import java.sql.SQLException; + +import static org.junit.Assert.assertEquals; + /** * Created by dajun on 4/30/17. */ public class ConnectTests { + @Test + public void databaseConnectionTest() throws SQLException, ClassNotFoundException { + + Connect connection = new Connect(); + String realUsername = "dajun"; + String correctPassword = "1234"; + String fakeUsername = "dd"; + String wrongPassword = "0000"; - public static void main(String [] args) { + assertEquals(connection.verify(realUsername,correctPassword), true); + assertEquals(connection.verify(realUsername,wrongPassword), false); + assertEquals(connection.verify(fakeUsername,correctPassword), true); + connection.disconnect(); } } diff --git a/Project/src/View/utils/ViewUtils.java b/Project/src/View/utils/ViewUtils.java index ccf4e6f..f024a18 100644 --- a/Project/src/View/utils/ViewUtils.java +++ b/Project/src/View/utils/ViewUtils.java @@ -101,7 +101,7 @@ public static void plotRectWithOutline(Graphics2D g2d, Color fillColor, int x, i } - // + //paint the border of cards public static void highlightButton(Graphics2D g2d, int w, int h){ Stroke oldStroke = g2d.getStroke(); g2d.setStroke(new BasicStroke(5)); @@ -111,7 +111,7 @@ public static void highlightButton(Graphics2D g2d, int w, int h){ } - // + //fill the background of gem buttons if it is selected public static ImageIcon plotGemButton(Gem gem, int left, Hashtable gemImages,int width, boolean selected){ BufferedImage buffered = new BufferedImage(width, width, BufferedImage.TYPE_INT_ARGB); @@ -132,7 +132,7 @@ public static ImageIcon plotGemButton(Gem gem, int left, Hashtable gemImages,int width, boolean selected){ BufferedImage buffered = new BufferedImage(width, width, BufferedImage.TYPE_INT_ARGB);