-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
__init__.py
185 lines (162 loc) · 6.7 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
from .api import Api
import ravestate as rs
import ravestate_idle as idle
import ravestate_nlp as nlp
import ravestate_rawio as rawio
from reggol import get_logger
logger = get_logger(__name__)
akinator_api: Api
CERTAINTY = "certainty_percentage"
with rs.Module(name="akinator", config={CERTAINTY: 90}):
prop_is_it = rs.Property(
name="is_it",
default_value="",
always_signal_changed=True,
allow_pop=False,
allow_push=False,
is_flag_property=True)
prop_question = rs.Property(
name="question",
default_value="",
always_signal_changed=True,
allow_pop=False,
allow_push=False,
is_flag_property=True)
prop_init_play_again = rs.Property(
name="initiate_play_again",
default_value="",
always_signal_changed=True,
allow_pop=False,
allow_push=False,
is_flag_property=True)
sig_initiate_play = rs.Signal("initiate-play")
sig_exit_game = rs.Signal("exit-game")
sig_wrong_input = rs.Signal("wrong-input")
sig_is_it_asked = rs.Signal("is-it")
@rs.state(
cond=nlp.sig_intent_play | idle.sig_bored_by_user,
write=rawio.prop_out,
signal=sig_initiate_play,
emit_detached=True,
weight=1.,
cooldown=30.)
def play_ask(ctx):
"""
Asks if interlocutor wants to play 20 question / akinator
Triggered when nlp:play property is changed by "i want to play a game" or a similar input
"""
ctx[rawio.prop_out] = "Do you want to play 20 questions?"
return rs.Emit()
@rs.state(cond=sig_initiate_play.min_age(10).max_age(13), write=rawio.prop_out)
def akinator_play_question_ignored(ctx):
ctx[rawio.prop_out] = "Oh well, maybe later!"
@rs.state(
cond=nlp.prop_yesno.changed() & (sig_initiate_play.max_age(13) | prop_init_play_again.changed().max_age(13.)),
read=nlp.prop_yesno,
write=(rawio.prop_out, "akinator:question"),
emit_detached=True)
def start(ctx):
"""
Starts akinator session
Triggered by signal from akinator_play_ask state and nlp:yesno:changed given by the input
It is also triggered if one game is finished and the interlocutor wants to play again
Output: First question
"""
global akinator_api
if ctx[nlp.prop_yesno].yes():
logger.info("Akinator session is started.")
akinator_api = Api()
ctx[prop_question] = True
ctx[rawio.prop_out] = "You can answer the questions with:" \
+ ' "yes", "no", "i do not know", "probably", "probably not"' \
+ " Question " + str(int(akinator_api.get_parameter('step')) + 1) \
+ ": " + akinator_api.get_parameter('question')
else:
return rs.Resign()
@rs.state(
cond=nlp.prop_triples.changed() & prop_question.changed().max_age(13),
read=nlp.prop_yesno,
write=(rawio.prop_out, prop_is_it, prop_question),
emit_detached=True,
signal=sig_wrong_input)
def question_answered(ctx):
"""
Reads the answer to a question and outputs the next question
Gets triggered by akinator:question which is always updated by a new question and nlp:yesno:changed signal
Triggers the wrong_input state id it cannot process the input
If the answer certainty of akinator is over the configurable CERTAINTY threshold the is_it state is triggered
"""
global akinator_api
response = akinator_api.answer_to_int_str(ctx[nlp.prop_yesno])
if not response == "-1":
akinator_api.response_get_request(response)
if not akinator_api.is_complete():
wrong_input(ctx)
elif float(akinator_api.get_parameter('progression')) <= ctx.conf(key=CERTAINTY) and int(akinator_api.get_parameter('step')) <= 20:
ctx[prop_question] = True
ctx[rawio.prop_out] = "Question " + str(int(akinator_api.get_parameter('step')) + 1) \
+ ": " + akinator_api.get_parameter('question')
else:
ctx["akinator:is_it"] = True
else:
return rs.Emit()
@rs.state(
cond=prop_is_it.changed(),
write=rawio.prop_out,
signal=sig_is_it_asked,
emit_detached=True)
def is_it(ctx):
"""
Outputs the solution guess of akinator: "Is this your character? ..."
Triggers the is_it_answer state
"""
global akinator_api
guess = akinator_api.guess_get_request()
ctx[rawio.prop_out] = \
f"Is this your character? {guess['name']}: {guess['desc']}." \
" Please answer with 'yes' or 'no'."
return rs.Emit()
@rs.state(
cond=nlp.prop_yesno.changed() & sig_is_it_asked.max_age(13),
read=nlp.prop_yesno,
write=(rawio.prop_out, "akinator:initiate_play_again"),
emit_detached=True)
def is_it_answered(ctx):
"""
Gets input from interlocutor on the "is it" question and posts the result
Asks if the interlocutor wants to play again.
"""
if ctx[nlp.prop_yesno].yes():
akinator_api.choice_get_request()
out = "Yeah! I guessed right! Thanks for playing with me! Do you want to play again?"
elif ctx[nlp.prop_yesno].no():
akinator_api.exclusion_get_request()
out = "Oh no! I guessed wrong but do you want to play again?"
else:
out = "What? But do you want to play again?"
ctx[rawio.prop_out] = out
ctx["akinator:initiate_play_again"] = True
@rs.state(
cond=sig_wrong_input,
write=rawio.prop_out,
emit_detached=True,
signal=sig_exit_game)
def wrong_input(ctx):
"""
Catches wrong inputs from the interlocutor during questions answering and loops back to the question state
"""
ctx[rawio.prop_out] = "Sadly I could not process that answer. Do you want to stop playing Akinator?"
return rs.Emit()
@rs.state(
cond=nlp.prop_yesno.changed() & sig_exit_game.max_age(13),
write=(rawio.prop_out, prop_question),
read=nlp.prop_yesno,
emit_detached=True)
def exit_game_answered(ctx):
if ctx[nlp.prop_yesno].yes():
ctx[rawio.prop_out] = "Thanks for playing with me!"
return rs.Resign()
else:
ctx[rawio.prop_out] = "Yeah! Let's keep playing! Remember that you have these five answering choices:" \
" 'yes', 'no', 'i do not know', 'probably', 'probably not'"
ctx[prop_question] = True