更新机器人随从牌选择策略
This commit is contained in:
parent
aa39fd5f4c
commit
2e018c887e
@ -189,4 +189,21 @@ export class GameEnv {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据值获取机器人等级对应的配置项值
|
||||
* @param {number} lvl
|
||||
* @return {number}
|
||||
*/
|
||||
public getRobotLvlKey(lvl: number = 0) {
|
||||
const nums = [
|
||||
BaseConst.ROBOT_LVL_LOW,
|
||||
BaseConst.ROBOT_LVL_MID,
|
||||
BaseConst.ROBOT_LVL_HIGHT,
|
||||
BaseConst.ROBOT_LVL_EXTRA
|
||||
]
|
||||
lvl = lvl < 0 ? 0 : lvl
|
||||
lvl = lvl > 3 ? 3 : lvl
|
||||
return nums[lvl]
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import { ItemCardCfg } from '../cfg/parsers/ItemCardCfg'
|
||||
import { MatchCfg } from '../cfg/parsers/MatchCfg'
|
||||
import { ItemFuncCfg } from '../cfg/parsers/ItemFuncCfg'
|
||||
import { IncomeCfg } from '../cfg/parsers/IncomeCfg'
|
||||
import { NpcTeamCfg } from '../cfg/parsers/NpcTeamCfg'
|
||||
|
||||
|
||||
export function initData() {
|
||||
@ -29,6 +30,7 @@ export function initData() {
|
||||
rP(BaseConst.MATCH, MatchCfg);
|
||||
rP(BaseConst.ITEMFUNC, ItemFuncCfg);
|
||||
rP(BaseConst.INCOME, IncomeCfg);
|
||||
rP(BaseConst.NPCTEAM, NpcTeamCfg);
|
||||
DataParser.loadAll();
|
||||
|
||||
let map = global.$cfg.get(BaseConst.SKILL);
|
||||
|
@ -92,4 +92,5 @@ export class BaseConst {
|
||||
public static readonly MATCH = 'match'
|
||||
public static readonly ITEMFUNC = 'itemfunc'
|
||||
public static readonly INCOME = 'income'
|
||||
public static readonly NPCTEAM = 'npcteam'
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ export class Robot {
|
||||
*/
|
||||
@wait('pickHeroTime')
|
||||
private async selectHero() {
|
||||
let data = assistantUtil.randomHero()
|
||||
let data = assistantUtil.randomHero(this.lvl)
|
||||
this.reply('select_hero_c2s', data)
|
||||
}
|
||||
|
||||
|
@ -262,7 +262,7 @@ export class RobotClient implements Client {
|
||||
*/
|
||||
@wait('pickHeroTime')
|
||||
private async selectHero() {
|
||||
let data = assistantUtil.randomHero()
|
||||
let data = assistantUtil.randomHero(this.lvl)
|
||||
this.reply('select_hero_c2s', data)
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,6 @@ import { GameStateConst } from '../../constants/GameStateConst'
|
||||
import gameUtil from '../../utils/game.util'
|
||||
import { GameEnv } from '../../cfg/GameEnv'
|
||||
import { NextTurnCommand } from './NextTurnCommand'
|
||||
import { debugRoom } from '../../common/Debug'
|
||||
import { DiceNextTurnCommand } from './DiceNextTurnCommand'
|
||||
|
||||
/**
|
||||
@ -20,37 +19,6 @@ export class BeginGameCommand extends Command<CardGameState, {}> {
|
||||
let card1 = gameUtil.initCardQue(card0.length + 1, this.state.advMode)
|
||||
let cardAll = card0.concat(card1)
|
||||
cardAll.randomSort()
|
||||
// 如果是匹配模式, 挑战机器人作弊比率
|
||||
if (this.state.mode == 1) {
|
||||
for (let [, player] of this.state.players) {
|
||||
if (!player.robot) {
|
||||
continue
|
||||
}
|
||||
let client = this.room.getClient(player)
|
||||
let oplayer = this.room.getOppositePlayer(player)
|
||||
if (oplayer.robot) {
|
||||
let eplayers = this.room.getOtherTeamPlayers(player.id, oplayer.id)
|
||||
if (!eplayers || eplayers.length == 0) {
|
||||
continue
|
||||
}
|
||||
for (let p of eplayers) {
|
||||
if (!p.robot) {
|
||||
oplayer = p
|
||||
break
|
||||
}
|
||||
}
|
||||
if (oplayer.robot) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
let assistClient = this.room.getAssistClient(player.id)
|
||||
let lvl = new GameEnv().getRobotLvl(oplayer.winRate * 100)
|
||||
debugRoom(`opposite play win rate: ${ oplayer.winRate }, robot lvl: ${ lvl }`)
|
||||
client.send('update_robot_level', { lvl })
|
||||
assistClient.send('update_robot_level', { lvl })
|
||||
}
|
||||
}
|
||||
|
||||
this.state.cardQueue = cardAll
|
||||
let i = 0
|
||||
|
@ -64,22 +64,50 @@ export class PlayReadyCommand extends Command<CardGameState, {
|
||||
this.room.broadcast('player_ready_s2c', { player: client.sessionId }, { except: client })
|
||||
// 如果所有人的状态都为已准备状态, 则开始发牌
|
||||
if (readyCount >= this.room.maxClients) {
|
||||
|
||||
// 比大小, 确定先手
|
||||
// return [new PrepareCommand()];
|
||||
// let i = 0;
|
||||
// for (let [,player] of this.state.players) {
|
||||
// player.team = (i == 1 || i == 2) ? 1 : 0;
|
||||
// i += 1;
|
||||
// }
|
||||
|
||||
// 如果是匹配模式, 挑战机器人作弊比率
|
||||
if (this.state.mode == 1) {
|
||||
updateRobotLvl(this.room)
|
||||
}
|
||||
self.room.stopSchedule(ClockNameConst.WAITING_PREPARE)
|
||||
await beginChangeHero(self.room)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新机器人等级
|
||||
* @param {Room} room
|
||||
*/
|
||||
const updateRobotLvl = function (room: Room) {
|
||||
for (let [, player] of room.state.players) {
|
||||
if (!player.robot) {
|
||||
continue
|
||||
}
|
||||
let oplayer = room.getOppositePlayer(player)
|
||||
if (oplayer.robot) {
|
||||
let eplayers = room.getOtherTeamPlayers(player.id, oplayer.id)
|
||||
if (!eplayers || eplayers.length == 0) {
|
||||
continue
|
||||
}
|
||||
for (let p of eplayers) {
|
||||
if (!p.robot) {
|
||||
oplayer = p
|
||||
break
|
||||
}
|
||||
}
|
||||
if (oplayer.robot) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
player.robotLvl = new GameEnv().getRobotLvl(oplayer.winRate * 100)
|
||||
let client = room.getClient(player)
|
||||
let assistClient = room.getAssistClient(player.id)
|
||||
debugRoom(`update robot level, robot lvl: ${ player.robotLvl }`)
|
||||
client.send('update_robot_level', { lvl: player.robotLvl })
|
||||
assistClient.send('update_robot_level', { lvl: player.robotLvl })
|
||||
}
|
||||
}
|
||||
const beginChangeHero = async function (room: Room) {
|
||||
/**
|
||||
* 超时后随机选一个英雄
|
||||
|
@ -9,6 +9,7 @@ import {GameEnv} from "../../cfg/GameEnv";
|
||||
import {StateTypeEnum} from "../enums/StateTypeEnum";
|
||||
import {getCardGroup} from "../../common/WebApi";
|
||||
import { ClockNameConst } from '../../constants/ClockNameConst'
|
||||
import { getHeroUnits } from '../../utils/game.util'
|
||||
|
||||
/**
|
||||
* 选择英雄
|
||||
@ -67,12 +68,7 @@ export class SelectHeroCommand extends Command<CardGameState, { client: Client,
|
||||
}
|
||||
}
|
||||
if (units.length == 0) {
|
||||
for (let i = 1; i < 10; i++) {
|
||||
if (!heroData[`follower${i}id`]) {
|
||||
break;
|
||||
}
|
||||
units.push(heroData[`follower${i}id`]);
|
||||
}
|
||||
units = getHeroUnits(player.heroId, player.robotLvl)
|
||||
}
|
||||
for (let unitId of units) {
|
||||
const eff = effectMap.get(unitId)
|
||||
|
@ -118,6 +118,8 @@ export class Player extends Schema {
|
||||
heros: number[]
|
||||
// 是否是机器人
|
||||
robot: boolean
|
||||
// 机器人等级
|
||||
robotLvl: number = 0
|
||||
// 十场胜率
|
||||
winRate: number
|
||||
|
||||
|
@ -5,7 +5,6 @@ import { SkillTargetType } from '../rooms/logic/skill/SkillConst'
|
||||
import CfgMan from '../rooms/logic/CfgMan'
|
||||
import { CardGameState } from '../rooms/schema/CardGameState'
|
||||
import { Player } from '../rooms/schema/Player'
|
||||
import { HeroCfg } from '../cfg/parsers/HeroCfg'
|
||||
import { EffectType } from '../cfg/enums/EffectType'
|
||||
import { CardType } from '../cfg/enums/CardType'
|
||||
import { GameEnv } from '../cfg/GameEnv'
|
||||
@ -13,6 +12,7 @@ import { error, robotLog } from '../common/Debug'
|
||||
import { PlayerStateConst } from '../constants/PlayerStateConst'
|
||||
import { Pet } from '../rooms/schema/Pet'
|
||||
import { getRandom } from './number.util'
|
||||
import { NpcTeamCfg } from '../cfg/parsers/NpcTeamCfg'
|
||||
|
||||
function pushMapVal(map: Map<number, Card[]>, key: number, value: Card) {
|
||||
if (map.has(key)) {
|
||||
@ -408,11 +408,31 @@ let assistantUtil = {
|
||||
}
|
||||
|
||||
},
|
||||
randomHero() {
|
||||
let heroMap: Map<number, HeroCfg> = global.$cfg.get(BaseConst.HERO)
|
||||
let heroArr = [...heroMap.values()]
|
||||
let hero: HeroCfg = heroArr.randomOne()
|
||||
return { heroId: hero.id }
|
||||
randomHero(lvl: number) {
|
||||
const cfgNum = new GameEnv().getRobotLvlKey(lvl)
|
||||
let npcCfgMap: Map<number, NpcTeamCfg> = global.$cfg.get(BaseConst.NPCTEAM)
|
||||
let total = 0
|
||||
let tmpArr: number[][] = []
|
||||
for (let [, cfg] of npcCfgMap) {
|
||||
if (cfg.difficultyid != cfgNum) {
|
||||
continue
|
||||
}
|
||||
total += cfg.weightid
|
||||
tmpArr.push([cfg.id, total])
|
||||
}
|
||||
const num = Math.random() * total
|
||||
let id: number
|
||||
for (let data of tmpArr) {
|
||||
if (data[1] >= num) {
|
||||
id = data[0]
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!id) {
|
||||
let data: number[] = tmpArr.randomOne()
|
||||
id = data[0]
|
||||
}
|
||||
return {heroId: npcCfgMap.get(id).teamheroid}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ import { GameEnv } from '../cfg/GameEnv'
|
||||
import { CardGameState } from '../rooms/schema/CardGameState'
|
||||
import { CardType } from '../cfg/enums/CardType'
|
||||
import { EffectType } from '../cfg/enums/EffectType'
|
||||
import { NpcTeamCfg } from '../cfg/parsers/NpcTeamCfg'
|
||||
|
||||
let gameUtil = {
|
||||
/**
|
||||
@ -55,7 +56,7 @@ let gameUtil = {
|
||||
randomEffect(advMode: boolean): number {
|
||||
let effCfgMap: Map<number, EffectCardCfg> = global.$cfg.get(BaseConst.EFFECTCARD)
|
||||
let results = []
|
||||
for (let [,effCfg] of effCfgMap) {
|
||||
for (let [, effCfg] of effCfgMap) {
|
||||
if (effCfg.type_id !== 2) {
|
||||
continue
|
||||
}
|
||||
@ -129,7 +130,7 @@ let gameUtil = {
|
||||
let effid = data[0]
|
||||
let effCfg = effCfgMap.get(effid)
|
||||
if (!effCfg) {
|
||||
error(`config of ${effid} not found`)
|
||||
error(`config of ${ effid } not found`)
|
||||
continue
|
||||
}
|
||||
if ((advMode && effCfg.intermediateaccess) || (!advMode && effCfg.primaryaccess)) {
|
||||
@ -388,3 +389,40 @@ let gameUtil = {
|
||||
|
||||
}
|
||||
export default gameUtil
|
||||
|
||||
/**
|
||||
* 获取英雄对应的随从配置
|
||||
*/
|
||||
export function getHeroUnits(heroId: number, lvl: number) {
|
||||
const cfgNum = new GameEnv().getRobotLvlKey(lvl)
|
||||
let npcCfgMap: Map<number, NpcTeamCfg> = global.$cfg.get(BaseConst.NPCTEAM)
|
||||
let units: number[] = []
|
||||
for (let [, cfg] of npcCfgMap) {
|
||||
if (cfg.difficultyid == cfgNum && cfg.teamheroid == heroId) {
|
||||
for (let i = 1; i < 10; i++) {
|
||||
// @ts-ignore
|
||||
if (!cfg[`entourage${ i }id`]) {
|
||||
break
|
||||
}
|
||||
// @ts-ignore
|
||||
units.push(cfg[`entourage${ i }id`])
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
if (units.length == 0) {
|
||||
const heroMap = global.$cfg.get(BaseConst.HERO)
|
||||
const heroData = heroMap.get(heroId)
|
||||
for (let i = 1; i < 10; i++) {
|
||||
if (!heroData[`follower${ i }id`]) {
|
||||
break
|
||||
}
|
||||
units.push(heroData[`follower${ i }id`])
|
||||
}
|
||||
}
|
||||
if (units.length == 0) {
|
||||
error(`无法获取英雄${ heroId }在等级${ cfgNum }下的随从配置`)
|
||||
}
|
||||
return units
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user