Java logical vending machine to give change

0

I am a student, I am making a machine, I almost end it, but I am having problems when my stock of coins is zero, in theory I would have to leave a message saying that it can not give change but it gives the same change and does not discount it of the stock I need to find the logic for when to give a message when I do not have enough coins to give change.

I leave my code here, this is when you pay:

//Payments
String selectedPayment = "";

//notes and coins values
public static double[] coinsAndNotes = new double[]{0.1, 0.2, 0.5, 1.0, 2.0, 5.0, 10.0, 20.0};

//counters of the money in
public static int[] counterMoneyIn = new int[]{0, 0, 0, 0, 0, 0, 0, 0};

// Total of money
double totalMoneyInMachine = (Stock.stockCoins[0] * coinsAndNotes[0]) + (Stock.stockCoins[1] * coinsAndNotes[1])
        + (Stock.stockCoins[2] * coinsAndNotes[2]) + (Stock.stockCoins[3] * coinsAndNotes[3]) + (Stock.stockCoins[4] * coinsAndNotes[4])
        + (Stock.stockNotes[0] * coinsAndNotes[5]) + (Stock.stockNotes[1] * coinsAndNotes[6]) + (Stock.stockNotes[2] * coinsAndNotes[7]);

double TotalMoneyInserted = (Stock.stockCoins[0] * counterMoneyIn[0]) + (Stock.stockCoins[1] * counterMoneyIn[1])
        + (Stock.stockCoins[2] * counterMoneyIn[2]) + (Stock.stockCoins[3] * counterMoneyIn[3]) + (Stock.stockCoins[4] * counterMoneyIn[4])
        + (Stock.stockNotes[0] * counterMoneyIn[5]) + (Stock.stockNotes[1] * counterMoneyIn[6]) + (Stock.stockNotes[2] * counterMoneyIn[7]);

private void jButtonPayActionPerformed(java.awt.event.ActionEvent evt) {                                           

    double change = 0.0;
    DecimalFormat df = new DecimalFormat("0.00");

    PaymentMethod pm = new PaymentMethod();

    change = TotalMoneyInserted - VMachine.price;


    if (TotalMoneyInserted < VMachine.price) {
        change *= -1;
        JOptionPane.showMessageDialog(null, "Sorry, not enough money, please enter" + " " + "€" + df.format(change) + " " + "more", "Insufficent Funds", JOptionPane.ERROR_MESSAGE);
      } else if (totalMoneyInMachine < change) {

        JOptionPane.showMessageDialog(null, "Sorry, There is not enough change in the machine, try to insert less money", "Change Insufficient", JOptionPane.ERROR_MESSAGE);

        //ten cent
        Stock.stockCoins[0] += -counterMoneyIn[0];
        //twenty cent
        Stock.stockCoins[1] += -counterMoneyIn[1];
        //fifty cent
        Stock.stockCoins[2] += -counterMoneyIn[2];
        //one euro
        Stock.stockCoins[3] += -counterMoneyIn[3];
        //two euros
        Stock.stockCoins[4] += -counterMoneyIn[4];
        //five note
        Stock.stockNotes[0] += -counterMoneyIn[5];
        //ten note
        Stock.stockNotes[1] += -counterMoneyIn[6];
        //twenty note
        Stock.stockNotes[2] += -counterMoneyIn[7];

        pm.setVisible(true);
        setVisible(false);

    } else {


        while (change > 0.01) {

            if (change >= 20) {
                change = roundAndReduce(change, 20);
                if (Stock.stockNotes[2] > 0) {
                    Stock.stockNotes[2]--;
                } else {
                    System.out.println("we don't have 20 to complete the operation");
                    pm.setVisible(true);
                    setVisible(false);
                }
            } else if (change >= 10) {
                change = roundAndReduce(change, 10);
                if (Stock.stockNotes[1] > 0) {
                    Stock.stockNotes[1]--;
                } else {
                    System.out.println("we don't have 10 to complete the operation");
                    pm.setVisible(true);
                    setVisible(false);
                }
            } else if (change >= 5) {
                change = roundAndReduce(change, 5);
                if (Stock.stockNotes[0] > 0) {
                    Stock.stockNotes[0]--;
                } else {
                    System.out.println("we don't have 5 to complete the operation");
                    pm.setVisible(true);
                    setVisible(false);
                }
            } else if (change >= 2) {
                change = roundAndReduce(change, 2);
                if (Stock.stockCoins[4] > 0) {
                    Stock.stockCoins[4]--;
                } else {
                    System.out.println("we don't have 2 to complete the operation");
                    pm.setVisible(true);
                    setVisible(false);
                }
            } else if (change >= 1) {
                change = roundAndReduce(change, 1);
                if (Stock.stockCoins[3] > 0) {
                    Stock.stockCoins[3]--;
                } else {
                    System.out.println("we don't have 1 to complete the operation");
                    pm.setVisible(true);
                    setVisible(false);
                }
            } else if (change >= 0.5) {
                change = roundAndReduce(change, 0.5);
                if (Stock.stockCoins[2] > 0) {
                    Stock.stockCoins[2]--;
                } else {
                    System.out.println("we don't have 0.5 to complete the operation");
                    pm.setVisible(true);
                    setVisible(false);
                }
            } else if (change >= 0.2) {
                change = roundAndReduce(change, 0.2);
                if (Stock.stockCoins[1] > 0) {
                    Stock.stockCoins[1]--;
                } else {
                    System.out.println("we don't have 0.2 to complete the operation");
                    pm.setVisible(true);
                    setVisible(false);
                }
            } else if (change >= 0.1) {
                change = roundAndReduce(change, 0.1);
                if (Stock.stockCoins[0] > 0) {
                    Stock.stockCoins[0]--;

                } else {
                    System.out.println("we don't have 0.1 to complete the operation");
                    pm.setVisible(true);
                    setVisible(false);
                }
            }

        }
       change = TotalMoneyInserted - VMachine.price;

        JOptionPane.showMessageDialog(null, "Your Change is: €" + df.format(change));
        ResetArrayCounter();
        mainMenu(this);

    }


}

roundAndReduce(double change, double reduction) { change -= reduction; 
change = (double) Math.round(change * 100) / 100; return change; } } 

Thank you very much for the help!

I think I'm close to solving this problem, but I'm with an infinite loop, taking that out, I think it would work. I leave it to you to give your opinions. Thanks!

 while (change > 0.01) {

            if (change >= 20 && Stock.stockNotes[2] > 0) {


                    change = roundAndReduce(change, 20);
                    Stock.stockNotes[2]--;
                 }else if (change >= 10 && Stock.stockNotes[1] > 0) {

                        change = roundAndReduce(change, 10);
                        Stock.stockNotes[1]--;

                } else if (change >= 5 && Stock.stockNotes[0] > 0) {
                        change = roundAndReduce(change, 5);
                        Stock.stockNotes[0]--;

                } else if (change >= 2 && Stock.stockCoins[4] > 0) {


                        change = roundAndReduce(change, 2);
                        Stock.stockCoins[4]--;

                }
            else if (change >= 1 && Stock.stockCoins[3] > 0) {


                    change = roundAndReduce(change, 1);
                    Stock.stockCoins[3]--;

            } else if (change >= 0.5 && Stock.stockCoins[2] > 0) {


                    change = roundAndReduce(change, 0.5);
                    Stock.stockCoins[2]--;

            } else if (change >= 0.2 && Stock.stockCoins[1] > 0) {


                    change = roundAndReduce(change, 0.2);
                    Stock.stockCoins[1]--;

            } else if (change >= 0.1 && Stock.stockCoins[0] > 0) {


                    change = roundAndReduce(change, 0.1);
                    Stock.stockCoins[0]--;

                }
            JOptionPane.showMessageDialog(null, "Sorry, There is not enough change in the machine, insert exact change", "Out of Change", JOptionPane.ERROR_MESSAGE);


        }
    
asked by Chris 07.12.2018 в 12:31
source

1 answer

1

This problem I have seen many times until I myself made the mistake. The double type variables are useful up to a point, the double sometimes does not keep your decimals well and when you are going to compare them, you will not recognize the conditional by this.

I see that you also round off these, even worse, since at some point you may not keep these properly.

The solution you can use is the BigDecimal class, which is suitable for working with exact decimals with operations that depend on you and which function almost exactly as the double data type, but since it is a class, it brings very Useful as the BigDecimal.Round that allows you to round the number to the nearest number, to the number above, to the number below and even letting you decide how many decimals you want to be rounded.

I recommend it, it's very useful and I'm sure it will solve your problem.

    
answered by 11.12.2018 в 15:15