├── students ├── adeel41 │ ├── arc-console.tpl │ ├── runner.go │ ├── arc_option.go │ ├── arc.tpl │ ├── console_runner.go │ ├── story_arc.go │ ├── story_arc_provider.go │ ├── web_runner.go │ ├── main.go │ ├── story.go │ └── gopher.json ├── ccallergard │ ├── adventure.go │ ├── html.go │ ├── scene_template.html │ ├── main │ │ └── main.go │ └── gopher.json ├── README.md ├── manan │ ├── story.html │ ├── cmd │ │ └── main.go │ ├── cyoa_test.go │ ├── cyoa.go │ └── gopher.json ├── cherednichenkoa │ ├── settings │ │ └── settings.go │ ├── templates │ │ └── story.html │ ├── main.go │ ├── source │ │ └── json_file.go │ └── route-handler │ │ └── route_handler.go ├── dennisvis │ ├── templates │ │ └── main.html │ ├── main.go │ └── gopher.json └── barisere │ ├── cyoa.html │ ├── main.go │ └── gopher.json ├── .gitignore ├── README.md └── gopher.json /students/adeel41/arc-console.tpl: -------------------------------------------------------------------------------- 1 | {{.Title}} 2 | {{.Paragraph}} 3 | 4 | {{range .Options}} 5 | {{.Number}}. {{.Text}} 6 | {{end}} -------------------------------------------------------------------------------- /students/adeel41/runner.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //Runner is implemented by ConsoleRunner and WebRunner 4 | type Runner interface { 5 | Start(provider *StoryArcProvider) 6 | } 7 | -------------------------------------------------------------------------------- /students/ccallergard/adventure.go: -------------------------------------------------------------------------------- 1 | package cyoa 2 | 3 | type Scene struct { 4 | Title string `json:"title"` 5 | Story []string `json:"story"` 6 | Options []struct { 7 | Text string `json:"text"` 8 | Arc string `json:"arc"` 9 | } `json:"options"` 10 | } 11 | 12 | type Adventure map[string]Scene 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 14 | .glide/ 15 | tmp/ 16 | .idea/ 17 | -------------------------------------------------------------------------------- /students/README.md: -------------------------------------------------------------------------------- 1 | # Student Examples 2 | 3 | The following are example implementations submitted by students/gophers learning from this course. 4 | 5 | The primary purposes of these examples are: 6 | 7 | 1. To provide example implementations to discuss and review when recording the screencasts for this course. 8 | 2. To provide a way for students to contribute to this course. 9 | -------------------------------------------------------------------------------- /students/adeel41/arc_option.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | //ArcOption is an option for the story 4 | type ArcOption struct { 5 | Number int 6 | Text string 7 | Arc string 8 | } 9 | 10 | //Load loads the json data into an ArcOption 11 | func (ao *ArcOption) Load(number int, data map[string]interface{}) { 12 | ao.Number = number 13 | ao.Text = data["text"].(string) 14 | ao.Arc = data["arc"].(string) 15 | } 16 | -------------------------------------------------------------------------------- /students/manan/story.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Choose Your Own Adventure 5 | 6 | 7 |

{{.Title}}

8 | {{range .Paragraphs}} 9 |

{{.}}

10 | {{end}} 11 | 16 | -------------------------------------------------------------------------------- /students/adeel41/arc.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{.Title}} 4 | 7 | 8 | 9 |

{{.Title}}

10 |

{{.Paragraph}}

11 | {{range .Options}} 12 | {{.Text}} 13 | {{end}} 14 | 15 | -------------------------------------------------------------------------------- /students/cherednichenkoa/settings/settings.go: -------------------------------------------------------------------------------- 1 | package settings 2 | 3 | type Settings struct { 4 | FilePath string 5 | ListenPort string 6 | TemplatePath string 7 | } 8 | 9 | func (conf *Settings) GetFilePath() string { 10 | return conf.FilePath 11 | } 12 | 13 | func (conf *Settings) GetListenPort() string { 14 | return conf.ListenPort 15 | } 16 | 17 | func (conf *Settings) GetTemplatePath() string { 18 | return conf.TemplatePath 19 | } -------------------------------------------------------------------------------- /students/manan/cmd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "Manan/cyoa" 5 | "flag" 6 | "fmt" 7 | "log" 8 | "net/http" 9 | "os" 10 | ) 11 | 12 | func main() { 13 | filename := flag.String("file", "gopher.json", "the JSON file with CYOA story") 14 | port := flag.Int("port", 8080, "the port to start CYOA Web Application") 15 | flag.Parse() 16 | f, err := os.Open(*filename) 17 | if err != nil { 18 | panic(err) 19 | } 20 | story, err := cyoa.ParseJSON(f) 21 | if err != nil { 22 | panic(err) 23 | } 24 | 25 | h := cyoa.NewHandler(story, nil) 26 | fmt.Printf("Started server at Port %d\n", *port) 27 | log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), h)) 28 | 29 | } 30 | -------------------------------------------------------------------------------- /students/ccallergard/html.go: -------------------------------------------------------------------------------- 1 | package cyoa 2 | 3 | import ( 4 | "html/template" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | // Generate uses given template to create HTML files based on an Adventure 10 | func Generate(cyoa Adventure, dirPath string, templatePath string) error { 11 | err := os.MkdirAll(dirPath, os.ModePerm) 12 | if err != nil { 13 | return err 14 | } 15 | 16 | cyoaTemplate, err := template.ParseFiles(templatePath) 17 | if err != nil { 18 | return err 19 | } 20 | 21 | for sceneName, scene := range cyoa { 22 | path := filepath.Join(dirPath, sceneName+".html") 23 | out, err := os.Create(path) 24 | if err != nil { 25 | return err 26 | } 27 | cyoaTemplate.Execute(out, &scene) 28 | out.Close() 29 | } 30 | 31 | return nil 32 | 33 | } 34 | -------------------------------------------------------------------------------- /students/cherednichenkoa/templates/story.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{.Title}} 6 | 7 | 8 |

{{.Title}}

9 |
10 | {{range .Story}} 11 |

{{.}}

12 | {{end}} 13 |
14 | 27 | 28 | -------------------------------------------------------------------------------- /students/cherednichenkoa/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "flag" 5 | "gopherex/cyoa/students/cherednichenkoa/route-handler" 6 | "gopherex/cyoa/students/cherednichenkoa/settings" 7 | ) 8 | 9 | const ( 10 | storyTemplate = "cherednichenkoa/templates/story.html" 11 | ) 12 | 13 | var ( 14 | filePath = flag.String("filePath","","path to the story source file") 15 | listenPort = flag.String("listenPort","","port number that app will listen") 16 | ) 17 | 18 | func main() { 19 | flag.Parse() 20 | if len(*listenPort) == 0 || len(*filePath) == 0 { 21 | panic("Please specify application params (listenPort and filePath)") 22 | } 23 | config := settings.Settings{FilePath: *filePath, ListenPort: *listenPort, TemplatePath: storyTemplate} 24 | handler := route_handler.RouteHandler{Settings: config} 25 | handler.ServeRequests() 26 | } -------------------------------------------------------------------------------- /students/cherednichenkoa/source/json_file.go: -------------------------------------------------------------------------------- 1 | package source 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "gopherex/cyoa/students/cherednichenkoa/settings" 7 | "io/ioutil" 8 | ) 9 | 10 | type JsonFileHandler struct { 11 | Settings settings.Settings 12 | } 13 | 14 | func (fh *JsonFileHandler) GetFileContent () (map[string]StoryDetails, error) { 15 | file, err := ioutil.ReadFile(fh.Settings.GetFilePath()) 16 | if err != nil { 17 | fmt.Println("Error during json file reading.") 18 | panic(err) 19 | } 20 | var out map[string]StoryDetails 21 | if err := json.Unmarshal(file, &out); err != nil { 22 | return nil, err 23 | } 24 | return out, nil 25 | } 26 | 27 | type StoryOption struct { 28 | Text string `json:"text"` 29 | Arc string `json:"arc"` 30 | } 31 | 32 | type StoryDetails struct { 33 | Title string `json:"title"` 34 | Story []string `json:"story"` 35 | Options []StoryOption `json:"options"` 36 | } 37 | -------------------------------------------------------------------------------- /students/adeel41/console_runner.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | ) 8 | 9 | //ConsoleRunner is a type of `Runner` which displays story in command prompt 10 | type ConsoleRunner struct { 11 | } 12 | 13 | //Start starts the runner by displaying the first story endpoint and then carry on from there 14 | func (cr ConsoleRunner) Start(provider *StoryArcProvider) { 15 | cr.displayArcText(*provider, "intro") 16 | } 17 | 18 | func (cr ConsoleRunner) displayArcText(provider StoryArcProvider, arcName string) { 19 | 20 | arc, err := provider.WriteTemplatedText(os.Stdout, arcName) 21 | if err != nil { 22 | log.Println(err) 23 | } 24 | if len(arc.Options) == 0 { 25 | return 26 | } 27 | fmt.Print("Your Option: ") 28 | var optionNumber int 29 | fmt.Scan(&optionNumber) 30 | for _, option := range arc.Options { 31 | if option.Number == optionNumber { 32 | cr.displayArcText(provider, option.Arc) 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /students/adeel41/story_arc.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | ) 6 | 7 | //StoryArc is an arc of the story which also contains the options to go to other arcs 8 | type StoryArc struct { 9 | Identifier string 10 | Title string 11 | Paragraph string 12 | Options []*ArcOption 13 | } 14 | 15 | //Load loads the json data and set StoryArc 16 | func (sa *StoryArc) Load(key string, data map[string]interface{}) { 17 | var buffer bytes.Buffer 18 | paragraphs := data["story"].([]interface{}) 19 | for _, p := range paragraphs { 20 | buffer.WriteString(p.(string) + "\r\n") 21 | } 22 | 23 | sa.Identifier = key 24 | sa.Title = data["title"].(string) 25 | sa.Paragraph = buffer.String() 26 | 27 | var options []*ArcOption 28 | for i, v := range data["options"].([]interface{}) { 29 | opt := new(ArcOption) 30 | opt.Load(i+1, v.(map[string]interface{})) 31 | options = append(options, opt) 32 | } 33 | sa.Options = options 34 | } 35 | -------------------------------------------------------------------------------- /students/ccallergard/scene_template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CYOA - {{ .Title }}} 6 | 32 | 33 | 34 | 35 |
36 |

{{ .Title }}

37 | {{ range $s := .Story }} 38 |

{{ $s }}

39 | {{ end }} 40 | 41 | {{ range $o := .Options }} 42 | {{ $o.Text }}

43 | {{ end }} 44 |
45 | 46 | 47 | -------------------------------------------------------------------------------- /students/adeel41/story_arc_provider.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "html/template" 5 | "io" 6 | ) 7 | 8 | type TemplateType int 9 | 10 | const ( 11 | ConsoleTemplate TemplateType = 0 12 | WebTemplate TemplateType = 1 13 | ) 14 | 15 | type StoryArcProvider struct { 16 | Story *Story 17 | TemplateType TemplateType 18 | tpl *template.Template 19 | } 20 | 21 | func (sap *StoryArcProvider) Initialize() error { 22 | templateName := "arc.tpl" 23 | if sap.TemplateType == 0 { 24 | templateName = "arc-console.tpl" 25 | } 26 | 27 | t := template.New(templateName) 28 | var err error 29 | sap.tpl, err = t.ParseFiles(templateName) 30 | return err 31 | } 32 | 33 | func (sap StoryArcProvider) WriteTemplatedText(w io.Writer, arcName string) (*StoryArc, error) { 34 | arc, err := sap.Story.GetArc(arcName) 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | err = sap.tpl.Execute(w, arc) 40 | if err != nil { 41 | return nil, err 42 | } 43 | 44 | return arc, nil 45 | } 46 | -------------------------------------------------------------------------------- /students/adeel41/web_runner.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | ) 7 | 8 | //WebRunner is a type of `Runner` which displays story on a web page 9 | type WebRunner struct { 10 | } 11 | 12 | //Start starts the runner by displaying the first story endpoint and then carry on from there 13 | func (wr WebRunner) Start(provider *StoryArcProvider) { 14 | http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { 15 | wr.rootEndpointHandler(provider, w, req) 16 | }) 17 | fmt.Println("Listening on 8888 port .....") 18 | http.ListenAndServe(":8888", nil) 19 | 20 | } 21 | 22 | func (wr WebRunner) rootEndpointHandler(provider *StoryArcProvider, w http.ResponseWriter, req *http.Request) { 23 | 24 | arcValues := req.URL.Query()["arc"] 25 | arcEndpoint := "intro" 26 | if len(arcValues) > 0 { 27 | arcEndpoint = arcValues[0] 28 | } 29 | 30 | _, err := provider.WriteTemplatedText(w, arcEndpoint) 31 | if err != nil { 32 | http.Error(w, err.Error(), 500) 33 | return 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /students/manan/cyoa_test.go: -------------------------------------------------------------------------------- 1 | package cyoa 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | ) 7 | 8 | func TestParseJSON(t *testing.T) { 9 | story := `{ 10 | "intro": { 11 | "title": "The Little Blue Gopher", 12 | "story": [ 13 | "Once upon a time,?", 14 | "On the other h" 15 | ], 16 | "options": [ 17 | { 18 | "text": "That story about the ", 19 | "arc": "new-york" 20 | }, 21 | { 22 | "text": "Gee, those b", 23 | "arc": "home" 24 | } 25 | ] 26 | }, 27 | "new-york": { 28 | "title": "Visiting New York", 29 | "story": [ 30 | "Upon arrivi d.", 31 | "As yto?" 32 | ], 33 | "options": [ 34 | { 35 | "text": "This is ge.", 36 | "arc": "home" 37 | }, 38 | { 39 | "text": "Maybe people .", 40 | "arc": "intro" 41 | } 42 | ] 43 | }, 44 | 45 | "home": { 46 | "title": "Home Sweet Home", 47 | "story": [ 48 | "Your little gopher bna." 49 | ], 50 | "options": [] 51 | } 52 | }` 53 | 54 | _, err := ParseJSON(strings.NewReader(story)) 55 | if err != nil { 56 | t.Error(err) 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /students/dennisvis/templates/main.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{.Title}} 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |
14 |

{{.Title}}

15 |
16 | {{range .Story}} 17 |

{{.}}

18 | {{end}} 19 |
20 |
21 | {{range .Options}} 22 | {{.Text}}

23 | {{end}} 24 |
25 |
26 |
27 |
28 |
29 | 30 | 31 | -------------------------------------------------------------------------------- /students/barisere/cyoa.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Create Your Own Adventure - {{ .Title }} 8 | 9 | 10 | 11 |
12 |

CYOA

13 | {{template "storyArc" .}} 14 |
15 | 16 | 23 | 24 | 26 | 28 | 29 | 30 | {{define "storyArc"}} 31 |

{{.Title}}

32 | {{range .Story}} 33 |

{{.}}

34 | {{end}} 35 | {{if .Options}} 36 | {{range .Options}} 37 |
{{.Text}} 38 | {{end}} 39 | {{else}} 40 |

The end

41 | {{end}} 42 | {{end}} -------------------------------------------------------------------------------- /students/ccallergard/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "flag" 6 | "fmt" 7 | "github.com/gophercises/cyoa/students/ccallergard" 8 | "io/ioutil" 9 | "log" 10 | "net/http" 11 | "strconv" 12 | ) 13 | 14 | var ( 15 | jsonf = flag.String("f", "gopher.json", "Adventure JSON file") 16 | dir = flag.String("d", "_html", "HTML output directory") 17 | port = flag.Int("p", 8080, "HTTP port") 18 | template = flag.String("t", "scene_template.html", "HTML template") 19 | ) 20 | 21 | func main() { 22 | flag.Parse() 23 | 24 | cyoajson, err := ioutil.ReadFile(*jsonf) 25 | if err != nil { 26 | log.Fatal(err) 27 | } 28 | 29 | var adv cyoa.Adventure 30 | err = json.Unmarshal(cyoajson, &adv) 31 | if err != nil { 32 | log.Fatal(err) 33 | } 34 | 35 | err = cyoa.Generate(adv, *dir, *template) 36 | if err != nil { 37 | log.Fatal(err) 38 | } 39 | 40 | cyoaMux := http.NewServeMux() 41 | cyoaMux.Handle("/", http.RedirectHandler("/cyoa/intro.html", http.StatusPermanentRedirect)) 42 | cyoaMux.Handle("/cyoa/", http.StripPrefix("/cyoa/", http.FileServer(http.Dir(*dir)))) 43 | fmt.Println("HTTP server listening on", *port) 44 | log.Fatal(http.ListenAndServe(":"+strconv.Itoa(*port), cyoaMux)) 45 | } 46 | -------------------------------------------------------------------------------- /students/cherednichenkoa/route-handler/route_handler.go: -------------------------------------------------------------------------------- 1 | package route_handler 2 | 3 | import ( 4 | "gopherex/cyoa/students/cherednichenkoa/settings" 5 | "gopherex/cyoa/students/cherednichenkoa/source" 6 | "html/template" 7 | "net/http" 8 | "strings" 9 | ) 10 | 11 | const ( 12 | defaultStory = "intro" 13 | ) 14 | 15 | type RouteHandler struct { 16 | Settings settings.Settings 17 | } 18 | 19 | func (rh *RouteHandler) ServeRequests() { 20 | fileHandler := source.JsonFileHandler{Settings: rh.Settings} 21 | fileContent, err := fileHandler.GetFileContent() 22 | if err != nil { 23 | panic(err) 24 | } 25 | urlHandler := rh.getMapHandler(fileContent) 26 | http.HandleFunc("/", urlHandler) 27 | http.ListenAndServe(rh.getPort(), nil) 28 | } 29 | 30 | func (rh *RouteHandler) getMapHandler(stories map[string]source.StoryDetails) http.HandlerFunc { 31 | return func(w http.ResponseWriter, req *http.Request) { 32 | tmpl := template.Must(template.ParseFiles(rh.Settings.GetTemplatePath())) 33 | path := rh.prepareUrl(req) 34 | story, ok := stories[path] 35 | if ok { 36 | tmpl.Execute(w, story) 37 | return 38 | } 39 | 40 | tmpl.Execute(w, stories[defaultStory]) 41 | } 42 | } 43 | 44 | func (rh *RouteHandler) getPort() string { 45 | port := ":" + rh.Settings.GetListenPort() 46 | return port 47 | } 48 | 49 | func (rh *RouteHandler) prepareUrl(req *http.Request) string { 50 | path := strings.Trim(req.URL.Path,"/") 51 | return path 52 | } -------------------------------------------------------------------------------- /students/adeel41/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "log" 7 | "os" 8 | "strings" 9 | "time" 10 | ) 11 | 12 | func main() { 13 | fmt.Println("Press y key to start the console and ENTER otherwise webserver will be started in 5 seconds...") 14 | keyEntered := make(chan string) 15 | timeout := time.NewTimer(5 * time.Second) 16 | go readInputFromUser(keyEntered) 17 | 18 | select { 19 | case input := <-keyEntered: 20 | if strings.HasPrefix(strings.ToLower(input), "y") { 21 | initliazeAndStart(ConsoleRunner{}) 22 | } else { 23 | initliazeAndStart(WebRunner{}) 24 | } 25 | case <-timeout.C: 26 | initliazeAndStart(WebRunner{}) 27 | } 28 | } 29 | 30 | func readInputFromUser(keyEntered chan string) { 31 | reader := bufio.NewReader(os.Stdin) 32 | input, err := reader.ReadString('\n') 33 | if err != nil { 34 | fmt.Println(err) 35 | } 36 | keyEntered <- input 37 | } 38 | 39 | func initliazeAndStart(runner Runner) { 40 | story := new(Story) 41 | err := story.Load("gopher.json") 42 | if err != nil { 43 | fmt.Println("Stopping program...") 44 | return 45 | } 46 | 47 | tt := ConsoleTemplate 48 | _, ok := runner.(WebRunner) 49 | if ok { 50 | tt = WebTemplate 51 | } 52 | 53 | provider := &StoryArcProvider{ 54 | Story: story, 55 | TemplateType: tt, 56 | } 57 | 58 | err = provider.Initialize() 59 | if err != nil { 60 | log.Panicln(err) 61 | return 62 | } 63 | runner.Start(provider) 64 | } 65 | -------------------------------------------------------------------------------- /students/adeel41/story.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "io/ioutil" 7 | "log" 8 | "os" 9 | ) 10 | 11 | //Story contains all arcs found in the file 12 | type Story struct { 13 | arcs []StoryArc 14 | } 15 | 16 | //Load loads the file and extract all arcs found in json file 17 | func (s *Story) Load(filePath string) error { 18 | jsonData, err := s.getJSON(filePath) 19 | if err != nil { 20 | return err 21 | } 22 | 23 | var arcs []StoryArc 24 | for key, data := range jsonData { 25 | arc := new(StoryArc) 26 | arc.Load(key, data.(map[string]interface{})) 27 | arcs = append(arcs, *arc) 28 | } 29 | s.arcs = arcs 30 | return nil 31 | } 32 | 33 | func (s Story) getJSON(filepath string) (map[string]interface{}, error) { 34 | file, err := os.Open(filepath) 35 | if err != nil { 36 | log.Println("Cannot find gopher.json file") 37 | return nil, err 38 | } 39 | defer file.Close() 40 | bytes, err := ioutil.ReadAll(file) 41 | if err != nil { 42 | log.Println("Unable to read gopher.json file") 43 | return nil, err 44 | } 45 | 46 | var data interface{} 47 | err = json.Unmarshal(bytes, &data) 48 | if err != nil { 49 | log.Println("Cannot parse json specified in gopher.json file") 50 | return nil, err 51 | } 52 | return data.(map[string]interface{}), nil 53 | } 54 | 55 | //GetArc finds the arc specified in the key argument and returns it 56 | func (s Story) GetArc(key string) (*StoryArc, error) { 57 | for _, arc := range s.arcs { 58 | if arc.Identifier == key { 59 | return &arc, nil 60 | } 61 | } 62 | return nil, errors.New("Cannot find " + key + " arc") 63 | } 64 | -------------------------------------------------------------------------------- /students/manan/cyoa.go: -------------------------------------------------------------------------------- 1 | package cyoa 2 | 3 | import ( 4 | "encoding/json" 5 | "io" 6 | "log" 7 | "net/http" 8 | "strings" 9 | "text/template" 10 | ) 11 | 12 | type Story map[string]Chapter 13 | 14 | type Chapter struct { 15 | Title string `json:"title"` 16 | Paragraphs []string `json:"story"` 17 | Options []Option `json:"options"` 18 | } 19 | 20 | type Option struct { 21 | Text string `json:"text"` 22 | Arc string `json:"arc"` 23 | } 24 | 25 | type handler struct { 26 | s Story 27 | t *template.Template 28 | } 29 | 30 | func init() { 31 | tpl = template.Must(template.New("").Parse(defaultHandlerTmpl)) 32 | } 33 | 34 | var tpl *template.Template 35 | 36 | var defaultHandlerTmpl = ` 37 | 38 | 39 | 40 | Choose Your Own Adventure 41 | 42 | 43 |

{{.Title}}

44 | {{range .Paragraphs}} 45 |

{{.}}

46 | {{end}} 47 | 52 | ` 53 | 54 | func ParseJSON(f io.Reader) (Story, error) { 55 | dec := json.NewDecoder(f) 56 | story := make(Story) 57 | if err := dec.Decode(&story); err != nil { 58 | return nil, err 59 | } 60 | return story, nil 61 | } 62 | 63 | func NewHandler(s Story, tmpl *template.Template) http.Handler { 64 | if tmpl == nil { 65 | tmpl = tpl 66 | } 67 | return handler{s, tpl} 68 | } 69 | 70 | func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 71 | 72 | path := strings.TrimSpace(r.URL.Path) 73 | if path == "" || path == "/" { 74 | path = "/intro" 75 | } 76 | path = path[1:] 77 | if chapter, ok := h.s[path]; ok { 78 | err := h.t.Execute(w, chapter) 79 | if err != nil { 80 | log.Printf("%v", err) 81 | http.Error(w, "Something went Wrong...", http.StatusInternalServerError) 82 | } 83 | return 84 | } 85 | http.Error(w, "Chapter Not Found.", http.StatusNotFound) 86 | 87 | } 88 | -------------------------------------------------------------------------------- /students/barisere/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "html/template" 7 | "io" 8 | "io/ioutil" 9 | "log" 10 | "net/http" 11 | "os" 12 | "strings" 13 | ) 14 | 15 | var cyoaTemplate = makeTemplate("cyoa.html") 16 | 17 | // StoryArc is a path in a story 18 | type StoryArc struct { 19 | Title string `json:"title"` 20 | Story []string `json:"story"` 21 | Options []struct { 22 | Text string `json:"text"` 23 | Arc string `json:"arc"` 24 | } `json:"options"` 25 | } 26 | 27 | func (s StoryArc) explainStoryArc() string { 28 | return fmt.Sprintf("%s\n\n\t%s\n", s.Title, strings.Join(s.Story, "\n\t")) 29 | } 30 | 31 | func cliHandler(s StoryArc) string { 32 | fmt.Fprintln(os.Stdout, s.explainStoryArc()) 33 | if len(s.Options) > 0 { 34 | fmt.Fprintln(os.Stdout, "Choose an option:") 35 | for index, option := range s.Options { 36 | fmt.Fprintf(os.Stdout, "\n%d %s: %s\n", index+1, option.Arc, option.Text) 37 | } 38 | var choice int 39 | if _, err := fmt.Fscanf(os.Stdin, "%d", &choice); err != nil { 40 | if err == io.EOF { 41 | return "" 42 | } 43 | log.Fatalln("Error reading option:", err) 44 | } 45 | fmt.Fprintln(os.Stdout, choice, s.Options[0].Arc) 46 | if nextArc := s.Options[choice-1].Arc; nextArc != "" { 47 | return nextArc 48 | } 49 | } 50 | return "" 51 | } 52 | 53 | func makeTemplate(filename string) *template.Template { 54 | return template.Must(template.ParseFiles(filename)) 55 | } 56 | 57 | func (story Story) httpHandler(arc string, w http.ResponseWriter) error { 58 | t, err := cyoaTemplate.Clone() 59 | if err != nil { 60 | return err 61 | } 62 | data := story[arc] 63 | // log.Printf("%+v", data) 64 | return t.Execute(w, data) 65 | } 66 | 67 | // Story is an adventure with story arcs 68 | type Story map[string]StoryArc 69 | 70 | func (story Story) ServeHTTP(w http.ResponseWriter, r *http.Request) { 71 | arc := strings.TrimSpace(r.URL.Path) 72 | if arc == "/" { 73 | arc = "/intro" 74 | } 75 | if strings.HasSuffix(arc, "/") { 76 | arc = strings.TrimSuffix(arc, "/") 77 | } 78 | if err := story.httpHandler(arc[1:], w); err != nil { 79 | log.Println("error rendering template", err) 80 | } 81 | } 82 | 83 | func parseStory(storyMap []byte) (story Story) { 84 | if err := json.Unmarshal(storyMap, &story); err != nil { 85 | log.Fatalf("Error parsing story map: %s", err) 86 | } 87 | return 88 | } 89 | 90 | func (story Story) traverseArcs(arc string, action func(StoryArc) string) { 91 | chosenArc := story[arc] 92 | if nextArc := action(chosenArc); nextArc != "" { 93 | story.traverseArcs(nextArc, action) 94 | } 95 | } 96 | 97 | func main() { 98 | storyMap, err := ioutil.ReadFile("gopher.json") 99 | if err != nil { 100 | log.Fatalf("Unable to read file: %s", err) 101 | } 102 | story := parseStory(storyMap) 103 | // story.traverseArcs("intro", cliHandler) 104 | // fmt.Fprintf(os.Stdout, "%s\n", "End of adventure.") 105 | 106 | r := http.DefaultServeMux 107 | 108 | r.Handle("/", story) 109 | 110 | fmt.Fprintln(os.Stderr, http.ListenAndServe(":3000", story)) 111 | } 112 | -------------------------------------------------------------------------------- /students/dennisvis/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "bytes" 6 | "encoding/json" 7 | "flag" 8 | "fmt" 9 | "net/http" 10 | "os" 11 | "strconv" 12 | "strings" 13 | 14 | "github.com/alecthomas/template" 15 | ) 16 | 17 | var useCLI = flag.Bool("useCLI", false, "Wheher or not to use the CLI version of the game, web-based otherwise") 18 | 19 | type storyOption struct { 20 | Text string 21 | Arc string 22 | } 23 | 24 | type storyArc struct { 25 | Title string 26 | Story []string 27 | Options []storyOption 28 | } 29 | 30 | type storyHandler struct { 31 | storyArcs map[string]storyArc 32 | template *template.Template 33 | } 34 | 35 | func (sh storyHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) { 36 | var path string 37 | if req.URL.Path == "/" { 38 | path = "intro" 39 | } else { 40 | path = strings.TrimLeft(req.URL.Path, "/") 41 | } 42 | storyArc := sh.storyArcs[path] 43 | sh.template.Execute(res, storyArc) 44 | } 45 | 46 | type storyCLI struct { 47 | storyArcs map[string]storyArc 48 | reader *bufio.Reader 49 | } 50 | 51 | func (scli storyCLI) getStoryOption(options []storyOption) storyOption { 52 | nrOfChoices := len(options) 53 | 54 | choice, err := scli.reader.ReadString('\n') 55 | if err != nil { 56 | fmt.Println("Sorry, you're choice could not be read, please try again...") 57 | return scli.getStoryOption(options) 58 | } 59 | 60 | choiceNr, err := strconv.Atoi(strings.TrimRight(choice, "\n")) 61 | if err != nil { 62 | fmt.Println("Sorry, you're choice has to be number, please try again...") 63 | return scli.getStoryOption(options) 64 | } 65 | if choiceNr <= 0 || choiceNr > nrOfChoices { 66 | fmt.Printf("Sorry, you're choice has to be number between %d and %d, please try again...\n", 1, nrOfChoices) 67 | return scli.getStoryOption(options) 68 | } 69 | 70 | return options[choiceNr-1] 71 | } 72 | 73 | func (scli storyCLI) presentStoryArc(storyArcName string) { 74 | storyArc := scli.storyArcs[storyArcName] 75 | 76 | fmt.Printf("\n--- %s ---\n\n", storyArc.Title) 77 | 78 | for _, p := range storyArc.Story { 79 | fmt.Println(p) 80 | } 81 | 82 | if len(storyArc.Options) == 0 { 83 | fmt.Printf("\n\nYour adventure has ended\n\n") 84 | os.Exit(0) 85 | } 86 | 87 | fmt.Println("\nWhat will you do?") 88 | for i, opt := range storyArc.Options { 89 | fmt.Printf("%d: %s\n", i+1, opt.Text) 90 | } 91 | fmt.Println("") 92 | 93 | so := scli.getStoryOption(storyArc.Options) 94 | scli.presentStoryArc(so.Arc) 95 | } 96 | 97 | func (scli storyCLI) start() { 98 | scli.presentStoryArc("intro") 99 | } 100 | 101 | func main() { 102 | flag.Parse() 103 | 104 | f, err := os.Open("gopher.json") 105 | if err != nil { 106 | panic(err) 107 | } 108 | 109 | buf := new(bytes.Buffer) 110 | _, err = buf.ReadFrom(f) 111 | if err != nil { 112 | panic(err) 113 | } 114 | 115 | var storyArcs map[string]storyArc 116 | err = json.Unmarshal(buf.Bytes(), &storyArcs) 117 | if err != nil { 118 | panic(err) 119 | } 120 | 121 | if *useCLI { 122 | storyCLI{storyArcs, bufio.NewReader(os.Stdin)}.start() 123 | } else { 124 | t, err := template.ParseFiles("templates/main.html") 125 | if err != nil { 126 | panic(err) 127 | } 128 | 129 | fmt.Println("Your adventure awaits, open your browser and visit localhost:8080 to begin") 130 | http.ListenAndServe(":8080", storyHandler{storyArcs, t}) 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Exercise #3: Choose your own adventure 2 | 3 | [![exercise status: released](https://img.shields.io/badge/exercise%20status-released-green.svg?style=for-the-badge)](https://gophercises.com/exercises/cyoa) [![demo: ->](https://img.shields.io/badge/demo-%E2%86%92-blue.svg?style=for-the-badge)](https://gophercises.com/demos/cyoa/) 4 | 5 | 6 | ## Exercise details 7 | 8 | [Choose Your Own Adventure](https://en.wikipedia.org/wiki/Choose_Your_Own_Adventure) is (was?) a series of books intended for children where as you read you would occasionally be given options about how you want to proceed. For instance, you might read about a boy walking in a cave when he stumbles across a dark passage or a ladder leading to an upper level and the reader will be presented with two options like: 9 | 10 | - Turn to page 44 to go up the ladder. 11 | - Turn to page 87 to venture down the dark passage. 12 | 13 | The goal of this exercise is to recreate this experience via a web application where each page will be a portion of the story, and at the end of every page the user will be given a series of options to choose from (or be told that they have reached the end of that particular story arc). 14 | 15 | Stories will be provided via a JSON file with the following format: 16 | 17 | ```json 18 | { 19 | // Each story arc will have a unique key that represents 20 | // the name of that particular arc. 21 | "story-arc": { 22 | "title": "A title for that story arc. Think of it like a chapter title.", 23 | "story": [ 24 | "A series of paragraphs, each represented as a string in a slice.", 25 | "This is a new paragraph in this particular story arc." 26 | ], 27 | // Options will be empty if it is the end of that 28 | // particular story arc. Otherwise it will have one or 29 | // more JSON objects that represent an "option" that the 30 | // reader has at the end of a story arc. 31 | "options": [ 32 | { 33 | "text": "the text to render for this option. eg 'venture down the dark passage'", 34 | "arc": "the name of the story arc to navigate to. This will match the story-arc key at the very root of the JSON document" 35 | } 36 | ] 37 | }, 38 | ... 39 | } 40 | ``` 41 | 42 | *See [gopher.json](https://github.com/gophercises/cyoa/blob/master/gopher.json) for a real example of a JSON story. I find that seeing the real JSON file really helps answer any confusion or questions about the JSON format.* 43 | 44 | You are welcome to design the code however you want. You can put everything in a single `main` package, or you can break the story into its own package and use that when creating your http handlers. 45 | 46 | The only real requirements are: 47 | 48 | 1. Use the `html/template` package to create your HTML pages. Part of the purpose of this exercise is to get practice using this package. 49 | 2. Create an `http.Handler` to handle the web requests instead of a handler function. 50 | 3. Use the `encoding/json` package to decode the JSON file. You are welcome to try out third party packages afterwards, but I recommend starting here. 51 | 52 | A few things worth noting: 53 | 54 | - Stories could be cyclical if a user chooses options that keep leading to the same place. This isn't likely to cause issues, but keep it in mind. 55 | - For simplicity, all stories will have a story arc named "intro" that is where the story starts. That is, every JSON file will have a key with the value `intro` and this is where your story should start. 56 | - Matt Holt's JSON-to-Go is a really handy tool when working with JSON in Go! Check it out - 57 | 58 | ## Bonus 59 | 60 | As a bonus exercises you can also: 61 | 62 | 1. Create a command-line version of our Choose Your Own Adventure application where stories are printed out to the terminal and options are picked via typing in numbers ("Press 1 to venture ..."). 63 | 2. Consider how you would alter your program in order to support stories starting form a story-defined arc. That is, what if all stories didn't start on an arc named `intro`? How would you redesign your program or restructure the JSON? This bonus exercises is meant to be as much of a thought exercise as an actual coding one. 64 | -------------------------------------------------------------------------------- /gopher.json: -------------------------------------------------------------------------------- 1 | { 2 | "intro": { 3 | "title": "The Little Blue Gopher", 4 | "story": [ 5 | "Once upon a time, long long ago, there was a little blue gopher. Our little blue friend wanted to go on an adventure, but he wasn't sure where to go. Will you go on an adventure with him?", 6 | "One of his friends once recommended going to New York to make friends at this mysterious thing called \"GothamGo\". It is supposed to be a big event with free swag and if there is one thing gophers love it is free trinkets. Unfortunately, the gopher once heard a campfire story about some bad fellas named the Sticky Bandits who also live in New York. In the stories these guys would rob toy stores and terrorize young boys, and it sounded pretty scary.", 7 | "On the other hand, he has always heard great things about Denver. Great ski slopes, a bad hockey team with cheap tickets, and he even heard they have a conference exclusively for gophers like himself. Maybe Denver would be a safer place to visit." 8 | ], 9 | "options": [ 10 | { 11 | "text": "That story about the Sticky Bandits isn't real, it is from Home Alone 2! Let's head to New York.", 12 | "arc": "new-york" 13 | }, 14 | { 15 | "text": "Gee, those bandits sound pretty real to me. Let's play it safe and try our luck in Denver.", 16 | "arc": "denver" 17 | } 18 | ] 19 | }, 20 | "new-york": { 21 | "title": "Visiting New York", 22 | "story": [ 23 | "Upon arriving in New York you and your furry travel buddy first attempt to hail a cab. Unfortunately nobody wants to give a ride to someone with a \"pet\". They kept saying something about shedding, as if gophers shed.", 24 | "Unwilling to accept defeat, you pull out your phone and request a ride using . In a few short minutes a car pulls up and the driver helps you load your luggage. He doesn't seem thrilled about your travel companion but he doesn't say anything.", 25 | "The ride to your hotel is fairly uneventful, with the exception of the driver droning on and on about how he barely breaks even driving around the city and how tips are necessary to make a living. After a while it gets pretty old so you slip in some earbuds and listen to your music.", 26 | "After arriving at your hotel you check in and walk to the conference center where GothamGo is being held. The friendly man at the desk helped you get your badge and you hurry in to take a seat.", 27 | "As you head down the aisle you notice a strange man on stage with a mask, cape, and poorly drawn abs on his stomach. Next to him is a man in a... is that a fox outfit? What are these two doing? And what have you gotten yourself into?" 28 | ], 29 | "options": [ 30 | { 31 | "text": "This is getting too weird for me. Let's bail and head back home.", 32 | "arc": "home" 33 | }, 34 | { 35 | "text": "Maybe people just dress funny in the big city. Grab a a seat and see what happens.", 36 | "arc": "debate" 37 | } 38 | ] 39 | }, 40 | "debate": { 41 | "title": "The Great Debate", 42 | "story": [ 43 | "After a bit everyone settles down the two people on stage begin having a debate. You don't recall too many specifics, but for some reason you have a feeling you are supposed to pick sides." 44 | ], 45 | "options": [ 46 | { 47 | "text": "Clearly that man in the fox outfit was the winner.", 48 | "arc": "sean-kelly" 49 | }, 50 | { 51 | "text": "I don't think those fake abs would help much in a feat of strength, but our caped friend clearly won this bout. Let's go congratulate him.", 52 | "arc": "mark-bates" 53 | }, 54 | { 55 | "text": "Slip out the back before anyone asks us to pick a side.", 56 | "arc": "home" 57 | } 58 | ] 59 | }, 60 | "sean-kelly": { 61 | "title": "Exit Stage Left", 62 | "story": [ 63 | "As you begin walking up to the fox-man you hear him introduce himself as Sean Kelly. While waiting in line you decide to do a little research to see what types of work Sean is into.", 64 | "A few clicks later and you drop your phone in horror. This guy's online handle is \"StabbyCutyou\". The stories about New York being dangerous were true!", 65 | "Without a thought you grab your gopher buddy and head for the door. \"I'll explain when we get to the hotel\" you tell him.", 66 | "After arriving at your hotel you both decide that you have had enough adventure. First thing tomorrow morning you are heading home." 67 | ], 68 | "options": [ 69 | { 70 | "text": "You change your flight to leave early and head to the airport in the morning.", 71 | "arc": "home" 72 | } 73 | ] 74 | }, 75 | "mark-bates": { 76 | "title": "Costume Time", 77 | "story": [ 78 | "After talking with the wannabe superhero for a while you come to learn that his name is Mark Bates, and aside from his costume obsession he seems like a nice enough guy.", 79 | "It turns our Mark has been working on this project called Buffalo and he is desperately looking for a mascot. He even purchased a little buffalo outfit, but it is too small for him.", 80 | "After looking over the costume you are certain it won't fit you, but as luck would have it your gopher companion fit in it perfectly. Mark quickly snapped a few photos, mumbling something about Ashley McNamara designing the best buffalo costume ever.", 81 | "Many great times are had with Mark and pals, but you eventually find yourself on the last night of your stay." 82 | ], 83 | "options": [ 84 | { 85 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 86 | "arc": "home" 87 | } 88 | ] 89 | }, 90 | "denver": { 91 | "title": "Hockey and Ski Slopes", 92 | "story": [ 93 | "You arrive in Denver and start your trip by attending a hockey game. The Avalanche had a rough season last year, but your gopher buddy is hopeful that they will do better this year. He also explains that he is tired of hearing about \"Two time Stanley Cup champion Phil Kessel.\" You suspect that he is still a little salty about the Penguins beating the San Jose Sharks in the Stanley Cup, but you decide to give him a break.", 94 | "The next day you head to the slopes and blaze a few trails. You can definitely see why Denver is called the \"Mile-High City\". Gorgeous mountain scenery doesn't come close to describing it.", 95 | "You consider checking out this GopherCon you have heard so much about, but a quick check on their website has your gopher buddy vetoing it. It turns out he has a strict, \"No Space Walks\" policy, and refuses to believe that it is just a graphic on the website.", 96 | "The week quickly flies by and before you know it you are packing up to head home." 97 | ], 98 | "options": [ 99 | { 100 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 101 | "arc": "home" 102 | } 103 | ] 104 | }, 105 | "home": { 106 | "title": "Home Sweet Home", 107 | "story": [ 108 | "Your little gopher buddy thanks you for taking him on an adventure. Perhaps next year you can look into travelling abroad - you have both heard that gophers are all the rage in China." 109 | ], 110 | "options": [] 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /students/manan/gopher.json: -------------------------------------------------------------------------------- 1 | { 2 | "intro": { 3 | "title": "The Little Blue Gopher", 4 | "story": [ 5 | "Once upon a time, long long ago, there was a little blue gopher. Our little blue friend wanted to go on an adventure, but he wasn't sure where to go. Will you go on an adventure with him?", 6 | "One of his friends once recommended going to New York to make friends at this mysterious thing called \"GothamGo\". It is supposed to be a big event with free swag and if there is one thing gophers love it is free trinkets. Unfortunately, the gopher once heard a campfire story about some bad fellas named the Sticky Bandits who also live in New York. In the stories these guys would rob toy stores and terrorize young boys, and it sounded pretty scary.", 7 | "On the other hand, he has always heard great things about Denver. Great ski slopes, a bad hockey team with cheap tickets, and he even heard they have a conference exclusively for gophers like himself. Maybe Denver would be a safer place to visit." 8 | ], 9 | "options": [ 10 | { 11 | "text": "That story about the Sticky Bandits isn't real, it is from Home Alone 2! Let's head to New York.", 12 | "arc": "new-york" 13 | }, 14 | { 15 | "text": "Gee, those bandits sound pretty real to me. Let's play it safe and try our luck in Denver.", 16 | "arc": "denver" 17 | } 18 | ] 19 | }, 20 | "new-york": { 21 | "title": "Visiting New York", 22 | "story": [ 23 | "Upon arriving in New York you and your furry travel buddy first attempt to hail a cab. Unfortunately nobody wants to give a ride to someone with a \"pet\". They kept saying something about shedding, as if gophers shed.", 24 | "Unwilling to accept defeat, you pull out your phone and request a ride using . In a few short minutes a car pulls up and the driver helps you load your luggage. He doesn't seem thrilled about your travel companion but he doesn't say anything.", 25 | "The ride to your hotel is fairly uneventful, with the exception of the driver droning on and on about how he barely breaks even driving around the city and how tips are necessary to make a living. After a while it gets pretty old so you slip in some earbuds and listen to your music.", 26 | "After arriving at your hotel you check in and walk to the conference center where GothamGo is being held. The friendly man at the desk helped you get your badge and you hurry in to take a seat.", 27 | "As you head down the aisle you notice a strange man on stage with a mask, cape, and poorly drawn abs on his stomach. Next to him is a man in a... is that a fox outfit? What are these two doing? And what have you gotten yourself into?" 28 | ], 29 | "options": [ 30 | { 31 | "text": "This is getting too weird for me. Let's bail and head back home.", 32 | "arc": "home" 33 | }, 34 | { 35 | "text": "Maybe people just dress funny in the big city. Grab a a seat and see what happens.", 36 | "arc": "debate" 37 | } 38 | ] 39 | }, 40 | "debate": { 41 | "title": "The Great Debate", 42 | "story": [ 43 | "After a bit everyone settles down the two people on stage begin having a debate. You don't recall too many specifics, but for some reason you have a feeling you are supposed to pick sides." 44 | ], 45 | "options": [ 46 | { 47 | "text": "Clearly that man in the fox outfit was the winner.", 48 | "arc": "sean-kelly" 49 | }, 50 | { 51 | "text": "I don't think those fake abs would help much in a feat of strength, but our caped friend clearly won this bout. Let's go congratulate him.", 52 | "arc": "mark-bates" 53 | }, 54 | { 55 | "text": "Slip out the back before anyone asks us to pick a side.", 56 | "arc": "home" 57 | } 58 | ] 59 | }, 60 | "sean-kelly": { 61 | "title": "Exit Stage Left", 62 | "story": [ 63 | "As you begin walking up to the fox-man you hear him introduce himself as Sean Kelly. While waiting in line you decide to do a little research to see what types of work Sean is into.", 64 | "A few clicks later and you drop your phone in horror. This guy's online handle is \"StabbyCutyou\". The stories about New York being dangerous were true!", 65 | "Without a thought you grab your gopher buddy and head for the door. \"I'll explain when we get to the hotel\" you tell him.", 66 | "After arriving at your hotel you both decide that you have had enough adventure. First thing tomorrow morning you are heading home." 67 | ], 68 | "options": [ 69 | { 70 | "text": "You change your flight to leave early and head to the airport in the morning.", 71 | "arc": "home" 72 | } 73 | ] 74 | }, 75 | "mark-bates": { 76 | "title": "Costume Time", 77 | "story": [ 78 | "After talking with the wannabe superhero for a while you come to learn that his name is Mark Bates, and aside from his costume obsession he seems like a nice enough guy.", 79 | "It turns our Mark has been working on this project called Buffalo and he is desperately looking for a mascot. He even purchased a little buffalo outfit, but it is too small for him.", 80 | "After looking over the costume you are certain it won't fit you, but as luck would have it your gopher companion fit in it perfectly. Mark quickly snapped a few photos, mumbling something about Ashley McNamara designing the best buffalo costume ever.", 81 | "Many great times are had with Mark and pals, but you eventually find yourself on the last night of your stay." 82 | ], 83 | "options": [ 84 | { 85 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 86 | "arc": "home" 87 | } 88 | ] 89 | }, 90 | "denver": { 91 | "title": "Hockey and Ski Slopes", 92 | "story": [ 93 | "You arrive in Denver and start your trip by attending a hockey game. The Avalanche had a rough season last year, but your gopher buddy is hopeful that they will do better this year. He also explains that he is tired of hearing about \"Two time Stanley Cup champion Phil Kessel.\" You suspect that he is still a little salty about the Penguins beating the San Jose Sharks in the Stanley Cup, but you decide to give him a break.", 94 | "The next day you head to the slopes and blaze a few trails. You can definitely see why Denver is called the \"Mile-High City\". Gorgeous mountain scenery doesn't come close to describing it.", 95 | "You consider checking out this GopherCon you have heard so much about, but a quick check on their website has your gopher buddy vetoing it. It turns out he has a strict, \"No Space Walks\" policy, and refuses to believe that it is just a graphic on the website.", 96 | "The week quickly flies by and before you know it you are packing up to head home." 97 | ], 98 | "options": [ 99 | { 100 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 101 | "arc": "home" 102 | } 103 | ] 104 | }, 105 | "home": { 106 | "title": "Home Sweet Home", 107 | "story": [ 108 | "Your little gopher buddy thanks you for taking him on an adventure. Perhaps next year you can look into travelling abroad - you have both heard that gophers are all the rage in China." 109 | ], 110 | "options": [] 111 | } 112 | } -------------------------------------------------------------------------------- /students/barisere/gopher.json: -------------------------------------------------------------------------------- 1 | { 2 | "intro": { 3 | "title": "The Little Blue Gopher", 4 | "story": [ 5 | "Once upon a time, long long ago, there was a little blue gopher. Our little blue friend wanted to go on an adventure, but he wasn't sure where to go. Will you go on an adventure with him?", 6 | "One of his friends once recommended going to New York to make friends at this mysterious thing called \"GothamGo\". It is supposed to be a big event with free swag and if there is one thing gophers love it is free trinkets. Unfortunately, the gopher once heard a campfire story about some bad fellas named the Sticky Bandits who also live in New York. In the stories these guys would rob toy stores and terrorize young boys, and it sounded pretty scary.", 7 | "On the other hand, he has always heard great things about Denver. Great ski slopes, a bad hockey team with cheap tickets, and he even heard they have a conference exclusively for gophers like himself. Maybe Denver would be a safer place to visit." 8 | ], 9 | "options": [ 10 | { 11 | "text": "That story about the Sticky Bandits isn't real, it is from Home Alone 2! Let's head to New York.", 12 | "arc": "new-york" 13 | }, 14 | { 15 | "text": "Gee, those bandits sound pretty real to me. Let's play it safe and try our luck in Denver.", 16 | "arc": "denver" 17 | } 18 | ] 19 | }, 20 | "new-york": { 21 | "title": "Visiting New York", 22 | "story": [ 23 | "Upon arriving in New York you and your furry travel buddy first attempt to hail a cab. Unfortunately nobody wants to give a ride to someone with a \"pet\". They kept saying something about shedding, as if gophers shed.", 24 | "Unwilling to accept defeat, you pull out your phone and request a ride using . In a few short minutes a car pulls up and the driver helps you load your luggage. He doesn't seem thrilled about your travel companion but he doesn't say anything.", 25 | "The ride to your hotel is fairly uneventful, with the exception of the driver droning on and on about how he barely breaks even driving around the city and how tips are necessary to make a living. After a while it gets pretty old so you slip in some earbuds and listen to your music.", 26 | "After arriving at your hotel you check in and walk to the conference center where GothamGo is being held. The friendly man at the desk helped you get your badge and you hurry in to take a seat.", 27 | "As you head down the aisle you notice a strange man on stage with a mask, cape, and poorly drawn abs on his stomach. Next to him is a man in a... is that a fox outfit? What are these two doing? And what have you gotten yourself into?" 28 | ], 29 | "options": [ 30 | { 31 | "text": "This is getting too weird for me. Let's bail and head back home.", 32 | "arc": "home" 33 | }, 34 | { 35 | "text": "Maybe people just dress funny in the big city. Grab a a seat and see what happens.", 36 | "arc": "debate" 37 | } 38 | ] 39 | }, 40 | "debate": { 41 | "title": "The Great Debate", 42 | "story": [ 43 | "After a bit everyone settles down the two people on stage begin having a debate. You don't recall too many specifics, but for some reason you have a feeling you are supposed to pick sides." 44 | ], 45 | "options": [ 46 | { 47 | "text": "Clearly that man in the fox outfit was the winner.", 48 | "arc": "sean-kelly" 49 | }, 50 | { 51 | "text": "I don't think those fake abs would help much in a feat of strength, but our caped friend clearly won this bout. Let's go congratulate him.", 52 | "arc": "mark-bates" 53 | }, 54 | { 55 | "text": "Slip out the back before anyone asks us to pick a side.", 56 | "arc": "home" 57 | } 58 | ] 59 | }, 60 | "sean-kelly": { 61 | "title": "Exit Stage Left", 62 | "story": [ 63 | "As you begin walking up to the fox-man you hear him introduce himself as Sean Kelly. While waiting in line you decide to do a little research to see what types of work Sean is into.", 64 | "A few clicks later and you drop your phone in horror. This guy's online handle is \"StabbyCutyou\". The stories about New York being dangerous were true!", 65 | "Without a thought you grab your gopher buddy and head for the door. \"I'll explain when we get to the hotel\" you tell him.", 66 | "After arriving at your hotel you both decide that you have had enough adventure. First thing tomorrow morning you are heading home." 67 | ], 68 | "options": [ 69 | { 70 | "text": "You change your flight to leave early and head to the airport in the morning.", 71 | "arc": "home" 72 | } 73 | ] 74 | }, 75 | "mark-bates": { 76 | "title": "Costume Time", 77 | "story": [ 78 | "After talking with the wannabe superhero for a while you come to learn that his name is Mark Bates, and aside from his costume obsession he seems like a nice enough guy.", 79 | "It turns our Mark has been working on this project called Buffalo and he is desperately looking for a mascot. He even purchased a little buffalo outfit, but it is too small for him.", 80 | "After looking over the costume you are certain it won't fit you, but as luck would have it your gopher companion fit in it perfectly. Mark quickly snapped a few photos, mumbling something about Ashley McNamara designing the best buffalo costume ever.", 81 | "Many great times are had with Mark and pals, but you eventually find yourself on the last night of your stay." 82 | ], 83 | "options": [ 84 | { 85 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 86 | "arc": "home" 87 | } 88 | ] 89 | }, 90 | "denver": { 91 | "title": "Hockey and Ski Slopes", 92 | "story": [ 93 | "You arrive in Denver and start your trip by attending a hockey game. The Avalanche had a rough season last year, but your gopher buddy is hopeful that they will do better this year. He also explains that he is tired of hearing about \"Two time Stanley Cup champion Phil Kessel.\" You suspect that he is still a little salty about the Penguins beating the San Jose Sharks in the Stanley Cup, but you decide to give him a break.", 94 | "The next day you head to the slopes and blaze a few trails. You can definitely see why Denver is called the \"Mile-High City\". Gorgeous mountain scenery doesn't come close to describing it.", 95 | "You consider checking out this GopherCon you have heard so much about, but a quick check on their website has your gopher buddy vetoing it. It turns out he has a strict, \"No Space Walks\" policy, and refuses to believe that it is just a graphic on the website.", 96 | "The week quickly flies by and before you know it you are packing up to head home." 97 | ], 98 | "options": [ 99 | { 100 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 101 | "arc": "home" 102 | } 103 | ] 104 | }, 105 | "home": { 106 | "title": "Home Sweet Home", 107 | "story": [ 108 | "Your little gopher buddy thanks you for taking him on an adventure. Perhaps next year you can look into travelling abroad - you have both heard that gophers are all the rage in China." 109 | ], 110 | "options": [] 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /students/ccallergard/gopher.json: -------------------------------------------------------------------------------- 1 | { 2 | "intro": { 3 | "title": "The Little Blue Gopher", 4 | "story": [ 5 | "Once upon a time, long long ago, there was a little blue gopher. Our little blue friend wanted to go on an adventure, but he wasn't sure where to go. Will you go on an adventure with him?", 6 | "One of his friends once recommended going to New York to make friends at this mysterious thing called \"GothamGo\". It is supposed to be a big event with free swag and if there is one thing gophers love it is free trinkets. Unfortunately, the gopher once heard a campfire story about some bad fellas named the Sticky Bandits who also live in New York. In the stories these guys would rob toy stores and terrorize young boys, and it sounded pretty scary.", 7 | "On the other hand, he has always heard great things about Denver. Great ski slopes, a bad hockey team with cheap tickets, and he even heard they have a conference exclusively for gophers like himself. Maybe Denver would be a safer place to visit." 8 | ], 9 | "options": [ 10 | { 11 | "text": "That story about the Sticky Bandits isn't real, it is from Home Alone 2! Let's head to New York.", 12 | "arc": "new-york" 13 | }, 14 | { 15 | "text": "Gee, those bandits sound pretty real to me. Let's play it safe and try our luck in Denver.", 16 | "arc": "denver" 17 | } 18 | ] 19 | }, 20 | "new-york": { 21 | "title": "Visiting New York", 22 | "story": [ 23 | "Upon arriving in New York you and your furry travel buddy first attempt to hail a cab. Unfortunately nobody wants to give a ride to someone with a \"pet\". They kept saying something about shedding, as if gophers shed.", 24 | "Unwilling to accept defeat, you pull out your phone and request a ride using . In a few short minutes a car pulls up and the driver helps you load your luggage. He doesn't seem thrilled about your travel companion but he doesn't say anything.", 25 | "The ride to your hotel is fairly uneventful, with the exception of the driver droning on and on about how he barely breaks even driving around the city and how tips are necessary to make a living. After a while it gets pretty old so you slip in some earbuds and listen to your music.", 26 | "After arriving at your hotel you check in and walk to the conference center where GothamGo is being held. The friendly man at the desk helped you get your badge and you hurry in to take a seat.", 27 | "As you head down the aisle you notice a strange man on stage with a mask, cape, and poorly drawn abs on his stomach. Next to him is a man in a... is that a fox outfit? What are these two doing? And what have you gotten yourself into?" 28 | ], 29 | "options": [ 30 | { 31 | "text": "This is getting too weird for me. Let's bail and head back home.", 32 | "arc": "home" 33 | }, 34 | { 35 | "text": "Maybe people just dress funny in the big city. Grab a a seat and see what happens.", 36 | "arc": "debate" 37 | } 38 | ] 39 | }, 40 | "debate": { 41 | "title": "The Great Debate", 42 | "story": [ 43 | "After a bit everyone settles down the two people on stage begin having a debate. You don't recall too many specifics, but for some reason you have a feeling you are supposed to pick sides." 44 | ], 45 | "options": [ 46 | { 47 | "text": "Clearly that man in the fox outfit was the winner.", 48 | "arc": "sean-kelly" 49 | }, 50 | { 51 | "text": "I don't think those fake abs would help much in a feat of strength, but our caped friend clearly won this bout. Let's go congratulate him.", 52 | "arc": "mark-bates" 53 | }, 54 | { 55 | "text": "Slip out the back before anyone asks us to pick a side.", 56 | "arc": "home" 57 | } 58 | ] 59 | }, 60 | "sean-kelly": { 61 | "title": "Exit Stage Left", 62 | "story": [ 63 | "As you begin walking up to the fox-man you hear him introduce himself as Sean Kelly. While waiting in line you decide to do a little research to see what types of work Sean is into.", 64 | "A few clicks later and you drop your phone in horror. This guy's online handle is \"StabbyCutyou\". The stories about New York being dangerous were true!", 65 | "Without a thought you grab your gopher buddy and head for the door. \"I'll explain when we get to the hotel\" you tell him.", 66 | "After arriving at your hotel you both decide that you have had enough adventure. First thing tomorrow morning you are heading home." 67 | ], 68 | "options": [ 69 | { 70 | "text": "You change your flight to leave early and head to the airport in the morning.", 71 | "arc": "home" 72 | } 73 | ] 74 | }, 75 | "mark-bates": { 76 | "title": "Costume Time", 77 | "story": [ 78 | "After talking with the wannabe superhero for a while you come to learn that his name is Mark Bates, and aside from his costume obsession he seems like a nice enough guy.", 79 | "It turns our Mark has been working on this project called Buffalo and he is desperately looking for a mascot. He even purchased a little buffalo outfit, but it is too small for him.", 80 | "After looking over the costume you are certain it won't fit you, but as luck would have it your gopher companion fit in it perfectly. Mark quickly snapped a few photos, mumbling something about Ashley McNamara designing the best buffalo costume ever.", 81 | "Many great times are had with Mark and pals, but you eventually find yourself on the last night of your stay." 82 | ], 83 | "options": [ 84 | { 85 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 86 | "arc": "home" 87 | } 88 | ] 89 | }, 90 | "denver": { 91 | "title": "Hockey and Ski Slopes", 92 | "story": [ 93 | "You arrive in Denver and start your trip by attending a hockey game. The Avalanche had a rough season last year, but your gopher buddy is hopeful that they will do better this year. He also explains that he is tired of hearing about \"Two time Stanley Cup champion Phil Kessel.\" You suspect that he is still a little salty about the Penguins beating the San Jose Sharks in the Stanley Cup, but you decide to give him a break.", 94 | "The next day you head to the slopes and blaze a few trails. You can definitely see why Denver is called the \"Mile-High City\". Gorgeous mountain scenery doesn't come close to describing it.", 95 | "You consider checking out this GopherCon you have heard so much about, but a quick check on their website has your gopher buddy vetoing it. It turns out he has a strict, \"No Space Walks\" policy, and refuses to believe that it is just a graphic on the website.", 96 | "The week quickly flies by and before you know it you are packing up to head home." 97 | ], 98 | "options": [ 99 | { 100 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 101 | "arc": "home" 102 | } 103 | ] 104 | }, 105 | "home": { 106 | "title": "Home Sweet Home", 107 | "story": [ 108 | "Your little gopher buddy thanks you for taking him on an adventure. Perhaps next year you can look into travelling abroad - you have both heard that gophers are all the rage in China." 109 | ], 110 | "options": [] 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /students/dennisvis/gopher.json: -------------------------------------------------------------------------------- 1 | { 2 | "intro": { 3 | "title": "The Little Blue Gopher", 4 | "story": [ 5 | "Once upon a time, long long ago, there was a little blue gopher. Our little blue friend wanted to go on an adventure, but he wasn't sure where to go. Will you go on an adventure with him?", 6 | "One of his friends once recommended going to New York to make friends at this mysterious thing called \"GothamGo\". It is supposed to be a big event with free swag and if there is one thing gophers love it is free trinkets. Unfortunately, the gopher once heard a campfire story about some bad fellas named the Sticky Bandits who also live in New York. In the stories these guys would rob toy stores and terrorize young boys, and it sounded pretty scary.", 7 | "On the other hand, he has always heard great things about Denver. Great ski slopes, a bad hockey team with cheap tickets, and he even heard they have a conference exclusively for gophers like himself. Maybe Denver would be a safer place to visit." 8 | ], 9 | "options": [ 10 | { 11 | "text": "That story about the Sticky Bandits isn't real, it is from Home Alone 2! Let's head to New York.", 12 | "arc": "new-york" 13 | }, 14 | { 15 | "text": "Gee, those bandits sound pretty real to me. Let's play it safe and try our luck in Denver.", 16 | "arc": "denver" 17 | } 18 | ] 19 | }, 20 | "new-york": { 21 | "title": "Visiting New York", 22 | "story": [ 23 | "Upon arriving in New York you and your furry travel buddy first attempt to hail a cab. Unfortunately nobody wants to give a ride to someone with a \"pet\". They kept saying something about shedding, as if gophers shed.", 24 | "Unwilling to accept defeat, you pull out your phone and request a ride using . In a few short minutes a car pulls up and the driver helps you load your luggage. He doesn't seem thrilled about your travel companion but he doesn't say anything.", 25 | "The ride to your hotel is fairly uneventful, with the exception of the driver droning on and on about how he barely breaks even driving around the city and how tips are necessary to make a living. After a while it gets pretty old so you slip in some earbuds and listen to your music.", 26 | "After arriving at your hotel you check in and walk to the conference center where GothamGo is being held. The friendly man at the desk helped you get your badge and you hurry in to take a seat.", 27 | "As you head down the aisle you notice a strange man on stage with a mask, cape, and poorly drawn abs on his stomach. Next to him is a man in a... is that a fox outfit? What are these two doing? And what have you gotten yourself into?" 28 | ], 29 | "options": [ 30 | { 31 | "text": "This is getting too weird for me. Let's bail and head back home.", 32 | "arc": "home" 33 | }, 34 | { 35 | "text": "Maybe people just dress funny in the big city. Grab a a seat and see what happens.", 36 | "arc": "debate" 37 | } 38 | ] 39 | }, 40 | "debate": { 41 | "title": "The Great Debate", 42 | "story": [ 43 | "After a bit everyone settles down the two people on stage begin having a debate. You don't recall too many specifics, but for some reason you have a feeling you are supposed to pick sides." 44 | ], 45 | "options": [ 46 | { 47 | "text": "Clearly that man in the fox outfit was the winner.", 48 | "arc": "sean-kelly" 49 | }, 50 | { 51 | "text": "I don't think those fake abs would help much in a feat of strength, but our caped friend clearly won this bout. Let's go congratulate him.", 52 | "arc": "mark-bates" 53 | }, 54 | { 55 | "text": "Slip out the back before anyone asks us to pick a side.", 56 | "arc": "home" 57 | } 58 | ] 59 | }, 60 | "sean-kelly": { 61 | "title": "Exit Stage Left", 62 | "story": [ 63 | "As you begin walking up to the fox-man you hear him introduce himself as Sean Kelly. While waiting in line you decide to do a little research to see what types of work Sean is into.", 64 | "A few clicks later and you drop your phone in horror. This guy's online handle is \"StabbyCutyou\". The stories about New York being dangerous were true!", 65 | "Without a thought you grab your gopher buddy and head for the door. \"I'll explain when we get to the hotel\" you tell him.", 66 | "After arriving at your hotel you both decide that you have had enough adventure. First thing tomorrow morning you are heading home." 67 | ], 68 | "options": [ 69 | { 70 | "text": "You change your flight to leave early and head to the airport in the morning.", 71 | "arc": "home" 72 | } 73 | ] 74 | }, 75 | "mark-bates": { 76 | "title": "Costume Time", 77 | "story": [ 78 | "After talking with the wannabe superhero for a while you come to learn that his name is Mark Bates, and aside from his costume obsession he seems like a nice enough guy.", 79 | "It turns our Mark has been working on this project called Buffalo and he is desperately looking for a mascot. He even purchased a little buffalo outfit, but it is too small for him.", 80 | "After looking over the costume you are certain it won't fit you, but as luck would have it your gopher companion fit in it perfectly. Mark quickly snapped a few photos, mumbling something about Ashley McNamara designing the best buffalo costume ever.", 81 | "Many great times are had with Mark and pals, but you eventually find yourself on the last night of your stay." 82 | ], 83 | "options": [ 84 | { 85 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 86 | "arc": "home" 87 | } 88 | ] 89 | }, 90 | "denver": { 91 | "title": "Hockey and Ski Slopes", 92 | "story": [ 93 | "You arrive in Denver and start your trip by attending a hockey game. The Avalanche had a rough season last year, but your gopher buddy is hopeful that they will do better this year. He also explains that he is tired of hearing about \"Two time Stanley Cup champion Phil Kessel.\" You suspect that he is still a little salty about the Penguins beating the San Jose Sharks in the Stanley Cup, but you decide to give him a break.", 94 | "The next day you head to the slopes and blaze a few trails. You can definitely see why Denver is called the \"Mile-High City\". Gorgeous mountain scenery doesn't come close to describing it.", 95 | "You consider checking out this GopherCon you have heard so much about, but a quick check on their website has your gopher buddy vetoing it. It turns out he has a strict, \"No Space Walks\" policy, and refuses to believe that it is just a graphic on the website.", 96 | "The week quickly flies by and before you know it you are packing up to head home." 97 | ], 98 | "options": [ 99 | { 100 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 101 | "arc": "home" 102 | } 103 | ] 104 | }, 105 | "home": { 106 | "title": "Home Sweet Home", 107 | "story": [ 108 | "Your little gopher buddy thanks you for taking him on an adventure. Perhaps next year you can look into travelling abroad - you have both heard that gophers are all the rage in China." 109 | ], 110 | "options": [] 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /students/adeel41/gopher.json: -------------------------------------------------------------------------------- 1 | { 2 | "intro": { 3 | "title": "The Little Blue Gopher", 4 | "story": [ 5 | "Once upon a time, long long ago, there was a little blue gopher. Our little blue friend wanted to go on an adventure, but he wasn't sure where to go. Will you go on an adventure with him?", 6 | "One of his friends once recommended going to New York to make friends at this mysterious thing called \"GothamGo\". It is supposed to be a big event with free swag and if there is one thing gophers love it is free trinkets. Unfortunately, the gopher once heard a campfire story about some bad fellas named the Sticky Bandits who also live in New York. In the stories these guys would rob toy stores and terrorize young boys, and it sounded pretty scary.", 7 | "On the other hand, he has always heard great things about Denver. Great ski slopes, a bad hockey team with cheap tickets, and he even heard they have a conference exclusively for gophers like himself. Maybe Denver would be a safer place to visit." 8 | ], 9 | "options": [ 10 | { 11 | "text": "That story about the Sticky Bandits isn't real, it is from Home Alone 2! Let's head to New York.", 12 | "arc": "new-york" 13 | }, 14 | { 15 | "text": "Gee, those bandits sound pretty real to me. Let's play it safe and try our luck in Denver.", 16 | "arc": "denver" 17 | } 18 | ] 19 | }, 20 | "new-york": { 21 | "title": "Visiting New York", 22 | "story": [ 23 | "Upon arriving in New York you and your furry travel buddy first attempt to hail a cab. Unfortunately nobody wants to give a ride to someone with a \"pet\". They kept saying something about shedding, as if gophers shed.", 24 | "Unwilling to accept defeat, you pull out your phone and request a ride using . In a few short minutes a car pulls up and the driver helps you load your luggage. He doesn't seem thrilled about your travel companion but he doesn't say anything.", 25 | "The ride to your hotel is fairly uneventful, with the exception of the driver droning on and on about how he barely breaks even driving around the city and how tips are necessary to make a living. After a while it gets pretty old so you slip in some earbuds and listen to your music.", 26 | "After arriving at your hotel you check in and walk to the conference center where GothamGo is being held. The friendly man at the desk helped you get your badge and you hurry in to take a seat.", 27 | "As you head down the aisle you notice a strange man on stage with a mask, cape, and poorly drawn abs on his stomach. Next to him is a man in a... is that a fox outfit? What are these two doing? And what have you gotten yourself into?" 28 | ], 29 | "options": [ 30 | { 31 | "text": "This is getting too weird for me. Let's bail and head back home.", 32 | "arc": "home" 33 | }, 34 | { 35 | "text": "Maybe people just dress funny in the big city. Grab a a seat and see what happens.", 36 | "arc": "debate" 37 | } 38 | ] 39 | }, 40 | "debate": { 41 | "title": "The Great Debate", 42 | "story": [ 43 | "After a bit everyone settles down the two people on stage begin having a debate. You don't recall too many specifics, but for some reason you have a feeling you are supposed to pick sides." 44 | ], 45 | "options": [ 46 | { 47 | "text": "Clearly that man in the fox outfit was the winner.", 48 | "arc": "sean-kelly" 49 | }, 50 | { 51 | "text": "I don't think those fake abs would help much in a feat of strength, but our caped friend clearly won this bout. Let's go congratulate him.", 52 | "arc": "mark-bates" 53 | }, 54 | { 55 | "text": "Slip out the back before anyone asks us to pick a side.", 56 | "arc": "home" 57 | } 58 | ] 59 | }, 60 | "sean-kelly": { 61 | "title": "Exit Stage Left", 62 | "story": [ 63 | "As you begin walking up to the fox-man you hear him introduce himself as Sean Kelly. While waiting in line you decide to do a little research to see what types of work Sean is into.", 64 | "A few clicks later and you drop your phone in horror. This guy's online handle is \"StabbyCutyou\". The stories about New York being dangerous were true!", 65 | "Without a thought you grab your gopher buddy and head for the door. \"I'll explain when we get to the hotel\" you tell him.", 66 | "After arriving at your hotel you both decide that you have had enough adventure. First thing tomorrow morning you are heading home." 67 | ], 68 | "options": [ 69 | { 70 | "text": "You change your flight to leave early and head to the airport in the morning.", 71 | "arc": "home" 72 | } 73 | ] 74 | }, 75 | "mark-bates": { 76 | "title": "Costume Time", 77 | "story": [ 78 | "After talking with the wannabe superhero for a while you come to learn that his name is Mark Bates, and aside from his costume obsession he seems like a nice enough guy.", 79 | "It turns our Mark has been working on this project called Buffalo and he is desperately looking for a mascot. He even purchased a little buffalo outfit, but it is too small for him.", 80 | "After looking over the costume you are certain it won't fit you, but as luck would have it your gopher companion fit in it perfectly. Mark quickly snapped a few photos, mumbling something about Ashley McNamara designing the best buffalo costume ever.", 81 | "Many great times are had with Mark and pals, but you eventually find yourself on the last night of your stay." 82 | ], 83 | "options": [ 84 | { 85 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 86 | "arc": "home" 87 | } 88 | ] 89 | }, 90 | "denver": { 91 | "title": "Hockey and Ski Slopes", 92 | "story": [ 93 | "You arrive in Denver and start your trip by attending a hockey game. The Avalanche had a rough season last year, but your gopher buddy is hopeful that they will do better this year. He also explains that he is tired of hearing about \"Two time Stanley Cup champion Phil Kessel.\" You suspect that he is still a little salty about the Penguins beating the San Jose Sharks in the Stanley Cup, but you decide to give him a break.", 94 | "The next day you head to the slopes and blaze a few trails. You can definitely see why Denver is called the \"Mile-High City\". Gorgeous mountain scenery doesn't come close to describing it.", 95 | "You consider checking out this GopherCon you have heard so much about, but a quick check on their website has your gopher buddy vetoing it. It turns out he has a strict, \"No Space Walks\" policy, and refuses to believe that it is just a graphic on the website.", 96 | "The week quickly flies by and before you know it you are packing up to head home." 97 | ], 98 | "options": [ 99 | { 100 | "text": "Pack your bags and head to bed. We have a long flight in the morning.", 101 | "arc": "home" 102 | } 103 | ] 104 | }, 105 | "home": { 106 | "title": "Home Sweet Home", 107 | "story": [ 108 | "Your little gopher buddy thanks you for taking him on an adventure. Perhaps next year you can look into travelling abroad - you have both heard that gophers are all the rage in China." 109 | ], 110 | "options": [ 111 | { 112 | "text": "Start again......", 113 | "arc": "intro" 114 | } 115 | ] 116 | } 117 | } --------------------------------------------------------------------------------