Implementing Alts

This commit is contained in:
2019-03-29 13:38:43 -06:00
parent f912393ad7
commit ae74178f8d
8 changed files with 39 additions and 10 deletions

View File

@@ -1,6 +1,6 @@
First output. 1 1 0 1
Second output. 1 1 1 1
1 1 1 2
1 1 1 2
Third output.
Fourth output.
Fifth output.

View File

@@ -13,6 +13,7 @@ enum AltBehavior {
}
@:allow(hank.AltInstance)
@:allow(hank.Output)
class Alt {
var behavior: AltBehavior;
var outputs: Array<Output>;
@@ -22,7 +23,7 @@ class Alt {
'!' => OnceOnly,
'&' => Cycle,
'~' => Shuffle,
'seq:' => Sequence,
'sequence:' => Sequence,
'once:' => OnceOnly,
'cycle:' => Cycle,
'shuffle:' => Shuffle

View File

@@ -2,6 +2,8 @@ package hank;
import haxe.ds.Option;
import hank.Alt.AltInstance;
typedef Choice = {id: Int, onceOnly: Bool, label: Option<String>, condition: Option<String>, depth: Int, output: Output, divertTarget: Option<String>};
enum ExprType {

View File

@@ -6,6 +6,7 @@ import haxe.ds.Option;
using Extensions.Extensions;
import hank.StoryTree;
import hank.Alt.AltInstance;
enum OutputType {
Text(t: String); // Pure text that is always displayed
@@ -150,7 +151,7 @@ class Output {
}
public function format(hInterface: HInterface, scope: Array<StoryNode>, displayToggles: Bool): String {
public function format(story: Story, hInterface: HInterface, random: Random, altInstances: Map<Alt, AltInstance>, scope: Array<StoryNode>, displayToggles: Bool): String {
var fullOutput = '';
for (part in parts) {
@@ -158,14 +159,28 @@ class Output {
case Text(t):
fullOutput += t;
case AltExpression(a):
// TODO evaluate the alt expression deterministically
// If this alt hasn't been evaluated yet, we need to make an instance for it
if (!altInstances.exists(a)) {
altInstances[a] = new AltInstance(a.behavior, a.outputs, random);
}
trace(a);
trace([for(key in altInstances.keys()) key].length);
trace(altInstances[a]);
fullOutput += altInstances[a].next().format(story, hInterface, random, altInstances, scope, displayToggles);
case HExpression(h):
fullOutput += hInterface.evaluateExpr(h, scope);
case InlineDivert(t):
// TODO follow the divert. If the next expression is an output, concatenate the pieces together. Otherwise, terminate formatting
// follow the divert. If the next expression is an output, concatenate the pieces together. Otherwise, terminate formatting
story.divertTo(t);
switch (story.nextFrame()) {
case HasText(text):
fullOutput += text;
default:
}
case ToggleOutput(o, b):
if (b == displayToggles) {
fullOutput += o.format(hInterface, scope, displayToggles);
fullOutput += o.format(story, hInterface, random, altInstances, scope, displayToggles);
}
}
}

View File

@@ -1,5 +1,6 @@
package hank;
using StringTools;
import haxe.ds.Option;
using hank.Extensions;
@@ -7,6 +8,7 @@ using HankAST.ASTExtension;
using HankAST.Choice;
import hank.HankAST.ExprType;
import hank.StoryTree;
import hank.Alt.AltInstance;
/**
Possible states of the story being executed.
@@ -31,6 +33,7 @@ class Story {
var storyTree: StoryNode;
var viewCounts: Map<StoryNode, Int>;
var nodeScopes: Array<StoryNode>;
var altInstances: Map<Alt, AltInstance> = new Map();
var parser: Parser;
@@ -109,7 +112,7 @@ class Story {
switch (expr) {
case EOutput(output):
exprIndex += 1;
return HasText(output.format(hInterface, nodeScopes, false));
return HasText(output.format(this, hInterface, random, altInstances, nodeScopes, false).trim());
case EHaxeLine(h):
exprIndex += 1;
@@ -142,7 +145,7 @@ class Story {
return nextFrame();
}
var optionsText = [for(c in availableChoices()) c.output.format(hInterface, nodeScopes, false)];
var optionsText = [for(c in availableChoices()) c.output.format(this, hInterface, random, altInstances, nodeScopes, false)];
if (optionsText.length > 0) {
return HasChoices(optionsText);
} else {
@@ -319,7 +322,7 @@ class Story {
exprIndex = ast.indexOfChoice(choice.id)+1;
}
var output = choice.output.format(hInterface, nodeScopes, true);
var output = choice.output.format(this, hInterface, random, altInstances, nodeScopes, true);
return output;
}

View File

@@ -1,6 +1,8 @@
package tests;
import haxe.CallStack;
using StringTools;
import utest.Assert;
class StoryTest extends hank.StoryTestCase {
function testAllExamples() {
@@ -19,7 +21,13 @@ class StoryTest extends hank.StoryTestCase {
var partial = file.indexOf("partial") != -1;
if (!disabled) {
trace(' Running ${file}');
validateAgainstTranscript('examples/${folder}/main.hank', 'examples/${folder}/${file}', !partial);
try {
validateAgainstTranscript('examples/${folder}/main.hank', 'examples/${folder}/${file}', !partial);
} catch (e: Dynamic) {
trace('Error testing $folder/$file: $e');
trace(CallStack.exceptionStack());
Assert.fail();
}
}
}
}