增加机器人的作弊模式
This commit is contained in:
parent
2f4e95df53
commit
579a3dd318
@ -1,105 +1,111 @@
|
||||
import {BaseCfg} from "./parsers/BaseCfg";
|
||||
import {BaseConst} from "../constants/BaseConst";
|
||||
import {singleton} from "../decorators/singleton.decorator";
|
||||
import { BaseCfg } from './parsers/BaseCfg'
|
||||
import { BaseConst } from '../constants/BaseConst'
|
||||
import { singleton } from '../decorators/singleton.decorator'
|
||||
|
||||
@singleton
|
||||
export class GameEnv {
|
||||
// 初始手牌数量
|
||||
public initCardNum: number;
|
||||
// 可更换的初始手牌上限
|
||||
public cardChangeNum : number;
|
||||
// 更换初始手牌时限
|
||||
public cardChangeTime: number;
|
||||
// 每回合发牌数量
|
||||
public roundDrawNum: number;
|
||||
// 每满几论决斗一次
|
||||
public duelRoundNum: number;
|
||||
// 第几次决斗后游戏结束
|
||||
public maxDuelNum: number;
|
||||
// 玩家手牌数量上限
|
||||
public maxCardNum: number;
|
||||
// 出牌公共时限
|
||||
public maxDiscardTime: number;
|
||||
// 吃牌公共时限
|
||||
public maxEatTime: number;
|
||||
// 操作公共时限
|
||||
public playerActTime: number;
|
||||
// 玩家灵活时限
|
||||
public maxExtTime: number;
|
||||
// 每回合增加玩家灵活时限数值
|
||||
public roundExtTime: number;
|
||||
// 玩家随从上限
|
||||
public maxPlayerPetCount: number;
|
||||
// 结算显示时间
|
||||
public resultShowTime: number;
|
||||
// 基本奖励分
|
||||
public baseAddScore: number;
|
||||
// 额外奖励分
|
||||
public extraAddScore: number;
|
||||
// 游戏结果显示时间, 也是游戏重开等待时间
|
||||
public gameResultTime: number;
|
||||
// 匹配等待时间, 时间结束后, 填充机器人;
|
||||
public waitingPlayerTime: number;
|
||||
// 匹配等待时, 每进入一个玩家, 等待时间延长n秒
|
||||
public waitingPlayerOnePlus: number;
|
||||
// 英雄选择时间
|
||||
public pickHeroTime: number;
|
||||
// 机器人操作最小时间
|
||||
public robotActTimeMin: number;
|
||||
// 机器人操作最大时间
|
||||
public robotActTimeMax: number;
|
||||
// 队友死亡后,补牌数量
|
||||
public teamDeadAddNum: number;
|
||||
// 胡牌张数(自摸)
|
||||
public selfEatCount: number;
|
||||
// 胡牌张数(吃牌)
|
||||
public otherEatCount: number;
|
||||
// 轮空轮的间隔时间
|
||||
public emptyRoundTime: number;
|
||||
// 玩家初始卡牌数
|
||||
public playerInitNums: number[] = [];
|
||||
// 初级场能否吃牌
|
||||
public canEatBase: boolean;
|
||||
// 进阶场能否吃牌
|
||||
public canEatAdv: boolean;
|
||||
// 随从继承战力的比率
|
||||
public petInheritRate: number;
|
||||
// 初始手牌数量
|
||||
public initCardNum: number
|
||||
// 可更换的初始手牌上限
|
||||
public cardChangeNum: number
|
||||
// 更换初始手牌时限
|
||||
public cardChangeTime: number
|
||||
// 每回合发牌数量
|
||||
public roundDrawNum: number
|
||||
// 每满几论决斗一次
|
||||
public duelRoundNum: number
|
||||
// 第几次决斗后游戏结束
|
||||
public maxDuelNum: number
|
||||
// 玩家手牌数量上限
|
||||
public maxCardNum: number
|
||||
// 出牌公共时限
|
||||
public maxDiscardTime: number
|
||||
// 吃牌公共时限
|
||||
public maxEatTime: number
|
||||
// 操作公共时限
|
||||
public playerActTime: number
|
||||
// 玩家灵活时限
|
||||
public maxExtTime: number
|
||||
// 每回合增加玩家灵活时限数值
|
||||
public roundExtTime: number
|
||||
// 玩家随从上限
|
||||
public maxPlayerPetCount: number
|
||||
// 结算显示时间
|
||||
public resultShowTime: number
|
||||
// 基本奖励分
|
||||
public baseAddScore: number
|
||||
// 额外奖励分
|
||||
public extraAddScore: number
|
||||
// 游戏结果显示时间, 也是游戏重开等待时间
|
||||
public gameResultTime: number
|
||||
// 匹配等待时间, 时间结束后, 填充机器人;
|
||||
public waitingPlayerTime: number
|
||||
// 匹配等待时, 每进入一个玩家, 等待时间延长n秒
|
||||
public waitingPlayerOnePlus: number
|
||||
// 英雄选择时间
|
||||
public pickHeroTime: number
|
||||
// 机器人操作最小时间
|
||||
public robotActTimeMin: number
|
||||
// 机器人操作最大时间
|
||||
public robotActTimeMax: number
|
||||
// 队友死亡后,补牌数量
|
||||
public teamDeadAddNum: number
|
||||
// 胡牌张数(自摸)
|
||||
public selfEatCount: number
|
||||
// 胡牌张数(吃牌)
|
||||
public otherEatCount: number
|
||||
// 轮空轮的间隔时间
|
||||
public emptyRoundTime: number
|
||||
// 玩家初始卡牌数
|
||||
public playerInitNums: number[] = []
|
||||
// 初级场能否吃牌
|
||||
public canEatBase: boolean
|
||||
// 进阶场能否吃牌
|
||||
public canEatAdv: boolean
|
||||
// 随从继承战力的比率
|
||||
public petInheritRate: number
|
||||
// 低级机器人的胜率值
|
||||
public robotLvlLow: number
|
||||
// 高级机器人的胜率值
|
||||
public robotLvlHigh: number
|
||||
|
||||
public init(data: Map<number, BaseCfg>) {
|
||||
this.initCardNum = data.get(BaseConst.INIT_CARD_NUM).value;
|
||||
this.cardChangeNum = data.get(BaseConst.CARD_CHANGE_NUM).value;
|
||||
this.cardChangeTime = data.get(BaseConst.CARD_CHANGE_TIME).value;
|
||||
this.roundDrawNum = data.get(BaseConst.ROUND_DRAW_NUM).value;
|
||||
this.duelRoundNum = data.get(BaseConst.DUEL_ROUND_NUM).value;
|
||||
this.maxDuelNum = data.get(BaseConst.MAX_DUEL_NUM).value;
|
||||
this.maxCardNum = data.get(BaseConst.MAX_CARD_NUM).value;
|
||||
this.maxDiscardTime = data.get(BaseConst.MAX_DISCARD_TIME).value;
|
||||
this.maxEatTime = data.get(BaseConst.MAX_EAT_TIME).value;
|
||||
this.playerActTime = data.get(BaseConst.PLAYER_ACT_TIME).value;
|
||||
this.maxExtTime = data.get(BaseConst.MAX_EXT_TIME).value;
|
||||
this.roundExtTime = data.get(BaseConst.ROUND_EXT_TIME).value;
|
||||
this.maxPlayerPetCount = data.get(BaseConst.MAX_PLAYER_PET_COUNT).value;
|
||||
this.resultShowTime = data.get(BaseConst.ROUND_SHOW_TIME).value;
|
||||
this.baseAddScore = data.get(BaseConst.BASE_ADD_SCORE).value;
|
||||
this.extraAddScore = data.get(BaseConst.EXTRA_ADD_SCORE).value;
|
||||
this.gameResultTime = data.get(BaseConst.GAME_RESULT_TIME).value;
|
||||
this.waitingPlayerTime = data.get(BaseConst.WAITING_PLAYER_TIME).value;
|
||||
this.waitingPlayerOnePlus = data.get(BaseConst.WAITING_PLAYER_ONEPLUS).value;
|
||||
this.pickHeroTime = data.get(BaseConst.PICK_HERO_TIME).value;
|
||||
this.robotActTimeMin = data.get(BaseConst.ROBOT_ACTTIME_MIN).value;
|
||||
this.robotActTimeMax = data.get(BaseConst.ROBOT_ACTTIME_MAX).value;
|
||||
this.teamDeadAddNum = data.get(BaseConst.TEAM_DEAD_ADDNUM).value;
|
||||
this.selfEatCount = data.get(BaseConst.SELF_EAT_COUNT).value;
|
||||
this.otherEatCount = data.get(BaseConst.OTHER_EAT_COUNT).value;
|
||||
this.emptyRoundTime = data.get(BaseConst.EMPTY_ROUND_TIME).value;
|
||||
this.playerInitNums = [
|
||||
data.get(BaseConst.PLAYER1_INIT_NUM).value,
|
||||
data.get(BaseConst.PLAYER2_INIT_NUM).value,
|
||||
data.get(BaseConst.PLAYER3_INIT_NUM).value,
|
||||
data.get(BaseConst.PLAYER4_INIT_NUM).value,
|
||||
]
|
||||
this.canEatBase = !!data.get(BaseConst.CAN_EAT_BASE).value;
|
||||
this.canEatAdv = !!data.get(BaseConst.CAN_EAT_ADV).value;
|
||||
this.petInheritRate = data.get(BaseConst.PET_INHERIT_RATE).value / 100;
|
||||
}
|
||||
public init(data: Map<number, BaseCfg>) {
|
||||
this.initCardNum = data.get(BaseConst.INIT_CARD_NUM).value
|
||||
this.cardChangeNum = data.get(BaseConst.CARD_CHANGE_NUM).value
|
||||
this.cardChangeTime = data.get(BaseConst.CARD_CHANGE_TIME).value
|
||||
this.roundDrawNum = data.get(BaseConst.ROUND_DRAW_NUM).value
|
||||
this.duelRoundNum = data.get(BaseConst.DUEL_ROUND_NUM).value
|
||||
this.maxDuelNum = data.get(BaseConst.MAX_DUEL_NUM).value
|
||||
this.maxCardNum = data.get(BaseConst.MAX_CARD_NUM).value
|
||||
this.maxDiscardTime = data.get(BaseConst.MAX_DISCARD_TIME).value
|
||||
this.maxEatTime = data.get(BaseConst.MAX_EAT_TIME).value
|
||||
this.playerActTime = data.get(BaseConst.PLAYER_ACT_TIME).value
|
||||
this.maxExtTime = data.get(BaseConst.MAX_EXT_TIME).value
|
||||
this.roundExtTime = data.get(BaseConst.ROUND_EXT_TIME).value
|
||||
this.maxPlayerPetCount = data.get(BaseConst.MAX_PLAYER_PET_COUNT).value
|
||||
this.resultShowTime = data.get(BaseConst.ROUND_SHOW_TIME).value
|
||||
this.baseAddScore = data.get(BaseConst.BASE_ADD_SCORE).value
|
||||
this.extraAddScore = data.get(BaseConst.EXTRA_ADD_SCORE).value
|
||||
this.gameResultTime = data.get(BaseConst.GAME_RESULT_TIME).value
|
||||
this.waitingPlayerTime = data.get(BaseConst.WAITING_PLAYER_TIME).value
|
||||
this.waitingPlayerOnePlus = data.get(BaseConst.WAITING_PLAYER_ONEPLUS).value
|
||||
this.pickHeroTime = data.get(BaseConst.PICK_HERO_TIME).value
|
||||
this.robotActTimeMin = data.get(BaseConst.ROBOT_ACTTIME_MIN).value
|
||||
this.robotActTimeMax = data.get(BaseConst.ROBOT_ACTTIME_MAX).value
|
||||
this.teamDeadAddNum = data.get(BaseConst.TEAM_DEAD_ADDNUM).value
|
||||
this.selfEatCount = data.get(BaseConst.SELF_EAT_COUNT).value
|
||||
this.otherEatCount = data.get(BaseConst.OTHER_EAT_COUNT).value
|
||||
this.emptyRoundTime = data.get(BaseConst.EMPTY_ROUND_TIME).value
|
||||
this.playerInitNums = [
|
||||
data.get(BaseConst.PLAYER1_INIT_NUM).value,
|
||||
data.get(BaseConst.PLAYER2_INIT_NUM).value,
|
||||
data.get(BaseConst.PLAYER3_INIT_NUM).value,
|
||||
data.get(BaseConst.PLAYER4_INIT_NUM).value
|
||||
]
|
||||
this.canEatBase = !!data.get(BaseConst.CAN_EAT_BASE).value
|
||||
this.canEatAdv = !!data.get(BaseConst.CAN_EAT_ADV).value
|
||||
this.petInheritRate = data.get(BaseConst.PET_INHERIT_RATE).value / 100
|
||||
this.robotLvlLow = data.get(BaseConst.ROBOT_LVL_LOW).value
|
||||
this.robotLvlHigh = data.get(BaseConst.ROBOT_LVL_HIGHT).value
|
||||
}
|
||||
}
|
||||
|
@ -62,6 +62,10 @@ export class BaseConst {
|
||||
public static readonly CAN_EAT_ADV = 99040
|
||||
// 随从继承比例
|
||||
public static readonly PET_INHERIT_RATE = 99041
|
||||
// 低级机器人的胜率值
|
||||
public static readonly ROBOT_LVL_LOW = 99042
|
||||
// 高级机器人的胜率值
|
||||
public static readonly ROBOT_LVL_HIGHT = 99044
|
||||
|
||||
public static readonly COMPOUND = 'compound'
|
||||
public static readonly EFFECTCARD = 'effectcard'
|
||||
|
8
src/global.d.ts
vendored
8
src/global.d.ts
vendored
@ -306,6 +306,14 @@ declare module 'colyseus' {
|
||||
*/
|
||||
getOppositePlayer(srcPlayer: string | Player): Player;
|
||||
|
||||
/**
|
||||
* 获取另外一队的玩家
|
||||
* @param {string | Player} srcPlayer
|
||||
* @param exPlayer
|
||||
* @return {Player[]}
|
||||
*/
|
||||
getOtherTeamPlayers(srcPlayer: string, exPlayer?: string ): Player[];
|
||||
|
||||
/**
|
||||
* 根据index获取玩家
|
||||
* @param {number} idx
|
||||
|
@ -14,6 +14,7 @@ export class Robot {
|
||||
client: Client
|
||||
myTurn: boolean = false
|
||||
player: Player
|
||||
cheatRate: number = 0
|
||||
|
||||
constructor(host: string, roomId: string) {
|
||||
this.host = host
|
||||
@ -64,6 +65,10 @@ export class Robot {
|
||||
self.selectPet()
|
||||
}
|
||||
break
|
||||
case 'update_change_rate':
|
||||
log(`update cheat rate to: ${data.val}`)
|
||||
self.cheatRate = data.val
|
||||
break
|
||||
}
|
||||
})
|
||||
|
||||
@ -170,7 +175,8 @@ export class Robot {
|
||||
}
|
||||
let self = this
|
||||
let cardArr = [...self.player.cards.values()]
|
||||
let cards = assistantUtil.checkDiscard(cardArr, targetCard)
|
||||
let result = assistantUtil.checkDiscard({cardArr, card: targetCard, rate: this.cheatRate})
|
||||
let cards = result.cards;
|
||||
if (!cards || cards.length == 0) {
|
||||
return
|
||||
}
|
||||
@ -191,6 +197,9 @@ export class Robot {
|
||||
if (hasEatCard) {
|
||||
repData.target = targetCard.id
|
||||
}
|
||||
if (result.nums) {
|
||||
repData.nums = result.nums
|
||||
}
|
||||
self.reply('discard_card_c2s', repData)
|
||||
}
|
||||
|
||||
@ -202,7 +211,8 @@ export class Robot {
|
||||
private async eatOrGiveUp() {
|
||||
let targetCard = [...this.room.state.cards.values()][0]
|
||||
let cardArr = [...this.player.cards.values()]
|
||||
let tmpCards = assistantUtil.checkDiscard(cardArr, targetCard)
|
||||
let result = assistantUtil.checkDiscard({cardArr, card: targetCard, rate: this.cheatRate})
|
||||
let tmpCards = result.cards;
|
||||
let next = this.giveup.bind(this)
|
||||
if (tmpCards.length > 1 && targetCard.type === 1) {
|
||||
let cardIds: number[] = []
|
||||
|
@ -31,6 +31,7 @@ export class RobotClient implements Client {
|
||||
listenerState: any
|
||||
listenerTurn: any
|
||||
active: boolean = false
|
||||
cheatRate: number = 0
|
||||
|
||||
constructor(sessionId: string, state: CardGameState, onMessageHandlers: { [id: string]: (client: Client, message: any) => void }) {
|
||||
this.sessionId = sessionId
|
||||
@ -86,6 +87,10 @@ export class RobotClient implements Client {
|
||||
self.selectPet()
|
||||
}
|
||||
break
|
||||
case 'update_change_rate':
|
||||
log(`update cheat rate to: ${data.val}`)
|
||||
self.cheatRate = data.val
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,7 +152,8 @@ export class RobotClient implements Client {
|
||||
}
|
||||
let self = this
|
||||
let cardArr = [...self.selfPlayer.cards.values()]
|
||||
let cards = assistantUtil.checkDiscard(cardArr, targetCard)
|
||||
let result = assistantUtil.checkDiscard({cardArr, card: targetCard, rate: this.cheatRate})
|
||||
let cards = result.cards
|
||||
if (!cards || cards.length == 0) {
|
||||
return
|
||||
}
|
||||
@ -168,6 +174,9 @@ export class RobotClient implements Client {
|
||||
if (hasEatCard) {
|
||||
repData.target = targetCard.id
|
||||
}
|
||||
if (result.nums) {
|
||||
repData.nums = result.nums
|
||||
}
|
||||
self.reply('discard_card_c2s', repData)
|
||||
}
|
||||
|
||||
@ -179,7 +188,8 @@ export class RobotClient implements Client {
|
||||
private async eatOrGiveUp() {
|
||||
let targetCard = [...this.svrstate.cards.values()][0]
|
||||
let cardArr = [...this.selfPlayer.cards.values()]
|
||||
let tmpCards = assistantUtil.checkDiscard(cardArr, targetCard)
|
||||
let result = assistantUtil.checkDiscard({cardArr, card: targetCard, rate: this.cheatRate})
|
||||
let tmpCards = result.cards
|
||||
let next = this.giveup.bind(this)
|
||||
if (tmpCards.length > 1 && targetCard.type === 1) {
|
||||
let cardIds: number[] = []
|
||||
|
@ -86,7 +86,8 @@ export class GeneralRoom extends Room {
|
||||
client,
|
||||
cards: message.cards,
|
||||
target: message.target,
|
||||
dtype: 0
|
||||
dtype: 0,
|
||||
nums: message.nums
|
||||
})
|
||||
})
|
||||
this.onMessage('eat_card_c2s', (client, message) => {
|
||||
@ -399,4 +400,16 @@ export class GeneralRoom extends Room {
|
||||
let opposIdx = ((this.maxClients / 2 | 0) + idx) % this.maxClients
|
||||
return this.getPlayerByIdx(opposIdx)
|
||||
}
|
||||
getOtherTeamPlayers(srcPlayer: string, exPlayer?: string): Player[] {
|
||||
let team = this.state.players.get(srcPlayer).team
|
||||
let results:Player[] = []
|
||||
for (let [,player] of this.state.players) {
|
||||
if (player.team !== team) {
|
||||
if (exPlayer && player.id != exPlayer) {
|
||||
results.push(player)
|
||||
}
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ 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'
|
||||
|
||||
/**
|
||||
* 开始游戏
|
||||
@ -18,9 +19,49 @@ export class BeginGameCommand extends Command<CardGameState, {}> {
|
||||
let card1 = gameUtil.initCardQue(card0.length + 1, this.state.advMode)
|
||||
let cardAll = card0.concat(card1)
|
||||
cardAll.randomSort()
|
||||
//FixMe:: 移除
|
||||
// let card0 = gameUtil.initSampleCards(1)
|
||||
// this.state.cardQueue = card0;
|
||||
// 如果是匹配模式, 挑战机器人作弊比率
|
||||
if (this.state.mode == 1) {
|
||||
let highRate = new GameEnv().robotLvlHigh / 100
|
||||
let lowRate = new GameEnv().robotLvlLow / 100
|
||||
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 rate = 0
|
||||
if (oplayer.winRate > highRate) {
|
||||
rate = oplayer.winRate * 100 | 0
|
||||
} else if (oplayer.winRate > lowRate) {
|
||||
rate = oplayer.winRate / 2 * 100 | 0
|
||||
}
|
||||
debugRoom(`opposite play win rate: ${oplayer.winRate}, robot change rate: ${rate}`)
|
||||
if (global.isProd) {
|
||||
client.send('update_change_rate', { val: rate })
|
||||
} else {
|
||||
client.send('update_change_rate', { val: 100 })
|
||||
}
|
||||
let assistClient = this.room.getAssistClient(player.id)
|
||||
assistClient.send('update_change_rate', { val: rate })
|
||||
}
|
||||
}
|
||||
|
||||
this.state.cardQueue = cardAll
|
||||
let i = 0
|
||||
for (let [id] of this.state.players) {
|
||||
|
@ -12,6 +12,7 @@ import { StateTypeEnum } from '../enums/StateTypeEnum'
|
||||
import { RULE_CANEAT, RULE_SINGLEEAT } from '../../cfg/RoomOptions'
|
||||
import { ClockNameConst } from '../../constants/ClockNameConst'
|
||||
import { stopDrawCardClock } from '../../utils/clock.util'
|
||||
import { CardType } from '../../cfg/enums/CardType'
|
||||
|
||||
/**
|
||||
* 出牌
|
||||
@ -19,13 +20,13 @@ import { stopDrawCardClock } from '../../utils/clock.util'
|
||||
* type: 0, 正常的抽牌
|
||||
* type: 1, 到时间后, 自动的抽牌
|
||||
*/
|
||||
export class DiscardCommand extends Command<CardGameState, { client: Client, cards: [string], target?: string, dtype: number }> {
|
||||
export class DiscardCommand extends Command<CardGameState, { client: Client, cards: [string], target?: string, dtype: number, nums?: [number] }> {
|
||||
// validate({ client, cards } = this.payload) {
|
||||
// const player = this.state.players.get(client.sessionId);
|
||||
// return player !== undefined && gameUtil.checkCardsExists(player.cards, cards);
|
||||
// }
|
||||
|
||||
async execute({ client, cards, target, dtype } = this.payload) {
|
||||
async execute({ client, cards, target, dtype , nums} = this.payload) {
|
||||
const player = this.state.players.get(client.sessionId)
|
||||
if (!player) {
|
||||
this.room.send(client, 'discard_card_s2c', {
|
||||
@ -58,6 +59,17 @@ export class DiscardCommand extends Command<CardGameState, { client: Client, car
|
||||
})
|
||||
return
|
||||
}
|
||||
if (player.robot && !!nums) {
|
||||
debugRoom(`change card numbers`)
|
||||
let i = 0
|
||||
for (let card of tmpCards) {
|
||||
if (card.type == CardType.double_effect || card.type == CardType.double_point) {
|
||||
card.type = CardType.general
|
||||
card.effect = gameUtil.randomEffect(this.state.advMode)
|
||||
}
|
||||
card.number = nums[i ++]
|
||||
}
|
||||
}
|
||||
let targetCard
|
||||
if (target) {
|
||||
if (!this.state.rules.get(RULE_CANEAT)) {
|
||||
|
@ -1,11 +1,10 @@
|
||||
import {Command} from "@colyseus/command";
|
||||
import {CardGameState} from "../schema/CardGameState";
|
||||
import {Player} from "../schema/Player";
|
||||
import {Client} from "colyseus";
|
||||
import {GameStateConst} from "../../constants/GameStateConst";
|
||||
import {GameEnv} from "../../cfg/GameEnv";
|
||||
import {BaseConst} from "../../constants/BaseConst";
|
||||
import {getRandom} from "../../utils/number.util";
|
||||
import { Command } from '@colyseus/command'
|
||||
import { CardGameState } from '../schema/CardGameState'
|
||||
import { Player } from '../schema/Player'
|
||||
import { Client } from 'colyseus'
|
||||
import { GameStateConst } from '../../constants/GameStateConst'
|
||||
import { GameEnv } from '../../cfg/GameEnv'
|
||||
import { BaseConst } from '../../constants/BaseConst'
|
||||
import { getUserInfo, randomUserInfo } from '../../common/WebApi'
|
||||
import { ClockNameConst } from '../../constants/ClockNameConst'
|
||||
|
||||
@ -18,23 +17,23 @@ export class OnJoinCommand extends Command<CardGameState, {
|
||||
seat?: number,
|
||||
score?: number
|
||||
}> {
|
||||
async execute({client, accountId, seat, score} = this.payload) {
|
||||
let count = this.state.players.size;
|
||||
async execute({ client, accountId, seat, score } = this.payload) {
|
||||
let count = this.state.players.size
|
||||
if (count >= this.room.maxClients) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
// begin of set seat and team
|
||||
let idx = count;
|
||||
let seatSet = new Set([0,1,2,3])
|
||||
let idx = count
|
||||
let seatSet = new Set([0, 1, 2, 3])
|
||||
let accounts: string[] = []
|
||||
for (let [,p] of this.state.players) {
|
||||
for (let [, p] of this.state.players) {
|
||||
seatSet.delete(p.idx)
|
||||
accounts.push(p.accountId)
|
||||
}
|
||||
if (seat != undefined) {
|
||||
seat = +seat
|
||||
if (seatSet.has(seat)) {
|
||||
idx = seat;
|
||||
idx = seat
|
||||
} else {
|
||||
idx = seatSet.values().next().value
|
||||
}
|
||||
@ -42,70 +41,73 @@ export class OnJoinCommand extends Command<CardGameState, {
|
||||
idx = seatSet.values().next().value
|
||||
}
|
||||
let team
|
||||
if (this.room.maxClients % 2 == 0 ) {
|
||||
team = (idx == 1 || idx == 2) ? 1 : 0;
|
||||
if (this.room.maxClients % 2 == 0) {
|
||||
team = (idx == 1 || idx == 2) ? 1 : 0
|
||||
} else {
|
||||
team = idx
|
||||
}
|
||||
// end of set seat and team
|
||||
let player = new Player(client.sessionId, idx, team);
|
||||
this.state.players.set(client.sessionId, player);
|
||||
let uinfo: {nickname: string, avatar: string, score: number, accountid: string, heros: number[]}
|
||||
let player = new Player(client.sessionId, idx, team)
|
||||
this.state.players.set(client.sessionId, player)
|
||||
let uinfo: { nickname: string, avatar: string, score: number, accountid: string, heros: number[], rate?: number }
|
||||
if (accountId && accountId != 'robot') {
|
||||
uinfo = await getUserInfo(accountId, !!this.room.match)
|
||||
player.heros = uinfo.heros.map(o => parseInt(o+''))
|
||||
player.heros = uinfo.heros.map(o => parseInt(o + ''))
|
||||
player.robot = false
|
||||
player.winRate = uinfo.rate < 0 ? 0 : uinfo.rate
|
||||
} else {
|
||||
const fc = global.$cfg.get(BaseConst.FORMULA);
|
||||
let low = (this.room.score * fc.get(70034).number / 100) | 0;
|
||||
let high = (this.room.score * fc.get(70035).number / 100) | 0;
|
||||
const fc = global.$cfg.get(BaseConst.FORMULA)
|
||||
let low = (this.room.score * fc.get(70034).number / 100) | 0
|
||||
let high = (this.room.score * fc.get(70035).number / 100) | 0
|
||||
uinfo = await randomUserInfo(low, high, accounts)
|
||||
player.robot = true
|
||||
}
|
||||
accountId = uinfo.accountid
|
||||
player.accountId = accountId;
|
||||
player.accountId = accountId
|
||||
player.nickname = uinfo.nickname
|
||||
player.avatar = uinfo.avatar
|
||||
player.score = uinfo.score
|
||||
this.room.addAssistClient(client.sessionId);
|
||||
let self = this;
|
||||
this.room.addAssistClient(client.sessionId)
|
||||
let self = this
|
||||
if (!this.room.match && !this.room.robotCount) {
|
||||
if (this.state.players.size >= this.room.maxClients) {
|
||||
this.room.lock().then(() => {
|
||||
});
|
||||
this.state.updateGameState(GameStateConst.STATE_WAIT_PREPARE);
|
||||
})
|
||||
this.state.updateGameState(GameStateConst.STATE_WAIT_PREPARE)
|
||||
}
|
||||
} else {
|
||||
if (this.room.clientCount() == 1) {
|
||||
// 正常的匹配逻辑进入的第一个玩家, 开启定时, 超过设定时间人没齐的话, 添加机器人
|
||||
let timeOutWaitingPlayer = async function () {
|
||||
let count = self.room.maxClients - self.room.clientCount();
|
||||
let count = self.room.maxClients - self.room.clientCount()
|
||||
if (count > 0) {
|
||||
for (let i = 0; i < count; i++) {
|
||||
await self.room.addRobot();
|
||||
await self.room.addRobot()
|
||||
}
|
||||
}
|
||||
}
|
||||
let time = new GameEnv().waitingPlayerTime * 1000;
|
||||
self.room.beginSchedule(time, timeOutWaitingPlayer, ClockNameConst.WAITING_PLAYER);
|
||||
let time = new GameEnv().waitingPlayerTime * 1000
|
||||
self.room.beginSchedule(time, timeOutWaitingPlayer, ClockNameConst.WAITING_PLAYER)
|
||||
} else if (this.room.clientCount() > 1 && this.room.clientCount() < this.room.maxClients) {
|
||||
let moreTime = new GameEnv().waitingPlayerOnePlus * 1000;
|
||||
let moreTime = new GameEnv().waitingPlayerOnePlus * 1000
|
||||
self.room.addScheduleTime(moreTime, 'play_join', ClockNameConst.WAITING_PLAYER)
|
||||
}
|
||||
if (this.state.players.size >= this.room.maxClients) {
|
||||
this.room.stopSchedule(ClockNameConst.WAITING_PLAYER);
|
||||
this.room.stopSchedule(ClockNameConst.WAITING_PLAYER)
|
||||
this.room.lock().then(() => {
|
||||
});
|
||||
this.state.updateGameState(GameStateConst.STATE_WAIT_PREPARE);
|
||||
})
|
||||
this.state.updateGameState(GameStateConst.STATE_WAIT_PREPARE)
|
||||
} else if (this.state.players.size < this.room.maxClients
|
||||
&& this.state.players.size >= this.room.maxClients - this.room.robotCount) {
|
||||
for (let i = 0; i < this.room.robotCount; i++) {
|
||||
this.room.robotCount --;
|
||||
await self.room.addRobot();
|
||||
this.room.robotCount--
|
||||
await self.room.addRobot()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.room.bUserJoin(`${client.sessionId}`, {except: client});
|
||||
this.room.bUserJoin(`${ client.sessionId }`, { except: client })
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ export class SelectPetCommand extends Command<CardGameState, {
|
||||
let time = this.room.battleMan.useCard(data)
|
||||
await this.delay(time)
|
||||
const multipEat = !!this.state.rules.get(RULE_MULTIPLEEAT)
|
||||
if (multipEat && assistantUtil.checkDiscard([...player.cards.values()]).length > 1) {
|
||||
if (multipEat && assistantUtil.checkDiscard({cardArr: [...player.cards.values()]}).cards.length > 1) {
|
||||
this.state.updateGameState(GameStateConst.STATE_BEGIN_DRAW)
|
||||
this.state.updateGameTurn(player.id, this.state.eatCount + 1)
|
||||
debugRoom(`more eatcount for player ${player.id}, ${this.state.eatCount}`)
|
||||
|
@ -108,8 +108,11 @@ export class Player extends Schema {
|
||||
* 用于记录pet值, 用于统计伤害
|
||||
*/
|
||||
petData: Map<number, number> = new Map();
|
||||
|
||||
heros: number[];
|
||||
// 是否是机器人
|
||||
robot: boolean;
|
||||
// 十场胜率
|
||||
winRate: number;
|
||||
|
||||
/**
|
||||
* 英雄绑定的卡组, 选好英雄后, 从默认配置或玩家卡组(待实现)中获取
|
||||
|
@ -12,6 +12,7 @@ import { GameEnv } from '../cfg/GameEnv'
|
||||
import { error, robotLog } from '../common/Debug'
|
||||
import { PlayerStateConst } from '../constants/PlayerStateConst'
|
||||
import { Pet } from '../rooms/schema/Pet'
|
||||
import { getRandom } from './number.util'
|
||||
|
||||
function pushMapVal(map: Map<number, Card[]>, key: number, value: Card) {
|
||||
if (map.has(key)) {
|
||||
@ -30,7 +31,7 @@ let assistantUtil = {
|
||||
* @param cardArr 待检查的卡组
|
||||
* @param card 目标牌
|
||||
*/
|
||||
checkDiscard(cardArr: Card[], card?: Card): Card[] {
|
||||
checkDiscard({cardArr, card, rate}: {cardArr: Card[], card?: Card, rate?: number}): {cards: Card[], nums?: number[]} {
|
||||
let maxCount = card ? new GameEnv().otherEatCount : new GameEnv().selfEatCount
|
||||
let pointMap: Map<number, Card[]> = new Map()
|
||||
let cardIdSet: Set<number> = new Set()
|
||||
@ -65,7 +66,7 @@ let assistantUtil = {
|
||||
|
||||
}
|
||||
if (fetched) {
|
||||
return result
|
||||
return {cards: result}
|
||||
}
|
||||
|
||||
let cardIds = [...cardIdSet]
|
||||
@ -115,9 +116,76 @@ let assistantUtil = {
|
||||
result.push(pointMap.get(point)[0])
|
||||
}
|
||||
}
|
||||
return result
|
||||
return {cards: result}
|
||||
} else {
|
||||
return [cardArr.randomOne()]
|
||||
if (cardArr.length > maxCount && rate > 0) {
|
||||
robotLog(`begin cheat ^_^`)
|
||||
let random = getRandom(0, 100)
|
||||
if (random <= rate) {
|
||||
let max = Math.min(maxCount+1, cardArr.length + 1)
|
||||
let randomCount = getRandom(maxCount, max)
|
||||
let resultCards: Card[] = cardArr.randomGet(randomCount)
|
||||
let sameVal = false
|
||||
if (getRandom(0, 100) > 50) {
|
||||
sameVal = true
|
||||
}
|
||||
let resultNums = []
|
||||
if (card && (card.type == CardType.general || card.type == CardType.variable_unit)) {
|
||||
if (sameVal) {
|
||||
for (let _c of resultCards) {
|
||||
resultNums.push(card.number)
|
||||
}
|
||||
} else {
|
||||
resultNums.push(card.number)
|
||||
for (let _c of resultCards) {
|
||||
let nextU: number = Math.max.apply(this, resultNums) + 1
|
||||
let nextD: number = Math.min.apply(this, resultNums) - 1
|
||||
if (getRandom(0, 100) > 50 ) {
|
||||
if (nextU <= 10) {
|
||||
resultNums.push(nextU)
|
||||
} else {
|
||||
resultNums.push(nextD)
|
||||
}
|
||||
} else {
|
||||
if (nextD > 0) {
|
||||
resultNums.push(nextD)
|
||||
} else {
|
||||
resultNums.push(nextU)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resultCards.push(card)
|
||||
} else {
|
||||
if (sameVal) {
|
||||
for (let i = 0; i < resultCards.length; i++) {
|
||||
resultNums.push(resultCards[0].number)
|
||||
}
|
||||
} else {
|
||||
resultNums.push(resultCards[0].number)
|
||||
for (let i = 1; i < resultCards.length; i++) {
|
||||
let nextU: number = Math.max.apply(this, resultNums) + 1
|
||||
let nextD: number = Math.min.apply(this, resultNums) - 1
|
||||
if (getRandom(0, 100) > 50 ) {
|
||||
if (nextU <= 10) {
|
||||
resultNums.push(nextU)
|
||||
} else {
|
||||
resultNums.push(nextD)
|
||||
}
|
||||
} else {
|
||||
if (nextD > 0) {
|
||||
resultNums.push(nextD)
|
||||
} else {
|
||||
resultNums.push(nextU)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {cards: resultCards, nums: resultNums}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {cards: [cardArr.randomOne()]}
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
@ -52,6 +52,19 @@ let gameUtil = {
|
||||
debugRoom(cards)
|
||||
return cards
|
||||
},
|
||||
randomEffect(advMode: boolean): number {
|
||||
let effCfgMap: Map<number, EffectCardCfg> = global.$cfg.get(BaseConst.EFFECTCARD)
|
||||
let results = []
|
||||
for (let [,effCfg] of effCfgMap) {
|
||||
if (effCfg.type_id !== 2) {
|
||||
continue
|
||||
}
|
||||
if ((advMode && effCfg.intermediateaccess) || (!advMode && effCfg.primaryaccess)) {
|
||||
results.push(effCfg.id)
|
||||
}
|
||||
}
|
||||
return results.randomOne()
|
||||
},
|
||||
/**
|
||||
* 随机生成一张指定效果的卡
|
||||
* @param effectId
|
||||
|
Loading…
x
Reference in New Issue
Block a user