375 lines
6.5 KiB
Go
375 lines
6.5 KiB
Go
package hunting
|
||
|
||
import (
|
||
"math/rand"
|
||
"mongo.games.com/game/common"
|
||
)
|
||
|
||
// 0 没有宝石
|
||
|
||
// level1
|
||
// 1 河心石
|
||
// 2 荒玉石
|
||
// 3 紫水晶
|
||
// 4 血榴石
|
||
// 5 锡黄晶
|
||
|
||
// level2
|
||
// 6 蓝锆晶
|
||
// 7 精灵榄
|
||
// 8 魇蛟眼
|
||
// 9 红玉髓
|
||
// 10 龙眼石
|
||
|
||
// level3
|
||
// 11 海洋之眼
|
||
// 12 梦境翡翠
|
||
// 13 影歌紫玉
|
||
// 14 地狱炎石
|
||
// 15 王者琥珀
|
||
|
||
// 16 炸弹
|
||
|
||
const (
|
||
// 关卡数量
|
||
LevelNum = 4
|
||
// 掉线重连保持时长,单位秒
|
||
DropLineTime = 30
|
||
// 最短多少秒通知一次奖池金额
|
||
CoinPoolTime = 1
|
||
// 没有宝石
|
||
NoGem = 0
|
||
// 炸弹
|
||
Bomb = 16
|
||
// 多长时间未操作踢出房间
|
||
TimeoutSecond = 180
|
||
)
|
||
|
||
// 游戏状态
|
||
const (
|
||
GamingState = 0
|
||
GameStateMax = 1 // 状态数量
|
||
)
|
||
|
||
func levelNum(n int) int {
|
||
if n-1 < 0 {
|
||
return 0
|
||
}
|
||
if n-1 >= LevelNum {
|
||
return LevelNum - 1
|
||
}
|
||
return n - 1
|
||
}
|
||
|
||
var levelPass = []int32{15, 15, 15, 0}
|
||
|
||
// 通关需要的炸弹数量
|
||
func LevelPassBombs(level int) int32 {
|
||
return levelPass[levelNum(level)]
|
||
}
|
||
|
||
var levelGemsNum = []int{4*4 + 4, 5*5 + 5, 6*6 + 6, 0}
|
||
|
||
// 每关的初始宝石数量
|
||
func LevelGemsNum(level int) int {
|
||
return levelGemsNum[levelNum(level)]
|
||
}
|
||
|
||
var levelColumn = []int{4, 5, 6, 0}
|
||
|
||
// 每关的宝石列数
|
||
func LevelColumn(level int) int {
|
||
return levelColumn[levelNum(level)]
|
||
}
|
||
|
||
var levelGemType = []int32{1, 2, 3, 4, 5}
|
||
|
||
// 每关的宝石类型
|
||
func LevelGemType(level int) []int32 {
|
||
l := levelNum(level)
|
||
if l == 0 {
|
||
return levelGemType
|
||
}
|
||
ret := make([]int32, len(levelGemType))
|
||
for i := 0; i < len(ret); i++ {
|
||
ret[i] = levelGemType[i] + int32(len(ret)*l)
|
||
}
|
||
return ret
|
||
}
|
||
|
||
var GemTypeName = map[int32]string{
|
||
1: "1河心石",
|
||
2: "2荒玉石",
|
||
3: "3紫水晶",
|
||
4: "4血榴石",
|
||
5: "5锡黄晶",
|
||
6: "1蓝锆晶",
|
||
7: "2精灵榄",
|
||
8: "3魇蛟眼",
|
||
9: "4红玉髓",
|
||
10: "5龙眼石",
|
||
11: "1海洋之眼",
|
||
12: "2梦境翡翠",
|
||
13: "3影歌紫玉",
|
||
14: "4地狱炎石",
|
||
15: "5王者琥珀",
|
||
16: "炸弹",
|
||
}
|
||
|
||
var gemProbability = []int{4100, 2700, 2000, 800, 400}
|
||
|
||
func GetGemIndex(r *rand.Rand, num int) int {
|
||
n := r.Intn(10000)
|
||
sum := 0
|
||
for i := 0; i < num; i++ {
|
||
sum += gemProbability[i]
|
||
if n < sum {
|
||
return i
|
||
}
|
||
}
|
||
return 0
|
||
}
|
||
|
||
var levelDelete = []int{4, 5, 6, 0}
|
||
|
||
// 每关宝石最少可消除的连接数量
|
||
func LevelDelete(level int) int {
|
||
return levelDelete[levelNum(level)]
|
||
}
|
||
|
||
var rate = []int32{2, 3, 4, 10, 20, 40, 80, 160, 320, 640, 1000, 2000, 3000, 4000, 5000, 6000, 7000}
|
||
var level1GemRate = [][]int32{
|
||
rate[:11],
|
||
rate[1:12],
|
||
rate[2:13],
|
||
rate[3:14],
|
||
rate[4:15],
|
||
}
|
||
var level2GemRate = [][]int32{
|
||
level1GemRate[1],
|
||
level1GemRate[2],
|
||
level1GemRate[3],
|
||
level1GemRate[4],
|
||
rate[5:16],
|
||
}
|
||
var level3GemRate = [][]int32{
|
||
level2GemRate[1],
|
||
level2GemRate[2],
|
||
level2GemRate[3],
|
||
level2GemRate[4],
|
||
rate[6:17],
|
||
}
|
||
|
||
// GemsRate 宝石倍率, 倍率比实际倍率扩大了10倍,使用后要除以10
|
||
// n 宝石连接数量
|
||
// tp 宝石类型
|
||
func GemsRate(level int, n int, tp int32) int64 {
|
||
if tp == Bomb {
|
||
return 0
|
||
}
|
||
switch levelNum(level) {
|
||
case 0:
|
||
if n < 4 || n > 14 {
|
||
return 0
|
||
}
|
||
return int64(level1GemRate[(tp-1)%5][n-4])
|
||
case 1:
|
||
if n < 5 || n > 15 {
|
||
return 0
|
||
}
|
||
return int64(level2GemRate[(tp-1)%5][n-5])
|
||
case 2:
|
||
if n < 6 || n > 16 {
|
||
return 0
|
||
}
|
||
return int64(level3GemRate[(tp-1)%5][n-6])
|
||
}
|
||
return 0
|
||
}
|
||
|
||
func rateScope(level int, a, b int32, f func([][]int32) []int32) []int32 {
|
||
if a > b {
|
||
a, b = b, a
|
||
}
|
||
var ret []int32
|
||
switch levelNum(level) {
|
||
case 0:
|
||
ret = f(level1GemRate)
|
||
case 1:
|
||
ret = f(level2GemRate)
|
||
case 2:
|
||
ret = f(level3GemRate)
|
||
}
|
||
tmp := map[int32]struct{}{}
|
||
for i := 0; i < len(ret); i++ {
|
||
tmp[ret[i]] = struct{}{}
|
||
}
|
||
ret = ret[:0]
|
||
for k := range tmp {
|
||
ret = append(ret, k)
|
||
}
|
||
return ret
|
||
}
|
||
|
||
// [a, b)
|
||
func RateScope(level int, a, b int32) []int32 {
|
||
return rateScope(level, a, b, func(data [][]int32) []int32 {
|
||
var ret []int32
|
||
for _, v := range data {
|
||
for i := 0; i < len(v); i++ {
|
||
if v[i] >= b {
|
||
break
|
||
}
|
||
if v[i] < a {
|
||
continue
|
||
}
|
||
ret = append(ret, v[i])
|
||
}
|
||
}
|
||
return ret
|
||
})
|
||
}
|
||
|
||
// [a, b]
|
||
func RateScope1(level int, a, b int32) []int32 {
|
||
return rateScope(level, a, b, func(data [][]int32) []int32 {
|
||
var ret []int32
|
||
for _, v := range data {
|
||
for i := 0; i < len(v); i++ {
|
||
if v[i] > b {
|
||
break
|
||
}
|
||
if v[i] < a {
|
||
continue
|
||
}
|
||
ret = append(ret, v[i])
|
||
}
|
||
}
|
||
return ret
|
||
})
|
||
}
|
||
|
||
func rateGems(level int, r int32, data [][]int32) map[int32]int {
|
||
ret := map[int32]int{}
|
||
for k, v := range data {
|
||
var n = LevelDelete(level) - 1
|
||
for i := 0; i < len(v); i++ {
|
||
n++
|
||
if v[i] < r {
|
||
continue
|
||
}
|
||
if v[i] > r {
|
||
break
|
||
}
|
||
if v[i] == r {
|
||
ret[int32(k)+1+int32(5*levelNum(level))] = n
|
||
break
|
||
}
|
||
}
|
||
}
|
||
return ret
|
||
}
|
||
|
||
// RateGems 根据需要的倍率,查询连接宝石和类型
|
||
// rate 倍率
|
||
func RateGems(level int, r int32) map[int32]int {
|
||
switch levelNum(level) {
|
||
case 0:
|
||
return rateGems(level, r, level1GemRate)
|
||
case 1:
|
||
return rateGems(level, r, level2GemRate)
|
||
case 2:
|
||
return rateGems(level, r, level3GemRate)
|
||
}
|
||
return map[int32]int{}
|
||
}
|
||
|
||
func GetsRateMin(level int) map[int32][]int {
|
||
ret := make(map[int32][]int)
|
||
gt := LevelGemType(level)
|
||
for i := 0; i < len(gt); i++ {
|
||
num := 1
|
||
var n = GemsRate(level, num, gt[i])
|
||
for n < 10 {
|
||
if n > 0 {
|
||
ret[gt[i]] = append(ret[gt[i]], num)
|
||
}
|
||
num++
|
||
n = GemsRate(level, num, gt[i])
|
||
}
|
||
}
|
||
return ret
|
||
}
|
||
|
||
// CoinPoolRate 奖池倍率
|
||
// n 宝石连接数量
|
||
func CoinPoolRate(level int, n int) int64 {
|
||
switch levelNum(level) {
|
||
case 0:
|
||
if n < 15 {
|
||
return 0
|
||
}
|
||
if n <= 16 {
|
||
return int64((n - 14) * 10)
|
||
}
|
||
return 20
|
||
case 1:
|
||
if n < 16 {
|
||
return 0
|
||
}
|
||
if n <= 18 {
|
||
return int64((n - 15) * 10)
|
||
}
|
||
return 30
|
||
case 2:
|
||
if n < 17 {
|
||
return 0
|
||
}
|
||
if n <= 21 {
|
||
return int64((n - 16) * 10)
|
||
}
|
||
return 50
|
||
}
|
||
return 0
|
||
}
|
||
|
||
// 每次下注,出现炸弹的概率是25%
|
||
func GetBomb(r *rand.Rand) bool {
|
||
return r.Intn(100) < 25
|
||
}
|
||
|
||
// 翻牌概率
|
||
var cardRate = []int32{3500, 3000, 2000, 1000, 500}
|
||
|
||
var baseRate = [][]int64{
|
||
{2, 5, 10, 15, 20, 30},
|
||
{1, 3, 6, 10, 15, 20},
|
||
{1, 2, 4, 6, 8, 10},
|
||
}
|
||
|
||
func CardScore(r *rand.Rand, baseScore int64, sceneType int32) int64 {
|
||
var sum int32
|
||
var i int
|
||
n := r.Int31n(10000)
|
||
for k, v := range cardRate {
|
||
sum += v
|
||
if n < sum {
|
||
i = k
|
||
break
|
||
}
|
||
}
|
||
|
||
var arr []int64
|
||
switch sceneType {
|
||
case common.SceneType_Primary:
|
||
arr = baseRate[0]
|
||
case common.SceneType_Middle:
|
||
arr = baseRate[1]
|
||
default: // 高级场、试玩场
|
||
arr = baseRate[2]
|
||
}
|
||
a := baseScore * arr[i]
|
||
b := baseScore * arr[i+1]
|
||
return a + r.Int63n(b-a+1)
|
||
}
|