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

186 lines
4 KiB
JavaScript
Raw Normal View History

'use strict'
2019-05-23 16:11:39 +00:00
import CardsDB from '@/plugins/ffdecks'
export default class {
2019-05-24 09:25:35 +00:00
constructor(id) {
this.id = id
2019-05-23 16:11:39 +00:00
this.name = ''
this.note = ''
this.cards = []
}
2019-05-24 09:25:35 +00:00
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
}
2019-05-23 16:11:39 +00:00
}
from_deckList(str) {
// select all lines containing card serial numbers
2019-05-24 09:25:35 +00:00
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!)
2019-05-24 09:25:35 +00:00
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
2019-05-23 16:11:39 +00:00
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 = []
2019-05-24 09:25:35 +00:00
for (let serial in cardCounts) {
this.cards.push({
serial: serial,
count: cardCounts[serial]
})
2019-05-23 16:11:39 +00:00
}
// 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()
}
}
2019-05-23 16:11:39 +00:00
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
2019-05-24 09:25:35 +00:00
for (let part of this.parts()) {
2019-05-23 16:11:39 +00:00
lines.push(`${part.heading} (${part.count}):`)
2019-05-24 09:25:35 +00:00
for (let card of part.cards)
2019-05-23 16:11:39 +00:00
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)
}
}