diff --git a/MerchantRPGCSE2102/src/controller/RPGame.java b/MerchantRPGCSE2102/src/controller/RPGame.java index 0e1e3b5..53f67df 100644 --- a/MerchantRPGCSE2102/src/controller/RPGame.java +++ b/MerchantRPGCSE2102/src/controller/RPGame.java @@ -5,16 +5,24 @@ import java.util.ArrayList; import java.util.Scanner; +import model.Merchant; +import model.Player; + public class RPGame { private ArrayList merchantInventoryList1 = new ArrayList(); // merchant 1's inventory list private ArrayList merchantInventoryList2 = new ArrayList(); // merchant 2's inventory list private ArrayList merchantInventoryList3 = new ArrayList(); // merchant 3's inventory list private ArrayList playerInventoryList = new ArrayList(); // the player's inventory list + private Player _player; + private Merchant _merchant1; + private Merchant _merchant2; + private Merchant _merchant3; + private boolean _movement; public RPGame() { //constructor } - + /** * This method scans the inventory.txt file located in src\config. It will read lines of the format and store them in the inventory list member variables * @@ -26,7 +34,7 @@ public void inventoryFromFile() { int currentMerchant = 0; // keeps track of which merchant's inventory the scanner is reading String token = null; String item = null; - + while(fileScanner.hasNextLine()) { // loops as long as there is another line to read token = fileScanner.next(); if (token.equals("merchant")) @@ -37,21 +45,43 @@ public void inventoryFromFile() { merchantInventoryList1.add(item); else if (currentMerchant == 2) merchantInventoryList2.add(item); - else + else if (currentMerchant == 3) merchantInventoryList3.add(item); playerInventoryList.add(item); } if (fileScanner.hasNextLine()) // only advances to the next line if there is one to read fileScanner.nextLine(); } - + } catch (FileNotFoundException e) { // if inventory.txt is deleted or missing System.out.println("Inventory file not found"); e.printStackTrace(); } - + } - + + /** + * Generates all three merchants + * will add them to the map, but function is not written yet + */ + public void buildMerchants() + { + _merchant1 = new Merchant("Merchant 1", 1000, merchantInventoryList1); + _merchant2 = new Merchant("Merchant 2", 1000, merchantInventoryList2); + _merchant3 = new Merchant("Merchant 3", 1000, merchantInventoryList3); + } + + /** + * Generates the player + * @param name Player name + * @param startingCash Amount of cash the player starts with + * @param startingInventory The Player's starting inventory + */ + public void buildPlayer(String name, int startingCash, ArrayList startingInventory) + { + _player = new Player(name, startingCash, startingInventory); + } + /** * This method returns the specified merchant inventory list * @@ -71,8 +101,7 @@ else if (merchantNumber == 3) return null; } } - - + /** * This method returns the player's inventory list * @@ -81,4 +110,72 @@ else if (merchantNumber == 3) public ArrayList getPlayerInventoryList() { return playerInventoryList; } + + /** + * This method will create a new instance of Transaction + * incomplete method + * + * @param player + * @param targetMerchant The merchant that the player is trading with + */ + public void createTransaction(Player player, Merchant targetMerchant) + { + toggleMovement("OFF"); + Transaction newTransaction = new Transaction(player, targetMerchant); + } + + /** + * Toggles the movement on or off based on the input + * @param command either "ON" or "OFF" + */ + public void toggleMovement(String command) + { + if(command.equals("ON")) + _movement = true; + else if(command.equals("OFF")) + _movement = false; + else + System.out.println("Invalid movement toggle command"); + } + + /** + * Returns the player + * @return Returns the player + */ + public Player getPlayer() + { + return _player; + } + + /** + * Returns a merchant based off of the input number + * @param merchantNum The number of the merchant you want + * @return Returns the merchant that you specified + */ + public Merchant getMerchant(int merchantNum) + { + if(merchantNum == 1) + return _merchant1; + else if(merchantNum == 2) + return _merchant2; + else + return _merchant3; + } + + /** + * Main method used to test the GUI components since test classes do not maintain the GUI + * @param args no need for input + */ + public static void main(String[] args) + { + RPGame _rpg = new RPGame(); + _rpg.inventoryFromFile(); + _rpg.buildMerchants(); + ArrayList playerInventory = _rpg.getMerchantInventoryList(1); + playerInventory.addAll(_rpg.getMerchantInventoryList(2)); + playerInventory.addAll(_rpg.getMerchantInventoryList(3)); + _rpg.buildPlayer("test", 500, playerInventory); + _rpg.getPlayer().getItem("armor").increaseQuantity(15); + _rpg.createTransaction(_rpg.getPlayer(), _rpg.getMerchant(1)); + } } diff --git a/MerchantRPGCSE2102/src/controller/Transaction.java b/MerchantRPGCSE2102/src/controller/Transaction.java new file mode 100644 index 0000000..4769e31 --- /dev/null +++ b/MerchantRPGCSE2102/src/controller/Transaction.java @@ -0,0 +1,107 @@ +package controller; + +import view.TransactionUI; +import model.Item; +import model.Merchant; +import model.Player; + +public class Transaction +{ + private Player _player; + private Merchant _targetMerchant; + private TransactionUI _window; + + public Transaction(Player player, Merchant targetMerchant) + { + _player = player; + _targetMerchant = targetMerchant; + _window = new TransactionUI(this); + _window.setVisible(true); + } + + /** + * Will be Transaction class's main method + * incomplete method + */ + public void runTransaction() + { + } + + /** + * This method invokes the related buy methods and checks in the Player and Merchant classes + * + * @param itemName name of the item + * @param amount amount that the player wants to buy + * @return returns true if transaction successful, false otherwise + */ + public boolean actionBuy(String itemName, int amount) + { + if(_player.buy(itemName, _targetMerchant, amount)) + return true; + else + return false; + } + + /** + * This method invokes the related sell methods and checks in the Player and Merchant classes + * + * @param itemName name of the item + * @param amount amount that the player wants to buy + * @return returns true if transaction successful, false otherwise + */ + public boolean actionSell(String itemName, int amount) + { + if(_player.sell(itemName, _targetMerchant, amount)) + return true; + else + return false; + } + + /** + * This method will push a true up to the class calling it + * incomplete method + * @return returns true + */ + public boolean actionCancel() + { + return true; + } + + /** + * Searches the player inventory for the item matching the item name + * @param itemName name of the item + * @return returns the item with the corresponding name + */ + public Item searchPlayerInventory(String itemName) + { + return _player.getItem(itemName); + } + + /** + * Searches the merchant's inventory for the item matching the item name + * @param itemName name of the item + * @return returns item with the corresponding name + */ + public Item searchMerchantInventory(String itemName) + { + return _targetMerchant.getItem(itemName); + } + + /** + * Returns the player in transaction + * @return returns the player + */ + public Player getPlayer() + { + return _player; + } + + /** + * Returns the merchant in transaction + * @return returns the merchant + */ + public Merchant getTargetMerchant() + { + return _targetMerchant; + } +} diff --git a/MerchantRPGCSE2102/src/model/Item.java b/MerchantRPGCSE2102/src/model/Item.java index 7cb3947..0adaca9 100644 --- a/MerchantRPGCSE2102/src/model/Item.java +++ b/MerchantRPGCSE2102/src/model/Item.java @@ -27,6 +27,7 @@ public Item(String itemName, int basePrice, int quantity) // max and min price not specified _maxPrice = 100000; // default max price _minPrice = 0; // default min price + _adjustedPrice = _basePrice; _quantity = quantity; } @@ -50,6 +51,35 @@ else if(calculatedPrice < _minPrice) return _adjustedPrice; } + /** + * This method increases the quantity of the items + * + * @param amount is the amount that the item will be increased by + */ + public void increaseQuantity(int amount) + { + _quantity += amount; + } + + /** + * This method decreases the quantity of the items + * + * @param amount is the amount that the item will be decreased by + */ + public boolean decreaseQuantity(int amount) + { + if(amount > getQuantity()) + { + System.out.println("Player does not have sufficient amount of " + getItemName()); + return false; + } + else + { + _quantity -= amount; + return true; + } + } + /** * Returns the item's name * diff --git a/MerchantRPGCSE2102/src/model/Merchant.java b/MerchantRPGCSE2102/src/model/Merchant.java index d4005ec..17997b5 100644 --- a/MerchantRPGCSE2102/src/model/Merchant.java +++ b/MerchantRPGCSE2102/src/model/Merchant.java @@ -54,7 +54,7 @@ public void refreshCash() } /** - * Adds the specified amount of cash to the merchant's cash amount for the start of a day + * Adds the specified amount of cash to the merchant's maximum allowed cash * @param amount the amount of cash to be added */ public void addCash(int amount) @@ -65,13 +65,14 @@ public void addCash(int amount) /** * Removes the specified amount of cash to the merchant's cash amount for the start of a day * @param amount the amount of cash to be subtracted + * @return the amount of cash the merchant has left or -1 if the merchant did not have sufficient cash */ public int subtractCash(int amount) { if(amount > _currentCash) // if more cash is being subtracted than the merchant has { - System.out.println("Merchant has insufficent cash"); + System.out.println("Merchant has insufficient cash"); return -1; // value of -1 indicates an unsuccessful subtraction } else { _currentCash -= amount; @@ -106,7 +107,7 @@ public void setDailyRandomPercentage(int minPercent, int maxPercent) } /** - * This method searches through the merchant's inventory for the specified item name and returns the corresponding item's price + * This method searches through the merchant's inventory for the specified item name and returns the corresponding item's adjusted price * * @param itemName string containing the name of the item to search for * @return the price of the item @@ -194,7 +195,7 @@ public int getRandomPercent() } /** - * Returns the merchant's item inventorys + * Returns the merchant's item inventory * @return item inventory array */ public Item[] getInventory() diff --git a/MerchantRPGCSE2102/src/model/Player.java b/MerchantRPGCSE2102/src/model/Player.java index 400e4f6..7856a9f 100644 --- a/MerchantRPGCSE2102/src/model/Player.java +++ b/MerchantRPGCSE2102/src/model/Player.java @@ -9,13 +9,11 @@ public class Player private Item[] _playerInventory; // the player's current inventory private int _x, _y; - public Player(String playerName, int startingCash, ArrayList startingInventory) { _name = playerName; _playerCash = startingCash; - if (startingInventory != null) - generatePlayerInventory(startingInventory); + generatePlayerInventory(startingInventory); } /** @@ -44,10 +42,25 @@ private void generatePlayerInventory(ArrayList itemList) * * @param itemName string containing the name of the item to be purchased * @param targetMerchant the merchant who the player is purchasing from + * @param amount the amount of the item that the player is buying + * @return returns true if transaction successful, false otherwise */ - public void buy(String itemName, Merchant targetMerchant) + public boolean buy(String itemName, Merchant targetMerchant, int amount) { + int totalPrice = targetMerchant.getItemPrice(itemName)* amount; //calculates the total price of the items + if(totalPrice > getPlayerCash()) + { + System.out.println("You do not have sufficent cash"); //will output error message if total price is over the player's cash amount + return false; + } + else + { + deductCash(totalPrice); + Item targetItem = getItem(itemName); + targetItem.increaseQuantity(amount); + return true; + } } /** @@ -55,10 +68,45 @@ public void buy(String itemName, Merchant targetMerchant) * * @param itemName string containing the name of the item to be sold * @param targetMerchant the merchant who the player is selling to + * @param amount the amount of the item that the player is selling + * @return returns true if transaction successful, false otherwise + */ + public boolean sell(String itemName, Merchant targetMerchant, int amount) + { + int totalPrice = targetMerchant.getItemPrice(itemName)* amount; //calculates the total price of the items + Item targetItem = getItem(itemName); + + if(targetMerchant.getCurrentCash() >= totalPrice) + { + if(targetItem.decreaseQuantity(amount)) + { + increaseCash(totalPrice); + targetMerchant.subtractCash(amount); + return true; + } + else + return false; + } + else + return false; + } + + /** + * Searches through the player's inventory for the item corresponding to the specified item name + * + * @param itemName string containing the name of the item + * @return the item matching the specified item name */ - public void sell(String itemName, Merchant targetMerchant) + public Item getItem(String itemName) { + for(int i = 0; i < _playerInventory.length; i++) + { + if(_playerInventory[i].getItemName().equals(itemName)) + return _playerInventory[i]; + } + System.out.println("No such item exists"); // item was not found by searching the inventory + return null; } /** @@ -117,20 +165,18 @@ public Item[] getInventory() } public int getX() { - return _x; - } - - public void setX(int x) { - _x = x; - } - - public int getY() { - return _y; - } + return _x; + } - public void setY(int y) { - _y = y; - } + public void setX(int x) { + _x = x; + } + public int getY() { + return _y; + } -} + public void setY(int y) { + _y = y; + } +} \ No newline at end of file diff --git a/MerchantRPGCSE2102/src/tests/TestPlayer.java b/MerchantRPGCSE2102/src/tests/TestPlayer.java index 3fd56da..da54a73 100644 --- a/MerchantRPGCSE2102/src/tests/TestPlayer.java +++ b/MerchantRPGCSE2102/src/tests/TestPlayer.java @@ -2,18 +2,21 @@ import controller.RPGame; import model.Item; +import model.Merchant; import model.Player; import junit.framework.TestCase; public class TestPlayer extends TestCase { private Player p; + private Merchant m; public void setup() { RPGame game = new RPGame(); //starting a new game game.inventoryFromFile(); //read from file p = new Player("TestPlayer", 1000, game.getPlayerInventoryList()); + m = new Merchant("TestMerchant1", 100000, game.getMerchantInventoryList(1)); } //test cash system for Player class @@ -34,4 +37,24 @@ public void testPlayerInventory() { System.out.println(item.getItemName() + " " + item.getQuantity()); } } + + public void testBuy() + { + setup(); + p.buy("water", m, 10); + assertEquals(970, p.getPlayerCash()); + assertEquals(10, p.getItem("water").getQuantity()); + } + + public void testSell() + { + setup(); + testBuy(); + p.sell("water", m, 11); + assertEquals(970, p.getPlayerCash()); + assertEquals(10, p.getItem("water").getQuantity()); + p.sell("water", m, 10); + assertEquals(1000, p.getPlayerCash()); + assertEquals(0, p.getItem("water").getQuantity()); + } } diff --git a/MerchantRPGCSE2102/src/tests/TestTransaction.java b/MerchantRPGCSE2102/src/tests/TestTransaction.java new file mode 100644 index 0000000..c529250 --- /dev/null +++ b/MerchantRPGCSE2102/src/tests/TestTransaction.java @@ -0,0 +1,28 @@ +package tests; + +import java.util.ArrayList; + +import controller.RPGame; +import junit.framework.TestCase; + +public class TestTransaction extends TestCase +{ + private RPGame _rpg; + + public void setup() + { + _rpg = new RPGame(); + _rpg.inventoryFromFile(); + _rpg.buildMerchants(); + ArrayList playerInventory = _rpg.getMerchantInventoryList(1); + playerInventory.addAll(_rpg.getMerchantInventoryList(2)); + playerInventory.addAll(_rpg.getMerchantInventoryList(3)); + _rpg.buildPlayer("test", 500, playerInventory); + } + + public void testActionSell() + { + setup(); + _rpg.createTransaction(_rpg.getPlayer(), _rpg.getMerchant(1)); + } +} diff --git a/MerchantRPGCSE2102/src/view/Test.java b/MerchantRPGCSE2102/src/view/Test.java new file mode 100644 index 0000000..072e852 --- /dev/null +++ b/MerchantRPGCSE2102/src/view/Test.java @@ -0,0 +1,70 @@ +package view; + +import java.awt.BorderLayout; +import java.awt.EventQueue; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; +import javax.swing.JComboBox; +import javax.swing.JTextField; +import javax.swing.JSlider; +import javax.swing.JLabel; +import javax.swing.JButton; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + +public class Test extends JFrame { + + private JPanel contentPane; + private JTextField textField; + + /** + * Launch the application. + */ + public static void main(String[] args) { + EventQueue.invokeLater(new Runnable() { + public void run() { + try { + Test frame = new Test(); + frame.setVisible(true); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + /** + * Create the frame. + */ + public Test() { + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setBounds(100, 100, 400, 400); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + contentPane.setLayout(null); + + JComboBox comboBox = new JComboBox(); + comboBox.setBounds(61, 141, 131, 20); + contentPane.add(comboBox); + + JLabel lblSelectTheItem = new JLabel("Select the Item you want:"); + lblSelectTheItem.setBounds(61, 105, 168, 14); + contentPane.add(lblSelectTheItem); + + JLabel lblSelectTheAmount = new JLabel("Enter the amount you wish to sell:"); + lblSelectTheAmount.setBounds(61, 197, 168, 14); + contentPane.add(lblSelectTheAmount); + + JButton btnAccept = new JButton("Accept"); + btnAccept.setBounds(247, 306, 89, 23); + contentPane.add(btnAccept); + + textField = new JTextField(); + textField.setBounds(61, 238, 86, 20); + contentPane.add(textField); + textField.setColumns(10); + } +} diff --git a/MerchantRPGCSE2102/src/view/TransactionUI.java b/MerchantRPGCSE2102/src/view/TransactionUI.java new file mode 100644 index 0000000..0db30eb --- /dev/null +++ b/MerchantRPGCSE2102/src/view/TransactionUI.java @@ -0,0 +1,205 @@ +package view; + +import java.awt.BorderLayout; +import java.awt.EventQueue; + +import javax.swing.BoxLayout; +import javax.swing.ComboBoxModel; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JSlider; +import javax.swing.border.EmptyBorder; +import javax.swing.JButton; +import javax.swing.JLabel; + +import java.awt.Font; + +import javax.swing.JTextField; + +import controller.Transaction; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + +public class TransactionUI extends JFrame { + + private static final ComboBoxModel[] Item = null; + private JPanel contentPane; + private static Transaction MASTER; //TransactionUI class will hold the instance of the Transaction that created it + + /** + * Launch the application. + */ + public static void main(String[] args) { + EventQueue.invokeLater(new Runnable() { + public void run() { + try { + TransactionUI frame = new TransactionUI(MASTER); + frame.setVisible(true); + } catch (Exception e) { + e.printStackTrace(); + } + } + }); + } + + /** + * Create the frame. + */ + public TransactionUI(Transaction master) { + MASTER = master; + setTitle("Transaction Window"); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + setBounds(100, 100, 600, 430); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + contentPane.setLayout(null); + + JButton btnBuy = new JButton("BUY"); + btnBuy.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + } + }); + btnBuy.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent arg0) { + System.out.println("BUY"); //temporary test code + createBuyWindow(); + } + }); + btnBuy.setBounds(58, 155, 169, 105); + contentPane.add(btnBuy); + + JButton btnSell = new JButton("SELL"); + btnSell.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + System.out.println("SELL"); //temporary test code + createSellWindow(); + } + }); + btnSell.setBounds(351, 155, 169, 105); + contentPane.add(btnSell); + + JButton btnCancel = new JButton("Cancel"); + btnCancel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + System.out.println("Cancel"); //temporary test code + MASTER.actionCancel(); + exitWindow(); + } + }); + btnCancel.setBounds(246, 344, 89, 23); + contentPane.add(btnCancel); + + JLabel lblWouldYouLike = new JLabel("Would you like to:"); + lblWouldYouLike.setFont(new Font("Tahoma", Font.PLAIN, 15)); + lblWouldYouLike.setBounds(233, 76, 193, 32); + contentPane.add(lblWouldYouLike); + + JLabel lblOr = new JLabel("OR"); + lblOr.setFont(new Font("Tahoma", Font.PLAIN, 15)); + lblOr.setBounds(277, 189, 35, 32); + contentPane.add(lblOr); + } + + /** + * Will exit the transaction window + * incomplete method + */ + public void exitWindow() + { + this.dispose(); + } + + /** + * Will create a window for the BUY option + * incomplete method + */ + public static void createBuyWindow() + { + EventQueue.invokeLater(new Runnable() + { + @Override + public void run() + { + JFrame frame = new JFrame("Buy"); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.setBounds(100, 100, 600, 600); + JPanel contentPane = new JPanel(); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + frame.setContentPane(contentPane); + contentPane.setLayout(null); + + frame.setVisible(true); + } + }); + } + + /** + * Will create a window for the SELL option + * incomplete method + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static void createSellWindow() + { + final JFrame frame = new JFrame("Sell"); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.setBounds(100, 100, 600, 600); + JPanel contentPane = new JPanel(); + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + frame.setContentPane(contentPane); + contentPane.setLayout(null); + + String[] itemList = new String[MASTER.getPlayer().getInventory().length]; //create a new array of strings with the length of the player's inventory //item that the player chooses from the combobox + for(int i = 0; i < itemList.length; i++) //adds all the item names to the item list + { + itemList[i] = MASTER.getPlayer().getInventory()[i].getItemName(); + } + + final JComboBox comboBox = new JComboBox(itemList); + comboBox.setBounds(61, 141, 131, 20); + contentPane.add(comboBox); + + final JTextField textField = new JTextField(); + textField.setBounds(61, 238, 86, 20); + contentPane.add(textField); + textField.setColumns(10); + + JLabel lblSelectTheItem = new JLabel("Select the Item you want:"); + lblSelectTheItem.setBounds(61, 105, 168, 14); + contentPane.add(lblSelectTheItem); + + JLabel lblSelectTheAmount = new JLabel("Enter the amount you wish to sell:"); + lblSelectTheAmount.setBounds(61, 197, 168, 14); + contentPane.add(lblSelectTheAmount); + + JButton btnAccept = new JButton("Accept"); + btnAccept.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + String chosenItem = comboBox.getSelectedItem().toString(); + System.out.println(chosenItem); + + try{ + int chosenAmount = Integer.parseInt(textField.getText()); + System.out.println(chosenAmount); + frame.dispose(); + } + catch(NumberFormatException ex){ + System.out.println("Must input a number less than or equal to the total amount of the item that you have"); + } + } + }); + btnAccept.setBounds(247, 306, 89, 23); + contentPane.add(btnAccept); + frame.setVisible(true); + } +}