diff --git a/utils/deck/deck.go b/utils/deck/deck.go new file mode 100644 index 0000000..8fda989 --- /dev/null +++ b/utils/deck/deck.go @@ -0,0 +1,80 @@ +package deck + +import ( + "github.com/kercylan98/minotaur/utils/hash" + "github.com/kercylan98/minotaur/utils/slice" +) + +// NewDeck 创建一个新的甲板 +func NewDeck[I Item]() *Deck[I] { + deck := &Deck[I]{ + groups: make(map[int64]*Group[I]), + } + return deck +} + +// Deck 甲板,用于针对一堆 Group 进行管理的数据结构 +type Deck[I Item] struct { + groups map[int64]*Group[I] + sort []int64 +} + +// AddGroup 将一个组添加到甲板中 +func (slf *Deck[I]) AddGroup(group *Group[I]) { + if !hash.Exist(slf.groups, group.GetGuid()) { + slf.groups[group.GetGuid()] = group + slf.sort = append(slf.sort, group.GetGuid()) + } +} + +// RemoveGroup 移除甲板中的一个组 +func (slf *Deck[I]) RemoveGroup(guid int64) { + delete(slf.groups, guid) + index := slice.GetIndex(slf.sort, guid) + if index != -1 { + slf.sort = append(slf.sort[:index], slf.sort[index+1:]...) + } +} + +// GetCount 获取甲板中的组数量 +func (slf *Deck[I]) GetCount() int { + return len(slf.groups) +} + +// GetGroups 获取所有组 +func (slf *Deck[I]) GetGroups() map[int64]*Group[I] { + return hash.Copy(slf.groups) +} + +// GetGroupsSlice 获取所有组 +func (slf *Deck[I]) GetGroupsSlice() []*Group[I] { + var groups = make([]*Group[I], 0, len(slf.groups)) + for _, guid := range slf.sort { + groups = append(groups, slf.groups[guid]) + } + return groups +} + +// GetNext 获取特定组的下一个组 +func (slf *Deck[I]) GetNext(guid int64) *Group[I] { + index := slice.GetIndex(slf.sort, guid) + if index == -1 { + return nil + } + if index == len(slf.sort)-1 { + return slf.groups[slf.sort[0]] + } + return slf.groups[slf.sort[index+1]] +} + +// GetPrev 获取特定组的上一个组 +func (slf *Deck[I]) GetPrev(guid int64) *Group[I] { + index := slice.GetIndex(slf.sort, guid) + if index == -1 { + return nil + } + if index == 0 { + return slf.groups[slf.sort[len(slf.sort)-1]] + } + return slf.groups[slf.sort[index-1]] +} diff --git a/utils/deck/doc.go b/utils/deck/doc.go new file mode 100644 index 0000000..17736b5 --- /dev/null +++ b/utils/deck/doc.go @@ -0,0 +1,2 @@ +// Package deck 包中的内容用于针对一堆内容的管理,适用但不限于牌堆、麻将牌堆等情况。 +package deck diff --git a/utils/deck/group.go b/utils/deck/group.go new file mode 100644 index 0000000..4aea08b --- /dev/null +++ b/utils/deck/group.go @@ -0,0 +1,129 @@ +package deck + +// NewGroup 创建一个新的组 +func NewGroup[I Item](guid int64, fillHandle func(guid int64) []I) *Group[I] { + if fillHandle == nil { + panic("deck.NewGroup: fillHandle is nil") + } + group := &Group[I]{ + guid: guid, + fillHandle: fillHandle, + } + return group +} + +// Group 甲板中的组,用于针对一堆内容进行管理的数据结构 +type Group[I Item] struct { + guid int64 // 组的 guid + fillHandle func(guid int64) []I // 组的填充函数 + items []I // 组中的所有内容 +} + +// GetGuid 获取组的 guid +func (slf *Group[I]) GetGuid() int64 { + return slf.guid +} + +// Fill 将该组的数据填充为 WithGroupFillHandle 中设置的内容 +func (slf *Group[I]) Fill() { + slf.items = slf.fillHandle(slf.guid) +} + +// Pop 从顶部获取一个内容 +func (slf *Group[I]) Pop() (item I) { + if len(slf.items) == 0 { + return item + } + item = slf.items[0] + slf.items = slf.items[1:] + return item +} + +// PopN 从顶部获取指定数量的内容 +func (slf *Group[I]) PopN(n int) (items []I) { + if len(slf.items) == 0 { + return items + } + if len(slf.items) < n { + n = len(slf.items) + } + items = slf.items[:n] + slf.items = slf.items[n:] + return items +} + +// PressOut 从底部压出一个内容 +func (slf *Group[I]) PressOut() (item I) { + if len(slf.items) == 0 { + return item + } + item = slf.items[len(slf.items)-1] + slf.items = slf.items[:len(slf.items)-1] + return item +} + +// PressOutN 从底部压出指定数量的内容 +func (slf *Group[I]) PressOutN(n int) (items []I) { + if len(slf.items) == 0 { + return items + } + if len(slf.items) < n { + n = len(slf.items) + } + items = slf.items[len(slf.items)-n:] + slf.items = slf.items[:len(slf.items)-n] + return items +} + +// Push 向顶部压入一个内容 +func (slf *Group[I]) Push(item I) { + slf.items = append([]I{item}, slf.items...) +} + +// PushN 向顶部压入指定数量的内容 +func (slf *Group[I]) PushN(items []I) { + slf.items = append(items, slf.items...) +} + +// Insert 向底部插入一个内容 +func (slf *Group[I]) Insert(item I) { + slf.items = append(slf.items, item) +} + +// InsertN 向底部插入指定数量的内容 +func (slf *Group[I]) InsertN(items []I) { + slf.items = append(slf.items, items...) +} + +// Pull 从特定位置拔出一个内容 +func (slf *Group[I]) Pull(index int) (item I) { + if len(slf.items) == 0 { + return item + } + item = slf.items[index] + slf.items = append(slf.items[:index], slf.items[index+1:]...) + return item +} + +// Thrust 向特定位置插入一个内容 +func (slf *Group[I]) Thrust(index int, item I) { + if len(slf.items) == 0 { + return + } + slf.items = append(slf.items[:index], append([]I{item}, slf.items[index:]...)...) +} + +// IsFree 检查组是否为空 +func (slf *Group[I]) IsFree() bool { + return len(slf.items) == 0 +} + +// GetCount 获取组中剩余的内容数量 +func (slf *Group[I]) GetCount() int { + return len(slf.items) +} + +// GetItem 获取组中的指定内容 +func (slf *Group[I]) GetItem(index int) I { + return slf.items[index] +} diff --git a/utils/deck/item.go b/utils/deck/item.go new file mode 100644 index 0000000..8b1c880 --- /dev/null +++ b/utils/deck/item.go @@ -0,0 +1,6 @@ +package deck + +// Item 甲板成员 +type Item interface { + // 占位 +}