Skip to content

Instantly share code, notes, and snippets.

@p4tin
Last active February 29, 2024 18:59
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save p4tin/d6261d4b79e4a65c27c1 to your computer and use it in GitHub Desktop.
Save p4tin/d6261d4b79e4a65c27c1 to your computer and use it in GitHub Desktop.
Writing a Text Adventure Game in Go - Part 1
package main
import (
"fmt"
"math/rand"
"time"
)
type Game struct {
Welcome string
Health int
CurrentLocation string
}
func (g *Game) Play() {
fmt.Println(g.Welcome)
for {
fmt.Println(locationMap[g.CurrentLocation].Description)
g.ProcessEvents(locationMap[g.CurrentLocation].Events)
if g.Health <= 0 {
fmt.Println("You are dead, game over!!!")
return
}
fmt.Printf("Health: %d\n", g.Health)
fmt.Println("You can go to these places:")
for index, loc := range locationMap[g.CurrentLocation].Transitions {
fmt.Printf("\t%d - %s\n", index+1, loc)
}
i := 0
for i < 1 || i > len(locationMap[g.CurrentLocation].Transitions) {
fmt.Printf("%s%d%s\n", "Where do you want to go (0 - to quit), [1...", len(locationMap[g.CurrentLocation].Transitions), "]: ")
fmt.Scan(&i)
}
newLoc := i - 1
g.CurrentLocation = locationMap[g.CurrentLocation].Transitions[newLoc]
}
}
func (g *Game) ProcessEvents(events []string) {
for _, evtName := range events {
g.Health += evts[evtName].ProcessEvent()
}
}
type Event struct {
Type string
Chance int
Description string
Health int
Evt string
}
func (e *Event) ProcessEvent() int {
s1 := rand.NewSource(time.Now().UnixNano())
r1 := rand.New(s1)
if e.Chance >= r1.Intn(100) {
hp := e.Health
if e.Type == "Combat" {
fmt.Println("Combat Event")
}
fmt.Printf("\t%s\n", e.Description)
if e.Evt != "" {
hp = hp + evts[e.Evt].ProcessEvent()
}
return hp
}
return 0
}
type Location struct {
Description string
Transitions []string
Events []string
}
var evts = map[string]*Event{
"alienAttack": {Type: "Combat", Chance: 20, Description: "An alien beams in front of you and shoots you with a ray gun.", Health: -50, Evt: "doctorTreatment"},
"doctorTreatment": {Type: "Story", Chance: 10, Description: "The doctor rushes in and inject you with a health boost.", Health: +30, Evt: ""},
"android": {Type: "Story", Chance: 50, Description: "Data is in the turbo lift and says hi to you", Health: 0, Evt: ""},
"relaxing": {Type: "Story", Chance: 100, Description: "In the lounge you are so relaxed that your health improves.", Health: +10, Evt: ""},
}
var locationMap = map[string]*Location{
"Bridge": {"You are on the bridge of a spaceship sitting in the Captain's chair.", []string{"Ready Room", "Turbo Lift"}, []string{"alienAttack"}},
"Ready Room": {"The Captain's ready room.", []string{"Bridge"}, []string{}},
"Turbo Lift": {"A Turbo Lift that takes you anywhere in the ship.", []string{"Bridge", "Lounge", "Engineering"}, []string{"android"}},
"Engineering": {"You are in engineering where you see the star drive", []string{"Turbo Lift"}, []string{"alienAttack"}},
"Lounge": {"You are in the lounge, you feel very relaxed", []string{"Turbo Lift"}, []string{"relaxing"}},
}
func main() {
g := &Game{Health: 100, Welcome: "Welcome to the Starship Enterprise\n\n", CurrentLocation: "Bridge"}
g.Play()
}
@dmitshur
Copy link

dmitshur commented Apr 1, 2016

Nice! But shouldn't it be:

if g.Health <= 0 {

As is, you can have 0 health and still live, which is kinda unusual.

@p4tin
Copy link
Author

p4tin commented Apr 25, 2016

@shurcooL - you are correct the code was fixed also there was a problem in the process event if there was a sub-event the main events (g.Health was being modified unintentionally that was also fixed.

@christophelg
Copy link

You should store a Location object in the Game struct, then your code in Game.Play would be simplified

@scottjbarr
Copy link

@christophelg Just for laughs, here is a version that uses a *Location instead of a string for Game.CurrentLocation https://gist.github.com/scottjbarr/b5ad784430a0aded9cbb07fdc9b39274

@christophelg
Copy link

@scottjbarr, Congratulations ! 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment