Libraryless. Click here for Pure Java version (1882L/12K/39K).
1 | !759 |
2 | |
3 | // by Stefan Reich and Omar Khan |
4 | |
5 | static abstract class Status {
|
6 | abstract S answer(S s); |
7 | } |
8 | |
9 | // Actually it's not really a status because it moves to the next status immediately (so we could get rid of this class) |
10 | static class InGame extends Status {
|
11 | QuestionNode node; |
12 | *() {}
|
13 | *(QuestionNode *node) {}
|
14 | |
15 | S answer(S s) {
|
16 | if (node.isAnswer()) {
|
17 | status(new IsIt(node)); |
18 | ret "Would your object happen to be " + node.data + "?"; |
19 | } else {
|
20 | status(new DoesIt(node)); |
21 | ret node.data; // the question |
22 | } |
23 | } |
24 | } |
25 | |
26 | static class IsIt extends Status {
|
27 | QuestionNode node; |
28 | *() {}
|
29 | *(QuestionNode *node) {}
|
30 | |
31 | S answer(S s) {
|
32 | if (isYes(s)) {
|
33 | status(null); |
34 | ret "I win!"; |
35 | } else if (isNo(s)) {
|
36 | status(new WhatIsIt(node)); |
37 | ret "I lose. What is your object?"; |
38 | } else |
39 | ret "Yes or no, sir?"; |
40 | } |
41 | } |
42 | |
43 | static class WhatIsIt extends Status {
|
44 | QuestionNode node; |
45 | *() {}
|
46 | *(QuestionNode *node) {}
|
47 | |
48 | S answer(S s) {
|
49 | status(new GiveQuestion(node, s)); |
50 | ret "Please type a question that is answered with \"yes\" for " + quote(s) + " and with \"no\" for " + quote(node.data) + "."; |
51 | } |
52 | } |
53 | |
54 | static class GiveQuestion extends Status {
|
55 | QuestionNode node; |
56 | S objectName; |
57 | |
58 | *() {}
|
59 | *(QuestionNode *node, S *objectName) {}
|
60 | |
61 | S answer(S s) {
|
62 | // original node goes to "no" |
63 | QuestionNode no = new QuestionNode(node.data); |
64 | no.yes = node.yes; |
65 | no.no = node.no; |
66 | |
67 | node.data = s; // question entered by user |
68 | node.yes = new QuestionNode(objectName); |
69 | node.no = no; |
70 | |
71 | // save |
72 | save("root");
|
73 | |
74 | status(new PlayAgain); |
75 | |
76 | ret "Thanks, I learned this :-)) Play again?"; |
77 | } |
78 | } |
79 | |
80 | static S play() {
|
81 | status(new InGame(root)); |
82 | ret "Alrighty! Type 'exit' at any time to cancel the game. Think of an object! Now tell me: " + status.answer("");
|
83 | } |
84 | |
85 | static class PlayAgain extends Status {
|
86 | S answer(S s) {
|
87 | if (isYes(s)) {
|
88 | ret play(); |
89 | } else {
|
90 | status(null); |
91 | ret "OK, goodbye :) To play again, say \"play 20 questions\"."; |
92 | } |
93 | } |
94 | } |
95 | |
96 | static class DoesIt extends Status {
|
97 | QuestionNode node; |
98 | *() {}
|
99 | *(QuestionNode *node) {}
|
100 | |
101 | S answer(S s) {
|
102 | if (isYes(s)) {
|
103 | status(new InGame(node.yes)); |
104 | ret status.answer("");
|
105 | } else if (isNo(s)) {
|
106 | status(new InGame(node.no)); |
107 | ret status.answer("");
|
108 | } else |
109 | ret "Yes or no, sir?"; |
110 | } |
111 | } |
112 | |
113 | |
114 | static QuestionNode root = new QuestionNode("computer");
|
115 | static Status status; |
116 | static S dialogID; |
117 | |
118 | p {
|
119 | load("root");
|
120 | load("status");
|
121 | load("dialogID");
|
122 | } |
123 | |
124 | answer {
|
125 | if (match("20 questions", s) || match("play 20 questions", s)) {
|
126 | dialogID = getDialogID(); |
127 | save("dialogID");
|
128 | ret play(); |
129 | } else if (eq(getDialogID(), dialogID) && status != null) {
|
130 | if "exit" {
|
131 | status(null); |
132 | ret "OK, game cancelled."; |
133 | } |
134 | ret status.answer(s); |
135 | } |
136 | |
137 | // inspect game structures |
138 | |
139 | if "20 questions dump" |
140 | ret structure(root); |
141 | |
142 | if "20 questions find *" |
143 | ret structure(findNode(m.unq(0))); |
144 | |
145 | if "20 questions fix question * *" {
|
146 | if (!onSlack()) |
147 | ret "Sorry... go on Slack for this"; |
148 | QuestionNode node = findNode(m.unq(0)); |
149 | if (node == null) |
150 | ret "Node not found, sorry"; |
151 | |
152 | fixlog(s); |
153 | node.data = m.unq(1); |
154 | save("root");
|
155 | status(null); |
156 | ret "OK, fixed!"; |
157 | } |
158 | |
159 | // question, branch to keep (yes/no) |
160 | if "20 questions collapse question * *" {
|
161 | if (!onSlack()) |
162 | ret "Sorry... go on Slack for this"; |
163 | QuestionNode node = findNode(m.unq(0)); |
164 | if (node == null) |
165 | ret "Node not found, sorry"; |
166 | |
167 | S field; // the one to keep |
168 | if (isYes(m.unq(1))) |
169 | field = "yes"; |
170 | else if (isNo(m.unq(1))) |
171 | field = "no"; |
172 | else |
173 | ret "Yes or no? " + quote(m.unq(1)); |
174 | |
175 | fixlog(s); |
176 | QuestionNode sub = cast get(node, field); |
177 | node.data = sub.data; |
178 | node.yes = sub.yes; |
179 | node.no = sub.no; |
180 | save("root");
|
181 | status(null); |
182 | ret "OK, collapsed!"; |
183 | } |
184 | } |
185 | |
186 | static void fixlog(S s) {
|
187 | logStructure("fixlog", s);
|
188 | logStructure("fixlog", root);
|
189 | } |
190 | |
191 | static void status(Status s) {
|
192 | status = s; |
193 | save("status");
|
194 | } |
195 | |
196 | // QuestionNodes have a String data field as well as a reference to two other QuestionNodes. |
197 | static class QuestionNode{
|
198 | |
199 | public String data; |
200 | public QuestionNode yes; |
201 | public QuestionNode no; |
202 | |
203 | //Constructs a new QuestionNode with no references so it is a leaf node. |
204 | *(String *data) {}
|
205 | *() {}
|
206 | |
207 | //Checks it the QuestionNode is a leaf node. |
208 | public boolean isAnswer(){
|
209 | return yes == null && no == null; |
210 | } |
211 | } |
212 | |
213 | static QuestionNode findNode(S q) {
|
214 | for (O node : scanTree(root, litlist("yes", "no")))
|
215 | if (match(q, getString(node, "data"))) |
216 | ret (QuestionNode) node; |
217 | null; |
218 | } |
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: | 1135 / 1533 |
| Referenced in: | [show references] |