import {Card} from "../rooms/schema/Card"; import arrUtil from "./array.util"; import {EffectCardCfg} from "../cfg/parsers/EffectCardCfg"; import {BaseConst} from "../constants/BaseConst"; 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"; import {error, robotLog} from "../common/Debug"; let assistantUtil = { /** * 检查是否可以吃牌 * @param cardArr 待检查的卡组 * @param card 目标牌 */ checkTriple(cardArr: Card[], card?: Card): Card[] { if (card) cardArr.push(card); let maxCount = card ? new GameEnv().otherEatCount : new GameEnv().selfEatCount; let pointMap: Map = new Map(); let cardIdSet: Set = new Set(); for (let c of cardArr) { if (!(c.type == CardType.general || c.type == CardType.variable_unit)) { continue; } if (pointMap.has(c.number)) { let arr = pointMap.get(c.number); arr.push(c); pointMap.set(c.number, arr); } else { pointMap.set(c.number, [c]); } cardIdSet.add(c.number); } let fetched = false; let result: Card[] = []; // 优先出对子 for (let [point, arr] of pointMap) { if (card) { if (point == card.number && arr.length >= maxCount) { fetched = true; result = arr; break; } } else { if (arr.length >= maxCount) { fetched = true; result = arr; break; } } } if (fetched) { return result; } let cardIds = [...cardIdSet]; cardIds.sort((a, b) => a - b); let tmp = []; for (let i = 0, length = cardIds.length; i < length; i++) { let cur = cardIds[i]; i == 0 && tmp.push(cur); if (i > 0) { if (cur != tmp[i - 1] + 1) { tmp.length = 0; } tmp.push(cur); } if (card) { if (tmp.indexOf(card.number) >= 0 && tmp.length >= maxCount) { break; } } else { if (tmp.length >= maxCount) { break; } } } if (tmp.length >= maxCount) { let subTmp = []; for (let i = tmp[0] - 1; i > 0; i--) { if (cardIdSet.has(i)) { subTmp.push(i); } else { break; } } for (let i = tmp[tmp.length]; i < cardIdSet.size; i++) { if (cardIdSet.has(i)) { subTmp.push(i); } else { break; } } tmp = tmp.concat(subTmp); for (let point of tmp) { if (card && point === card.number) { result.push(card); } else { result.push(pointMap.get(point)[0]); } } return result; } else { return arrUtil.randomGet(cardArr, 1); } }, /** * 随机获取敌对玩家 * @private */ getEnemyPlayer(dstPlayer: Player, state: CardGameState): Player { let enemys = []; for (let [, player] of state.players) { if (player.team !== dstPlayer.team) { enemys.push(player); } } return arrUtil.randomOne(enemys); }, /** * 随机获取可用的随从 * @param player * @private */ getRandomPet(player: Player): number { let pets = []; for (let [, pet] of player.pets) { if (pet.ap > 0 && pet.state == 1) pets.push(pet); } let result; if (pets.length > 0) { result = arrUtil.randomOne(pets); } return result ? result.pos : -1; }, /** * 选择一个法术或者一个随从 * @private */ async selectPet(dstPlayer: Player, state: CardGameState) { let cards = [...state.cards.values()]; let result: Card; let effectMap: Map = global.$cfg.get(BaseConst.EFFECTCARD); let spellCards: Card[] = []; let petCards: Card[] = []; // 优先取随从 let petCount = 0; for (let [,pet] of dstPlayer.pets) { if (pet.state == 1 && !pet.isHero) petCount ++; } let noMorePet = petCount >= new GameEnv().maxPlayerPetCount; let noPet = Math.random2(0, 100) > 70; for (let card of cards) { if (card.type == CardType.variable_unit) { petCards.push(card); } else if (card.type == CardType.general) { spellCards.push(card); } } if (!noMorePet && !noPet && petCards.length > 0) { result = petCards.randomOne(); } if (!result && spellCards.length > 0) { result = spellCards.randomOne(); } let oldpos = -1; if (!result && petCards.length > 0) { result = petCards.randomOne(); if (noMorePet) { oldpos = 1; } } if (!result) { error(`无法选择随从或法术, 随从数: ${petCount}, 法术牌数量: ${spellCards.length}`); return null; } robotLog(`select_pet ${dstPlayer.id}: ${result.effect} 类型: ${effectMap.get(result.effect).type_id == EffectType.skill ? '法术' : '随从'}`) let targetType: SkillTargetType = CfgMan.getTargetByCard(result.effect); let targetPlayer; let targetPos; switch (targetType) { case SkillTargetType.ENEMY_PLAYER: targetPlayer = this.getEnemyPlayer(dstPlayer, state); break; case SkillTargetType.ENEMY_PET: for (let [, player] of state.players) { if (player.team !== dstPlayer.team) { let pos = this.getRandomPet(player); if (pos > -1) { targetPlayer = player; targetPos = pos; break; } } } break; case SkillTargetType.FRIEND_PET: for (let [, player] of state.players) { if (player.team == dstPlayer.team) { let pos = this.getRandomPet(player); if (pos > -1) { targetPlayer = player; targetPos = pos; break; } } } break; case SkillTargetType.SELF_PET: let pos = this.getRandomPet(dstPlayer); if (pos > -1) { targetPlayer = dstPlayer; targetPos = pos; break; } break; } //TODO: 增加效果卡 let effCards: number[] = []; for (let [,card] of dstPlayer.cards) { if (card.type == CardType.double_effect || card.type == CardType.double_point) { effCards.push(card.id); } } return { card: result.id, player: targetPlayer?.id, pos: targetPos, effCards, oldpos } }, randomHero() { let heroMap: Map = global.$cfg.get(BaseConst.HERO); let heroArr = [...heroMap.values()]; let hero = arrUtil.randomGet(heroArr, 1); return {heroId: hero[0].id} } } export default assistantUtil;