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

175 lines
3.8 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-23 16:11:39 +00:00
constructor() {
this.id = null
this.name = ''
this.note = ''
this.cards = []
}
from_plainObject(obj) {
this.id = obj.id
this.name = obj.content.name
this.note = obj.content.note
this.cards = obj.content.cards
}
from_deckList(str) {
// select all lines containing card serial numbers
let cardLinesRE = /^.*\b\d-\d{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-\d{3})[A-Z]?\b/i
let serial = serialRE.exec(cardLine)[1]
// 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-23 16:11:39 +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()
}
}
plainObject() {
return {
name: this.name,
note: this.note,
cards: this.cards
}
}
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
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)
}
populate() {
for (let card of this.cards) {
card.dbentry = CardsDB[card.serial]
}
}
}