refactor: 移除过时的 round.Round 实现,使用 round.TurnBased 替代
This commit is contained in:
parent
fde6d52c60
commit
1e0ef4b062
|
@ -1,263 +0,0 @@
|
|||
package fight
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/kercylan98/minotaur/utils/random"
|
||||
"github.com/kercylan98/minotaur/utils/slice"
|
||||
"github.com/kercylan98/minotaur/utils/timer"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RoundGameOverVerifyHandle 回合制游戏结束验证函数
|
||||
type RoundGameOverVerifyHandle[Data RoundData] func(round *Round[Data]) bool
|
||||
|
||||
// NewRound 创建一个新的回合制游戏
|
||||
// - data 游戏数据
|
||||
// - camps 阵营
|
||||
// - roundGameOverVerifyHandle 游戏结束验证函数
|
||||
// - options 选项
|
||||
//
|
||||
// Deprecated: 从 Minotaur 0.2.7 开始,由于设计原因已弃用,请尝试考虑使用 fight.TurnBased 进行代替
|
||||
func NewRound[Data RoundData](data Data, camps []*RoundCamp, roundGameOverVerifyHandle RoundGameOverVerifyHandle[Data], options ...RoundOption[Data]) *Round[Data] {
|
||||
mark := random.HostName()
|
||||
round := &Round[Data]{
|
||||
mark: mark,
|
||||
data: data,
|
||||
camps: make(map[int][]int),
|
||||
actionTimeoutTickerName: fmt.Sprintf("round_action_timeout_%s", mark),
|
||||
roundGameOverVerifyHandle: roundGameOverVerifyHandle,
|
||||
}
|
||||
for _, camp := range camps {
|
||||
round.camps[camp.campId] = camp.entities
|
||||
round.campOrder = append(round.campOrder, camp.campId)
|
||||
}
|
||||
round.campOrderSource = slice.Copy(round.campOrder)
|
||||
for _, option := range options {
|
||||
option(round)
|
||||
}
|
||||
if round.ticker == nil {
|
||||
round.ticker = timer.GetTicker(5, timer.WithMark(mark))
|
||||
}
|
||||
return round
|
||||
}
|
||||
|
||||
// Round 回合制游戏结构
|
||||
type Round[Data RoundData] struct {
|
||||
mark string // 标记
|
||||
data Data // 游戏数据
|
||||
ticker *timer.Ticker // 计时器
|
||||
camps map[int][]int // 阵营
|
||||
campOrder []int // 阵营顺序
|
||||
campOrderSource []int // 阵营顺序源
|
||||
actionTimeout time.Duration // 行动超时时间
|
||||
actionTimeoutTickerName string // 行动超时计时器名称
|
||||
actionTimeoutTime int64 // 行动超时时间
|
||||
round int // 回合数
|
||||
roundCount int // 回合计数
|
||||
currentCamp int // 当前行动阵营
|
||||
currentEntity int // 当前行动的阵营实体索引
|
||||
shareAction bool // 是否共享行动(同阵营共享行动时间)
|
||||
roundGameOverVerifyHandle RoundGameOverVerifyHandle[Data] // 游戏结束验证函数
|
||||
campCounterclockwise bool // 是否阵营逆时针
|
||||
entityCounterclockwise bool // 是否对象逆时针
|
||||
|
||||
swapCampEventHandles []RoundSwapCampEvent[Data] // 阵营交换事件
|
||||
swapEntityEventHandles []RoundSwapEntityEvent[Data] // 实体交换事件
|
||||
gameOverEventHandles []RoundGameOverEvent[Data] // 游戏结束事件
|
||||
changeEventHandles []RoundChangeEvent[Data] // 游戏回合变更事件
|
||||
actionTimeoutEventHandles []RoundActionTimeoutEvent[Data] // 行动超时事件
|
||||
actionRefreshEventHandles []RoundActionRefreshEvent[Data] // 行动刷新事件
|
||||
|
||||
//actionMutex sync.Mutex
|
||||
}
|
||||
|
||||
// GetData 获取游戏数据
|
||||
func (slf *Round[Data]) GetData() Data {
|
||||
return slf.data
|
||||
}
|
||||
|
||||
// Start 开始回合
|
||||
// - 将通过传入的 Camp 进行初始化,Camp 为一个二维数组,每个数组内的元素都是一个行动标识
|
||||
func (slf *Round[Data]) Start() {
|
||||
slf.currentEntity = -1
|
||||
slf.round = 1
|
||||
//slf.actionMutex.Lock()
|
||||
//defer slf.actionMutex.Unlock()
|
||||
slf.loop(false)
|
||||
}
|
||||
|
||||
// Stop 停止回合
|
||||
// - 停止回合时仅会停止行动超时计时器,其他所有数据均会保留
|
||||
// - 若要重置回合,需要调用 Reset 方法
|
||||
func (slf *Round[Data]) Stop() {
|
||||
slf.ticker.StopTimer(slf.actionTimeoutTickerName)
|
||||
}
|
||||
|
||||
// Reset 重置回合
|
||||
func (slf *Round[Data]) Reset() {
|
||||
slf.ticker.StopTimer(slf.actionTimeoutTickerName)
|
||||
slf.currentCamp = 0
|
||||
slf.currentEntity = 0
|
||||
slf.round = 0
|
||||
slf.roundCount = 0
|
||||
slf.campOrder = slice.Copy(slf.campOrderSource)
|
||||
}
|
||||
|
||||
// Release 释放资源
|
||||
func (slf *Round[Data]) Release() {
|
||||
if slf.mark == slf.ticker.Mark() {
|
||||
slf.ticker.Release()
|
||||
return
|
||||
}
|
||||
slf.ticker.StopTimer(slf.actionTimeoutTickerName)
|
||||
}
|
||||
|
||||
func (slf *Round[Data]) loop(timeout bool) {
|
||||
slf.ticker.StopTimer(slf.actionTimeoutTickerName)
|
||||
if timeout {
|
||||
slf.OnActionTimeoutEvent()
|
||||
}
|
||||
if slf.roundGameOverVerifyHandle(slf) {
|
||||
slf.OnGameOverEvent()
|
||||
return
|
||||
} else {
|
||||
slf.ActionRefresh()
|
||||
}
|
||||
if slf.currentEntity == -1 || slf.currentEntity >= len(slf.camps[slf.currentCamp])-1 {
|
||||
if !slf.campCounterclockwise {
|
||||
slf.currentCamp = slf.campOrder[0]
|
||||
slf.campOrder = append(slf.campOrder[1:], slf.currentCamp)
|
||||
} else {
|
||||
slf.currentCamp = slf.campOrder[len(slf.campOrder)-1]
|
||||
slf.campOrder = append([]int{slf.currentCamp}, slf.campOrder[:len(slf.campOrder)-1]...)
|
||||
}
|
||||
|
||||
slf.currentEntity = -1
|
||||
slf.roundCount++
|
||||
if slf.roundCount > len(slf.camps) {
|
||||
slf.round++
|
||||
slf.roundCount = 1
|
||||
slf.OnChangeEvent()
|
||||
}
|
||||
slf.OnSwapCampEvent()
|
||||
}
|
||||
slf.currentEntity++
|
||||
slf.OnSwapEntityEvent()
|
||||
}
|
||||
|
||||
// SetCurrent 设置当前行动对象
|
||||
func (slf *Round[Data]) SetCurrent(campId int, entityId int) {
|
||||
camp, exist := slf.camps[campId]
|
||||
if !exist || !slice.Contains(camp, entityId) {
|
||||
return
|
||||
}
|
||||
slf.currentCamp = campId
|
||||
slf.currentEntity = slice.GetIndex(camp, entityId)
|
||||
}
|
||||
|
||||
// SkipCamp 跳过当前阵营剩余对象的行动
|
||||
func (slf *Round[Data]) SkipCamp() {
|
||||
slf.currentEntity = -1
|
||||
}
|
||||
|
||||
// ActionRefresh 刷新行动超时时间
|
||||
func (slf *Round[Data]) ActionRefresh() {
|
||||
slf.actionTimeoutTime = time.Now().Add(slf.actionTimeout).Unix()
|
||||
slf.ticker.After(slf.actionTimeoutTickerName, slf.actionTimeout, func(timeout bool) {
|
||||
//slf.actionMutex.Lock()
|
||||
//defer slf.actionMutex.Unlock()
|
||||
slf.loop(timeout)
|
||||
}, true)
|
||||
}
|
||||
|
||||
// ActionFinish 结束行动
|
||||
func (slf *Round[Data]) ActionFinish() {
|
||||
slf.ticker.StopTimer(slf.actionTimeoutTickerName)
|
||||
if slf.shareAction {
|
||||
slf.currentEntity = -1
|
||||
}
|
||||
//slf.actionMutex.Lock()
|
||||
//defer slf.actionMutex.Unlock()
|
||||
slf.loop(false)
|
||||
}
|
||||
|
||||
// GetRound 获取当前回合数
|
||||
func (slf *Round[Data]) GetRound() int {
|
||||
return slf.round
|
||||
}
|
||||
|
||||
// GetActionTimeoutTime 获取行动超时时间
|
||||
func (slf *Round[Data]) GetActionTimeoutTime() int64 {
|
||||
return slf.actionTimeoutTime
|
||||
}
|
||||
|
||||
// AllowAction 是否允许行动
|
||||
func (slf *Round[Data]) AllowAction(camp, entity int) bool {
|
||||
return (slf.currentCamp == camp && slf.currentEntity == entity) || slf.shareAction && camp == slf.currentCamp
|
||||
}
|
||||
|
||||
// CampAllowAction 阵容是否允许行动
|
||||
func (slf *Round[Data]) CampAllowAction(camp int) bool {
|
||||
return slf.currentCamp == camp
|
||||
}
|
||||
|
||||
// GetCurrentCamp 获取当前行动的阵营
|
||||
func (slf *Round[Data]) GetCurrentCamp() int {
|
||||
return slf.currentCamp
|
||||
}
|
||||
|
||||
// GetCurrentRoundProgressRate 获取当前回合进度
|
||||
func (slf *Round[Data]) GetCurrentRoundProgressRate() float64 {
|
||||
return float64(slf.roundCount / len(slf.camps))
|
||||
}
|
||||
|
||||
// GetCurrent 获取当前行动的阵营和对象
|
||||
func (slf *Round[Data]) GetCurrent() (camp, entity int) {
|
||||
return slf.currentCamp, slf.camps[slf.currentCamp][slf.currentEntity]
|
||||
}
|
||||
|
||||
// OnSwapCampEvent 触发阵营交换事件
|
||||
func (slf *Round[Data]) OnSwapCampEvent() {
|
||||
for _, handle := range slf.swapCampEventHandles {
|
||||
handle(slf, slf.currentCamp)
|
||||
}
|
||||
}
|
||||
|
||||
// OnSwapEntityEvent 触发实体交换事件
|
||||
func (slf *Round[Data]) OnSwapEntityEvent() {
|
||||
for _, handle := range slf.swapEntityEventHandles {
|
||||
if slf.entityCounterclockwise {
|
||||
handle(slf, slf.currentCamp, slf.camps[slf.currentCamp][len(slf.camps[slf.currentCamp])-slf.currentEntity-1])
|
||||
} else {
|
||||
handle(slf, slf.currentCamp, slf.camps[slf.currentCamp][slf.currentEntity])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// OnGameOverEvent 触发游戏结束事件
|
||||
func (slf *Round[Data]) OnGameOverEvent() {
|
||||
for _, handle := range slf.gameOverEventHandles {
|
||||
handle(slf)
|
||||
}
|
||||
}
|
||||
|
||||
// OnChangeEvent 触发回合变更事件
|
||||
func (slf *Round[Data]) OnChangeEvent() {
|
||||
for _, handle := range slf.changeEventHandles {
|
||||
handle(slf)
|
||||
}
|
||||
}
|
||||
|
||||
// OnActionTimeoutEvent 触发行动超时事件
|
||||
func (slf *Round[Data]) OnActionTimeoutEvent() {
|
||||
for _, handle := range slf.actionTimeoutEventHandles {
|
||||
handle(slf, slf.currentCamp, slf.camps[slf.currentCamp][slf.currentEntity])
|
||||
}
|
||||
}
|
||||
|
||||
// OnActionRefreshEvent 触发行动刷新事件
|
||||
func (slf *Round[Data]) OnActionRefreshEvent() {
|
||||
for _, handle := range slf.actionRefreshEventHandles {
|
||||
handle(slf, slf.currentCamp, slf.camps[slf.currentCamp][slf.currentEntity])
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package fight
|
||||
|
||||
// NewRoundCamp 创建一个新的回合制游戏阵营
|
||||
func NewRoundCamp(campId, entity int, entities ...int) *RoundCamp {
|
||||
return &RoundCamp{
|
||||
campId: campId,
|
||||
entities: append([]int{entity}, entities...),
|
||||
}
|
||||
}
|
||||
|
||||
// RoundCamp 回合制游戏阵营
|
||||
type RoundCamp struct {
|
||||
campId int
|
||||
entities []int
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
package fight
|
||||
|
||||
// RoundData 回合制游戏数据
|
||||
type RoundData interface {
|
||||
// 占位
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
package fight
|
||||
|
||||
import (
|
||||
"github.com/kercylan98/minotaur/utils/timer"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RoundOption 回合制游戏选项
|
||||
type RoundOption[Data RoundData] func(round *Round[Data])
|
||||
|
||||
type (
|
||||
RoundSwapCampEvent[Data RoundData] func(round *Round[Data], campId int)
|
||||
RoundSwapEntityEvent[Data RoundData] func(round *Round[Data], campId, entity int)
|
||||
RoundGameOverEvent[Data RoundData] func(round *Round[Data])
|
||||
RoundChangeEvent[Data RoundData] func(round *Round[Data])
|
||||
RoundActionTimeoutEvent[Data RoundData] func(round *Round[Data], campId, entity int)
|
||||
RoundActionRefreshEvent[Data RoundData] func(round *Round[Data], campId, entity int)
|
||||
)
|
||||
|
||||
// WithRoundTicker 设置游戏的计时器
|
||||
func WithRoundTicker[Data RoundData](ticker *timer.Ticker) RoundOption[Data] {
|
||||
return func(round *Round[Data]) {
|
||||
round.ticker = ticker
|
||||
}
|
||||
}
|
||||
|
||||
// WithRoundActionTimeout 设置游戏的行动超时时间
|
||||
func WithRoundActionTimeout[Data RoundData](timeout time.Duration) RoundOption[Data] {
|
||||
return func(round *Round[Data]) {
|
||||
round.actionTimeout = timeout
|
||||
}
|
||||
}
|
||||
|
||||
// WithRoundShareAction 设置游戏的行动是否共享
|
||||
func WithRoundShareAction[Data RoundData](share bool) RoundOption[Data] {
|
||||
return func(round *Round[Data]) {
|
||||
round.shareAction = share
|
||||
}
|
||||
}
|
||||
|
||||
// WithRoundSwapCampEvent 设置游戏的阵营交换事件
|
||||
// - 该事件在触发时已经完成了阵营的交换
|
||||
func WithRoundSwapCampEvent[Data RoundData](swapCampEventHandle RoundSwapCampEvent[Data]) RoundOption[Data] {
|
||||
return func(round *Round[Data]) {
|
||||
round.swapCampEventHandles = append(round.swapCampEventHandles, swapCampEventHandle)
|
||||
}
|
||||
}
|
||||
|
||||
// WithRoundSwapEntityEvent 设置游戏的实体交换事件
|
||||
// - 该事件在触发时已经完成了实体的交换
|
||||
func WithRoundSwapEntityEvent[Data RoundData](swapEntityEventHandle RoundSwapEntityEvent[Data]) RoundOption[Data] {
|
||||
return func(round *Round[Data]) {
|
||||
round.swapEntityEventHandles = append(round.swapEntityEventHandles, swapEntityEventHandle)
|
||||
}
|
||||
}
|
||||
|
||||
// WithRoundGameOverEvent 设置游戏的结束事件
|
||||
func WithRoundGameOverEvent[Data RoundData](gameOverEventHandle RoundGameOverEvent[Data]) RoundOption[Data] {
|
||||
return func(round *Round[Data]) {
|
||||
round.gameOverEventHandles = append(round.gameOverEventHandles, gameOverEventHandle)
|
||||
}
|
||||
}
|
||||
|
||||
// WithRoundChangeEvent 设置游戏的回合变更事件
|
||||
// - 该事件在触发时已经完成了回合的变更
|
||||
func WithRoundChangeEvent[Data RoundData](changeEventHandle RoundChangeEvent[Data]) RoundOption[Data] {
|
||||
return func(round *Round[Data]) {
|
||||
round.changeEventHandles = append(round.changeEventHandles, changeEventHandle)
|
||||
}
|
||||
}
|
||||
|
||||
// WithRoundActionTimeoutEvent 设置游戏的超时事件
|
||||
func WithRoundActionTimeoutEvent[Data RoundData](timeoutEventHandle RoundActionTimeoutEvent[Data]) RoundOption[Data] {
|
||||
return func(round *Round[Data]) {
|
||||
round.actionTimeoutEventHandles = append(round.actionTimeoutEventHandles, timeoutEventHandle)
|
||||
}
|
||||
}
|
||||
|
||||
// WithRoundCampCounterclockwise 设置游戏阵营逆序执行
|
||||
func WithRoundCampCounterclockwise[Data RoundData]() RoundOption[Data] {
|
||||
return func(round *Round[Data]) {
|
||||
round.campCounterclockwise = true
|
||||
}
|
||||
}
|
||||
|
||||
// WithRoundEntityCounterclockwise 设置游戏实体逆序执行
|
||||
func WithRoundEntityCounterclockwise[Data RoundData]() RoundOption[Data] {
|
||||
return func(round *Round[Data]) {
|
||||
round.entityCounterclockwise = true
|
||||
}
|
||||
}
|
||||
|
||||
// WithRoundActionRefreshEvent 设置游戏的行动刷新事件
|
||||
func WithRoundActionRefreshEvent[Data RoundData](refreshEventHandle RoundActionRefreshEvent[Data]) RoundOption[Data] {
|
||||
return func(round *Round[Data]) {
|
||||
round.actionRefreshEventHandles = append(round.actionRefreshEventHandles, refreshEventHandle)
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package fight
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestName(t *testing.T) {
|
||||
var wait sync.WaitGroup
|
||||
var camps []*RoundCamp
|
||||
camps = append(camps, NewRoundCamp(1, 1, 2, 3))
|
||||
camps = append(camps, NewRoundCamp(2, 4, 5, 6))
|
||||
camps = append(camps, NewRoundCamp(3, 7, 8, 9))
|
||||
r := NewRound("", camps, func(round *Round[string]) bool {
|
||||
return round.GetRound() == 2
|
||||
},
|
||||
WithRoundActionTimeout[string](time.Second),
|
||||
WithRoundSwapEntityEvent[string](func(round *Round[string], campId, entity int) {
|
||||
fmt.Println(campId, entity)
|
||||
if campId == 1 && entity == 2 {
|
||||
round.SetCurrent(1, 1)
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
wait.Add(1)
|
||||
r.Start()
|
||||
wait.Wait()
|
||||
}
|
Loading…
Reference in New Issue