更新机器人随从牌选择策略

This commit is contained in:
zhl 2021-04-01 13:33:17 +08:00
parent aa39fd5f4c
commit 2e018c887e
11 changed files with 130 additions and 58 deletions

View File

@ -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]
}
}

View File

@ -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);

View File

@ -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'
}

View File

@ -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)
}

View File

@ -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)
}

View File

@ -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

View File

@ -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) {
/**
*

View File

@ -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)

View File

@ -118,6 +118,8 @@ export class Player extends Schema {
heros: number[]
// 是否是机器人
robot: boolean
// 机器人等级
robotLvl: number = 0
// 十场胜率
winRate: number

View File

@ -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}
}
}

View File

@ -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
}