Created
May 12, 2026 02:00
-
-
Save thebergamo/8881c3e3c573a98a88cc0ff08d639eb2 to your computer and use it in GitHub Desktop.
tribe troops ratio
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (() => { | |
| const table = document.querySelector('#ally_content table.vis.w100'); | |
| if (!table) { | |
| alert('Table not found: #ally_content table.vis.w100'); | |
| return; | |
| } | |
| const normalize = (s) => String(s || '').replace(/\s+/g, ' ').trim(); | |
| const parseIntLoose = (s) => { | |
| const cleaned = String(s || '').replace(/[^\d]/g, ''); | |
| return cleaned ? parseInt(cleaned, 10) : 0; | |
| }; | |
| const UNIT_POP = { | |
| spear: 1, | |
| sword: 1, | |
| axe: 1, | |
| archer: 1, | |
| spy: 2, | |
| light: 4, | |
| marcher: 5, | |
| heavy: 6, | |
| ram: 5, | |
| catapult: 8, | |
| knight: 10, | |
| snob: 100, | |
| militia: 0 | |
| }; | |
| const headerRow = table.querySelector('tr'); | |
| const headerCells = headerRow ? Array.from(headerRow.querySelectorAll('th')) : []; | |
| if (!headerCells.length) { | |
| alert('Header row not found.'); | |
| return; | |
| } | |
| const unitByCol = {}; | |
| const headers = headerCells.map((th, i) => { | |
| const img = th.querySelector('img'); | |
| if (img) { | |
| const src = img.getAttribute('src') || ''; | |
| const m = src.match(/unit_([a-z_]+)/i); | |
| if (m) { | |
| const unit = m[1].toLowerCase(); | |
| unitByCol[i] = unit; | |
| } | |
| const title = normalize(img.getAttribute('data-title')); | |
| return title || (m ? m[1] : `col_${i + 1}`); | |
| } | |
| const txt = normalize(th.textContent); | |
| return txt || `col_${i + 1}`; | |
| }); | |
| const rows = Array.from(table.querySelectorAll('tr')).slice(1); | |
| const dataRows = rows.filter((tr) => { | |
| const firstTd = tr.querySelector('td'); | |
| if (!firstTd) return false; | |
| const firstText = normalize(firstTd.textContent).toLowerCase(); | |
| if (firstText === 'sumário' || firstText === 'sumario' || firstText === 'summary') return false; | |
| return !!tr.querySelector('a[href*="screen=info_player"][href*="id="]'); | |
| }); | |
| const records = dataRows.map((tr) => { | |
| const tds = Array.from(tr.querySelectorAll('td')); | |
| const values = tds.map((td) => { | |
| const raw = normalize(td.textContent); | |
| return raw === '' ? '0' : raw; | |
| }); | |
| const player = values[0] || ''; | |
| const points = parseIntLoose(values[1] || '0'); | |
| let troopsPop = 0; | |
| let hasQuestion = false; | |
| values.forEach((v, colIdx) => { | |
| const unit = unitByCol[colIdx]; | |
| if (!unit || !(unit in UNIT_POP)) return; | |
| if (v === '?') { | |
| hasQuestion = true; | |
| return; | |
| } | |
| const count = parseIntLoose(v); | |
| troopsPop += count * UNIT_POP[unit]; | |
| }); | |
| const shared = hasQuestion ? 'nao' : 'sim'; | |
| const ratio = points > 0 ? troopsPop / points : 0; | |
| return { | |
| player, | |
| points, | |
| troopsPop, | |
| ratio, | |
| shared, | |
| baseValues: values | |
| }; | |
| }); | |
| records.sort((a, b) => { | |
| if (b.ratio !== a.ratio) return b.ratio - a.ratio; | |
| if (b.troopsPop !== a.troopsPop) return b.troopsPop - a.troopsPop; | |
| if (b.points !== a.points) return b.points - a.points; | |
| return a.player.localeCompare(b.player); | |
| }); | |
| const outHeaders = [ | |
| ...headers, | |
| 'Compartilhado', | |
| 'TroopsPop', | |
| 'Ratio' | |
| ]; | |
| const outRows = records.map((r) => [ | |
| ...r.baseValues, | |
| r.shared, | |
| String(r.troopsPop), | |
| r.ratio.toFixed(2).replace('.', ',') | |
| ]); | |
| const escapeCsv = (v) => `"${String(v).replace(/"/g, '""')}"`; | |
| const separator = ';'; // Better for pt-BR Excel | |
| const csv = [ | |
| outHeaders.map(escapeCsv).join(separator), | |
| ...outRows.map((row) => row.map(escapeCsv).join(separator)) | |
| ].join('\n'); | |
| const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' }); | |
| const url = URL.createObjectURL(blob); | |
| const now = new Date(); | |
| const y = now.getFullYear(); | |
| const m = String(now.getMonth() + 1).padStart(2, '0'); | |
| const d = String(now.getDate()).padStart(2, '0'); | |
| const hh = String(now.getHours()).padStart(2, '0'); | |
| const mm = String(now.getMinutes()).padStart(2, '0'); | |
| const a = document.createElement('a'); | |
| a.href = url; | |
| a.download = `ally_members_troops_ratio_${y}${m}${d}_${hh}${mm}.csv`; | |
| document.body.appendChild(a); | |
| a.click(); | |
| a.remove(); | |
| URL.revokeObjectURL(url); | |
| console.log(`[CSV] Exported ${records.length} players with TroopsPop + Ratio`); | |
| alert(`CSV exported: ${records.length} players`); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment