Minecraft Spigot Remove item from inventory - java

I'm making a bedwars plugin in spigot 1.8_R3, I'm currently working on the shop system, when you click on an item to purchase it, 4 iron ingots should be removed from the players inventory.
inventory.remove(new ItemStack(getResource(Main.plugin.getConfigValue("shop." + e.getCurrentItem().getTypeId() + ".type")), Integer.parseInt(Main.plugin.getConfigValue("shop." + e.getCurrentItem().getTypeId() + ".cost"))));
However, this code only removes the iron if there are exactly 4 iron ingots. How would I make it so 4 iron ingots would be removed from different amounts such as 5?
Edit :
I tried to use this code :
public void removeItemFromInventory(Inventory inv, ItemStack currentItem, Player p) {
ItemStack item = new ItemStack(getResource(Main.plugin.getConfigValue("shop." + currentItem.getTypeId() + ".type")), Integer.parseInt(Main.plugin.getConfigValue("shop." + currentItem.getTypeId() + ".cost")));
if(inv.contains(item)) { // contains the exact item
inv.remove(item); // remove first time it find this item
} else { // doesn't contains this item
for(ItemStack invItem : inv.getContents()) {
if(invItem.getType().equals(item.getType())) { // if it's this type of item.
// You can add other check specially for ItemMeta ...
int amount = invItem.getAmount(); // amount of actual item
int stay = item.getAmount(); // keep amount
if(amount > stay) { // too many item, just change amount
invItem.setAmount(amount - stay); // change amount to remove it
break; // stop loop
} else if(amount < stay) { // not enough item
invItem.setAmount(0); // you can also remove the item by setting air to this slot
item.setAmount(stay - amount); // reduce amount of item to delete
}
}
}
}
FastShop shop = new FastShop(p );
p.closeInventory();
p.openInventory(shop.getInventory());
}
I'm currently getting a nullpointer error. I'm still need of help!

This part of code will search an item similar to "Iron Ingot x4". If it's not similar, it doesn't change what is it because it's just different.
You should do like that :
ItemStack item = new ItemStack(getResource(Main.plugin.getConfigValue("shop." + e.getCurrentItem().getTypeId() + ".type")), Integer.parseInt(Main.plugin.getConfigValue("shop." + e.getCurrentItem().getTypeId() + ".cost")));
if(inv.contains(item)) { // contains the exact item
inv.remove(item); // remove first time it find this item
} else { // doesn't contains this item
for(ItemStack invItem : inv.getContents()) {
if(invItem != null && invItem.getType().equals(item.getType()) { // if it's this type of item.
// You can add other check specially for ItemMeta ...
int amount = invItem.getAmount(); // amount of actual item
int stay = item.getAmount(); // keep amount
if(amount > stay) { // too many item, just change amount
invItem.setAmount(amount - stay); // change amount to remove it
break; // stop loop
} else if(amount < stay) { // not enough item
invItem.setAmount(0); // you can also remove the item by setting air to this slot
item.setAmount(stay - amount); // reduce amount of item to delete
}
}
}
}
player.updateInventory();

This isn't exactly a full solution with code. However, you can do this.
Create an integer for the amount of iron required.
Create a for loop that iterates through a players inventory and if that slot contains iron then:
if the amount in the slot is greater than the iron integer, remove the iron
integer from that slot and give the item that is owed. else remove the amount in the slot from the iron integer and delete that slot.
I hope you can solve your issue from this.

Related

Option menu that increases and decreases with number of arraylist objects

I've created a for loop that lists all objects in my array-list but i need it to be a dynamic option menu that always ends with exit. I have used switch case option menu in other parts of the program in different methods. But I'm not sure how to create an incrementing case switch in here or if it would have to be put into the for loop?
private static void subCar(Scanner keyboard, CarLot carLot) {
if (carLot.getCar().size() == 0) {
System.out.println("No Cars on the Car Lot to Remove");
}else {
System.out.println("");
System.out.println("Cars Available to Remove: ");
System.out.printf("%-7s%-6s%-35s%-5s\n","Option"," ID","Make/Model/Year","Price");
for (int index=0; index < carLot.getCar().size(); index++) {
System.out.printf("%-7s%-6s%-2s%-5s\n",carLot.getCar().get(index).getID(),
carLot.getCar().get(index).getMake(),carLot.getCar().get(index).getModel(),
carLot.getCar().get(index).getPrice());
}
}
}
I'm trying to create a menu option so I can select which object to delete from my array-list
I want the output to look like this:
option ID Make/Model/Year Price
1. 2 Chevrolet cavalier 2000 1999.99
2. Exit
enter option:
exit option needs to always come last
Your last option will always be bigger then size of list of cars.
int option = //read it form scanner;
if (option > carLot.getCar().size()) {
// exit
} else {
carLot.getCar().remove(option);
}
To print all options and an exit one. You need to extract index outside the loop, loop and one print after loop. One of the example:
int index = 0;
for (; index < carLot.getCar().size(); index++) {
System.out.printf("%-7s%-6s%-2s%-5s\n",
index,
carLot.getCar().get(index).getID(),
carLot.getCar().get(index).getMake() + " " + carLot.getCar().get(index).getModel(),
carLot.getCar().get(index).getPrice());
}
System.out.printf("%-7s%-6s", index, "Exit");

If else statement inside for loop trouble with Hashmaps

Basically I am having trouble with my if statement. I would like it to say "No CDs found for " + val, however this is the output I am getting:
Welcome to the CD Database
Enter search, add, name, list, or quit:
name
Enter the full or partial name:
asdfa
Enter search, add, name, list, or quit:
as you can see it is not returning anything.
my code:
public void printByName(String val) {
int i = 0;
for (CompactDisc values : database.values()) {
if (values.getArtist().contains(val)) {
System.out.println(values);
} else if (i > database.size() && !values.getArtist().contains(val)) {
System.out.println("No CDs found for " + val);
}
i++;
}
}
for some reason my counter is not iterating and this has been driving me crazy for hours.I want it to say no CDs found after it loops through the hashmap and does not find a partial match of the string the user entered
additional output:
Welcome to the CD Database
Enter search, add, name, list, or quit:
name
Enter the full or partial name:
Mo
Artist:Modest Mouse Title:We Were Dead Before the Ship Even Sank price:5.99
Artist:Thelonious Monk Title:Monk's Dream price:5.99
Enter search, add, name, list, or quit:
list
Artist:Isley Brothers Title:Funky Family price:5.99
Artist:Muddy Waters Title:At Newport price:6.99
Artist:Sly & The Family Stone Title:Greatest Hits price:6.99
Artist:Modest Mouse Title:We Were Dead Before the Ship Even Sank price:5.99
Artist:St. Germain Title:Tourist price:5.99
Artist:Bob Dylan Title:Desire price:6.99
Artist:The Beatles Title:Abbey Road price:6.99
Artist:Los Straitjackets Title:The Velvet Touch of... price:5.99
Artist:The Velvet Underground Title:Peel Slowly and See price:6.99
Artist:Thelonious Monk Title:Monk's Dream price:5.99
Enter search, add, name, list, or quit:
quit
Program ending.
The condition i > database.size() will never be true because the loop will exit before i reaches the database size. Try changing your code to this:
public void printByName(String val) {
for (CompactDisc values : database.values()) {
if (values.getArtist().contains(val)) {
System.out.println(values);
} else {
System.out.println("No CDs found for " + val);
}
}
}
There is a problem in your logic structure.
Your 'if' is inside your "loop" block. It must be outside. Take a look:
public void printByName(String val) {
int i = 0;
for (CompactDisc values : database.values()) {
if (values.getArtist().contains(val)) {
System.out.println(values);
i++;
}
}
if (i==0) {
System.out.println("No CDs found for " + val);
}
}
It should be else if (i >= database.size() && !values.getArtist().contains(val))for the reason stated above.

Java: Continuing iteration through an arraylist only when the right menu item is selected

I'm trying to create a console app that iterates through an arrayList of meal ideas every time the correct menu item is selected. The problem is that I can't seem to continue the iteration every time the correct menu item is selected, it just restarts the loop.
Scanner in = new Scanner(System.in);
ArrayList<String> meals = new ArrayList<String>();
meals.add("pasta");
meals.add("potatoes");
meals.add("pork");
String select = "";
while(!select.equals("q")){
System.out.println("What would you like to do?");
System.out.println("\t 1. See next suggestion.");
System.out.println("\t 2. <Another option>");
System.out.println("\t 3. <Another option>");
select = in.next();
switch(select){
case "1":
//Here's where the problem is:
int nextIdea = 0;
while(){
System.out.println("\tToday: " + meals.get(nextIdea));
nextIdea++;
break;
}
System.in.read();
break;
}
}
After the user selects to show the daily selection, the first item in the list should be displayed then it should go back to the "What would you like to do menu" then next time the user selects option 1 in the menu it should display the next item in the menu but instead it restarts the loop. I understand it's because the counter variable ("nextIdea") is set to zero every time before the loop executes but how can I get it to remember which arrayList index number was last used and then use that next time the user selects to see the daily meal. The list should only reset to 0 once it's gone through all the items in the list.
Any help would be appreciated, thank you!!
You need to move the nextIdea index out of the first loop. Then you also don't have to iterate the list when the user selects "See next suggestion." - You just display the next idea:
int nextIdea = 0;
while(!select.equals("q")){
System.out.println("What would you like to do?");
System.out.println("\t 1. See next suggestion.");
System.out.println("\t 2. <Another option>");
System.out.println("\t 3. <Another option>");
select = in.next();
switch(select){
case "1":
System.out.println("\tToday: " + meals.get(nextIdea));
nextIdea++;
System.in.read();
break;
}
}
So, basically, you don't need the inner loop to iterate over the meal ideas. You already do the iteration with the outside loop: Every time the user selects menu item #1, you show her the next idea.
You should also make sure that nextIdea is always a valid index in the array list. Something like:
case "1":
if(nextIdea >= meals.size()) {
nextIdea = 0;
}
System.out.println("\tToday: " + meals.get(nextIdea));
nextIdea++;
System.in.read();
break;
Firstly, instantiate nextIdea outside of the while loop like you have mentioned.
Then, includ a simple if statement which checks if the nextIdea has reached the end, like so:
while(true)
{
if (nextIdea < meals.size())
{
System.out.println("\tToday: " + meals.get(nextIdea));
nextIdea++;
}
else
{
nextIdea = 0;
}
break;
}
You didn't have a condition in the while loop, so I'm assuming you meant 'true' which means it'll run infinitely until broken out of.
Although, technically, the loop here isn't really doing anything as it just runs once and breaks out, so you can just get rid of it like so:
if (nextIdea < meals.size())
{
System.out.println("\tToday: " + meals.get(nextIdea));
nextIdea++;
}
else
{
nextIdea = 0;
}
I think you need to think carefully about what it is you actually want to achieve and what the best way to do this is.
Feel free to ask my further questions.

I'm trying to solve the "knapsack" problem using Java and recursion

This is for a school assignment and the professor stipulates that recursion must be used, and it must take a single line input in a gui box where the first number is the max capacity (weight) the knapsack can hold and the rest are item weights. This doesn't include the value, just weight.
It is partially working, as it is following the tree properly and indicating how many solutions there are (via debugging output) but I am having trouble being able to record the valid solutions. It seems to work fine on returns from recursive calls when at the ends of the branches due to storing and removing the items from the sack[] array.
As far as I can tell from stepping through the code a million times is that it fails when returning somewhere else. This leaves stray items sitting in the sack that shouldn't be there. Hopefully someone will be able to see where I am doing something dumb and help me go in the correct direction. I have deleted and rewritten the code in this so many times that I am about to throw my computer out of a window. lol
I know this is a lot, but I couldn't think of how to properly describe what I am having trouble with other than just posting the entire program. Thanks in advance for any help anyone might be able to provide.
import javax.swing.*;
import java.util.Arrays;
// Main Program
class n00868494 {
static int itemCount = 0; // total number of items
static int pos = 0; // position indicator in the "sack" array
static int sack[] = new int[25]; // sack to hold items on right branches
public static void main(String[] args) {
String sinput[] = new String[25]; // temp string array to hold parameters before converting to integers
int items[] = new int[25]; // array to hold the items
int capacity = 0; // knapsack capacity
String s = null; // temp string to hold user input
while (true) { // infinite loop
// Use a JOptionPane dialog to get the user's input
s = JOptionPane.showInputDialog(new JFrame("Input Params"), "Please enter total weight, followed a list of item weights)","Run Parameters",JOptionPane.QUESTION_MESSAGE);
if ((s == null) || (s.equals(""))) { // user pressed X, cancel or left it blank.
System.exit(0); // exit cleanly
}
sinput = s.split(" "); // split the parameters on the whitespace
for (int i = 0; i < sinput.length; i++) { // iterate through the array and copy the elements to the correct variables
if (i == 0) {
capacity = Integer.parseInt(sinput[i], 10); // knapsack weight in the first position
} else {
items[i-1] = Integer.parseInt(sinput[i], 10); // the rest are item weights
}
}
items = Arrays.copyOfRange(items, 0, sinput.length - 1); // truncate the items array to remove empty elements at the end
knapSack(capacity, items); // call the knapsack method that will in turn call the recursive function
}
}
public static void knapSack(int capacity, int[] items) {
itemCount = items.length; // keep track of original number of items
recknapSack(capacity, items, 0); // start recursive calls
}
/*
recursive knapsack method: called repeatedly to find the correct combinations of items such that their weights
total to the max capacity that the knapsack can hold
capacity: knapsack capacity
items: array of items (weights)
branch: flag indicating whether the call is a left branch (item not included) or right branch (item included)
0 - initial call, non recursive
1 - left branch, weight not included
2 - right branch, weight included
*/
public static void recknapSack(int capacity, int[] items, int branch) {
System.out.print("\nCap: " + capacity + " Items: " + Arrays.toString(items)); // recursive call tracking debugging
if (capacity == 0){ // debugging - for breaking at certain points in the tree
assert Boolean.TRUE; // set breakpoint on this line
}
// base cases - ends of the branches
if (capacity == 0){ // sack is exactly full, item weights = total weight
System.out.print("\t -> good tree"); // debugging
//JOptionPane.showMessageDialog(new JFrame("Results"), "The valid combinations are: ");
Arrays.fill(sack, 0); // clear the sack, this was a successful branch, will start again for another solution
return;
} else if (capacity < 0) { // bag overloaded
System.out.print("\t -> overload tree"); // debugging
if (branch == 2) // if this is an "included" branch
sack[--pos] = 0; // remove the last item placed in the sack
return;
} else if (items.length == 0){ // out of items and/or capacity not reached
System.out.print("\t -> empty src tree"); // debugging
if (branch == 2)
sack[--pos] = 0;
return;
} else {
int firstItem; // this the first item, it will either be discarded (not included) or placed in the sack array (included)
firstItem = items[0];
items = Arrays.copyOfRange(items, 1, items.length); // for either recursive branch: remove the first item from the list
recknapSack(capacity, items, 1); // call recursive function, left branch, where item is discarded and not placed in sack
// prepare for right branch, where item is placed in sack
capacity -= firstItem; // subtract the left most item weight from from capacity
sack[pos++] = firstItem; // place the item in the sack
recknapSack(capacity, items, 2); // recursive right branch call, item is placed in sack, weight subtracted from capacity
}
return;
}
}
What is happening in your code is that when it gets to the last else statement, it is not removing the initial value that was put in. I made a small change to your code that may get you the results you are looking for. First, I had the recursive function return an int, which would be the capacity:
public static int recknapSack(int capacity, int[] items, int branch) {
I changed every return statement to:
return capacity;
Then inside of the else statement, I added the following:
else {
int firstItem; // this the first item, it will either be discarded (not included) or placed in the sack array (included)
firstItem = items[0];
items = Arrays.copyOfRange(items, 1, items.length); // for either recursive branch: remove the first item from the list
recknapSack(capacity, items, 1); // call recursive function, left branch, where item is discarded and not placed in sack
// prepare for right branch, where item is placed in sack
capacity -= firstItem; // subtract the left most item weight from from capacity
int temp = pos;
sack[pos++] = firstItem; // place the item in the sack
System.out.println("First item " + firstItem);
int ret = recknapSack(capacity, items, 2); // recursive right branch call, item is placed in sack, weight subtracted from capacity
if(ret != 0)
{
System.out.println("Removing " + sack[temp] + " at position " + (temp));
sack[temp] = 0;
pos = temp;
}
}
This will keep the sack the same unless the capacity were not 0. You are still removing everything from the sack if you find it to be 0, so if you need to store that information, I would suggest that in the situation where it does work, you store the sack into an ArrayList of arrays that will contain all of the perfect solutions. If you need solutions in a situation where there is no perfect solution, you can also store every solution in there and have it ordered by the lowest capacity.
Hope that helps.

How to increment properly

i have an issue with my code where i can only increment the last input data value, this code it linked to another class where i have song list etc. however im tryin to create a playlist where when i press play it increments the playcount of all the songs in the playlist. however my problem is once i add the songs to a playlist, when i press play it only increments the last track in entered into the text field. for example i type "01" then add then i type "02" and add, but it only increments track 2 (hence the last track i added) instead of incrementing both 1 and 2. im very new to java so forgive me if this seems trivial, and thanks in advance.
public void actionPerformed(ActionEvent e) {
if (e.getSource() == add) {
String key = trackNo.getText();
String name = LibraryData.getName(key);
if (name == null) {
playcount.setText("No such track number");
} else {
playcount.append("\n" + name + " - " + LibraryData.getArtist(key));
}
}
if (e.getSource() == reset) {
playcount.setText("");
}
if (e.getSource() == play) {
String key = trackNo.getText();
LibraryData.incrementPlayCount(key);
}
}
}

Categories