完善机器人逻辑

This commit is contained in:
zhl 2020-12-11 20:15:54 +08:00
parent 54c161a8e1
commit ee488c85e5
6 changed files with 135 additions and 51 deletions

View File

@ -23,7 +23,7 @@ const server = http.createServer(app);
const gameServer = new Server({ const gameServer = new Server({
server, server,
// driver: new MongooseDriver('mongodb://127.0.0.1/card-development'), // driver: new MongooseDriver('mongodb://127.0.0.1/card-development'),
driver: new MongooseDriver('mongodb://192.168.100.24/card-development-x'), driver: new MongooseDriver('mongodb://192.168.100.24/card-development-y'),
}); });
// register your room handlers // register your room handlers

View File

@ -1,6 +1,6 @@
import {Client, Room} from "colyseus"; import {Client, Room} from "colyseus";
import {ClientState, ISendOptions} from "colyseus/lib/transport/Transport"; import {ClientState, ISendOptions} from "colyseus/lib/transport/Transport";
import { EventEmitter } from 'events'; import {EventEmitter} from 'events';
import {robotLog as log} from '../common/Debug'; import {robotLog as log} from '../common/Debug';
import {CardGameState} from "../rooms/schema/CardGameState"; import {CardGameState} from "../rooms/schema/CardGameState";
import Clock from "@gamestdio/timer"; import Clock from "@gamestdio/timer";
@ -9,6 +9,9 @@ import {Card} from "../rooms/schema/Card";
import {BaseConst} from "../constants/BaseConst"; import {BaseConst} from "../constants/BaseConst";
import arrUtil from "../utils/array.util"; import arrUtil from "../utils/array.util";
import {HeroCfg} from "../cfg/parsers/HeroCfg"; import {HeroCfg} from "../cfg/parsers/HeroCfg";
import {EffectCardCfg} from "../cfg/parsers/EffectCardCfg";
import CfgMan from '../rooms/logic/CfgMan';
import {SkillTargetType} from "../rooms/logic/skill/SkillConst";
export class RobotClient implements Client { export class RobotClient implements Client {
id: string; id: string;
@ -27,6 +30,7 @@ export class RobotClient implements Client {
this.sessionId = sessionId; this.sessionId = sessionId;
this.svrstate = state; this.svrstate = state;
this.clock = clock; this.clock = clock;
this.ref = new EventEmitter();
this.onMessageHandlers = onMessageHandlers; this.onMessageHandlers = onMessageHandlers;
let self = this; let self = this;
let time = Math.random() * 2500 | 0; let time = Math.random() * 2500 | 0;
@ -46,11 +50,11 @@ export class RobotClient implements Client {
self.selectHero(); self.selectHero();
break; break;
case GameStateConst.STATE_CHANGE_CARD: case GameStateConst.STATE_CHANGE_CARD:
self.changeCard([]); self.changeCard();
break; break;
case GameStateConst.STATE_BEGIN_EAT: case GameStateConst.STATE_BEGIN_EAT:
if (!self.myTurn) { if (!self.myTurn) {
setTimeout(self.giveup.bind(self), 1000); self.eatOrGiveUp();
} }
break; break;
case GameStateConst.STATE_ROUND_RESULT: case GameStateConst.STATE_ROUND_RESULT:
@ -77,6 +81,7 @@ export class RobotClient implements Client {
} }
leave(code?: number, data?: string): void { leave(code?: number, data?: string): void {
} }
raw(data: ArrayLike<number>, options?: ISendOptions): void { raw(data: ArrayLike<number>, options?: ISendOptions): void {
@ -84,13 +89,19 @@ export class RobotClient implements Client {
public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) { public send(messageOrType: any, messageOrOptions?: any | ISendOptions, options?: ISendOptions) {
log(`receive server msg: ${messageOrType}, ${messageOrOptions}`); log(`receive server msg: ${messageOrType}, ${messageOrOptions}`);
let self = this;
let data = messageOrOptions;
switch (messageOrType) { switch (messageOrType) {
case 'draw_card_s2c': case 'draw_card_s2c':
break; break;
case 'player_ready_s2c': case 'player_ready_s2c':
break; break;
case 'steal_card_s2c': case 'steal_card_s2c':
break;
case 'eat_card_s2c':
if (data.errcode == 0 && data.player == self.sessionId) {
self.selectPet();
}
break; break;
} }
} }
@ -103,23 +114,79 @@ export class RobotClient implements Client {
} }
} }
private checkTriple(cardArr: Card[], card?: Card): Card[] {
if (card) cardArr.push(card);
let cards = cardArr.filter(o => o.type == 1);
cards.sort((a, b) => a.number - b.number);
let result = [];
for (let i = 0, length = cards.length; i < length; i ++) {
let cur = cards[i];
i == 0 && result.push(cur);
if (i > 0) {
let isSame = false;
if (result.length > 1) {
if (result[result.length - 1].number == result[result.length - 2].number) {
isSame = true;
}
}
if ((result[result.length - 1].number == cur.number) && (isSame || result.length == 1)) {
result.push(cur);
} else if ((result[result.length - 1].number + 1 == cur.number) && (!isSame || result.length == 1)) {
result.push(cur);
} else {
result.length = 0;
result.push(cur);
}
}
}
if (result.length < 3) {
return [result[0]];
} else {
return result;
}
}
// >>>>>>>>>>>>>>>>>> begin // >>>>>>>>>>>>>>>>>> begin
private discard() { private discard() {
let card; let self = this;
for (let [key, d] of this.cards) { let next = function () {
card = d; let cardArr = [...self.cards.values()];
break; // cardArr.sort((a, b) => a.number - b.number);
let cards = self.checkTriple(cardArr);
if (!cards) {
return;
}
let cardIds = cards.map(o => o.id);
self.reply('discard_card_c2s', {
cards: cardIds
});
} }
if (!card) { this.clock.setTimeout(next, 1500);
return; }
private eatOrGiveUp() {
let targetCard = [...this.svrstate.cards.values()][0];
let cardArr = [...this.cards.values()];
let tmpCards = this.checkTriple(cardArr, targetCard);
let next = this.giveup.bind(this);
if (tmpCards.length > 1) {
let cardIds: number[] = [];
for (let card of tmpCards) {
if (card.id !== targetCard.id) {
cardIds.push(card.id);
}
}
next = this.eatCard.bind(this, cardIds, targetCard.id);
} }
this.reply('discard_card_c2s', {
cards: [card.id] this.clock.setTimeout(next, 1500);
}
private eatCard(cardIds: number[], target: number) {
log(`${this.sessionId} 吃牌 ${cardIds} -> ${target}`);
this.reply('eat_card_c2s', {
cards: cardIds,
target
}); });
} }
private giveup () { private giveup () {
this.reply('give_up_eat_c2s', {}); this.reply('give_up_eat_c2s', {});
} }
@ -132,10 +199,44 @@ export class RobotClient implements Client {
heroId: hero[0].id heroId: hero[0].id
}); });
} }
private changeCard(cardIds: number[]) { private changeCard() {
let cardIds: number[] = [];
this.reply('change_card_c2s', { this.reply('change_card_c2s', {
cards: cardIds cards: cardIds
}); });
} }
private selectPet() {
let cards = [...this.svrstate.cards.values()];
let result;
let effectMap: Map<number, EffectCardCfg> = global.$cfg.get(BaseConst.EFFECTCARD);
for (let card of cards) {
let effect = effectMap.get(card.effect);
if (effect.type_id == 1) {
result = card;
break;
}
}
if (!result) {
result = arrUtil.randomGet(cards, 1)[0];
}
let targetType: SkillTargetType = CfgMan.getTargetByCard(result.id);
switch (targetType) {
case SkillTargetType.ENEMY_PLAYER:
break;
case SkillTargetType.ENEMY_PET:
break;
case SkillTargetType.FRIEND_PET:
break;
case SkillTargetType.SELF_PET:
break;
}
this.reply('select_pet_c2s', {
card: result.id,
player: null,
pos: null,
effCards: []
})
}
} }

View File

@ -79,6 +79,7 @@ export class DiscardCommand extends Command<CardGameState, { client: Client, car
this.room.battleMan.onCardLinkOver(player, cardArr); this.room.battleMan.onCardLinkOver(player, cardArr);
this.state.updateGameState(GameStateConst.STATE_PICK_PET); this.state.updateGameState(GameStateConst.STATE_PICK_PET);
let self = this; let self = this;
client.send('eat_card_s2c', {player: player.id, errcode: 0, errmsg: ''});
let time = singleton(GameEnv).playerActTime * 1000 + player.extraTime; let time = singleton(GameEnv).playerActTime * 1000 + player.extraTime;
// 开启选随从计时, 计时结束后结束当前轮 // 开启选随从计时, 计时结束后结束当前轮
let timeOverSelectPet = function () { let timeOverSelectPet = function () {

View File

@ -64,6 +64,9 @@ export class EatConfirmCommand extends Command<CardGameState, { timeUp: boolean
* *
*/ */
// 吃牌逻辑 // 吃牌逻辑
if (player) {
debugRoom(`有人吃牌了: ${player}, 场上牌: ${this.state.cards.size}, isFirst: ${isFirst}, timeUp: ${timeUp}`);
}
if (player != null && (isFirst || timeUp)) { if (player != null && (isFirst || timeUp)) {
// 如果有吃牌计时的话,停止吃牌计时 // 如果有吃牌计时的话,停止吃牌计时
this.room.stopSchedule(); this.room.stopSchedule();
@ -87,12 +90,7 @@ export class EatConfirmCommand extends Command<CardGameState, { timeUp: boolean
self.room.dispatcher.dispatch(new TurnEndCommand()); self.room.dispatcher.dispatch(new TurnEndCommand());
} }
self.room.beginSchedule(time, timeOverSelectPet, `select_pet_${player.id}`); self.room.beginSchedule(time, timeOverSelectPet, `select_pet_${player.id}`);
// this.room.mainClock = this.clock.setTimeout(function () {
// player.extraTime = 0;
// self.room.mainClock.clear();
// debugRoom('选随从或者法术时间到, 自动出牌, 自动进入下一轮');
// self.room.dispatcher.dispatch(new TurnEndCommand());
// }, time);
let fromPlayer = this.state.players.get(this.state.currentTurn); let fromPlayer = this.state.players.get(this.state.currentTurn);
if (fromPlayer.id !== player.id) { if (fromPlayer.id !== player.id) {
this.room.battleMan.onCardLinkOver(player, cardArr, fromPlayer); this.room.battleMan.onCardLinkOver(player, cardArr, fromPlayer);
@ -100,7 +98,9 @@ export class EatConfirmCommand extends Command<CardGameState, { timeUp: boolean
this.room.battleMan.onCardLinkOver(player, cardArr); this.room.battleMan.onCardLinkOver(player, cardArr);
} }
// 成功后广播吃牌成功消息 // 成功后广播吃牌成功消息
this.room.broadcast('eat_card_s2c', {player: player.id, errocode: 0, errmsg: ''}); let client = this.room.getClient(player.id);
this.room.broadcast('eat_card_s2c', {player: player.id, errcode: 0, errmsg: ''}, {except: client});
client.send('eat_card_s2c', {player: player.id, errcode: 0, errmsg: ''});
// 向其他玩家发送吃卡失败的消息 // 向其他玩家发送吃卡失败的消息
for (let [key, val] of tmpActionMap) { for (let [key, val] of tmpActionMap) {
if (typeof val != 'number' && key !== player.id) { if (typeof val != 'number' && key !== player.id) {

View File

@ -5,7 +5,7 @@ import {PlayerStateConst} from "../../constants/PlayerStateConst";
import {Pet} from "../schema/Pet"; import {Pet} from "../schema/Pet";
import {singleton} from "../../common/Singleton"; import {singleton} from "../../common/Singleton";
import {GameEnv} from "../../cfg/GameEnv"; import {GameEnv} from "../../cfg/GameEnv";
import {error} from "../../common/Debug"; import {debugRoom, error} from "../../common/Debug";
/** /**
* *
@ -21,19 +21,18 @@ export class GameResultCommand extends Command<CardGameState, {}> {
let resultTimeOver = async function () { let resultTimeOver = async function () {
let restartCount = 0; let restartCount = 0;
// 踢出没离开并没点击重新开始的玩家 // 踢出没离开并没点击重新开始的玩家
for (let [,player] of self.state.players) { debugRoom(`restart_schedule 倒计时结束, 有 ${restartCount} 人点击重玩`)
if (player.state !== PlayerStateConst.PLAYER_READY) { if (self.state.restartCount == 0) {
let client = self.room.getClient(player);
client.leave();
} else {
restartCount ++;
}
}
if (restartCount == 0) {
// 没有任何人点重新开始, 则解散房间 // 没有任何人点重新开始, 则解散房间
await self.room.disconnect(); await self.room.disconnect();
} else if (restartCount < self.room.maxClients){ } else if (self.state.restartCount < self.room.maxClients){
// 如果点击重开的玩家少于房间最大人数, 则把房间设为公开, 等待其他玩家匹配进来 // 如果点击重开的玩家少于房间最大人数, 则把房间设为公开, 等待其他玩家匹配进来
for (let [,player] of self.state.players) {
if (player.state !== PlayerStateConst.PLAYER_READY) {
let client = self.room.getClient(player);
client.leave();
}
}
await self.room.unlock(); await self.room.unlock();
await self.room.setPrivate(false); await self.room.setPrivate(false);
} else { // 如果4个人都点击了重开, 理论上不存在这种情况 } else { // 如果4个人都点击了重开, 理论上不存在这种情况

View File

@ -1,17 +0,0 @@
import {Command} from "@colyseus/command";
import {CardGameState} from "../schema/CardGameState";
import {GameStateConst} from "../../constants/GameStateConst";
/**
* TODO::
* ,
* ,
* 退线, ??
*/
export class ReStartCommand extends Command<CardGameState, {}> {
execute() {
}
}