-
Notifications
You must be signed in to change notification settings - Fork 0
/
peachTurnipData.js
385 lines (349 loc) · 9.95 KB
/
peachTurnipData.js
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
const { SlippiGame } = require("@slippi/slippi-js");
const { Frames } = require("@slippi/slippi-js");
const fs = require('fs');
const prompt = require('prompt-sync')();
var files = [];
var out = ""
const replayFolder = prompt('Enter the directory containing .slp files. Include ./ if this is located in the current directory. I.e. ./slippi/: ');
fs.readdirSync(replayFolder).forEach(file => {
files.push(file);
});
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
// Get input for player's connect code we are looking at stats for
const playerCode = prompt('Enter the connect code of the Peach player whose turnip stats you would like to calculate (I.e. TOES#318): ');
/*
Character IDs:
0 - Captain Falcon
1 - Donkey Kong
2 - Fox
3 - Mr. Game & Watch
4 - Kirby
5 - Bowser
6 - Link
7 - Luigi
8 - Mario
9 - Marth
10 - Mewtwo
11 - Ness
12 - Peach
13 - Pikachu
14 - Ice Climbers
15 - Jigglypuff
16 - Samus
17 - Yoshi
18 - Zelda
19 - Sheik
20 - Falco
21 - Young Link
22 - Dr. Mario
23 - Roy
24 - Pichu
25 - Ganondorf
*/
// Struct for games against each character
function charData(games, totalPulls, normalPulls, winkPulls, dotPulls, stitchPulls, saturnPulls, beamswordPulls, bombPulls) {
// Number of games played against this character in this dataset
this.games = games;
// Total turnips pulled against this character in this data set
this. totalPulls = totalPulls;
// Normal turnips pulled against this character in this data set
this.normalPulls = normalPulls;
// Wink faces pulled against this character in this data set
this.winkPulls = winkPulls;
// Dot faces pulled against this character in this data set
this.dotPulls = dotPulls;
// Stitch faces pulled against this character in this data set
this.stitchPulls = stitchPulls;
// Mr. Saturns pulled against this character in this data set
this.saturnPulls = saturnPulls;
// Beam Swords pulled against this character in this data set
this.beamswordPulls = beamswordPulls;
// Bob-ombs pulled against this character in this data set
this.bombPulls = bombPulls;
}
// Struct for a single game's turnip pull stats
function gameData(totalPulls, normalPulls, winkPulls, dotPulls, stitchPulls, saturnPulls, beamswordPulls, bombPulls) {
// Total turnips pulled in this game
this. totalPulls = totalPulls;
// Normal turnips pulled in this game
this.normalPulls = normalPulls;
// Wink faces pulled in this game
this.winkPulls = winkPulls;
// Dot faces pulled in this game
this.dotPulls = dotPulls;
// Stitch faces pulled in this game
this.stitchPulls = stitchPulls;
// Mr. Saturns pulled in this game
this.saturnPulls = saturnPulls;
// Beam Swords pulled in this game
this.beamswordPulls = beamswordPulls;
// Bob-ombs pulled in this game
this.bombPulls = bombPulls;
}
// Array to store data for each opposing character
var charArray = [];
// Fill array - array index corresponds to character ID
for(i = 0; i < 26; i++) {
c = new charData(0, 0, 0, 0, 0, 0, 0, 0, 0);
charArray.push(c);
}
//console.log(charArray);
let x = 1;
let y = 1;
files.forEach(file => {
const filename = replayFolder + file;
// Create game object
const game = new SlippiGame(filename);
// Get game settings
const settings = game.getSettings();
const metadata = game.getMetadata();
var peach = -1;
//console.log(filename);
// We only want singles games.
// Currently ignoring games where metadata is null. Will try to figure those out eventually if possible.
if (!settings.isTeams && metadata != null && metadata.players[0] != null) {
// Check if the specified player is player 1 and playing peach
if(metadata.players[0].names.code == playerCode && settings.players[0].characterId == 12) {
peach = 0;
}
// Check if the specified player is player 2 and playing peach
else if(metadata.players[1].names.code == playerCode && settings.players[1].characterId == 12) {
peach = 1;
}
// If neither is true, we can ignore the game
}
// Check to see if all 4 stocks were taken. Will ignore timeouts (exceedingly rare) for now.
var fullGame = false;
if (peach != -1) {
const stats = game.getStats();
if(stats.overall[0].killCount == 4 || stats.overall[1].killCount == 4) {
fullGame = true;
}
}
if (peach != -1 && fullGame) {
var opponentChar = -1;
if(peach == 0) {
opponentChar = settings.players[1].characterId;
} else {
opponentChar = settings.players[0].characterId;
}
//console.log(opponentChar);
//Process the game and return a gameData object
g = processGame(game);
console.log("Processed " + x + " game(s).");
x++;
//console.log(g);
const c = charArray[opponentChar];
var c2 = new charData(c.games + 1,
c.totalPulls + g.totalPulls,
c.normalPulls + g.normalPulls,
c.winkPulls + g.winkPulls,
c.dotPulls + g.dotPulls,
c.stitchPulls + g.stitchPulls,
c.saturnPulls + g.saturnPulls,
c.beamswordPulls + g.beamswordPulls,
c.bombPulls + g.bombPulls);
charArray[opponentChar] = c2;
} else {
console.log("Ignored " + y + " game(s).");
y++;
}
})
console.log(" ");
console.log("Per Character Turnip Stats: ");
out += "Per Character Turnip Stats: \n"
console.log(" ");
for(j = 0; j < 26; j++) {
switch(j) {
case 0:
out += "Stats Vs. Captain Falcon: \n";
break;
case 1:
out += "Stats Vs. Donkey Kong: \n";
break;
case 2:
out += "Stats Vs. Fox: \n";
break;
case 3:
out += "Stats Vs. Mr. Game and Watch: \n";
break;
case 4:
out += "Stats Vs. Kirby: \n";
break;
case 5:
out += "Stats Vs. Bowser: \n";
break;
case 6:
out += "Stats Vs. Link: \n";
break;
case 7:
out += "Stats Vs. Luigi: \n";
break;
case 8:
out += "Stats Vs. Mario: \n";
break;
case 9:
out += "Stats Vs. Marth: \n";
break;
case 10:
out += "Stats Vs. Mewtwo: \n";
break;
case 11:
out += "Stats Vs. Ness: \n";
break;
case 12:
out += "Stats Vs. Peach: \n";
break;
case 13:
out += "Stats Vs. Pikachu: \n";
break;
case 14:
out += "Stats Vs. Ice Climbers: \n";
break;
case 15:
out += "Stats Vs. Jigglypuff: \n";
break;
case 16:
out += "Stats Vs. Samus: \n";
break;
case 17:
out += "Stats Vs. Yoshi: \n";
break;
case 18:
out += "Stats Vs. Zelda: \n";
break;
case 19:
out += "Stats Vs. Sheik: \n";
break;
case 20:
out += "Stats Vs. Falco: \n";
break;
case 21:
out += "Stats Vs. Young Link: \n";
break;
case 22:
out += "Stats Vs. Dr. Mario: \n";
break;
case 23:
out += "Stats Vs. Roy: \n";
break;
case 24:
out += "Stats Vs. Pichu: \n";
break;
case 25:
out += "Stats Vs. Ganondorf: \n";
break;
}
const c = charArray[j];
out +="Total Games: " + c.games + "\n";
out +="Total Pulls: " + c.totalPulls + "\n";
out +="Average Pulls Per Game: " + (c.totalPulls / c.games) + "\n";
out +="Normal Turnips Pulled: " + c.normalPulls + "\n";
out +="Wink Faces Pulled: " + c.winkPulls + "\n";
out +="Dot Faces Pulled: " + c.dotPulls + "\n";
out +="Stitch Faces Pulled: " + c.stitchPulls + "\n";
out +="Mr. Saturns Pulled: " + c.saturnPulls + "\n";
out +="Beam Swords Pulled: " + c.beamswordPulls + "\n";
out +="Bob-ombs Pulled: " + c.bombPulls + "\n";
out +=" " + "\n";
fs.writeFile(playerCode + 'turnipdata.txt', out, (err) => {
if (err) throw err;
})
}
// Process the given game object and return a gameData object containing turnip pull stats
function processGame(game) {
const frames = game.getFrames();
let lastSpawnId = -1;
// Face Names
let face0 = 0; //Normal
let face1 = 0; //Eyebrow
let face2 = 0; //Line
let face3 = 0; //Circle
let face4 = 0; //Carrot
let face5 = 0; //Wink
let face6 = 0; //Dot
let face7 = 0; //Stitch
let face255 = 0; //Undefined, should never occur if filtering properly
let beam = 0; //Beam Sword
let saturn = 0; //Mr. Saturn
let bobomb = 0; //Bob-omb
// Count turnips
for (let frameNum = Frames.FIRST; frames[frameNum]; frameNum++) {
const frame = frames[frameNum];
if (frame.items) {
frame.items.forEach((i) => {
if (lastSpawnId < i.spawnId) {
if(i.typeId == 99) {
switch(i.turnipFace) {
case 0:
face0++;
break;
case 1:
face1++;
break;
case 2:
face2++;
break;
case 3:
face3++;
break;
case 4:
face4++;
break;
case 5:
face5++;
break;
case 6:
face6++;
break;
case 7:
face7++;
break;
case 255:
face255++;
break;
default:
console.log("Invalid turnip face found: " + i.turnipFace);
}
} else if(i.typeId == 12) {
beam++;
} else if(i.typeId == 6) {
bobomb++;
} else if(i.typeId == 7) {
saturn++;
}
lastSpawnId = i.spawnId;
}
});
}
}
if(face255 > 0) {
console.log("This many Undefined turnips were pulled: " + face255);
}
let totalPulls = face0+face1+face2+face3+face4+face5+face6+face7+beam+bobomb+saturn;
let normalTurnips = face0+face1+face2+face3+face4;
// console.log("Total Turnips Pulled: " + totalPulls);
// console.log("Normal Turnips Pulled: " + normalTurnips);
// console.log("Winky Faces Pulled: " + face5);
// console.log("Dot Faces Pulled: " + face6);
// console.log("Stitch Faces Pulled: " + face7);
// console.log("Beam Swords Pulled: "+ beam);
// console.log("Bob-ombs Pulled: "+ bobomb);
// console.log("Mr. Saturns Pulled: "+ saturn);
// console.log(" ");
// console.log("Detailed face breakdown:");
// console.log("face0: "+ face0);
// console.log("face1: "+ face1);
// console.log("face2: "+ face2);
// console.log("face3: "+ face3);
// console.log("face4: "+ face4);
// console.log("face5: "+ face5);
// console.log("face6: "+ face6);
// console.log("face7: "+ face7);
// console.log("face255: "+ face255);
g = new gameData(totalPulls, normalTurnips, face5, face6, face7, saturn, beam, bobomb);
return g;
}