Task: Finite state machine




Go: package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
    "strings"
)

type state int

const (
    ready state = iota
    waiting
    exit
    dispense
    refunding
)

func check(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

func fsm() {
    fmt.Println("Please enter your option when prompted")
    fmt.Println("(any characters after the first will be ignored)")
    state := ready
    var trans string
    scanner := bufio.NewScanner(os.Stdin)
    for {
        switch state {
        case ready:
            for {
                fmt.Print("\n(D)ispense or (Q)uit : ")
                scanner.Scan()
                trans = scanner.Text()
                check(scanner.Err())
                if len(trans) == 0 {
                    continue
                }
                option := strings.ToLower(trans)[0]
                if option == 'd' {
                    state = waiting
                    break
                } else if option == 'q' {
                    state = exit
                    break
                }
            }
        case waiting:
            fmt.Println("OK, put your money in the slot")
            for {
                fmt.Print("(S)elect product or choose a (R)efund : ")
                scanner.Scan()
                trans = scanner.Text()
                check(scanner.Err())
                if len(trans) == 0 {
                    continue
                }
                option := strings.ToLower(trans)[0]
                if option == 's' {
                    state = dispense
                    break
                } else if option == 'r' {
                    state = refunding
                    break
                }
            }
        case dispense:
            for {
                fmt.Print("(R)emove product : ")
                scanner.Scan()
                trans = scanner.Text()
                check(scanner.Err())
                if len(trans) == 0 {
                    continue
                }
                option := strings.ToLower(trans)[0]
                if option == 'r' {
                    state = ready
                    break
                }
            }
        case refunding:
            
            fmt.Println("OK, refunding your money")
            state = ready
        case exit:
            fmt.Println("OK, quitting")
            return
        }
    }
}

func main() {
    fsm()
}


Java: import java.util.*;

public class FiniteStateMachine {

    private enum State {
        Ready(true, "Deposit", "Quit"),
        Waiting(true, "Select", "Refund"),
        Dispensing(true, "Remove"),
        Refunding(false, "Refunding"),
        Exiting(false, "Quiting");

        State(boolean exp, String... in) {
            inputs = Arrays.asList(in);
            explicit = exp;
        }

        State nextState(String input, State current) {
            if (inputs.contains(input)) {
                return map.getOrDefault(input, current);
            }
            return current;
        }

        final List<String> inputs;
        final static Map<String, State> map = new HashMap<>();
        final boolean explicit;

        static {
            map.put("Deposit", State.Waiting);
            map.put("Quit", State.Exiting);
            map.put("Select", State.Dispensing);
            map.put("Refund", State.Refunding);
            map.put("Remove", State.Ready);
            map.put("Refunding", State.Ready);
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        State state = State.Ready;

        while (state != State.Exiting) {
            System.out.println(state.inputs);
            if (state.explicit){
                System.out.print("> ");
                state = state.nextState(sc.nextLine().trim(), state);
            } else {
                state = state.nextState(state.inputs.get(0), state);
            }
        }
    }
}