This repository has been archived on 2024-04-29. You can view files and clone it, but cannot push or open issues or pull requests.
node-fftcg/frontend/src/classes/Deck.js

185 lines
4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use strict'
import CardsDB from '@/plugins/ffdecks'
export default class {
constructor(id) {
this.id = id
this.name = ''
this.note = ''
this.cards = []
}
populate() {
for (let card of this.cards) {
card.dbentry = CardsDB[card.serial]
}
}
from_object(obj) {
if (obj) {
this.name = obj.name
this.note = obj.note
this.cards = obj.cards
}
}
plainObject() {
let plainCards = []
for (let card of this.cards) {
plainCards.push({
serial: card.serial,
count: card.count
})
}
return {
name: this.name,
note: this.note,
cards: plainCards
}
}
from_deckList(str) {
// select all lines containing card serial numbers
let cardLinesRE = /^.*\b\d+-0*\d{1,3}[A-Z]?\b.*$/gm
let cardLines = str.match(cardLinesRE)
let cardCounts = {}
cardLines.forEach(cardLine => {
// extract serial (guaranteed to be in here!)
let serialRE = /\b(\d+)-0*(\d{1,3})[A-Z]?\b/i
let serial = serialRE.exec(cardLine)
// force format 'x-xxx'
serial = `${serial[1]}-${serial[2].padStart(3, '0')}`
// strip out serial number
cardLine = cardLine.replace(serialRE, '')
let countREs = [
// prioritize a count with "times" symbol *, x, ×
/\b([0-9]+)(?:[*×]|[x]\b)/,
/(?:[*×]|\b[x])([0-9]+)\b/,
// next priority: count with whitespace
/\s+([0-9]+)\s+/,
/\s+([0-9]+)\b/,
/\b([0-9]+)\s+/,
// least priority: any simple number
/\b([0-9]+)\b/
]
// fallback value
let count = 1
for (let countRE of countREs) {
let data = countRE.exec(cardLine)
if (data) {
count = Number(data[1])
break
}
}
// count copies
if (!cardCounts[serial]) {
cardCounts[serial] = 0
}
cardCounts[serial] += count
})
// push card data into deck
this.cards = []
for (let serial in cardCounts) {
this.cards.push({
serial: serial,
count: cardCounts[serial]
})
}
// strip out lines with serial numbers
str = str.replace(cardLinesRE, '')
// then strip out anything after the first empty line
str = str.replace(/^[\s]*$[^]*/m, '')
// select the line containing 'deck name:'
// and its successor (ffdecks format)
let metaRE = /^Deck Name: (.+)$[\s]*?^(.+)$/m
let metaData = metaRE.exec(str)
// fallback
this.name = 'Unnamed Deck'
this.note = ''
if (!metaData) {
// use lax format: <anything>:[deck name][newline][note]
metaRE = /[^]*?:(.+)$[\s]*?^([^]*)/m
metaData = metaRE.exec(str)
}
// look again, I am not an else!
if (metaData) {
// extract matches
this.name = metaData[1].trim()
this.note = metaData[2].trim()
}
}
parts() {
let retval = ['Forwards', 'Backups', 'Summons, Monsters & more'].map(
item => ({
heading: item,
cards: [],
count: 0
})
)
for (let card of this.cards) {
let target
switch (card.dbentry.type) {
case 'Forward':
target = 0
break
case 'Backup':
target = 1
break
default:
target = 2
break
}
retval[target].cards.push(card)
retval[target].count += card.count
}
for (let part of retval) {
part.cards.sort(
(card_l, card_r) => card_l.dbentry.cost - card_r.dbentry.cost
)
}
return retval
}
deckList() {
let lines = []
// begin with deck name and note
lines.push('Deck Name: ' + this.name)
lines.push(this.note)
lines.push('')
// list each deck part
for (let part of this.parts()) {
lines.push(`${part.heading} (${part.count}):`)
for (let card of part.cards)
lines.push(`${card.count}x ${card.serial} "${card.dbentry.name}"`)
lines.push('')
}
return lines.join('\n')
}
count() {
return this.cards.reduce((total, card) => total + card.count, 0)
}
}