package order

import (
	"math"
	mergeDataCfg "server/conf/merge_data"
	orderCfg "server/conf/order"
	userCfg "server/conf/user"
	GoUtil "server/game_util"
	"sort"
)

var reflectChess = map[int]int{} // 棋子难度映射表

var orderCfgMap = map[int]orderConfig{
	1: {
		Min: 15,
		Max: 150,
		Pool: map[int]orderConfigInfo{
			1: {lv: 5, energy: 16, t: 0},
			2: {lv: 6, energy: 32, t: 0},
			3: {lv: 7, energy: 64, t: 0},
			4: {lv: 8, energy: 128, t: 0},
		},
	},
	2: {
		Min: 20,
		Max: 300,
		Pool: map[int]orderConfigInfo{
			2: {lv: 6, energy: 32, t: 0},
			3: {lv: 7, energy: 64, t: 0},
			4: {lv: 8, energy: 128, t: 0},
		},
	},
	3: {
		Min: 40,
		Max: 400,
		Pool: map[int]orderConfigInfo{
			1: {lv: 5, energy: 16, t: 0},
			2: {lv: 6, energy: 32, t: 0},
			3: {lv: 7, energy: 64, t: 0},
			4: {lv: 8, energy: 128, t: 0},
			5: {lv: 9, energy: 256, t: 0},
		},
	},
	4: {
		Min: 40,
		Max: 200,
		Pool: map[int]orderConfigInfo{
			1: {lv: 5, energy: 16, t: 1},
			2: {lv: 6, energy: 32, t: 1},
			3: {lv: 7, energy: 64, t: 0},
			4: {lv: 8, energy: 128, t: 0},
		},
	},
	5: {
		Min: 100,
		Max: 600,
		Pool: map[int]orderConfigInfo{
			1: {lv: 6, energy: 32, t: 1},
			2: {lv: 7, energy: 64, t: 1},
			3: {lv: 8, energy: 128, t: 0},
			4: {lv: 9, energy: 256, t: 0},
			5: {lv: 10, energy: 512, t: 0},
		},
	},
	6: {
		Min: 500,
		Max: 1200,
		Pool: map[int]orderConfigInfo{
			1: {lv: 6, energy: 32, t: 1},
			2: {lv: 7, energy: 64, t: 1},
			3: {lv: 8, energy: 128, t: 0},
			4: {lv: 9, energy: 256, t: 0},
			5: {lv: 10, energy: 512, t: 0},
			6: {lv: 11, energy: 1024, t: 0},
		},
	},
}

type orderConfig struct {
	Min  int
	Max  int
	Pool map[int]orderConfigInfo
}

type orderConfigInfo struct {
	lv     int
	energy int
	t      int
}

// 根据上一个订单难度和系数 生成订单难度
func getOrderDiffRand(Lv, Diff int) map[int]int {
	var d map[int]int
	if Lv < 24 {
		switch Diff {
		case DIFF_MID:
			d = map[int]int{
				DIFF_LOW: 50,
				DIFF_MID: 50,
			}
		default:
			d = map[int]int{
				DIFF_LOW: 30,
				DIFF_MID: 70,
			}
		}
		return d
	}
	switch Diff {
	case DIFF_MID:
		d = map[int]int{
			DIFF_LOW:  21,
			DIFF_MID:  49,
			DIFF_HIGH: 30,
		}
	case DIFF_HIGH:
		d = map[int]int{
			DIFF_LOW:  60,
			DIFF_MID:  30,
			DIFF_HIGH: 10,
		}
	default:
		d = map[int]int{
			DIFF_LOW:  10,
			DIFF_MID:  30,
			DIFF_HIGH: 60,
		}
	}
	return d
}

func getChessByDiff(Lv, Diff, Type int) (int, int, int) {
	if Type == Common_type {
		switch Diff {
		case DIFF_MID:
			return 100, 600, GoUtil.RandMap(map[int]int{1: 50, 2: 50})
		case DIFF_HIGH:
			return 500, 1200, GoUtil.RandMap(map[int]int{1: 33, 2: 67})
		default:
			if Lv < 23 {
				return 15, 150, GoUtil.RandMap(map[int]int{1: 67, 2: 33})
			}
			return 30, 200, GoUtil.RandMap(map[int]int{1: 67, 2: 33})
		}
	}
	if Type == Pet_type {
		return 40, 200, GoUtil.RandMap(map[int]int{1: 50, 2: 50})
	}
	if Type == Part_type {
		return 100, 600, GoUtil.RandMap(map[int]int{1: 50, 2: 50})
	}
	if Type == COMFORT_TYPE {
		return 15, 150, GoUtil.RandMap(map[int]int{1: 33, 2: 67})
	}
	return 100, 600, GoUtil.RandMap(map[int]int{1: 50, 2: 50})
}

// 根据订单难度生成棋子难度
func getChessDiff(ChessNum, OrderDiff int) map[int]int {
	var rs map[int]int
	switch ChessNum {
	case 1:
		rs = map[int]int{
			1: OrderDiff,
		}
	case 2:
		switch OrderDiff {
		case DIFF_LOW:
			rand := map[int]int{
				DIFF_LOW: 99,
				DIFF_MID: 1,
			}
			secondDiff := GoUtil.RandMap(rand)
			rs = map[int]int{
				1: DIFF_LOW,
				2: secondDiff,
			}
		case DIFF_MID:
			rand := map[int]int{
				DIFF_LOW: 50,
				DIFF_MID: 50,
			}
			secondDiff := GoUtil.RandMap(rand)
			rs = map[int]int{
				1: DIFF_LOW,
				2: secondDiff,
			}
		case DIFF_HIGH:
			rand := map[int]int{
				DIFF_LOW:  95,
				DIFF_MID:  4,
				DIFF_HIGH: 1,
			}
			secondDiff := GoUtil.RandMap(rand)
			rs = map[int]int{
				1: DIFF_LOW,
				2: secondDiff,
			}
		}
	case 3:
		switch OrderDiff {
		case DIFF_LOW:
			rand := map[int]int{
				DIFF_LOW: 95,
				DIFF_MID: 5,
			}
			secondDiff := GoUtil.RandMap(rand)
			rand = map[int]int{
				DIFF_LOW: 70,
				DIFF_MID: 30,
			}
			thirdDiff := GoUtil.RandMap(rand)
			rs = map[int]int{
				1: DIFF_LOW,
				2: secondDiff,
				3: thirdDiff,
			}
		case DIFF_MID:
			rand := map[int]int{
				DIFF_LOW: 95,
				DIFF_MID: 5,
			}
			secondDiff := GoUtil.RandMap(rand)
			rand = map[int]int{
				DIFF_MID:  80,
				DIFF_HIGH: 20,
			}
			thirdDiff := GoUtil.RandMap(rand)
			rs = map[int]int{
				1: DIFF_MID,
				2: secondDiff,
				3: thirdDiff,
			}
		case DIFF_HIGH:
			rand := map[int]int{
				DIFF_LOW: 95,
				DIFF_MID: 5,
			}
			secondDiff := GoUtil.RandMap(rand)
			rand = map[int]int{
				DIFF_MID:  70,
				DIFF_HIGH: 30,
			}
			thirdDiff := GoUtil.RandMap(rand)
			rs = map[int]int{
				1: DIFF_HIGH,
				2: secondDiff,
				3: thirdDiff,
			}
		}
	}
	return rs
}

// 根据难度生成棋子等级
func getChessLv(Min, Max, Diff int) int {
	Start := Min
	End := Max
	if Max-Min >= 5 {
		switch Diff {
		case DIFF_LOW:
			End = Min + (Max-Min+1)/3 - 1
		case DIFF_MID:
			Start = Min + (Max-Min+1)/3
			End = Min + (Max-Min+1)/3*2 - 1
		case DIFF_HIGH:
			Start = Min + (Max-Min+1)/3*2
		}
	}
	if Max-Min == 2 {
		Start = Max - Diff + 1
		End = Start
	}
	if Max-Min == 3 {
		switch Diff {
		case DIFF_LOW:
			End = Min + 1
		case DIFF_MID:
			Start = Min + 2
			End = Min + 2
		case DIFF_HIGH:
			Start = Min + 3
			End = Min + 3
		}
	}
	if Max-Min == 4 {
		switch Diff {
		case DIFF_LOW:
			End = Min + 1
		case DIFF_MID:
			Start = Min + 2
			End = Min + 3
		case DIFF_HIGH:
			Start = Min + 4
			End = Min + 4
		}
	}

	Start = max(Min, Start)
	End = max(Start, End)
	End = min(Max, End)
	return GoUtil.RandNum(Start, End)
}

func getChessLvRange(Min, Max, Diff int) []int {
	Start := Min
	End := Max
	if Max-Min >= 5 {
		switch Diff {
		case DIFF_LOW:
			End = Min + (Max-Min+1)/3 - 1
		case DIFF_MID:
			Start = Min + (Max-Min+1)/3
			End = Min + (Max-Min+1)/3*2 - 1
		case DIFF_HIGH:
			Start = Min + (Max-Min+1)/3*2
		}
	}
	if Max-Min == 4 {
		switch Diff {
		case DIFF_LOW:
			End = Min + 1
		case DIFF_MID:
			Start = Min + 2
			End = Min + 3
		case DIFF_HIGH:
			Start = Min + 4
		}
	}
	if Max-Min == 3 {
		switch Diff {
		case DIFF_LOW:
			End = Min + 1
		case DIFF_MID:
			Start = Min + 2
			End = Min + 2
		case DIFF_HIGH:
			Start = Min + 3
		}
	}
	Start = max(Min, Start)
	End = max(Start, End)
	End = min(Max, End)
	r := make([]int, 0)
	for i := Start; i <= End; i++ {
		r = append(r, i)
	}
	return r
}

// 宝箱雨随机棋子类型
func RandChessColor(Emit []int) string {
	r := make(map[string]int)
	for _, v := range Emit {
		Produce := mergeDataCfg.GetEmitProduceType(v)
		if len(Produce) == 0 {
			continue
		}
		if len(Produce) == 1 {
			if Produce[0] == "" {
				continue
			}
			r[Produce[0]] = 100
			continue
		}
		r[Produce[0]] = 80
		r[Produce[1]] = 20
	}
	return GoUtil.RandStringMap(r)
}

// 获取棋子等级范围
func getChesslvRange(Emit int, EnergyMul int, IsCharge bool) (int, int) {
	RandEmitLv := mergeDataCfg.GetLvById(Emit)
	EmitId := mergeDataCfg.GetEmitId(Emit)
	RandMaxLv := mergeDataCfg.GetMaxLvById(Emit)
	RandEmitMinLv := mergeDataCfg.GetEmitMinLvById(EmitId)
	Ratio := mergeDataCfg.GetEmitRatio(EmitId)
	m := int(float64(1+RandEmitLv-RandEmitMinLv) / float64(1+RandMaxLv-RandEmitMinLv) / Ratio * 100)
	if IsCharge {
		m += 10
	}
	m = max(1, m)
	m = min(100, m)
	ChessMinLev := orderCfg.GetLvMin(EnergyMul)
	ChessMaxLev := orderCfg.GetLvMax(EnergyMul, m)
	return ChessMinLev, ChessMaxLev
}

// 根据类型获取发射器id
func GetEmitByColor(Emit []int, color string) int {
	for _, v := range Emit {
		Produce := mergeDataCfg.GetEmitProduceChessType(v)
		for _, c := range Produce {
			if c == color {
				return v
			}
		}
	}
	return 0
}

func GetVirtualEnergy(MergeList, EmitList []int) int {
	eneryg := 0
	for _, v := range MergeList {
		ChessLv := mergeDataCfg.GetLvById(v)
		Color := mergeDataCfg.GetColorById(v)
		EmitId := GetEmitByColor(EmitList, Color)
		if EmitId == 0 {
			continue
		}
		NewChessLv := mergeDataCfg.DynamicLevRev(ChessLv, EmitId, Color)
		eneryg += int(math.Pow(2, float64(NewChessLv-1)))
	}
	return eneryg
}

// randSuperOrderChess 随机生成超级订单棋子
func randSuperOrderChess(o *OrderMod, lv int, Emit []int, EnergyMul, OrderDiff int) ([]int, int, error) {
	initReflectChess(Emit, EnergyMul)
	filterPool(o)
	OrderN, err := userCfg.GetOrderNByLv(lv)
	RandChessNum := map[int]int{
		2: 70 - OrderN,
		3: 30 + OrderN,
	}
	if err != nil {
		return nil, DIFF_LOW, err
	}
	ChessNum := GoUtil.RandMap(RandChessNum)
	ChessDiff := getChessDiff(ChessNum, OrderDiff)
	return buildMergeListFromDiff(o, ChessDiff, Emit, EnergyMul, OrderDiff)
}

// randOrderChessWithDiff 随机生成订单棋子
func randOrderChessWithDiff(o *OrderMod, Emit []int, EnergyMul, OrderDiff, ChessNum int) ([]int, int, error) {
	initReflectChess(Emit, EnergyMul)
	filterPool(o)
	ChessDiff := getChessDiff(ChessNum, OrderDiff)
	return buildMergeListFromDiff(o, ChessDiff, Emit, EnergyMul, OrderDiff)
}

// 随机生成订单棋子
func randOrderChess(o *OrderMod, lv int, Emit []int, EnergyMul, OrderType int) ([]int, int, error) {
	initReflectChess(Emit, EnergyMul)
	filterPool(o)
	// 生成订单难度和棋子数量
	OrderDiffRand := getOrderDiffRand(lv, o.LastDiff)
	OrderDiff := GoUtil.RandMap(OrderDiffRand)
	if o.NextDiff != 0 {
		OrderDiff = o.NextDiff
		o.NextDiff = 0
	}
	//获取订单体力范围和棋子数量
	MinEnergy, MaxEnergy, ChessNum := getChessByDiff(lv, OrderDiff, OrderType)
	mergeList := getChessFromPoolByEnergy(o, MinEnergy, MaxEnergy, ChessNum, Emit, EnergyMul, OrderDiff, OrderType)
	return mergeList, OrderDiff, nil
}

func randOrderChessSeed(o *OrderMod, Emit []int, EnergyMul, OrderDiff int) ([]int, int, error) {
	initReflectChess(Emit, EnergyMul)
	filterPool(o)
	ChessDiff := getChessDiff(2, OrderDiff)
	return buildMergeListFromDiff(o, ChessDiff, Emit, EnergyMul, OrderDiff)
}

// buildMergeListFromDiff 根据棋子难度映射表从池中取棋子（提取三处重复逻辑）
func buildMergeListFromDiff(o *OrderMod, ChessDiff map[int]int, Emit []int, EnergyMul, OrderDiff int) ([]int, int, error) {
	mergeList := make([]int, 0, len(ChessDiff))
	for _, v := range ChessDiff {
		ChessId := 0
		for n := 0; n < 50; n++ {
			ChessId = getChessFromPoolByDiff(o, v, Emit, EnergyMul)
			if ChessId != 0 && !GoUtil.InArray(ChessId, mergeList) {
				break
			}
		}
		mergeList = append(mergeList, ChessId)
	}
	return mergeList, OrderDiff, nil
}

// 筛选棋子池 从中剔除不符合难度的棋子
func filterPool(o *OrderMod) {
	var NewPool []int
	for _, v := range o.ChessPool {
		if _, ok := reflectChess[v]; ok {
			NewPool = append(NewPool, v)
		}
	}
	o.ChessPool = NewPool
}

func ShuffleColor(List []string, Last string) []string {
	if len(List) <= 1 {
		return List
	}
	Break := 0
	var List2 []string
	var List3 []string
	for _, v := range List {
		if mergeDataCfg.GetEmitProductNumByColor(v) == 1 {
			List3 = append(List3, v)
		} else {
			List2 = append(List2, v)
		}
	}

	for {
		Break++
		if Break > 1000 {
			break
		}
		Same := false
		NewList := GoUtil.ShuffleStringArray(List2)
		for i := 1; i < len(NewList); i++ {
			BeforeSries := mergeDataCfg.GetEmitTypeByColor(NewList[i-1])
			NowSries := mergeDataCfg.GetEmitTypeByColor(NewList[i])
			if BeforeSries == NowSries {
				Same = true
				break
			}
		}
		// 将 List3 随机插入 NewList 中
		if len(List3) > 0 {
			for _, v := range GoUtil.ShuffleStringArray(List3) {
				idx := GoUtil.RandNum(0, len(NewList))
				if idx >= len(NewList) {
					NewList = append(NewList, v)
				} else {
					NewList = append(NewList[:idx+1], NewList[idx:]...)
					NewList[idx] = v
				}
			}
		}
		if NewList[0] == Last {
			continue
		}

		if !Same {
			return NewList
		}
	}
	L1 := make(map[string][]string, 0)
	for _, v := range List {
		Sries := mergeDataCfg.GetEmitTypeByColor(v)
		L1[Sries] = append(L1[Sries], v)
	}
	List = make([]string, 0)
	for _, v := range L1 {

		List = append(List, v[0])
	}
	for _, v := range L1 {
		if len(v) > 1 {
			List = append(List, v[1])
		}
	}
	for _, v := range L1 {
		if len(v) > 2 {
			List = append(List, v[2])
		}
	}
	if List[0] == Last {
		List[0], List[1] = List[1], List[0]
	}
	return List
}

// 获取发射器系列
func getEmitSeries(o *OrderMod, Emit []int, OrderType int) string {
	o.initColorShuffle(Emit)
	PopEmitId := ""
	NewSlice := make([]string, 0)
	ChessColorNum := map[string]int{}
	for _, v := range o.OrderList {
		for _, c := range v.MergeId {
			Color := mergeDataCfg.GetColorById(c)
			ChessColorNum[Color]++
		}
	}
	Break := 0
	for {
		if Break > 1000 {
			break
		}
		Break++
		PopEmitId, NewSlice = GoUtil.PopStringArray(o.ColorShuffle)
		o.ColorShuffle = NewSlice
		if PopEmitId == "" {
			o.initColorShuffle(Emit)
			continue
		}
		if o.LastColor == PopEmitId {
			continue
		}

		if OrderType == Pet_type {
			EmitId := getEmitBySeries(Emit, PopEmitId)
			EmitInfo, _ := mergeDataCfg.GetOne(EmitId)
			if EmitInfo.Emit_Type == "auto" {
				continue
			}
		}
		PopEmitIdProductNum := mergeDataCfg.GetEmitProductNumByColor(PopEmitId)
		o.initColorShuffle(Emit)
		// 单链棋子 且订单中已有两个 跳过
		if PopEmitIdProductNum == 1 && ChessColorNum[PopEmitId] >= 2 {
			continue
		} else {
			break
		}
	}
	o.ColorShuffle = NewSlice
	o.LastColor = PopEmitId
	o.initColorShuffle(Emit)
	return PopEmitId
}

func (o *OrderMod) initColorShuffle(Emit []int) {
	if len(o.ColorShuffle) == 0 {
		ColorShuffle := make([]string, 0)
		for _, v := range Emit {
			EmitId := mergeDataCfg.GetEmitId(v)
			if GoUtil.InStringArray(EmitId, o.AutoEmit) {
				continue
			}
			EmitProduct := mergeDataCfg.GetEmitProduceType(v)

			if len(EmitProduct) == 0 || EmitProduct[0] == "" {
				continue
			}
			Preheat, ok := o.PreheatStep[EmitProduct[0]]
			// 预热订单未全部完成 排除
			if ok && Preheat < 5 {
				continue
			}
			ColorShuffle = append(ColorShuffle, EmitProduct...)
		}
		o.ColorShuffle = ShuffleColor(ColorShuffle, o.LastColor)
	}
}

// 订单能获取的宠物币
func GetOrderStar(ChessList []int, EmitList []int) int {
	Star := 0
	for _, v := range ChessList {
		ChessLv := mergeDataCfg.GetLvById(v)
		Color := mergeDataCfg.GetColorById(v)
		EmitId := GetEmitByColor(EmitList, Color)
		if EmitId == 0 {
			continue
		}
		NewChessLv := mergeDataCfg.DynamicLevRev(ChessLv, EmitId, Color)
		n := orderCfg.GetOrderK(NewChessLv)
		Star += n
	}
	return Star
}

func GetChessByDiff(EmitId, EnergyMul, Diff int, Color string) []int {
	ChessMinLv, ChessMaxLv := getChesslvRange(EmitId, EnergyMul, false)
	LvRange := getChessLvRange(ChessMinLv, ChessMaxLv, Diff)
	var ChessIds []int
	for _, v := range LvRange {
		NewLev1 := mergeDataCfg.DynamicLev(v, EmitId, Color)
		MaxLev := mergeDataCfg.GetMaxLvByColor(Color)
		NewLev1 = min(NewLev1, MaxLev)
		ChessId := mergeDataCfg.GetChessIdByLvAndColor(NewLev1, Color)
		ChessIds = append(ChessIds, ChessId)
	}
	return GoUtil.UniqueInts(ChessIds)
}
func (o *OrderMod) getChessLvFromConfig1(MinEnergy, MaxEnergy, MinLv, MaxLv, LastEnergy int) []int {
	var rand []int
	t := 0
	if LastEnergy > 0 {
		t = 1
	}
	for _, v := range orderCfgMap {
		if MinEnergy >= v.Min && MaxEnergy <= v.Max {
			for _, info := range v.Pool {
				if MinLv <= info.lv && MaxLv >= info.lv && LastEnergy+info.energy <= MaxEnergy && LastEnergy+info.energy >= MinEnergy && t >= info.t {
					rand = append(rand, info.lv)
				}
			}
		}
	}
	return rand
}

func (o *OrderMod) ChessPoolChess(Color string, Lv int) bool {
	for _, v := range o.ChessPool2[Color] {
		if v > Lv {
			return true
		}
	}
	return false
}

func (o *OrderMod) getFromPool(Emit int, Color string, Lv int) {
	for i, v := range o.ChessPool2[Color] {
		if v == Lv {
			o.ChessPool2[Color] = append(o.ChessPool2[Color][:i], o.ChessPool2[Color][i+1:]...)
			return
		}
	}
	for i, v := range o.ChessPool2[Color] {
		if v > Lv {
			o.ChessPool2[Color] = append(o.ChessPool2[Color][:i], o.ChessPool2[Color][i+1:]...)
			for k := Lv; k < v; k++ {
				o.ChessPool2[Color] = append(o.ChessPool2[Color], k)
			}
			return
		}
	}
	Product := mergeDataCfg.GetEmitProduceType(Emit)
	if len(Product) < 2 {
		return
	}
	for _, v := range Product {
		if Color == v {
			continue
		}
		o.ChessPool2[Color] = append(o.ChessPool2[Color], Lv)
	}
}

func (o *OrderMod) getChessIdPool(Emit []int, Color string, EnergyMul, MinEnergy, MaxEnergy, OrderDiff, LastEnergy int) (int, int) {
	ChessLv := 0
	EmitChessId := getEmitBySeries(Emit, Color)
	ChessMinLv, ChessMaxLv := getChesslvRange(EmitChessId, EnergyMul, o.IsCharge)
	ChessLvRand := o.getChessLvFromConfig1(MinEnergy, MaxEnergy, ChessMinLv, ChessMaxLv, LastEnergy)
	Pool := o.ChessPool2[Color]
	ChessLvRand2 := make([]int, 0)
	for _, v := range ChessLvRand {
		if GoUtil.InArray(v, Pool) {
			ChessLvRand2 = append(ChessLvRand2, v)
		}
	}
	if len(ChessLvRand2) > 0 {
		ChessLv = GoUtil.RandSlice(ChessLvRand2)
	}
	sort.Ints(ChessLvRand)
	if len(ChessLvRand) > 0 && len(ChessLvRand2) == 0 && o.ChessPoolChess(Color, ChessLvRand[len(ChessLvRand)-1]) {
		ChessLv = ChessLvRand[len(ChessLvRand)-1]
	}
	if len(ChessLvRand) > 0 && len(ChessLvRand2) == 0 && !o.ChessPoolChess(Color, ChessLvRand[len(ChessLvRand)-1]) && len(ChessLvRand) > 0 {
		ChessLv = GoUtil.RandSlice(ChessLvRand)
	}
	if ChessLv == 0 {
		ChessLv = 6
		o.NextDiff = OrderDiff
	}
	o.getFromPool(EmitChessId, Color, ChessLv)
	NewLev := mergeDataCfg.DynamicLev(ChessLv, EmitChessId, Color)
	MaxLev := mergeDataCfg.GetMaxLvByColor(Color)
	NewLev1 := adjustLev(NewLev, EnergyMul)
	NewLev2 := min(NewLev1, MaxLev)
	Chess := mergeDataCfg.GetChessIdByLvAndColor(NewLev2, Color)
	if Chess == 0 {
		Chess = mergeDataCfg.GetChessIdByLvAndColor(6, Color)
	}
	return Chess, ChessLv
}
func getChessFromPoolByEnergy(o *OrderMod, MinEnergy, MaxEnergy, ChessNum int, Emit []int, EnergyMul, OrderDiff, OrderType int) []int {
	ColorArr := make([]string, 0)
	for i := 0; i < ChessNum; i++ {
		ColorArr = append(ColorArr, getEmitSeries(o, Emit, OrderType))
	}
	if len(ColorArr) == 2 && ColorArr[0] == ColorArr[1] {
	}
	if len(ColorArr) == 1 {
		Chess, _ := o.getChessIdPool(Emit, ColorArr[0], EnergyMul, MinEnergy, MaxEnergy, OrderDiff, 0)
		if Chess == 0 {
			Chess = mergeDataCfg.GetChessIdByLvAndColor(6, ColorArr[0])
		}
		return []int{Chess}
	}
	if len(ColorArr) == 2 {
		Chess1, Chess1Lv := o.getChessIdPool(Emit, ColorArr[0], EnergyMul, MinEnergy, MaxEnergy, OrderDiff, 0)
		if Chess1 == 0 {
			Chess1 = mergeDataCfg.GetChessIdByLvAndColor(6, ColorArr[0])
		}
		Energy := int(math.Pow(2, float64(Chess1Lv-1)))
		Chess2, _ := o.getChessIdPool(Emit, ColorArr[1], EnergyMul, MinEnergy, MaxEnergy, OrderDiff, Energy)
		return []int{Chess1, Chess2}
	}
	return nil
}

// 从棋子池中获取棋子
func getChessFromPoolByDiff(o *OrderMod, Diff int, Emit []int, EnergyMul int) int {
	Color := getEmitSeries(o, Emit, 0)
	EmitChessId := getEmitBySeries(Emit, Color)
	//ColorRand := mergeDataCfg.GetEmitProduceType(EmitChessId)
	// 从棋子池中获取棋子
	MinChessId := 0
	for i, chess := range o.ChessPool {
		chessColor := mergeDataCfg.GetColorById(chess)
		if Color != chessColor {
			continue
		}
		if reflectChess[chess] > Diff {
			MinChessId = chess
		}

		ChessLv := mergeDataCfg.GetLvById(chess)
		if reflectChess[chess] == Diff && ChessLv >= EnergyMul+1 && ChessLv <= EnergyMul+12 {
			o.ChessPool = append(o.ChessPool[:i], o.ChessPool[i+1:]...)
			return chess
		}
	}
	/** 获取不到时选最接近的棋子
	 * 1. 选取最接近的棋子
	 */
	if MinChessId != 0 {
		ColorRand := mergeDataCfg.GetEmitProduceType(EmitChessId)
		ChessMinLv, ChessMaxLv := getChesslvRange(EmitChessId, EnergyMul, o.IsCharge)
		NewLev := getChessLv(ChessMinLv, ChessMaxLv, Diff)
		MinChessLv := mergeDataCfg.GetLvById(MinChessId)
		NewLev2 := mergeDataCfg.DynamicLev2(NewLev, EmitChessId, ColorRand[0], Color)
		NewLev3 := adjustLev(NewLev2, EnergyMul)
		o.ChessPool = GoUtil.DeleteEleByValue(o.ChessPool, MinChessId)
		for i := NewLev3; i < MinChessLv; i++ {
			ChessId2 := mergeDataCfg.GetChessIdByLvAndColor(i, Color)
			if ChessId2 != 0 {
				o.ChessPool = append(o.ChessPool, ChessId2)
			}
		}
		Chess := mergeDataCfg.GetChessIdByLvAndColor(NewLev2, Color)
		return Chess
	}
	ChessMinLv, ChessMaxLv := getChesslvRange(EmitChessId, EnergyMul, o.IsCharge)
	NewLev := getChessLv(ChessMinLv, ChessMaxLv, Diff)
	NewLev1 := mergeDataCfg.DynamicLev(NewLev, EmitChessId, Color)
	MaxLev := mergeDataCfg.GetMaxLvByColor(Color)
	NewLev1 = min(NewLev1, MaxLev)
	ChessId := mergeDataCfg.GetChessIdByLvAndColor(NewLev1, Color)
	ProductColor := mergeDataCfg.GetEmitProduceType(EmitChessId)
	for _, i := range ProductColor {
		if i == Color {
			continue
		}
		NewLev2 := mergeDataCfg.DynamicLev2(NewLev1, EmitChessId, Color, i)
		NewLev2 = adjustLev(NewLev2, EnergyMul)
		MaxLev := mergeDataCfg.GetMaxLvByColor(i)
		NewLev2 = min(NewLev2, MaxLev)
		ChessId2 := mergeDataCfg.GetChessIdByLvAndColor(NewLev2, i)
		if ChessId2 != 0 {
			o.ChessPool = append(o.ChessPool, ChessId2)
		}
	}
	o.ChessPool = GoUtil.ShuffleArray(o.ChessPool)
	if len(o.ChessPool) > 200 {
		o.ChessPool = o.ChessPool[:200]
	}
	return ChessId
}

// 初始化棋子难度映射表
func initReflectChess(Emits []int, EnergyMul int) {
	reflectChess = make(map[int]int)
	Start, End := 0, 0
	for _, Emit := range Emits {
		ProduceColor := mergeDataCfg.GetEmitProduceType(Emit)
		if len(ProduceColor) == 0 || ProduceColor[0] == "" {
			continue
		}
		ChessMinLv, ChessMaxLv := getChesslvRange(Emit, EnergyMul, false)
		Product := mergeDataCfg.GetEmitProduceChessType(Emit)
		Start = ChessMinLv
		End = ChessMinLv + (ChessMaxLv-ChessMinLv+1)/3 - 1
		for _, v := range Product {
			Adjust := mergeDataCfg.DynamicAdjust(Emit, v, EnergyMul)
			initReflectChess2(v, Start, End, DIFF_LOW, Adjust)
		}
		Start = ChessMinLv + (ChessMaxLv-ChessMinLv+1)/3
		End = ChessMinLv + (ChessMaxLv-ChessMinLv+1)/3*2 - 1
		for _, v := range Product {
			Adjust := mergeDataCfg.DynamicAdjust(Emit, v, EnergyMul)
			initReflectChess2(v, Start, End, DIFF_MID, Adjust)
		}
		Start = ChessMinLv + (ChessMaxLv-ChessMinLv+1)/3*2
		End = ChessMaxLv
		for _, v := range Product {
			Adjust := mergeDataCfg.DynamicAdjust(Emit, v, EnergyMul)
			initReflectChess2(v, Start, End, DIFF_HIGH, Adjust)
		}
	}
}

func initReflectChess2(Color string, Start, End, Diff, adjust int) {
	for i := Start; i <= End; i++ {
		Lv := max(i-adjust, 1)
		ChessId := mergeDataCfg.GetChessIdByLvAndColor(Lv, Color)
		if ChessId == 0 {
			continue
		}
		reflectChess[ChessId] = Diff
	}
}
func AdjustLev(Lev, EnergyMul int) int {
	return adjustLev(Lev, EnergyMul)
}

// 调整棋子等级
func adjustLev(Lev, EnergyMul int) int {
	randMapList := map[int]map[int]int{
		1:  {},
		2:  {0: 30, 1: 70},
		3:  {1: 90, 2: 10},
		4:  {1: 30, 2: 70},
		5:  {2: 40, 3: 60},
		6:  {2: 10, 3: 50, 4: 40},
		7:  {3: 20, 4: 40, 5: 40},
		8:  {4: 40, 5: 60},
		9:  {4: 20, 5: 40, 6: 40},
		10: {5: 40, 6: 60},
		11: {5: 20, 6: 70, 7: 10},
	}
	if v, ok := randMapList[EnergyMul]; ok {
		Lev += GoUtil.RandMap(v)
	}
	return Lev
}

// 获取发射器系列
func getEmitBySeries(EmitList []int, EmitId string) int {
	for _, v := range EmitList {
		ProduceColor := mergeDataCfg.GetEmitProduceType(v)
		if len(ProduceColor) == 0 || ProduceColor[0] == "" {
			continue
		}
		if GoUtil.InStringArray(EmitId, ProduceColor) {
			return v
		}
	}
	return 0
}
