-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathcompiler.js
More file actions
133 lines (116 loc) · 4.69 KB
/
compiler.js
File metadata and controls
133 lines (116 loc) · 4.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
function compileAction(action, card, indentLevel = 0) {
if (!Array.isArray(action)) return null;
if (action.length === 0) return "";
// If we get an array of actions, compile each one
if (Array.isArray(action[0])) {
return action.map(a => compileAction(a, card, indentLevel)).join('\n');
}
const indent = ' '.repeat(indentLevel);
const [cmd, ...args] = action;
// Handle if-clauses uniformly
const ifClauses = {
'cloud_hit': 'if_cloud_hit',
'wood_spirit': 'if_wood_spirit',
'fire_spirit': 'if_fire_spirit',
'earth_spirit': 'if_earth_spirit',
'metal_spirit': 'if_metal_spirit',
'water_spirit': 'if_water_spirit',
'star_point': 'if_star_point',
'injured': 'if_injured',
'if_c_pct_do': 'if_c_pct',
'if_played_continuous_do': 'if_played_continuous',
'if_any_element_activated_do': 'if_any_element_activated',
'if_either_has_def_do': 'if_either_has_def',
'if_enemy_has_debuff_do': 'if_enemy_has_debuff',
'if_no_debuff_do': 'if_no_debuff',
'post_action': 'if_post_action'
};
if (cmd in ifClauses) {
const condition = ifClauses[cmd];
if (args.length === 2 && !cmd.endsWith('_do')) {
// Has both true and false branches
return `${indent}if (game.${condition}()) {\n` +
compileAction(args[0], card, indentLevel + 1) + '\n' +
`${indent}} else {\n` +
compileAction(args[1], card, indentLevel + 1) + '\n' +
`${indent}}`;
} else {
// Just true branch
const actionArg = cmd === 'if_c_pct_do' ? args[1] : args[0];
const condArgs = cmd === 'if_c_pct_do' ? `(${args[0]})` : '()';
return `${indent}if (game.${condition}${condArgs}) {\n` +
compileAction(actionArg, card, indentLevel + 1) + '\n' +
`${indent}}`;
}
}
// Special handling for x/c conditions
if (cmd === 'if_x_at_least_c_do' || cmd === 'if_x_at_most_c_do') {
const operator = cmd === 'if_x_at_least_c_do' ? '>=' : '<=';
return `${indent}if (game.players[0].${args[0]} ${operator} ${args[1]}) {\n` +
compileAction(args[2], card, indentLevel + 1) + '\n' +
`${indent}}`;
}
// rep needs special handling for bonus_rep_amt
if (cmd === 'rep') {
const count = args[0];
const usesBonusRep = JSON.stringify(card.actions).includes('bonus_rep_amt');
const loopCount = usesBonusRep ?
`${count} + game.players[0].bonus_rep_amt` :
count;
return `${indent}for (let i = 0; i < ${loopCount}; i++) {\n` +
compileAction(args[1], card, indentLevel + 1) + '\n' +
`${indent}}`;
}
if (cmd === 'do_one_randomly') {
const choices = args[0];
let result = `${indent}switch (game.random_int(${choices.length})) {\n`;
choices.forEach((choice, i) => {
result += `${indent} case ${i}:\n`;
if (Array.isArray(choice[0])) {
// Multiple actions for this choice
choice.forEach(action => {
result += compileAction(action, card, indentLevel + 2);
result += '\n';
});
} else {
// Single action for this choice
result += compileAction(choice, card, indentLevel + 2);
result += '\n';
}
result += `${indent} break;\n`;
});
result += `${indent}}`;
return result;
}
// Default case - direct function call with proper argument handling
const processedArgs = args.map(arg => {
if (typeof arg === 'string' && !arg.match(/^[0-9.]+$/)) {
return `"${arg}"`;
}
if (Array.isArray(arg)) {
return JSON.stringify(arg);
}
return arg;
}).join(', ');
return `${indent}game.${cmd}(${processedArgs});`;
}
function compileCard(cardId, card) {
let output = `card_actions["${cardId}"] = (game) => {\n`;
output += compileAction([card.actions], card, 1) + '\n';
output += '}';
return output;
}
function compileSwogi(swogi) {
let output = 'export const card_actions = {};\n\n';
for (const [cardId, card] of Object.entries(swogi)) {
if (!card.actions) continue;
output += `// ${card.name || cardId}\n`;
output += compileCard(cardId, card) + '\n\n';
}
return output;
}
if (require.main === module) {
const swogi = require('./swogi.json');
console.log(compileSwogi(swogi));
}
module.exports = { compileAction, compileCard, compileSwogi };