Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

218
LINES

< > BotCompany Repo | #1002519 // 20 Questions with status objects [one player at a time]

JavaX source code [tags: use-pretranspiled] - run with: x30.jar

Libraryless. Click here for Pure Java version (1882L/12K/39K).

!759

// by Stefan Reich and Omar Khan

static abstract class Status {
  abstract S answer(S s);
}

// Actually it's not really a status because it moves to the next status immediately (so we could get rid of this class)
static class InGame extends Status {
  QuestionNode node;
  *() {}
  *(QuestionNode *node) {}
  
  S answer(S s) {
    if (node.isAnswer()) {
      status(new IsIt(node));
      ret "Would your object happen to be " + node.data + "?";
    } else {
      status(new DoesIt(node));
      ret node.data; // the question
    }
  }
}
  
static class IsIt extends Status {
  QuestionNode node;
  *() {}
  *(QuestionNode *node) {}
  
  S answer(S s) {
    if (isYes(s)) {
      status(null);
      ret "I win!";
    } else if (isNo(s)) {
      status(new WhatIsIt(node));
      ret "I lose. What is your object?";
    } else
      ret "Yes or no, sir?";
  }
}

static class WhatIsIt extends Status {
  QuestionNode node;
  *() {}
  *(QuestionNode *node) {}
  
  S answer(S s) {
    status(new GiveQuestion(node, s));
    ret "Please type a question that is answered with \"yes\" for " + quote(s) + " and with \"no\" for " + quote(node.data) + ".";
  }
}

static class GiveQuestion extends Status {
  QuestionNode node;
  S objectName;
  
  *() {}
  *(QuestionNode *node, S *objectName) {}
  
  S answer(S s) {
    // original node goes to "no"
    QuestionNode no = new QuestionNode(node.data);
    no.yes = node.yes;
    no.no = node.no;
    
    node.data = s; // question entered by user
    node.yes = new QuestionNode(objectName);
    node.no = no;
    
    // save
    save("root");
    
    status(new PlayAgain);
    
    ret "Thanks, I learned this :-)) Play again?";
  }
}

static S play() {
  status(new InGame(root));
  ret "Alrighty! Type 'exit' at any time to cancel the game. Think of an object! Now tell me: " + status.answer("");
}

static class PlayAgain extends Status {
  S answer(S s) {
    if (isYes(s)) {
      ret play();
    } else {
      status(null);
      ret "OK, goodbye :) To play again, say \"play 20 questions\".";
    }
  }
}

static class DoesIt extends Status {
  QuestionNode node;
  *() {}
  *(QuestionNode *node) {}
  
  S answer(S s) {
    if (isYes(s)) {
      status(new InGame(node.yes));
      ret status.answer("");
    } else if (isNo(s)) { 
      status(new InGame(node.no));
      ret status.answer("");
    } else
      ret "Yes or no, sir?";
  }
}

  
static QuestionNode root = new QuestionNode("computer");
static Status status;
static S dialogID;

p {
  load("root");
  load("status");
  load("dialogID");
}

answer {
  if (match("20 questions", s) || match("play 20 questions", s)) {
    dialogID = getDialogID();
    save("dialogID");
    ret play();
  } else if (eq(getDialogID(), dialogID) && status != null) {
    if "exit" {
      status(null);
      ret "OK, game cancelled.";
    }
    ret status.answer(s);
  }
  
  // inspect game structures
  
  if "20 questions dump"
    ret structure(root);
    
  if "20 questions find *"
    ret structure(findNode(m.unq(0)));
    
  if "20 questions fix question * *" {
    if (!onSlack())
      ret "Sorry... go on Slack for this";
    QuestionNode node = findNode(m.unq(0));
    if (node == null)
      ret "Node not found, sorry";
      
    fixlog(s);
    node.data = m.unq(1);
    save("root");
    status(null);
    ret "OK, fixed!";
  }
  
  // question, branch to keep (yes/no)
  if "20 questions collapse question * *" {
    if (!onSlack())
      ret "Sorry... go on Slack for this";
    QuestionNode node = findNode(m.unq(0));
    if (node == null)
      ret "Node not found, sorry";
      
    S field; // the one to keep
    if (isYes(m.unq(1)))
      field = "yes";
    else if (isNo(m.unq(1)))
      field = "no";
    else
      ret "Yes or no? " + quote(m.unq(1));
      
    fixlog(s);
    QuestionNode sub = cast get(node, field);
    node.data = sub.data;
    node.yes = sub.yes;
    node.no = sub.no;
    save("root");
    status(null);
    ret "OK, collapsed!";
  }
}

static void fixlog(S s) {
  logStructure("fixlog", s);
  logStructure("fixlog", root);
}

static void status(Status s) {
  status = s;
  save("status");
}

// QuestionNodes have a String data field as well as a reference to two other QuestionNodes.
static class QuestionNode{

   public String data;
   public QuestionNode yes;
   public QuestionNode no;
   
   //Constructs a new QuestionNode with no references so it is a leaf node.
   *(String *data) {}
   *() {}
   
   //Checks it the QuestionNode is a leaf node.
   public boolean isAnswer(){
      return yes == null && no == null;
   }
}

static QuestionNode findNode(S q) {
  for (O node : scanTree(root, litlist("yes", "no")))
    if (match(q, getString(node, "data")))
      ret (QuestionNode) node;
  null;
}

download  show line numbers  debug dex  old transpilations   

Travelled to 14 computer(s): afvcxyesxakz, aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1002519
Snippet name: 20 Questions with status objects [one player at a time]
Eternal ID of this version: #1002519/1
Text MD5: 9c3ffa5ac8bf4d0a7f9788eaf8c174bc
Transpilation MD5: 833531dc9a85b218ffe20706d64fb96f
Author: stefan
Category: javax
Type: JavaX source code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2016-02-02 17:22:19
Source code size: 4994 bytes / 218 lines
Pitched / IR pitched: No / No
Views / Downloads: 830 / 1135
Referenced in: [show references]