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: | 896 / 1223 |
Referenced in: | [show references] |