Commit 3a8c96b5 authored by biluo.shen's avatar biluo.shen

Add response

parent 2d1ca98c
Pipeline #28097 failed with stages
in 21 seconds
This diff is collapsed.
import { PredictReq, ygopro } from "@/api"; import {
PredictReq,
ygopro,
sendSelectIdleCmdResponse,
sendSelectPlaceResponse,
sendSelectMultiResponse,
sendSelectSingleResponse,
sendSelectEffectYnResponse,
sendSelectPositionResponse,
sendSelectOptionResponse,
sendSelectBattleCmdResponse,
sendSortCardResponse,
} from "@/api";
import { cardStore, matStore } from "@/stores"; import { cardStore, matStore } from "@/stores";
import { Global, convertPhase, convertCard, parsePlayerFromMsg, convertActionMsg, Input } from "@/api/ygoAgent/schema"; import { ActionMsgName, Global, convertPhase, convertCard, convertDeckCard, parsePlayerFromMsg, convertActionMsg, Input } from "@/api/ygoAgent/schema";
import { predictDuel } from "@/api/ygoAgent/predict";
export function genPredictReq(msg: ygopro.StocGameMessage): PredictReq { export function genPredictReq(msg: ygopro.StocGameMessage): PredictReq {
...@@ -24,8 +37,24 @@ export function genPredictReq(msg: ygopro.StocGameMessage): PredictReq { ...@@ -24,8 +37,24 @@ export function genPredictReq(msg: ygopro.StocGameMessage): PredictReq {
const opponent = 1 - player; const opponent = 1 - player;
const cards = cardStore.inner const cards = cardStore.inner
.filter((card) => zones.includes(card.location.zone)) .filter((card) =>
.map((card) => convertCard(card, player)); zones.includes(card.location.zone) &&
!(card.location.zone === ygopro.CardZone.DECK
&& card.location.controller === player
)
)
.map((card) => convertCard(card, player));
const card_codes_me = new Set(
cardStore.inner
.filter((card) =>
zones.includes(card.location.zone) && card.location.controller === player
)
.map((card) => card.code));
const deck_cards_me = matStore.main_deck_cards
.filter((meta) => card_codes_me.has(meta.id))
.map(convertDeckCard);
const turnPlayer = mat.currentPlayer; const turnPlayer = mat.currentPlayer;
const global: Global = { const global: Global = {
...@@ -42,7 +71,7 @@ export function genPredictReq(msg: ygopro.StocGameMessage): PredictReq { ...@@ -42,7 +71,7 @@ export function genPredictReq(msg: ygopro.StocGameMessage): PredictReq {
const input: Input = { const input: Input = {
global: global, global: global,
cards: cards, cards: deck_cards_me.concat(cards),
action_msg: actionMsg, action_msg: actionMsg,
} }
...@@ -53,3 +82,85 @@ export function genPredictReq(msg: ygopro.StocGameMessage): PredictReq { ...@@ -53,3 +82,85 @@ export function genPredictReq(msg: ygopro.StocGameMessage): PredictReq {
prev_action_idx: 0, prev_action_idx: 0,
} }
} }
export async function sendAIPredictAsResponse(msg: ygopro.StocGameMessage) {
const req = genPredictReq(msg);
console.log("Sending predict request:", req);
const duelId = matStore.duelId;
const resp = await predictDuel(duelId, req);
if (!resp) {
console.error("Failed to get predict response");
return;
}
const preds = resp.predict_results.action_preds;
const action_idx = argmax(preds, (r) => r.prob);
const response = preds[action_idx].response;
const msg_name = req.input.action_msg.name;
switch (msg_name) {
case ActionMsgName.AnnounceAttrib:
case ActionMsgName.AnnounceNumber:
sendSelectOptionResponse(response);
break;
case ActionMsgName.SelectBattlecmd:
sendSelectBattleCmdResponse(response);
break;
case ActionMsgName.SelectChain:
sendSelectSingleResponse(response);
break;
case ActionMsgName.SelectYesno:
case ActionMsgName.SelectEffectyn:
sendSelectEffectYnResponse(response === 1);
break;
case ActionMsgName.SelectIdlecmd:
sendSelectIdleCmdResponse(response);
break;
case ActionMsgName.SelectOption:
sendSelectOptionResponse(response);
break;
case ActionMsgName.SelectPosition:
sendSelectPositionResponse(convertPositionResponse(response));
break;
case ActionMsgName.SelectUnselectCard:
case ActionMsgName.SelectDisfield:
case ActionMsgName.SelectPlace:
case ActionMsgName.SelectCard:
case ActionMsgName.SelectSum:
case ActionMsgName.SelectTribute:
default:
throw new Error(`Unsupported msg_name: ${msg_name}`);
}
}
function argmax<T>(arr: T[], getValue: (item: T) => number): number {
if (arr.length === 0) {
throw new Error("Array is empty");
}
let maxIndex = 0;
let maxValue = getValue(arr[0]);
for (let i = 1; i < arr.length; i++) {
const currentValue = getValue(arr[i]);
if (currentValue > maxValue) {
maxValue = currentValue;
maxIndex = i;
}
}
return maxIndex;
}
function convertPositionResponse(response: number): ygopro.CardPosition {
switch (response) {
case 0x1: return ygopro.CardPosition.FACEUP_ATTACK;
case 0x2: return ygopro.CardPosition.FACEDOWN_ATTACK;
case 0x4: return ygopro.CardPosition.FACEUP_DEFENSE;
case 0x8: return ygopro.CardPosition.FACEDOWN_DEFENSE;
default:
throw new Error(`Invalid position response: ${response}`);
}
}
\ No newline at end of file
...@@ -5,6 +5,7 @@ import { ...@@ -5,6 +5,7 @@ import {
InteractType, InteractType,
matStore, matStore,
} from "@/stores"; } from "@/stores";
// import { sendAIPredictAsResponse } from "@/service/duel/agent";
import MsgSelectIdleCmd = ygopro.StocGameMessage.MsgSelectIdleCmd; import MsgSelectIdleCmd = ygopro.StocGameMessage.MsgSelectIdleCmd;
...@@ -17,6 +18,9 @@ export default (selectIdleCmd: MsgSelectIdleCmd) => { ...@@ -17,6 +18,9 @@ export default (selectIdleCmd: MsgSelectIdleCmd) => {
card.idleInteractivities = []; card.idleInteractivities = [];
}); });
// sendAIPredictAsResponse(selectIdleCmd as unknown as ygopro.StocGameMessage);
// return;
cmds.forEach((cmd) => { cmds.forEach((cmd) => {
const interactType = idleTypeToInteractType(cmd.idle_type); const interactType = idleTypeToInteractType(cmd.idle_type);
......
import { flatten } from "lodash-es"; import { flatten } from "lodash-es";
import { v4 as v4uuid } from "uuid"; import { v4 as v4uuid } from "uuid";
import { createDuel, ygopro } from "@/api"; import { createDuel, ygopro, fetchCard } from "@/api";
import { useConfig } from "@/config"; import { useConfig } from "@/config";
import { sleep } from "@/infra"; import { sleep } from "@/infra";
import { import {
...@@ -92,6 +92,10 @@ export default async (start: ygopro.StocGameMessage.MsgStart) => { ...@@ -92,6 +92,10 @@ export default async (start: ygopro.StocGameMessage.MsgStart) => {
const { duelId, index } = (await createDuel())!; const { duelId, index } = (await createDuel())!;
matStore.duelId = duelId; matStore.duelId = duelId;
matStore.agentIndex = index; matStore.agentIndex = index;
const main_deck_cards = matStore.main_deck.map((code) => {
return fetchCard(code);
});
matStore.main_deck_cards = main_deck_cards;
if (replayStore.isReplay) { if (replayStore.isReplay) {
replayStart(); replayStart();
......
...@@ -95,7 +95,9 @@ const initialState: Omit<MatState, "reset"> = { ...@@ -95,7 +95,9 @@ const initialState: Omit<MatState, "reset"> = {
isMe, isMe,
duelId: "", duelId: "",
agentIndex: 0, agentIndex: 0,
actionMsg: undefined actionMsg: undefined,
main_deck: [],
main_deck_cards: [],
}; };
class MatStore implements MatState, NeosStore { class MatStore implements MatState, NeosStore {
...@@ -115,6 +117,8 @@ class MatStore implements MatState, NeosStore { ...@@ -115,6 +117,8 @@ class MatStore implements MatState, NeosStore {
duelId = initialState.duelId; duelId = initialState.duelId;
agentIndex = initialState.agentIndex; agentIndex = initialState.agentIndex;
actionMsg = initialState.actionMsg; actionMsg = initialState.actionMsg;
main_deck = initialState.main_deck;
main_deck_cards = initialState.main_deck_cards;
// methods // methods
isMe = initialState.isMe; isMe = initialState.isMe;
...@@ -144,6 +148,11 @@ class MatStore implements MatState, NeosStore { ...@@ -144,6 +148,11 @@ class MatStore implements MatState, NeosStore {
selectedList: [], selectedList: [],
}; };
this.duelEnd = false; this.duelEnd = false;
this.duelId = "";
this.agentIndex = 0;
this.actionMsg = undefined;
this.main_deck = [];
this.main_deck_cards = [];
} }
} }
......
import type { ygopro } from "@/api"; import type { CardMeta, ygopro } from "@/api";
// >>> play mat state >>> // >>> play mat state >>>
...@@ -53,6 +53,8 @@ export interface MatState { ...@@ -53,6 +53,8 @@ export interface MatState {
duelId: string; duelId: string;
agentIndex: number; agentIndex: number;
actionMsg?: any; actionMsg?: any;
main_deck: number[];
main_deck_cards: CardMeta[];
} }
export interface InitInfo { export interface InitInfo {
......
...@@ -32,6 +32,7 @@ import { ...@@ -32,6 +32,7 @@ import {
RoomStage, RoomStage,
roomStore, roomStore,
sideStore, sideStore,
matStore,
} from "@/stores"; } from "@/stores";
import { Background, IconFont, Select, SpecialButton } from "@/ui/Shared"; import { Background, IconFont, Select, SpecialButton } from "@/ui/Shared";
...@@ -64,6 +65,7 @@ export const Component: React.FC = () => { ...@@ -64,6 +65,7 @@ export const Component: React.FC = () => {
const updateDeck = (deck: IDeck) => { const updateDeck = (deck: IDeck) => {
sendUpdateDeck(deck); sendUpdateDeck(deck);
matStore.main_deck = deck.main;
// 设置side里面的卡组 // 设置side里面的卡组
sideStore.setSideDeck(deck); sideStore.setSideDeck(deck);
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment