Hypothetical Questions
version 2/080626 by Jesse McGrew
Version 2/080626 of Hypothetical Questions (for Glulx only) by Jesse McGrew begins here.
"Allows us to test the consequences of a phrase or action without permanently changing the game state."
[I7 does some weird things with curly braces in the generated source when we use phrases as parameters, so we have to work around that here. Specifically, I7 adds an opening brace before {ph} and a closing brace after the end of our code.]
To hypothetically (ph - a phrase) and consider (R - a rule): (- switch (Hypo_Start({phrase options})) { 1: do {ph} } until (1); Hypo_Middle({R}); 2: Hypo_End(); } if (0) { -).
To say the/-- hypothetical output: (- Hypo_Capture_Print(); -).
Use hypothetical output length of at least 256 translates as (- Constant HYPO_CAPTURE_BYTES = {N}; -).
Include (-
Constant HYPO_RESULT_WORDS = 2;
! hypo_result-->0 = rule success flag
! hypo_result-->1 = rule result
Array hypo_result --> HYPO_RESULT_WORDS;
#ifndef HYPO_CAPTURE_BYTES;
Constant HYPO_CAPTURE_BYTES = 256;
#endif;
Array hypo_capture -> HYPO_CAPTURE_BYTES;
Global hypo_capture_len;
Global hypo_capture_previous;
! returns 1 when entering the hypothetical universe, 2 when returning to reality, 0 if entering failed in the first place
[ Hypo_Start flags rv seed strtbl iosys iorock;
do { @random 0 seed; } until (seed ~= 0);
@getstringtbl strtbl;
@getiosys iosys iorock;
@saveundo rv;
@setrandom seed;
@setstringtbl strtbl;
@setiosys iosys iorock;
switch (rv) {
0: Hypo_Capture_Start(); return 1; ! saveundo succeeded
1: print "[This game requires an interpreter with undo support.]^"; return 0; ! saveundo failed
-1: return 2; ! restoreundo
}
];
! consider a rule, protect its result, and restore the state saved by Hypo_Start
[ Hypo_Middle rule a b save_sp;
Hypo_Capture_End();
save_sp = say__p; say__p = 0;
ProcessRulebook(rule);
if (say__p == false) say__p = save_sp;
hypo_result-->0 = RulebookOutcome();
if (hypo_result-->0 == RS_FAILS or RS_SUCCEEDS)
hypo_result-->1 = ResultOfRule();
@protect hypo_result (HYPO_RESULT_WORDS * WORDSIZE);
@restoreundo rule; ! never returns if successful
print "[What happened to my undo state? --hypo]^";
];
! load the rule result from Hypo_Middle back onto the rulebook stack
[ Hypo_End;
switch (hypo_result-->0) {
RS_FAILS: RulebookFails(1, hypo_result-->1);
RS_SUCCEEDS: RulebookSucceeds(1, hypo_result-->1);
default: RuleHasNoOutcome();
}
];
! start capturing output
[ Hypo_Capture_Start;
#ifdef is_fyrevm;
if (is_fyrevm) {
! use the filter I/O system
OpenOutputBuffer(hypo_capture, HYPO_CAPTURE_BYTES);
return;
}
#endif;
! use a Glk memory stream
hypo_capture_previous = glk_stream_get_current();
glk_stream_set_current(glk_stream_open_memory(hypo_capture, HYPO_CAPTURE_BYTES, filemode_Write, 0));
];
! stop capturing output
[ Hypo_Capture_End f;
#ifdef is_fyrevm;
if (is_fyrevm) {
hypo_capture_len = CloseOutputBuffer(0);
return;
}
#endif;
glk_stream_close(glk_stream_get_current(), gg_arguments);
hypo_capture_len = gg_arguments-->1;
glk_stream_set_current(hypo_capture_previous);
hypo_capture_previous = 0;
];
! print the capture buffer
[ Hypo_Capture_Print i;
for (i=0: i<hypo_capture_len: i++)
print (char) hypo_capture->i;
];
-).
Hypothetical Questions ends here.