pet_home_server/src/server/game/mod/chess/Chess.go
2026-02-12 10:25:41 +08:00

741 lines
17 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package chess
import (
"errors"
"fmt"
mergeDataCfg "server/conf/merge_data"
startMergeCfg "server/conf/start_merge"
userCfg "server/conf/user"
"server/game/mod/item"
GoUtil "server/game_util"
"server/msg"
"sort"
"strings"
)
const (
ModuleName = "chess"
ChessBoradMaxNum = 63
CHESS_ENERGY_CHEST = 562
CHESS_SURPRISE_CHEST_LOCK = 563
CHESS_SURPRISE_CHEST = 564
CHESS_ZIXUAN_CHEST = 701 // 自选宝箱
CHESS_HIGH_ZIXUAN_CHEST = 702 // 高级自选宝箱
CHESS_TREASURE_CHEST = 703 // 宝藏宝箱
CHESS_HIGH_TREASURE_CHEST = 704 // 高级宝藏宝箱
CHESS_SOURCE_CHEST = 705 // 资源补给箱
CHESS_HIGH_SOURCE_CHEST = 706 // 高级资源补给箱
CHESS_SEPARATE = 707 // 分解器
CHESS_UPGRADE = 708 // 升级器
)
const (
EMIT_RETIRE_START = 1
EMIT_RETIRE_ING = 2
EMIT_RETIRE_END = 3
)
type ChessBorad struct {
ChessList []int
EmitList map[int]int
ChessBuff []int
ChessBag ChessBag
PartBag PartBag
ChessMap map[string]int32
Honor map[int]int // 荣誉室
Retire map[string]int // 退役发射器系列
RetireReward map[string]bool
RetireChessMap map[string][]int
}
type PartBag struct {
List map[int]PartBagGrid // 零件背包
}
type ChessBag struct {
List map[int]ChessBagGrid
Buy int
Free int
}
type ChessBagGrid struct {
ChessId int // 棋子id
EmitId int // 发射器id
}
type PartBagGrid struct {
PartId int // 零件id
Num int // 零件数量
}
func (cb *ChessBorad) IsEmpty() bool {
cb.ver()
return len(cb.ChessList) == 0
}
// 初始化棋盘
func (cb *ChessBorad) InitData() {
StartMerge := startMergeCfg.GetStartChessList()
cb.EmitList = make(map[int]int)
cb.ChessList = StartMerge
if cb.ChessBag.List == nil {
cb.ChessBag.List = make(map[int]ChessBagGrid)
InitNum := mergeDataCfg.GetChessBagInitNum()
for i := 1; i <= InitNum; i++ {
cb.ChessBag.List[i] = ChessBagGrid{}
}
}
if cb.RetireReward == nil {
cb.RetireReward = make(map[string]bool)
}
if cb.PartBag.List == nil {
cb.PartBag.List = make(map[int]PartBagGrid)
}
if cb.ChessMap == nil {
cb.ChessMap = make(map[string]int32)
}
if cb.RetireChessMap == nil {
cb.RetireChessMap = make(map[string][]int)
}
if cb.Retire == nil {
cb.Retire = make(map[string]int)
}
if cb.Honor == nil {
cb.Honor = make(map[int]int)
}
}
func (cb *ChessBorad) ver() {
if cb.EmitList == nil {
cb.EmitList = make(map[int]int)
}
if cb.ChessBag.List == nil {
cb.ChessBag.List = make(map[int]ChessBagGrid)
InitNum := mergeDataCfg.GetChessBagInitNum()
for i := 1; i <= InitNum; i++ {
cb.ChessBag.List[i] = ChessBagGrid{}
}
}
if cb.RetireReward == nil {
cb.RetireReward = make(map[string]bool)
}
if cb.PartBag.List == nil {
cb.PartBag.List = make(map[int]PartBagGrid)
}
if cb.ChessMap == nil {
cb.ChessMap = make(map[string]int32)
}
if cb.RetireChessMap == nil {
cb.RetireChessMap = make(map[string][]int)
}
if cb.Retire == nil {
cb.Retire = make(map[string]int)
}
if cb.Honor == nil {
cb.Honor = make(map[int]int)
}
}
func (cb *ChessBorad) GetChessBuf() []int {
return cb.ChessBuff
}
// 棋子合成
func (cb *ChessBorad) ComposeChess(id int) (int, error) {
CfgRecord, err := mergeDataCfg.GetOne(id)
if err != nil {
return 0, errors.New("配置错误")
}
if CfgRecord.Lv == CfgRecord.MaxLv {
return 0, errors.New("已达最大等级")
}
count := 0
newList := make([]int, 0, len(cb.ChessList))
for _, chess := range cb.ChessList {
if chess == id && count < 2 {
count++
continue
}
newList = append(newList, chess)
}
if count < 2 {
return 0, errors.New("次数不足" + fmt.Sprintf("Id: %d", id))
}
ChessType := mergeDataCfg.GetTypeById(id)
if ChessType == "Emitter" {
cb.EmitList[id+1]++
cb.EmitList[id]--
cb.EmitList[id]--
}
id++
newList = append(newList, id)
cb.ChessList = newList
return id, nil
}
func (cb *ChessBorad) GetChessList() []int {
return cb.ChessList
}
func (cb *ChessBorad) GetUnlockChessList() []int {
r := make([]int, 0, len(cb.ChessList))
for k, v := range cb.ChessMap {
arr := strings.Split(k, "@")
if arr[2] == "0" {
r = append(r, int(v))
}
}
return r
}
// func (cb *ChessBorad) GetUnlockChessList() []int {
// return cb.ChessBag.List
// }
// 添加棋子
func (cb *ChessBorad) AddChess(id int) error {
_, err := mergeDataCfg.GetOne(id)
if err != nil {
return errors.New("配置错误")
}
NewChessList := append(cb.ChessList, id)
if len(NewChessList) > ChessBoradMaxNum { // 棋盘满了 加入缓存区
cb.ChessBuff = append(cb.ChessBuff, id)
return nil
}
ChessType := mergeDataCfg.GetTypeById(id)
if ChessType == "Emitter" {
cb.EmitList[id]++
}
cb.ChessList = append(cb.ChessList, id)
return nil
}
// 购买棋子
func (cb *ChessBorad) BuyChess(id int) (int, error) {
CfgRecord, err := mergeDataCfg.GetOne(id)
if err != nil {
return 0, errors.New("配置错误")
}
cb.ChessList = append(cb.ChessList, id)
ChessType := mergeDataCfg.GetTypeById(id)
if ChessType == "Emitter" {
cb.EmitList[id]++
}
return CfgRecord.SellNum, nil
}
// 出售棋子
func (cb *ChessBorad) SellChess(id int) ([]*item.Item, error) {
CfgRecord, err := mergeDataCfg.GetOne(id)
if err != nil {
return nil, errors.New("配置错误")
}
count := 0
newList := make([]int, 0, len(cb.ChessList))
for _, chess := range cb.ChessList {
if chess == id && count < 1 {
count++
continue
}
newList = append(newList, chess)
}
if count < 1 {
return nil, errors.New("次数不足")
}
cb.ChessList = newList
var items []*item.Item
switch CfgRecord.SellType {
case "star":
items = append(items, &item.Item{Id: item.ITEM_STAR_ID, Num: CfgRecord.SellNum})
case "diamond":
items = append(items, &item.Item{Id: item.ITEM_DIAMOND_ID, Num: CfgRecord.SellNum})
case "energy":
items = append(items, &item.Item{Id: item.ITEM_ENERGY_ID, Num: CfgRecord.SellNum})
case "Racing Battery":
items = append(items, &item.Item{Id: item.ITEM_RACING_BATTERY_ID, Num: CfgRecord.SellNum})
}
return items, nil
}
// 移除棋子
func (cb *ChessBorad) RemoveChess(Id int) error {
find := false
for k, v := range cb.ChessList {
if v == Id {
cb.ChessList = append(cb.ChessList[:k], cb.ChessList[k+1:]...)
find = true
break
}
}
if !find {
return errors.New("chess id not exist")
}
ChessType := mergeDataCfg.GetTypeById(Id)
if ChessType == "Emitter" {
v, ok := cb.EmitList[Id]
if v > 0 && ok {
cb.EmitList[Id]--
}
}
return nil
}
func (cb *ChessBorad) GetStarEmitList() []int {
result := make([]int, 0, len(cb.EmitList))
EM := make(map[string]int)
for k, v := range cb.EmitList {
if v <= 0 {
delete(cb.EmitList, k)
continue
}
EmitID := mergeDataCfg.GetEmitId(k)
if EmitID == "" {
continue
}
EmitType := mergeDataCfg.GetEmitType(k)
if EmitType == "sub" {
continue
}
if v > 0 {
EM[EmitID] = max(EM[EmitID], k)
}
}
for _, v := range EM {
result = append(result, v)
}
return result
}
func (cb *ChessBorad) GetEmitList() []int {
result := make([]int, 0, len(cb.EmitList))
EM := make(map[string]int)
for k, v := range cb.EmitList {
if v <= 0 {
delete(cb.EmitList, k)
continue
}
EmitID := mergeDataCfg.GetEmitId(k)
if EmitID == "" {
continue
}
if cb.Retire[EmitID] >= EMIT_RETIRE_START {
continue
}
EmitType := mergeDataCfg.GetEmitType(k)
if EmitType == "sub" {
continue
}
if v > 0 {
EM[EmitID] = max(EM[EmitID], k)
}
}
for _, v := range EM {
result = append(result, v)
}
return result
}
// 完成订单 移除棋子
func (cb *ChessBorad) FinishOrder(ChessId []int) error {
unlockChessList := cb.GetUnlockChessList()
unlockChessMap := make(map[int]int)
for _, v := range unlockChessList {
unlockChessMap[v]++
}
boardChess := []int{}
BagChess := []int{}
for _, v := range ChessId {
if unlockChessMap[v] > 0 {
unlockChessMap[v]--
boardChess = append(boardChess, v)
} else {
BagChess = append(BagChess, v)
}
}
for _, v := range boardChess {
err := cb.FinishOrderChess(v)
if err != nil {
return err
}
}
for _, v := range BagChess {
err := cb.FinishOrderChessByBag(v)
if err != nil {
return err
}
}
return nil
}
func (cb *ChessBorad) FinishOrderChess(Chess int) error {
for k, v := range cb.ChessList {
if v == Chess {
cb.ChessList = append(cb.ChessList[:k], cb.ChessList[k+1:]...)
return nil
}
}
return fmt.Errorf("order finish board chess id%d not exist", Chess)
}
func (cb *ChessBorad) FinishOrderChessByBag(Chess int) error {
for k, v := range cb.ChessBag.List {
if v.ChessId == Chess {
cb.ChessBag.List[k] = ChessBagGrid{}
return nil
}
}
return fmt.Errorf("order finish bag chess id%d not exist", Chess)
}
// 棋子转换
func (cb *ChessBorad) ExChess(OldChessId, NewChessId int) error {
if OldChessId > 0 {
newList, b := GoUtil.PopElemSlice(cb.ChessList, OldChessId)
if !b {
return fmt.Errorf("ExChess chess id not exist")
}
cb.ChessList = newList
}
return cb.AddChess(NewChessId)
}
// 增加棋盘缓冲器
func (cb *ChessBorad) AddChessBuff(chess int) {
cb.ChessBuff = append(cb.ChessBuff, chess)
}
func (cb *ChessBorad) AddHonor(Id int) {
cb.Honor[Id] = 1
}
func (cb *ChessBorad) RemoveHonor(Id int) {
delete(cb.Honor, Id)
}
func (cb *ChessBorad) GetChessFromBuff(Chess int) error {
for i, v := range cb.ChessBuff {
if v == Chess {
cb.ChessBuff = append(cb.ChessBuff[:i], cb.ChessBuff[i+1:]...)
cb.AddChess(Chess)
ChessType := mergeDataCfg.GetTypeById(Chess)
if ChessType == "Emitter" {
cb.EmitList[Chess]++
}
return nil
}
}
return errors.New("chess id not exist")
}
func (cb *ChessBorad) LosePart(PartId int, Num int) error {
v, ok := cb.PartBag.List[PartId]
if !ok || v.Num < Num {
return errors.New("part id not exist or num not enough" + fmt.Sprintf("PartId: %d, Num: %d, ok: %v", PartId, Num, ok))
}
v.Num -= Num
cb.PartBag.List[PartId] = v
return nil
}
// 返回数据
func (cb *ChessBorad) BackData() *msg.ResPlayerChessInfo {
var ChessBagGrids []*msg.ChessBagGrid
for k, v := range cb.ChessBag.List {
ChessBagGrids = append(ChessBagGrids, &msg.ChessBagGrid{
Id: int32(k),
ChessId: int32(v.ChessId),
EmitId: int32(v.EmitId),
})
}
var PartBagGrids []*msg.PartBagGrid
for k, v := range cb.PartBag.List {
PartBagGrids = append(PartBagGrids, &msg.PartBagGrid{
PartId: int32(k),
Count: int32(v.Num),
})
}
Re := make([]string, 0, len(cb.Retire))
for k, v := range cb.Retire {
if v == EMIT_RETIRE_END {
Re = append(Re, k)
}
}
Ho := make([]int32, 0, len(cb.Honor))
for k := range cb.Honor {
Ho = append(Ho, int32(k))
}
Rw := make([]string, 0, len(cb.RetireReward))
for k, v := range cb.RetireReward {
if v == true {
Rw = append(Rw, k)
}
}
return &msg.ResPlayerChessInfo{
ChessList: GoUtil.SliceIntToInt32(cb.ChessList),
ChessBuff: GoUtil.SliceIntToInt32(cb.ChessBuff),
RetireEmit: Re,
RetireReward: Rw,
Honor: Ho,
ChessBag: &msg.ChessBag{
ChessBagGrids: ChessBagGrids,
ChessBuyCnt: int32(cb.ChessBag.Buy),
ChessFreeCnt: int32(cb.ChessBag.Free),
},
PartBag: &msg.PartBag{
PartBagGrids: PartBagGrids,
},
}
}
// 解锁棋盘背包
func (cb *ChessBorad) BuyChessBagGrid() error {
if cb.ChessBag.Free > 0 {
cb.ChessBag.List[len(cb.ChessBag.List)+1] = ChessBagGrid{}
cb.ChessBag.Free--
return nil
}
MaxBuy := mergeDataCfg.GetChessBagBugNum()
if cb.ChessBag.Buy >= MaxBuy {
return fmt.Errorf("ChessBag can buy is full")
}
cb.ChessBag.Buy++
cb.ChessBag.List[len(cb.ChessBag.List)+1] = ChessBagGrid{}
return nil
}
func (cb *ChessBorad) GetBuyChessBagGridCost() []*item.Item {
if cb.ChessBag.Free > 0 {
return nil
}
NeedDiamond := 10 + 15*cb.ChessBag.Buy
return []*item.Item{{Id: item.ITEM_DIAMOND_ID, Num: -NeedDiamond}}
}
// 升级触发解锁棋盘背包
func (cb *ChessBorad) TriggerChessBagUnlock(Lv int) bool {
UnlockPack := userCfg.GetUnlockPack(Lv)
if UnlockPack > 0 {
cb.ChessBag.Free += UnlockPack
return true
}
return false
}
func (cb *ChessBorad) PutChessInBag(Grid, ChessId, EmitId int) error {
err := cb.RemoveChess(ChessId)
if err != nil {
return err
}
EmitColorId := mergeDataCfg.GetEmitId(ChessId)
// ChessLv := mergeDataCfg.GetLvById(ChessId)
// ChessMaxLv := mergeDataCfg.GetMaxLvById(ChessId)
if Grid == 0 && cb.RetireReward[EmitColorId] { // 背包id为0且发射器已退役奖励已领取 直接放入荣誉室
cb.AddHonor(ChessId)
return nil
}
v, ok := cb.ChessBag.List[Grid]
if !ok {
return errors.New("ChessBag Grid unlock")
}
if v.ChessId > 0 {
return errors.New("ChessBag Grid is not empty")
}
cb.ChessBag.List[Grid] = ChessBagGrid{
ChessId: ChessId,
EmitId: EmitId,
}
return nil
}
func (cb *ChessBorad) PutPartInBag(ChessId int) error {
err := cb.RemoveChess(ChessId)
if err != nil {
return err
}
ChessLv := mergeDataCfg.GetLvById(ChessId)
ChessMaxLv := mergeDataCfg.GetMaxLvById(ChessId)
if ChessLv != ChessMaxLv { // 零件只能放入满级棋子
return errors.New("part Lv is not max")
}
Num := 0
v, ok := cb.PartBag.List[ChessId]
if ok {
Num = v.Num
}
if cb.PartBag.List == nil {
cb.PartBag.List = make(map[int]PartBagGrid)
}
cb.PartBag.List[ChessId] = PartBagGrid{
PartId: ChessId,
Num: Num + 1,
}
return nil
}
func (cb *ChessBorad) TakeChessOutBag(Grid int) (int, error) {
if Grid < 0 {
cb.RemoveHonor(-Grid)
cb.AddChess(-Grid)
return 0, nil
}
GridInfo, ok := cb.ChessBag.List[Grid]
if !ok {
return 0, errors.New("ChessBag Grid unlock")
}
if GridInfo.ChessId == 0 {
return 0, errors.New("ChessBag Grid is empty")
}
cb.ChessBag.List[Grid] = ChessBagGrid{}
return GridInfo.ChessId, cb.AddChess(GridInfo.ChessId)
}
func (cb *ChessBorad) GetOrderEmit() []int {
return cb.GetEmitList()
}
func (cb *ChessBorad) GetRetireEmit() map[string]int {
return cb.Retire
}
func (cb *ChessBorad) GetRetireChess(EmitType string) []int {
v, ok := cb.RetireChessMap[EmitType]
if !ok {
return nil
}
if len(v) == 1 {
cb.RetireChessMap[EmitType] = nil
return v
}
if len(v) == 0 {
return nil
}
cb.RetireChessMap[EmitType] = v[2:]
return v[:2]
}
func (cb *ChessBorad) BeginRetire(EmitType string) error {
if cb.Retire == nil {
cb.Retire = make(map[string]int)
}
_, ok := cb.Retire[EmitType]
if ok {
return errors.New("chess has been retired")
}
cb.Retire[EmitType] = EMIT_RETIRE_START
return nil
}
func (cb *ChessBorad) RetireOrder(EmitType string) error {
if cb.Retire[EmitType] != 1 {
return errors.New("chess has not been retired")
}
chess := make([]int, 0, len(cb.ChessMap))
EmitProduct := mergeDataCfg.GetEmitOrderProduce(EmitType)
for k, v := range cb.ChessMap {
arr := strings.Split(k, "@")
Color := mergeDataCfg.GetColorById(int(v))
if arr[2] == "0" && GoUtil.InStringArray(Color, EmitProduct) {
chess = append(chess, int(v))
}
}
sort.Sort(sort.Reverse(sort.IntSlice(chess)))
cb.RetireChessMap[EmitType] = chess
cb.Retire[EmitType] = EMIT_RETIRE_ING
return nil
}
func (cb *ChessBorad) FinishRetire(EmitType string) error {
_, ok := cb.Retire[EmitType]
if !ok {
return errors.New("chess has not been retired")
}
cb.Retire[EmitType] = EMIT_RETIRE_END
return nil
}
func (cb *ChessBorad) SourceChest(ChessId int) ([]*item.Item, error) {
err := cb.RemoveChess(ChessId)
if err != nil {
return nil, err
}
if ChessId == CHESS_SOURCE_CHEST {
return mergeDataCfg.GetSourceChestItem(), nil
}
if ChessId == CHESS_HIGH_SOURCE_CHEST {
return mergeDataCfg.GetHighSourceChestItem(), nil
}
return nil, nil
}
func (cb *ChessBorad) SeparateChess(ChessId int) (int, error) {
ChessLv := mergeDataCfg.GetLvById(ChessId)
if ChessLv == 1 {
return 0, errors.New("chess lv is 1")
}
ChessType := mergeDataCfg.GetTypeById(ChessId)
if ChessType != "Product" {
return 0, errors.New("chess type is not product")
}
err := cb.RemoveChess(ChessId)
if err != nil {
return 0, err
}
err = cb.RemoveChess(CHESS_SEPARATE)
if err != nil {
return 0, err
}
ChessColor := mergeDataCfg.GetColorById(ChessId)
NewChess := mergeDataCfg.GetChessIdByLvAndColor(ChessLv-1, ChessColor)
cb.AddChess(NewChess)
cb.AddChess(NewChess)
return NewChess, nil
}
func (cb *ChessBorad) UpgradeChess(ChessId int) (int, error) {
ChessLv := mergeDataCfg.GetLvById(ChessId)
ChessMaxLv := mergeDataCfg.GetMaxLvById(ChessId)
if ChessLv == ChessMaxLv {
return 0, errors.New("chess lv is max")
}
ChessType := mergeDataCfg.GetTypeById(ChessId)
if ChessType != "Product" {
return 0, errors.New("chess type is not product")
}
err := cb.RemoveChess(ChessId)
if err != nil {
return 0, err
}
err = cb.RemoveChess(CHESS_UPGRADE)
if err != nil {
return 0, err
}
NewChess := mergeDataCfg.GetChessIdByLvAndColor(ChessLv+1, mergeDataCfg.GetColorById(ChessId))
cb.AddChess(NewChess)
return NewChess, nil
}
func (cb *ChessBorad) GetPartBag() map[int]int {
res := make(map[int]int)
for k, v := range cb.PartBag.List {
res[k] = v.Num
}
return res
}
func (cb *ChessBorad) GetRetireReward(Id string) ([]*item.Item, error) {
if cb.RetireReward[Id] == true {
return nil, errors.New("emit retire reward has been get")
}
if cb.Retire[Id] != EMIT_RETIRE_END {
return nil, errors.New("emit not finish retire")
}
cb.RetireReward[Id] = true
return mergeDataCfg.GetRetireReward(), nil
}