Commit 16f32409 authored by Chunchi Che's avatar Chunchi Che

add isDeclarable

parent a7340d82
Pipeline #26686 passed with stages
in 11 minutes and 21 seconds
import { ygopro } from "@/api";
import PhaseType = ygopro.StocGameMessage.MsgNewPhase.PhaseType;
import { CardMeta } from "@/api";
//! 一些Neos中基础的数据结构
// 类型
......@@ -284,3 +285,153 @@ export const Phase2StringCodeMap: Map<number, number> = new Map([
[PhaseType.MAIN2, 22],
[PhaseType.END, 26],
]);
// For Announce Card
const OPCODE_ADD = 0x40000000;
const OPCODE_SUB = 0x40000001;
const OPCODE_MUL = 0x40000002;
const OPCODE_DIV = 0x40000003;
const OPCODE_AND = 0x40000004;
const OPCODE_OR = 0x40000005;
const OPCODE_NEG = 0x40000006;
const OPCODE_NOT = 0x40000007;
const OPCODE_ISCODE = 0x40000100;
const OPCODE_ISSETCARD = 0x40000101;
const OPCODE_ISTYPE = 0x40000102;
const OPCODE_ISRACE = 0x40000103;
const OPCODE_ISATTRIBUTE = 0x40000104;
/*
* 判断一张卡是否能被宣言
* 用于处理`AnnounceCard`
* */
export function isDeclarable(card: CardMeta, opcodes: number[]): boolean {
const stack: number[] = [];
for (const opcode of opcodes) {
switch (opcode) {
case OPCODE_ADD: {
if (stack.length >= 2) {
const rhs = stack.pop()!;
const lhs = stack.pop()!;
stack.push(lhs + rhs);
}
break;
}
case OPCODE_SUB: {
if (stack.length >= 2) {
const rhs = stack.pop()!;
const lhs = stack.pop()!;
stack.push(lhs - rhs);
}
break;
}
case OPCODE_MUL: {
if (stack.length >= 2) {
const rhs = stack.pop()!;
const lhs = stack.pop()!;
stack.push(lhs * rhs);
}
break;
}
case OPCODE_DIV: {
if (stack.length >= 2) {
const rhs = stack.pop()!;
const lhs = stack.pop()!;
stack.push(lhs / rhs);
}
break;
}
case OPCODE_AND: {
if (stack.length >= 2) {
const rhs = stack.pop()!;
const lhs = stack.pop()!;
const b0 = rhs !== 0;
const b1 = lhs !== 0;
stack.push(Number(b0 && b1));
}
break;
}
case OPCODE_OR: {
if (stack.length >= 2) {
const rhs = stack.pop()!;
const lhs = stack.pop()!;
const b0 = rhs !== 0;
const b1 = lhs !== 0;
stack.push(Number(b0 || b1));
}
break;
}
case OPCODE_NEG: {
if (stack.length >= 1) {
const rhs = stack.pop()!;
stack.push(-rhs);
}
break;
}
case OPCODE_NOT: {
if (stack.length >= 1) {
const rhs = stack.pop()!;
stack.push(Number(rhs === 0));
}
break;
}
case OPCODE_ISCODE: {
if (stack.length >= 1) {
const code = stack.pop()!;
stack.push(Number(code === card.id));
}
break;
}
case OPCODE_ISSETCARD: {
if (stack.length >= 1) {
const setCode = stack.pop()!;
stack.push(Number(ifSetCard(setCode, card.data.setcode ?? 0)));
}
break;
}
case OPCODE_ISTYPE: {
if (stack.length >= 1) {
const type_ = stack.pop()!;
stack.push(Number((type_ & (card.data.type ?? 0)) > 0));
}
break;
}
case OPCODE_ISRACE: {
if (stack.length >= 1) {
const race_ = stack.pop()!;
stack.push(Number((race_ & (card.data.race ?? 0)) > 0));
}
break;
}
case OPCODE_ISATTRIBUTE: {
if (stack.length >= 1) {
const attribute_ = stack.pop()!;
stack.push(Number((attribute_ & (card.data.attribute ?? 0)) > 0));
}
break;
}
default: {
stack.push(opcode);
break;
}
}
}
return false;
}
function ifSetCard(setCodeToAnalyse: number, setCodeFromCard: number): boolean {
let res = false;
const settype = setCodeToAnalyse & 0xfff;
const setsubtype = setCodeToAnalyse & 0xf000;
let sc = setCodeFromCard;
while (sc !== 0) {
if ((sc & 0xfff) === settype && (sc & 0xf000 & setsubtype) === setsubtype)
res = true;
sc = sc >> 16;
}
return res;
}
......@@ -6,7 +6,8 @@ import { CardType } from "@/stores";
// 自动从code推断出meta
//
// TODO: 其实不是很推荐这样做,因为随着项目复杂度增加,这样可能会带来meta更新的时序问题
// TODO: 其实不是很推荐这样做,因为随着项目复杂度增加,
// 这样可能会带来meta更新的时序问题
export const genCard = (card: CardType) => {
const t = proxy(card);
subscribeKey(t, "code", async (code) => {
......
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