usage in main:

Code:

        VNPrompt vn = new VNPrompt();
        vn.setPrompt("one");
        VNPrompt vn2 = new VNPrompt();
        vn2.setPrompt("choose waifu: rem, or ram");
        vn2.setRegex("rem|ram");
        VNPrompt vn3_0 = new VNPrompt();
        vn3_0.setPrompt("you chose rem");
        vn3_0.setAnswers(new Responder("rem"));
        VNPrompt vn3_1 = new VNPrompt();
        vn3_1.setPrompt("you chose ram");
        vn3_1.setAnswers(new Responder("ram"));
        vn.getNextPrompts().add(vn2); // linear story progression: add vn_X+1 to VN_x
        vn2.getNextPrompts().add(vn3_0); // option select in story
        // : add options vn_x+1_n, vn_x+1_n+1... to vn_x
        vn2.getNextPrompts().add(vn3_1);
        vn.activate();
        System.out.println(vn.getPrompt());
        System.out.println(vn.getActive());
        vn.process("enter");
        System.out.println(vn.getPrompt());
        System.out.println(vn.getActive());
        vn.process("ram");
        System.out.println(vn.getPrompt());
        System.out.println(vn.getActive());

output:
one
true
choose waifu: rem, or ram
true
you chose ram
true

class code:

Code:

package AXJava;

import LivinGrimoire.RegexUtil;

import java.util.ArrayList;

public class VNPrompt {
    private RegexUtil regexUtil = new RegexUtil();
    private Boolean isActive = false;
    private String prompt = ""; // change to responder
    private String regex = "^.+$"; // any not empty string
    private Responder answers = new Responder("default"); // link to prompt
    private String resultKey = "";
    public ArrayList<VNPrompt> nextPrompts = new ArrayList<VNPrompt>();

    // setters

    public void setPrompt(String prompt) {
        this.prompt = prompt;
    }

    public void setRegex(String regex) {
        this.regex = regex;
    }

    public void setAnswers(Responder answers) {
        this.answers = answers;
    }

    public void setResultKey(String resultKey) {
        this.resultKey = resultKey;
    }

    // end setters
    // getters
    public Responder getAnswers() {
        return answers;
    }

    public String getPrompt() {
        return prompt;
    }

    public String getRegex() {
        return regex;
    }

    public String getResultKey() {
        return resultKey;
    }

    public ArrayList<VNPrompt> getNextPrompts() {
        return nextPrompts;
    }

    public Boolean getActive() {
        return isActive;
    }
    // end getters
    // reset
    public void dectivate(){
        isActive = false;
    }
    public void activate(){
        isActive = true;
    }
    public void process(String in1){
        if (!isActive){return;}
        String temp = regexUtil.extractRegex(regex,in1);
        if (temp.isEmpty()){return;}
        // got a valid answer: can return key value pair of {resultKey,temp}
        if (nextPrompts.isEmpty()){isActive = false;return;} // end of VN
        // valid answer + not end of VN
        for (int i = 0; i < nextPrompts.size(); i++) {
            if(nextPrompts.get(i).getAnswers().responsesContainsStr(temp)){
                transfer(nextPrompts.get(i));
                return;
            }
        }
        // linear vn mode
        transfer(nextPrompts.get(0));
    }
    private void transfer(VNPrompt newVNPrompt){
        this.answers = newVNPrompt.getAnswers();
        this.nextPrompts = newVNPrompt.getNextPrompts();
        this.prompt = newVNPrompt.getPrompt();
        this.regex = newVNPrompt.getRegex();
    }
}


while it's made for visual novels, some use this technique for chatbots, or even for automated answering machines.

it's not my cup of tea, mainly because I prefer linear VNs, so I won't be porting it to other programming languages, but it was a puzzle that just begged to be solved. dark