diff --git a/MerchantRPGCSE2102/rpgclass diagram.mgc b/MerchantRPGCSE2102/rpgclass diagram.mgc new file mode 100644 index 0000000..59536ad --- /dev/null +++ b/MerchantRPGCSE2102/rpgclass diagram.mgc @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/MerchantRPGCSE2102/src/controller/RPGame.java b/MerchantRPGCSE2102/src/controller/RPGame.java index 0e1e3b5..692abff 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,32 +34,54 @@ 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 + + while(fileScanner.hasNextLine()) { // loops as long as there is another line to read token = fileScanner.next(); if (token.equals("merchant")) currentMerchant = fileScanner.nextInt(); else { - item = token + " " + fileScanner.nextInt(); // a string containing the item name and price + item = token + " " + fileScanner.nextInt(); // a string containing the item name and price if (currentMerchant == 1) 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 + 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 + + } 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 which runs independently + * + * @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); + toggleMovement("ON"); + } + + /** + * 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..def3e51 --- /dev/null +++ b/MerchantRPGCSE2102/src/controller/Transaction.java @@ -0,0 +1,109 @@ +package controller; + +import exceptions.NotInInventoryException; +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 + * @throws NotInInventoryException + */ + public boolean actionSell(String itemName, int amount) throws NotInInventoryException + { + 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/exceptions/NotInInventoryException.java b/MerchantRPGCSE2102/src/exceptions/NotInInventoryException.java new file mode 100644 index 0000000..83e5086 --- /dev/null +++ b/MerchantRPGCSE2102/src/exceptions/NotInInventoryException.java @@ -0,0 +1,10 @@ +package exceptions; + +@SuppressWarnings("serial") +public class NotInInventoryException extends Exception +{ + public NotInInventoryException() + { + super(); + } +} diff --git a/MerchantRPGCSE2102/src/graph/Edge.java b/MerchantRPGCSE2102/src/graph/Edge.java new file mode 100644 index 0000000..f560ced --- /dev/null +++ b/MerchantRPGCSE2102/src/graph/Edge.java @@ -0,0 +1,35 @@ +package graph; + + +public class Edge { + private Vertex _v; + private Vertex _w; + + + public Vertex getV() { + return _v; + } + + public void setV(Vertex v) { + _v = v; + } + + public Vertex getW() { + return _w; + } + + public void setW(Vertex w) { + _w = w; + } + + public Vertex opposite(Vertex v) { + if (v == _v) + return _w; + else if (v == _w) + return _v; + return null; + + } + + +} diff --git a/MerchantRPGCSE2102/src/graph/Graph.java b/MerchantRPGCSE2102/src/graph/Graph.java new file mode 100644 index 0000000..1acff8b --- /dev/null +++ b/MerchantRPGCSE2102/src/graph/Graph.java @@ -0,0 +1,79 @@ +package graph; + +public class Graph +{ + private Vertex[] _vertexList; + private int _size; + + public Graph(int size) + { + _size = size; + _vertexList = new Vertex[size*size]; + } + + public void initializeGraph() { + initializeVertices(); + initializeEdges(); + } + + public void initializeVertices() { + for (int row = 0; row < _size; row++) { + for (int col = 0; col < _size; col++) { + int cellNum = row*_size + col; + Vertex v = new Vertex(cellNum, _size); + setVertex(cellNum, v); + } + } + } + + public void initializeEdges() { + for (int row = 0; row < _size; row++) { + for (int col = 0; col < _size; col++) { + + if (row !=0) + connectWithEdge(getVertex(_size*row + col), getVertex(_size*(row - 1) + col)); + + if (col != _size - 1) + connectWithEdge(getVertex(_size*row + col), getVertex(_size*row + col + 1)); + } + } + } + + public void connectWithEdge(Vertex v, Vertex w) { + Edge edge = new Edge(); + v.addEdge(edge); + w.addEdge(edge); + edge.setV(v); + edge.setW(w); + } + + public int getSize() + { + return _size; + } + + public Vertex getVertex(int vertexNum) + { + return _vertexList[vertexNum]; + } + + public void setVertex(int vertexNum, Vertex vertex) { + _vertexList[vertexNum] = vertex; + } + + /** + * Checks if two vertices are adjacent + */ + public boolean areAdjacent(Vertex v, Vertex w) { + for (Edge edge : v.getIncidentList()) { + if (edge.getV() == w || edge.getW() == w) + return true; + } + return false; + } + + public Vertex[] getVertexList() { + return _vertexList; + } + +} diff --git a/MerchantRPGCSE2102/src/graph/Vertex.java b/MerchantRPGCSE2102/src/graph/Vertex.java new file mode 100644 index 0000000..4b69807 --- /dev/null +++ b/MerchantRPGCSE2102/src/graph/Vertex.java @@ -0,0 +1,53 @@ +package graph; + +import java.util.LinkedList; + +public class Vertex +{ + private int _cellNum; + private int _row; + private int _col; + private Object _occupant = null; + private LinkedList _incidentEdges = new LinkedList(); + + + public Vertex(int cellNum, int n) { + _cellNum = cellNum; + _row = 0; + int temp = _cellNum; + while (temp - n >= 0) { // Calculates the row of the vertex + temp = temp - n; + _row++; + } + _col = _cellNum - _row*n; // Calculates the column of the vertex + } + + public void addEdge(Edge edge) { + _incidentEdges.add(edge); + } + + public int getCellNum() { + return _cellNum; + } + + public int getRow() { + return _row; + } + + public int getCol() { + return _col; + } + + public LinkedList getIncidentList() { + return _incidentEdges; + } + + public Object getOccupant() { + return _occupant; + } + + public void setOccupant(Object occupant) { + _occupant = occupant; + } + +} 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/Map.java b/MerchantRPGCSE2102/src/model/Map.java new file mode 100644 index 0000000..7c61a0b --- /dev/null +++ b/MerchantRPGCSE2102/src/model/Map.java @@ -0,0 +1,110 @@ +package model; + +import graph.Graph; + +public class Map { + + private Graph _mapGraph; // Graph representation of the map + private int _mapSize; // The n*n dimension of the map + + public Map(int size) { + _mapSize = size; + _mapGraph = new Graph(_mapSize); + _mapGraph.initializeGraph(); + } + + /** + * This method stores the sepcified instance of Player at the specified position on the map + * @param player The player to be initialized + * @param x The x coordinate of the player's location + * @param y The y coordinate of the player's location + */ + public void initializePlayer(Player player, int x, int y) { + int vertexNum = y*_mapSize + x; + player.setX(x); + player.setY(y); + _mapGraph.getVertex(vertexNum).setOccupant(player); + } + + /** + * This method stores the sepcified instance of Merchant at the specified position on the map + * @param player The merchant to be initialized + * @param x The x coordinate of the merchant's location + * @param y The y coordinate of the merchant's location + */ + public void initializeMerchant(Merchant merchant, int x, int y) { + int vertexNum = y*_mapSize + x; + merchant.setX(x); + merchant.setY(y); + _mapGraph.getVertex(vertexNum).setOccupant(merchant); + } + + /** + * Moves the specified instance of Player in the specified direction on the map + * @param player The player to be moved + * @param String The direction to be moved (north, west, east, or south) + */ + public void movePlayer(Player player, String direction) { + int currentX = player.getX(); + int currentY = player.getY(); + + if (direction.equals("north")) { + if (currentY != 0) { + if (!isOccupied(currentX, currentY - 1)) { + _mapGraph.getVertex(currentY*_mapSize + currentX).setOccupant(null); + _mapGraph.getVertex((currentY - 1)*_mapSize + currentX).setOccupant(player); + player.setY(currentY - 1); + } + } + } + + if (direction.equals("east")) { + if (currentX != _mapSize - 1) { + if (!isOccupied(currentX + 1, currentY)) { + _mapGraph.getVertex(currentY*_mapSize + currentX).setOccupant(null); + _mapGraph.getVertex(currentY*_mapSize + (currentX + 1)).setOccupant(player); + player.setX(currentX + 1); + } + } + } + + if (direction.equals("south")) { + if (currentY != _mapSize - 1) { + if (!isOccupied(currentX, currentY + 1)) { + _mapGraph.getVertex(currentY*_mapSize + currentX).setOccupant(null); + _mapGraph.getVertex((currentY + 1)*_mapSize + currentX).setOccupant(player); + player.setY(currentY + 1); + } + } + } + + if (direction.equals("west")) { + if (currentX != 0) { + if (!isOccupied(currentX - 1, currentY)) { + _mapGraph.getVertex(currentY*_mapSize + currentX).setOccupant(null); + _mapGraph.getVertex(currentY*_mapSize + (currentX - 1)).setOccupant(player); + player.setX(currentX - 1); + } + } + } + } + + /** + * Returns the graph representation of the map + * @return graph + */ + public Graph getGraph() { + return _mapGraph; + } + + /** + * Checks if a location on the map is occupied by a merchant or player + * @param x x coordinate to check + * @param y y coordinate to check + * @return Boolean value + */ + public boolean isOccupied(int x, int y) { + return _mapGraph.getVertex(y*_mapSize + x).getOccupant() != null; + } + +} diff --git a/MerchantRPGCSE2102/src/model/Merchant.java b/MerchantRPGCSE2102/src/model/Merchant.java index 9bab251..17997b5 100644 --- a/MerchantRPGCSE2102/src/model/Merchant.java +++ b/MerchantRPGCSE2102/src/model/Merchant.java @@ -10,6 +10,7 @@ public class Merchant private int _baseCash; private int _dailyRandomPercent; private Item[] _merchantInventory; + private int _x, _y; public Merchant(String name, int cashLimit, ArrayList inventory) @@ -17,7 +18,8 @@ public Merchant(String name, int cashLimit, ArrayList inventory) _name = name; _currentCash = cashLimit; _baseCash = cashLimit; - generateMerchantInventory(inventory); + if (inventory != null) + generateMerchantInventory(inventory); _dailyRandomPercent = 0; //placeholder percentage } @@ -52,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) @@ -63,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; @@ -104,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 @@ -192,11 +195,27 @@ public int getRandomPercent() } /** - * Returns the merchant's item inventorys + * Returns the merchant's item inventory * @return item inventory array */ public Item[] getInventory() { return _merchantInventory; } + + public int getX() { + return _x; + } + + public void setX(int x) { + _x = x; + } + + public int getY() { + return _y; + } + + public void setY(int y) { + _y = y; + } } diff --git a/MerchantRPGCSE2102/src/model/Player.java b/MerchantRPGCSE2102/src/model/Player.java index b31793a..1cf4ea0 100644 --- a/MerchantRPGCSE2102/src/model/Player.java +++ b/MerchantRPGCSE2102/src/model/Player.java @@ -2,20 +2,22 @@ import java.util.ArrayList; +import exceptions.NotInInventoryException; + public class Player { private String _name; // player's name private int _playerCash; // current amount of cash the player has private Item[] _playerInventory; // the player's current inventory - - + private int _x, _y; + public Player(String playerName, int startingCash, ArrayList startingInventory) { _name = playerName; _playerCash = startingCash; generatePlayerInventory(startingInventory); } - + /** * Read's the player's item list provided by RPGame and store's instances of each item into the player's inventory * @@ -36,27 +38,84 @@ private void generatePlayerInventory(ArrayList itemList) _playerInventory[i] = new Item(name, Integer.parseInt(price), 0); // stores a new instance of the item in the player's inventory (quantity begins at 0) } } - + /** * Allows player to buy an item from a target merchant * * @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; + } } - + /** * Allows player to sell an item to a target merchant * * @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 + * @throws NotInInventoryException */ - public void sell(String itemName, Merchant targetMerchant) + public boolean sell(String itemName, Merchant targetMerchant, int amount) throws NotInInventoryException { + int totalPrice = targetMerchant.getItemPrice(itemName)* amount; //calculates the total price of the items + + if(totalPrice == -1 * amount) + { + throw new NotInInventoryException(); //returns false if the merchant does not buy that item + } + 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 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; } /** @@ -73,7 +132,7 @@ public void deductCash(int deductAmount) else _playerCash -= deductAmount; } - + /** * Increase's the player's cash by the specified amount * @@ -83,7 +142,7 @@ public void increaseCash(int increaseAmount) { _playerCash += increaseAmount; } - + /** * Returns a string containing the player's name * @@ -93,7 +152,7 @@ public String getName() { return _name; } - + /** * Returns the current amount of cash the player has * @@ -103,7 +162,7 @@ public int getPlayerCash() { return _playerCash; } - + /** * Returns the player's current inventory * @@ -113,4 +172,20 @@ public Item[] getInventory() { return _playerInventory; } -} + + public int getX() { + return _x; + } + + 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/TestMap.java b/MerchantRPGCSE2102/src/tests/TestMap.java new file mode 100644 index 0000000..4560aa1 --- /dev/null +++ b/MerchantRPGCSE2102/src/tests/TestMap.java @@ -0,0 +1,71 @@ +package tests; + +import graph.Graph; +import graph.Vertex; +import graph.Edge; +import model.Map; +import model.Merchant; +import model.Player; +import static org.junit.Assert.*; + +import org.junit.Test; + +public class TestMap { + + Map map; + + @Test + public void test() { + setup(); + testMapInit(); + testOccupancy(); + testMovePlayer(); + } + + public void setup() { + map = new Map(4); + } + + public void testMapInit() { + Graph graph = map.getGraph(); + for (Vertex v : graph.getVertexList()) { + System.out.print("Vertex " + v.getCellNum() + " is adjacent with "); + for (Edge edge : v.getIncidentList()) + System.out.print(edge.opposite(v).getCellNum() + " "); + System.out.println(); + } + } + + public void testOccupancy() { + for (Vertex v : map.getGraph().getVertexList()) { + assertEquals(v.getOccupant(), null); + } + } + + public void testMovePlayer() { + Player player = new Player("TestPlayer", 0, null); + Merchant merchant = new Merchant("TestMerchant", 0, null); + map.initializePlayer(player, 3, 3); + map.initializeMerchant(merchant, 0, 2); + map.movePlayer(player, "west"); + map.movePlayer(player, "south"); + map.movePlayer(player, "north"); + map.movePlayer(player, "east"); + map.movePlayer(player, "east"); + map.movePlayer(player, "north"); + map.movePlayer(player, "north"); + map.movePlayer(player, "north"); + map.movePlayer(player, "west"); + map.movePlayer(player, "west"); + map.movePlayer(player, "west"); + map.movePlayer(player, "west"); + map.movePlayer(player, "south"); + map.movePlayer(player, "south"); + map.movePlayer(player, "south"); + map.movePlayer(player, "south"); + assertEquals(player.getX(), 0); + assertEquals(player.getY(), 1); + assertEquals(map.isOccupied(player.getX(), player.getY()), true); + } + +} diff --git a/MerchantRPGCSE2102/src/tests/TestPlayer.java b/MerchantRPGCSE2102/src/tests/TestPlayer.java index 1f77d92..f1e424a 100644 --- a/MerchantRPGCSE2102/src/tests/TestPlayer.java +++ b/MerchantRPGCSE2102/src/tests/TestPlayer.java @@ -1,19 +1,23 @@ package tests; import controller.RPGame; +import exceptions.NotInInventoryException; 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 @@ -27,10 +31,31 @@ public void testPlayerCashSystem() } public void testPlayerInventory() { + // tests that the player is able to load their inventory which the RPGame read from the text file setup(); Item[] inventory = p.getInventory(); for (Item item : inventory) { 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() throws NotInInventoryException + { + 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/TestRPGame.java b/MerchantRPGCSE2102/src/tests/TestRPGame.java index 0bc5f45..7c56296 100644 --- a/MerchantRPGCSE2102/src/tests/TestRPGame.java +++ b/MerchantRPGCSE2102/src/tests/TestRPGame.java @@ -14,6 +14,7 @@ public void setup() public void testFile() { + // tests that the RPGame is able to read from the text file correctly setup(); game.inventoryFromFile(); assertEquals("water 3", game.getMerchantInventoryList(1).get(0)); 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/TransactionUI.java b/MerchantRPGCSE2102/src/view/TransactionUI.java new file mode 100644 index 0000000..8d1be0e --- /dev/null +++ b/MerchantRPGCSE2102/src/view/TransactionUI.java @@ -0,0 +1,303 @@ +package view; + +import java.awt.EventQueue; + +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JRootPane; +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 exceptions.NotInInventoryException; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + +@SuppressWarnings("serial") +public class TransactionUI extends JFrame { + + private JPanel contentPane; + private static Transaction MASTER; //TransactionUI class will hold the instance of the Transaction that created it + private static boolean _inTransaction; //Prevents the user from making multiple transaction windows + + /** + * 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; + _inTransaction = false; + 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"); //creates a "Buy" button + 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 + if(!_inTransaction) //checks if there is another transaction window open if not, then creates a buy transaction window + createBuyWindow(); + } + }); + btnBuy.setBounds(58, 155, 169, 105); + contentPane.add(btnBuy); + + JButton btnSell = new JButton("SELL"); //creates a "Sell" button + btnSell.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + System.out.println("SELL"); //temporary test code + if(!_inTransaction) //checks if there is another transaction window open, if not creates a sell transaction window + createSellWindow(); + } + }); + btnSell.setBounds(351, 155, 169, 105); + contentPane.add(btnSell); + + JButton btnCancel = new JButton("End Transaction"); //creates a button to end the transaction + btnCancel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + System.out.println("Cancel"); //temporary test code + if(!_inTransaction) + { + MASTER.actionCancel(); + exitWindow(); //Will end the transaction main screen but only if player does not have another transaction screen open + } + } + }); + btnCancel.setBounds(210, 310, 160, 50); + 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() + { + _inTransaction = true; //does not allow new transaction windows to be opened while buy window is + final JFrame frame = new JFrame("Buy"); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.setBounds(100, 100, 400, 400); + frame.setUndecorated(true); + frame.getRootPane().setWindowDecorationStyle(JRootPane.NONE); + 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.getTargetMerchant().getInventory().length]; //create a new array of strings with the length of the player's inventory + for(int i = 0; i < itemList.length; i++) //adds all the item names to the item list + { + itemList[i] = MASTER.getTargetMerchant().getInventory()[i].getItemName(); + itemList[i] = itemList[i] + " ($" + MASTER.getTargetMerchant().getInventory()[i].getAdjustedPrice() + ")"; + } + + JLabel lblYouHave = new JLabel("You have: $" + MASTER.getPlayer().getPlayerCash()); + lblYouHave.setBounds(61, 27, 86, 14); + contentPane.add(lblYouHave); + + @SuppressWarnings({ "rawtypes", "unchecked" }) + final JComboBox comboBox = new JComboBox(itemList); //create a drop-down menu for the player to choose from + comboBox.setBounds(61, 141, 131, 20); + contentPane.add(comboBox); + + final JTextField textField = new JTextField(); //create a text field for the player to enter the amount desired into + textField.setBounds(61, 238, 86, 20); + contentPane.add(textField); + textField.setColumns(10); + + JLabel lblSelectTheItem = new JLabel("Select the Item you want:"); //label containing instructions + lblSelectTheItem.setBounds(61, 105, 168, 14); + contentPane.add(lblSelectTheItem); + + JLabel lblSelectTheAmount = new JLabel("Enter the amount you wish to buy:"); //label containing instructions + lblSelectTheAmount.setBounds(61, 197, 275, 30); + contentPane.add(lblSelectTheAmount); + + JButton btnCancel = new JButton("Cancel"); //cancel button, re-enables the player's ability to call new transaction windows + btnCancel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent arg0) { + _inTransaction = false; + frame.dispose(); + } + }); + btnCancel.setBounds(61, 306, 89, 23); + contentPane.add(btnCancel); + + JButton btnAccept = new JButton("Accept"); //create an accept button to consume the information the player entered into the menu and text field + btnAccept.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { //information is consumed when player clicks the accept button + String chosenItem = comboBox.getSelectedItem().toString().split(" ")[0]; //consumes the String name of the item from drop-down menu + System.out.println(chosenItem); + + try{ //will attempt to parse the number player entered, will stay on the same screen if it cannot + int chosenAmount = Integer.parseInt(textField.getText()); + if(MASTER.actionBuy(chosenItem, chosenAmount)) //will attempt to buy the specified amount of the chosen item + { + System.out.println(chosenAmount); + _inTransaction = false; + frame.dispose(); + } + else + throw new NumberFormatException(); //will throw a NumberFormatException if actionBuy returns a false + } + catch(NumberFormatException exception){ + System.out.println("Must input an amount that you can afford"); + } + } + }); + btnAccept.setBounds(247, 306, 89, 23); + contentPane.add(btnAccept); + frame.setVisible(true); + } + + /** + * Will create a window for the SELL option + * INCOMPLETE METHOD: Still needs to integrate with the transaction limit in the daily cycle + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static void createSellWindow() + { + _inTransaction = true; //does not allow new transaction windows to be opened if sell window is + final JFrame frame = new JFrame("Sell"); + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + frame.setBounds(100, 100, 400, 400); + frame.setUndecorated(true); + frame.getRootPane().setWindowDecorationStyle(JRootPane.NONE); + 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(); + itemList[i] = itemList[i] + " (x" + MASTER.getPlayer().getInventory()[i].getQuantity() + ")"; + } + + JLabel lblYouHave = new JLabel(MASTER.getTargetMerchant().getName() + " has: $" + MASTER.getTargetMerchant().getCurrentCash()); + lblYouHave.setBounds(61, 27, 299, 14); + contentPane.add(lblYouHave); + + final JComboBox comboBox = new JComboBox(itemList); //create a drop-down menu for the player to choose from + comboBox.setBounds(61, 141, 131, 20); + contentPane.add(comboBox); + + final JTextField textField = new JTextField(); //create a text field for the player to enter the amount desired into + textField.setBounds(61, 238, 86, 20); + contentPane.add(textField); + textField.setColumns(10); + + JLabel lblSelectTheItem = new JLabel("Select the Item you want:"); //label containing instructions + lblSelectTheItem.setBounds(61, 105, 168, 14); + contentPane.add(lblSelectTheItem); + + JLabel lblSelectTheAmount = new JLabel("Enter the amount you wish to sell:"); //label containing instructions + lblSelectTheAmount.setBounds(61, 197, 275, 30); + contentPane.add(lblSelectTheAmount); + + JButton btnCancel = new JButton("Cancel"); //cancel button, re-enables the player's ability to call new transaction windows + btnCancel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent arg0) { + _inTransaction = false; + frame.dispose(); + } + }); + btnCancel.setBounds(61, 306, 89, 23); + contentPane.add(btnCancel); + + JButton btnAccept = new JButton("Accept"); //create an accept button to consume the information the player entered into the menu and text field + btnAccept.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { //information is consumed when player clicks the accept button + String chosenItem = comboBox.getSelectedItem().toString().split(" ")[0]; //consumes the String name of the item from drop-down menu + System.out.println(chosenItem); + boolean isGood = false; + + try{ + try{ //will attempt to parse the number player entered, will stay on the same screen if it cannot + int chosenAmount = Integer.parseInt(textField.getText()); + isGood = MASTER.actionSell(chosenItem, chosenAmount); //checks if the merchant will buy that item + if(isGood) //will attempt to sell the specified amount of the chosen item + { + System.out.println(chosenAmount); + _inTransaction = false; + frame.dispose(); + } + else + throw new NumberFormatException(); //will throw a NumberFormatException if actionSell returns a false + } + catch(NumberFormatException exception){ + System.out.println("Must input a number less than or equal to the total amount of the item that you have"); + } + } + catch(NotInInventoryException niiexception){ + System.out.println("Merchant does not accept that item");; + } + } + }); + btnAccept.setBounds(247, 306, 89, 23); + contentPane.add(btnAccept); + frame.setVisible(true); + } +}