feat: fight 包的 Round 新增操作超时事件,优化事件逻辑
This commit is contained in:
parent
237cbd79cb
commit
9198faa061
|
@ -3,6 +3,7 @@ package fight
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/kercylan98/minotaur/utils/random"
|
"github.com/kercylan98/minotaur/utils/random"
|
||||||
|
"github.com/kercylan98/minotaur/utils/slice"
|
||||||
"github.com/kercylan98/minotaur/utils/timer"
|
"github.com/kercylan98/minotaur/utils/timer"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -16,10 +17,12 @@ type RoundGameOverVerifyHandle[Data RoundData] func(round *Round[Data]) bool
|
||||||
// - roundGameOverVerifyHandle 游戏结束验证函数
|
// - roundGameOverVerifyHandle 游戏结束验证函数
|
||||||
// - options 选项
|
// - options 选项
|
||||||
func NewRound[Data RoundData](data Data, camps []*RoundCamp, roundGameOverVerifyHandle RoundGameOverVerifyHandle[Data], options ...RoundOption[Data]) *Round[Data] {
|
func NewRound[Data RoundData](data Data, camps []*RoundCamp, roundGameOverVerifyHandle RoundGameOverVerifyHandle[Data], options ...RoundOption[Data]) *Round[Data] {
|
||||||
|
mark := random.HostName()
|
||||||
round := &Round[Data]{
|
round := &Round[Data]{
|
||||||
|
mark: mark,
|
||||||
data: data,
|
data: data,
|
||||||
camps: make(map[int][]int),
|
camps: make(map[int][]int),
|
||||||
actionTimeoutTickerName: fmt.Sprintf("round_action_timeout_%s", random.HostName()),
|
actionTimeoutTickerName: fmt.Sprintf("round_action_timeout_%s", mark),
|
||||||
roundGameOverVerifyHandle: roundGameOverVerifyHandle,
|
roundGameOverVerifyHandle: roundGameOverVerifyHandle,
|
||||||
}
|
}
|
||||||
for _, camp := range camps {
|
for _, camp := range camps {
|
||||||
|
@ -30,13 +33,14 @@ func NewRound[Data RoundData](data Data, camps []*RoundCamp, roundGameOverVerify
|
||||||
option(round)
|
option(round)
|
||||||
}
|
}
|
||||||
if round.ticker == nil {
|
if round.ticker == nil {
|
||||||
round.ticker = timer.GetTicker(5)
|
round.ticker = timer.GetTicker(5, timer.WithMark(mark))
|
||||||
}
|
}
|
||||||
return round
|
return round
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round 回合制游戏结构
|
// Round 回合制游戏结构
|
||||||
type Round[Data RoundData] struct {
|
type Round[Data RoundData] struct {
|
||||||
|
mark string // 标记
|
||||||
data Data // 游戏数据
|
data Data // 游戏数据
|
||||||
ticker *timer.Ticker // 计时器
|
ticker *timer.Ticker // 计时器
|
||||||
camps map[int][]int // 阵营
|
camps map[int][]int // 阵营
|
||||||
|
@ -57,6 +61,7 @@ type Round[Data RoundData] struct {
|
||||||
swapEntityEventHandles []RoundSwapEntityEvent[Data] // 实体交换事件
|
swapEntityEventHandles []RoundSwapEntityEvent[Data] // 实体交换事件
|
||||||
gameOverEventHandles []RoundGameOverEvent[Data] // 游戏结束事件
|
gameOverEventHandles []RoundGameOverEvent[Data] // 游戏结束事件
|
||||||
changeEventHandles []RoundChangeEvent[Data] // 游戏回合变更事件
|
changeEventHandles []RoundChangeEvent[Data] // 游戏回合变更事件
|
||||||
|
actionTimeoutEventHandles []RoundActionTimeoutEvent[Data] // 行动超时事件
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetData 获取游戏数据
|
// GetData 获取游戏数据
|
||||||
|
@ -69,15 +74,25 @@ func (slf *Round[Data]) GetData() Data {
|
||||||
func (slf *Round[Data]) Run() {
|
func (slf *Round[Data]) Run() {
|
||||||
slf.currentEntity = -1
|
slf.currentEntity = -1
|
||||||
slf.round = 1
|
slf.round = 1
|
||||||
slf.loop()
|
slf.loop(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *Round[Data]) loop() {
|
// Release 释放游戏
|
||||||
slf.ticker.StopTimer(slf.actionTimeoutTickerName)
|
func (slf *Round[Data]) Release() {
|
||||||
if slf.roundGameOverVerifyHandle(slf) {
|
if slf.mark == slf.ticker.Mark() {
|
||||||
for _, handle := range slf.gameOverEventHandles {
|
slf.ticker.Release()
|
||||||
handle(slf)
|
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
|
return
|
||||||
} else {
|
} else {
|
||||||
slf.ActionRefresh()
|
slf.ActionRefresh()
|
||||||
|
@ -96,22 +111,22 @@ func (slf *Round[Data]) loop() {
|
||||||
if slf.roundCount > len(slf.camps) {
|
if slf.roundCount > len(slf.camps) {
|
||||||
slf.round++
|
slf.round++
|
||||||
slf.roundCount = 1
|
slf.roundCount = 1
|
||||||
for _, handle := range slf.changeEventHandles {
|
slf.OnChangeEvent()
|
||||||
handle(slf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, handle := range slf.swapCampEventHandles {
|
|
||||||
handle(slf, slf.currentCamp)
|
|
||||||
}
|
}
|
||||||
|
slf.OnSwapCampEvent()
|
||||||
}
|
}
|
||||||
slf.currentEntity++
|
slf.currentEntity++
|
||||||
for _, handle := range slf.swapEntityEventHandles {
|
slf.OnSwapEntityEvent()
|
||||||
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])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 跳过当前阵营剩余对象的行动
|
// SkipCamp 跳过当前阵营剩余对象的行动
|
||||||
|
@ -122,7 +137,7 @@ func (slf *Round[Data]) SkipCamp() {
|
||||||
// ActionRefresh 刷新行动超时时间
|
// ActionRefresh 刷新行动超时时间
|
||||||
func (slf *Round[Data]) ActionRefresh() {
|
func (slf *Round[Data]) ActionRefresh() {
|
||||||
slf.currentEndTime = time.Now().Unix()
|
slf.currentEndTime = time.Now().Unix()
|
||||||
slf.ticker.After(slf.actionTimeoutTickerName, slf.actionTimeout, slf.loop)
|
slf.ticker.After(slf.actionTimeoutTickerName, slf.actionTimeout, slf.loop, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActionFinish 结束行动
|
// ActionFinish 结束行动
|
||||||
|
@ -130,10 +145,8 @@ func (slf *Round[Data]) ActionFinish() {
|
||||||
slf.ticker.StopTimer(slf.actionTimeoutTickerName)
|
slf.ticker.StopTimer(slf.actionTimeoutTickerName)
|
||||||
if slf.shareAction {
|
if slf.shareAction {
|
||||||
slf.currentEntity = -1
|
slf.currentEntity = -1
|
||||||
} else {
|
|
||||||
slf.currentEntity++
|
|
||||||
}
|
}
|
||||||
slf.loop()
|
slf.loop(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRound 获取当前回合数
|
// GetRound 获取当前回合数
|
||||||
|
@ -165,3 +178,42 @@ func (slf *Round[Data]) GetCurrentRoundProgressRate() float64 {
|
||||||
func (slf *Round[Data]) GetCurrent() (camp, entity int) {
|
func (slf *Round[Data]) GetCurrent() (camp, entity int) {
|
||||||
return slf.currentCamp, slf.camps[slf.currentCamp][slf.currentEntity]
|
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])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ type (
|
||||||
RoundSwapEntityEvent[Data RoundData] func(round *Round[Data], campId, entity int)
|
RoundSwapEntityEvent[Data RoundData] func(round *Round[Data], campId, entity int)
|
||||||
RoundGameOverEvent[Data RoundData] func(round *Round[Data])
|
RoundGameOverEvent[Data RoundData] func(round *Round[Data])
|
||||||
RoundChangeEvent[Data RoundData] func(round *Round[Data])
|
RoundChangeEvent[Data RoundData] func(round *Round[Data])
|
||||||
|
RoundActionTimeoutEvent[Data RoundData] func(round *Round[Data], campId, entity int)
|
||||||
)
|
)
|
||||||
|
|
||||||
// WithRoundTicker 设置游戏的计时器
|
// WithRoundTicker 设置游戏的计时器
|
||||||
|
@ -37,6 +38,7 @@ func WithRoundShareAction[Data RoundData](share bool) RoundOption[Data] {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithRoundSwapCampEvent 设置游戏的阵营交换事件
|
// WithRoundSwapCampEvent 设置游戏的阵营交换事件
|
||||||
|
// - 该事件在触发时已经完成了阵营的交换
|
||||||
func WithRoundSwapCampEvent[Data RoundData](swapCampEventHandle RoundSwapCampEvent[Data]) RoundOption[Data] {
|
func WithRoundSwapCampEvent[Data RoundData](swapCampEventHandle RoundSwapCampEvent[Data]) RoundOption[Data] {
|
||||||
return func(round *Round[Data]) {
|
return func(round *Round[Data]) {
|
||||||
round.swapCampEventHandles = append(round.swapCampEventHandles, swapCampEventHandle)
|
round.swapCampEventHandles = append(round.swapCampEventHandles, swapCampEventHandle)
|
||||||
|
@ -44,6 +46,7 @@ func WithRoundSwapCampEvent[Data RoundData](swapCampEventHandle RoundSwapCampEve
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithRoundSwapEntityEvent 设置游戏的实体交换事件
|
// WithRoundSwapEntityEvent 设置游戏的实体交换事件
|
||||||
|
// - 该事件在触发时已经完成了实体的交换
|
||||||
func WithRoundSwapEntityEvent[Data RoundData](swapEntityEventHandle RoundSwapEntityEvent[Data]) RoundOption[Data] {
|
func WithRoundSwapEntityEvent[Data RoundData](swapEntityEventHandle RoundSwapEntityEvent[Data]) RoundOption[Data] {
|
||||||
return func(round *Round[Data]) {
|
return func(round *Round[Data]) {
|
||||||
round.swapEntityEventHandles = append(round.swapEntityEventHandles, swapEntityEventHandle)
|
round.swapEntityEventHandles = append(round.swapEntityEventHandles, swapEntityEventHandle)
|
||||||
|
@ -58,12 +61,20 @@ func WithRoundGameOverEvent[Data RoundData](gameOverEventHandle RoundGameOverEve
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithRoundChangeEvent 设置游戏的回合变更事件
|
// WithRoundChangeEvent 设置游戏的回合变更事件
|
||||||
|
// - 该事件在触发时已经完成了回合的变更
|
||||||
func WithRoundChangeEvent[Data RoundData](changeEventHandle RoundChangeEvent[Data]) RoundOption[Data] {
|
func WithRoundChangeEvent[Data RoundData](changeEventHandle RoundChangeEvent[Data]) RoundOption[Data] {
|
||||||
return func(round *Round[Data]) {
|
return func(round *Round[Data]) {
|
||||||
round.changeEventHandles = append(round.changeEventHandles, changeEventHandle)
|
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 设置游戏阵营逆序执行
|
// WithRoundCampCounterclockwise 设置游戏阵营逆序执行
|
||||||
func WithRoundCampCounterclockwise[Data RoundData]() RoundOption[Data] {
|
func WithRoundCampCounterclockwise[Data RoundData]() RoundOption[Data] {
|
||||||
return func(round *Round[Data]) {
|
return func(round *Round[Data]) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package fight
|
package fight
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -17,14 +18,11 @@ func TestName(t *testing.T) {
|
||||||
},
|
},
|
||||||
WithRoundActionTimeout[string](time.Second),
|
WithRoundActionTimeout[string](time.Second),
|
||||||
WithRoundSwapEntityEvent[string](func(round *Round[string], campId, entity int) {
|
WithRoundSwapEntityEvent[string](func(round *Round[string], campId, entity int) {
|
||||||
t.Log(time.Now(), "swap entity", round.GetRound(), campId, entity)
|
fmt.Println(campId, entity)
|
||||||
|
if campId == 1 && entity == 2 {
|
||||||
|
round.SetCurrent(1, 1)
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
WithRoundGameOverEvent[string](func(round *Round[string]) {
|
|
||||||
t.Log(time.Now(), "game over", round.GetRound())
|
|
||||||
wait.Done()
|
|
||||||
}),
|
|
||||||
WithRoundCampCounterclockwise[string](),
|
|
||||||
WithRoundEntityCounterclockwise[string](),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
wait.Add(1)
|
wait.Add(1)
|
||||||
|
|
Loading…
Reference in New Issue