OnJava8-Examples/enumerated/VendingMachine.java

163 lines
3.8 KiB
Java
Raw Normal View History

2015-04-20 15:36:01 -07:00
//: enumerated/VendingMachine.java
// {CompileTimeError} Not working in Java 8
2015-04-20 15:36:01 -07:00
// {Args: VendingMachineInput.txt}
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
enum Category {
MONEY(NICKEL, DIME, QUARTER, DOLLAR),
ITEM_SELECTION(TOOTHPASTE, CHIPS, SODA, SOAP),
QUIT_TRANSACTION(ABORT_TRANSACTION),
SHUT_DOWN(STOP);
private Input[] values;
2015-05-18 23:05:20 -07:00
Category(Input... types) { values = types; }
2015-04-20 15:36:01 -07:00
private static EnumMap<Input,Category> categories =
2015-05-05 11:20:13 -07:00
new EnumMap<>(Input.class);
2015-04-20 15:36:01 -07:00
static {
for(Category c : Category.class.getEnumConstants())
for(Input type : c.values)
categories.put(type, c);
}
public static Category categorize(Input input) {
return categories.get(input);
}
2015-05-18 23:05:20 -07:00
}
2015-04-20 15:36:01 -07:00
public class VendingMachine {
private static State state = State.RESTING;
private static int amount = 0;
private static Input selection = null;
enum StateDuration { TRANSIENT } // Tagging enum
enum State {
RESTING {
2015-05-05 11:20:13 -07:00
@Override
2015-04-20 15:36:01 -07:00
void next(Input input) {
switch(Category.categorize(input)) {
case MONEY:
amount += input.amount();
state = ADDING_MONEY;
break;
case SHUT_DOWN:
state = TERMINAL;
default:
}
}
2015-05-18 23:05:20 -07:00
},
2015-04-20 15:36:01 -07:00
ADDING_MONEY {
2015-05-05 11:20:13 -07:00
@Override
2015-04-20 15:36:01 -07:00
void next(Input input) {
switch(Category.categorize(input)) {
case MONEY:
amount += input.amount();
break;
case ITEM_SELECTION:
selection = input;
if(amount < selection.amount())
print("Insufficient money for " + selection);
else state = DISPENSING;
break;
case QUIT_TRANSACTION:
state = GIVING_CHANGE;
break;
case SHUT_DOWN:
state = TERMINAL;
default:
}
}
2015-05-18 23:05:20 -07:00
},
2015-04-20 15:36:01 -07:00
DISPENSING(StateDuration.TRANSIENT) {
2015-05-05 11:20:13 -07:00
@Override
2015-04-20 15:36:01 -07:00
void next() {
print("here is your " + selection);
amount -= selection.amount();
state = GIVING_CHANGE;
}
},
GIVING_CHANGE(StateDuration.TRANSIENT) {
2015-05-05 11:20:13 -07:00
@Override
2015-04-20 15:36:01 -07:00
void next() {
if(amount > 0) {
print("Your change: " + amount);
amount = 0;
}
state = RESTING;
}
2015-05-18 23:05:20 -07:00
},
2015-05-05 11:20:13 -07:00
TERMINAL {@Override
void output() { print("Halted"); } };
2015-04-20 15:36:01 -07:00
private boolean isTransient = false;
State() {}
State(StateDuration trans) { isTransient = true; }
void next(Input input) {
throw new RuntimeException("Only call " +
"next(Input input) for non-transient states");
}
void next() {
throw new RuntimeException("Only call next() for " +
"StateDuration.TRANSIENT states");
}
void output() { print(amount); }
2015-05-18 23:05:20 -07:00
}
2015-04-20 15:36:01 -07:00
static void run(Generator<Input> gen) {
while(state != State.TERMINAL) {
state.next(gen.next());
while(state.isTransient)
state.next();
state.output();
}
}
public static void main(String[] args) {
Generator<Input> gen = new RandomInputGenerator();
if(args.length == 1)
gen = new FileInputGenerator(args[0]);
run(gen);
}
2015-05-18 23:05:20 -07:00
}
2015-04-20 15:36:01 -07:00
// For a basic sanity check:
class RandomInputGenerator implements Generator<Input> {
2015-05-05 11:20:13 -07:00
@Override
2015-04-20 15:36:01 -07:00
public Input next() { return Input.randomSelection(); }
}
// Create Inputs from a file of ';'-separated strings:
class FileInputGenerator implements Generator<Input> {
private Iterator<String> input;
public FileInputGenerator(String fileName) {
input = new TextFile(fileName, ";").iterator();
}
2015-05-05 11:20:13 -07:00
@Override
2015-04-20 15:36:01 -07:00
public Input next() {
if(!input.hasNext())
return null;
return Enum.valueOf(Input.class, input.next().trim());
}
} /* Output:
25
50
75
here is your CHIPS
0
100
200
here is your TOOTHPASTE
0
25
35
Your change: 35
0
25
35
Insufficient money for SODA
35
60
70
75
Insufficient money for SODA
75
Your change: 75
0
Halted
2015-05-05 11:20:13 -07:00
*///:~