分享一个golang数据结构相关的文字迷宫小游戏

文字游戏效果图

在这里插入图片描述

代码

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

type choices struct {
	cmd         string
	description string
	nextNode    *storyNode
	nextChoice  *choices
}

type storyNode struct {
	text    string
	choices *choices
}

func (node *storyNode) addChoice(cmd string, description string, nextNode *storyNode) {
	choice := &choices{cmd, description, nextNode, nil}
	if node.choices == nil {
		node.choices = choice
	} else {
		currentChoice := node.choices

		for currentChoice.nextChoice != nil {
			currentChoice = currentChoice.nextChoice
		}
		currentChoice.nextChoice = choice
	}
}

func (node *storyNode) render() {
	fmt.Println(node.text)

	currentChoice := node.choices

	for currentChoice != nil {
		fmt.Println(currentChoice.cmd, ":", currentChoice.description)
		currentChoice = currentChoice.nextChoice
	}
}

func (node *storyNode) executeCmd(cmd string) *storyNode {
	currentChoice := node.choices

	for currentChoice != nil {
		if strings.ToLower(currentChoice.cmd) == strings.ToLower(cmd) {
			return currentChoice.nextNode
		}

		currentChoice = currentChoice.nextChoice
	}
	fmt.Println("Sorry I didn't understand that.")

	return node
}

var scanner *bufio.Scanner

func (node *storyNode) play() {
	node.render()

	if node.choices != nil {
		scanner.Scan()
		node.executeCmd(scanner.Text()).play()
	}
}
func main() {
	scanner = bufio.NewScanner(os.Stdin)

	start := storyNode{text: `You are in large chamber,deep underground.You see three passages leading out.A north passage 
	into darkness.To the south,a passage appears to head upward.The easter appears flat and well traveled.`}
	darkRoom := storyNode{text: `It is pitch black.You cannot see a thing.`}
	darkRoomLit := storyNode{text: `The dark passage is now lit by your lantern. You can continue north or head back south.`}
	grue := storyNode{text: `while stumbling around in the darkness, you are eaten by a grue`}
	trap := storyNode{text: `You head down the well traveled path when suddenly a trap door opens and yo u fall into a pit`}
	treasure := storyNode{text: `You arrive at a small chamber,filled with treasure!`}

	start.addChoice("N", "go north", &darkRoom)
	start.addChoice("S", "go south", &darkRoom)
	start.addChoice("E", "go east", &trap)

	darkRoom.addChoice("S", "Try to go back south", &grue)
	darkRoom.addChoice("O", "Turn on lantern", &darkRoomLit)

	darkRoomLit.addChoice("N","Go North",&treasure)
	darkRoomLit.addChoice("S","Go South",&start)

	start.play()

	fmt.Println()
	fmt.Println("The End.")
}

理解

storyNode是一堆离散的故事节点,choice是一组行为链表,
每一个离散的故事节点会在尾部衔接一堆choice行为,每个choice又会通过输入连接到不同的故事节点。很适合理解go关于图的数据结构。

视频原连接 go游戏编程系列 油管上找到的。

https://www.youtube.com/watch?v=u87bfwSGtrg&list=PLDZujg-VgQlZUy1iCqBbe5faZLMkA3g2x&index=6

在这里插入图片描述
画了上面这张图来解释一下,这是一个关于图的文字游戏,方块是故事节点,圈是行为链表。然后他们的关系就是图中画的那样,理解代码最重要,我写的英文和字以及图很丑不重要,学习到东西才是重点。

链表更换为数组

下面贴出数组实现的代码,很简单就是把行为链表换成数组就行了。

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

type choices struct {
	cmd         string
	description string
	nextNode    *storyNode
}

type storyNode struct {
	text    string
	choices []*choices
}

func (node *storyNode) addChoice(cmd string, description string, nextNode *storyNode) {
	choice:=&choices{cmd,description,nextNode}
	node.choices=append(node.choices,choice)
}

func (node *storyNode) render() {
	fmt.Println(node.text)

	if node.choices!=nil{
		for _,choice:=range  node.choices{
			fmt.Println(choice.cmd,choice.description)
		}
	}
}

func (node *storyNode) executeCmd(cmd string) *storyNode {
	for _,choice:=range node.choices{
		if strings.ToLower(choice.cmd)==strings.ToLower(cmd){
			return choice.nextNode
		}
	}

	fmt.Println("sorry ,i didn't understand that.")

	return node
}

var scanner *bufio.Scanner

func (node *storyNode) play() {
	node.render()

	if node.choices != nil {
		scanner.Scan()
		node.executeCmd(scanner.Text()).play()
	}
}
func main() {
	scanner = bufio.NewScanner(os.Stdin)

	start := storyNode{text: `You are in large chamber,deep underground.You see three passages leading out.A north passage 
	into darkness.To the south,a passage appears to head upward.The easter appears flat and well traveled.`}
	darkRoom := storyNode{text: `It is pitch black.You cannot see a thing.`}
	darkRoomLit := storyNode{text: `The dark passage is now lit by your lantern. You can continue north or head back south.`}
	grue := storyNode{text: `while stumbling around in the darkness, you are eaten by a grue`}
	trap := storyNode{text: `You head down the well traveled path when suddenly a trap door opens and yo u fall into a pit`}
	treasure := storyNode{text: `You arrive at a small chamber,filled with treasure!`}

	start.addChoice("N", "go north", &darkRoom)
	start.addChoice("S", "go south", &darkRoom)
	start.addChoice("E", "go east", &trap)

	darkRoom.addChoice("S", "Try to go back south", &grue)
	darkRoom.addChoice("O", "Turn on lantern", &darkRoomLit)

	darkRoomLit.addChoice("N", "Go North", &treasure)
	darkRoomLit.addChoice("S", "Go South", &start)

	start.play()

	fmt.Println()
	fmt.Println("The End.")
}

优化 实现

下图是优化后的版本
在这里插入图片描述
方块依旧是故事节点,数组是行为列表,当输入遍历的角色来到没有行为列表的故事节点后游戏终止。

其实如果有精力的话,下面是油管博主的额外建议可拓展
//homework
//add npc non player characters talk to them,fight
//npc move around the graph
//items can picked up or placed down
//accept natural language as input

//verb noun
//north south east west

//build you own with this
//big state machine

可以添加故事节点支持玩家对话,npc对话,以及npc移动,包括可以打怪。
也可以做自然语言输入来进行交互,当然如果有足够精力的话可以搞一些当输入对话中含有某些动词,名词时候触发新的行为,故事,boss等。

加油学习,GO万岁

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值