From 6b0442396c2a6dc3b83c100295ce1dc81aefc76b Mon Sep 17 00:00:00 2001 From: Albert Cui Date: Wed, 31 Jul 2019 13:11:56 -0700 Subject: [PATCH 1/2] creating non-optimial cross table --- src/components/App/App.tsx | 6 + .../HeroesCrossTablePage.tsx | 114 ++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 src/components/HeroesCrossTablePage/HeroesCrossTablePage.tsx diff --git a/src/components/App/App.tsx b/src/components/App/App.tsx index eb7efcb..fd2a275 100644 --- a/src/components/App/App.tsx +++ b/src/components/App/App.tsx @@ -18,6 +18,7 @@ import { generateURL, SUPPORTED_LANGUAGES } from '../../utils'; import FourOFourPage from '../FourOFourPage/FourOFourPage'; import TeamBuilderPage from '../TeamBuilderPage/TeamBuilderPage'; import { ServiceWorkerContext } from '../../context/ServiceWorkerContext'; +import HeroesCrossTablePage from '../HeroesCrossTablePage/HeroesCrossTablePage'; type MatchParams = { [lang: string]: string } @@ -60,6 +61,10 @@ export default class App extends React.Component { { to: generateURL('builder'), name: "app_team_builder" + }, + { + to: generateURL('cross'), + name: "app_team_builder" } ]; @@ -124,6 +129,7 @@ export default class App extends React.Component { + diff --git a/src/components/HeroesCrossTablePage/HeroesCrossTablePage.tsx b/src/components/HeroesCrossTablePage/HeroesCrossTablePage.tsx new file mode 100644 index 0000000..8348be3 --- /dev/null +++ b/src/components/HeroesCrossTablePage/HeroesCrossTablePage.tsx @@ -0,0 +1,114 @@ +import React, { useEffect, useState } from 'react'; +import heroes from 'underlordsconstants/build/underlords_heroes.json'; +import commonStyles from '../../common.module.css'; +import { Hero } from '../../types'; +import HeroCard from '../HeroCard/HeroCard'; +import ReactTooltip from 'react-tooltip'; +import { alliances, underlordsLoc, strings } from '../Localization/Localization'; +import SortButtons from '../SortButtons/SortButtons'; +import Helmet from 'react-helmet'; + +export default function HeroesCrossTablePage() { + + const [crossAlliances, setCrossAlliances] = useState(); + const [emptyRows, setEmptyRows] = useState(); + const [nonEmptyColumns, setNonEmptyColumns] = useState(); + + useEffect(() => { + const allianceIndex = Object.keys(alliances); + const cross: Array[][] = []; + for (let i = 0; i < allianceIndex.length; i++) { + cross[i] = []; + for (let j = 0; j < allianceIndex.length; j++) { + cross[i][j] = []; + } + } + + // const cross: { [index: string]: { [index: string]: string[]}}= {}; + + function addPair(heroKey: string, firstAll: string, secAll: string) { + const i = allianceIndex.findIndex((e) => e === firstAll); + const j = allianceIndex.findIndex((e) => e === secAll); + + cross[i][j].push(heroKey); + // if (firstAll in cross) { + // if (secAll in cross[firstAll]) { + // cross[firstAll][secAll].push(heroKey); + // } else { + // cross[firstAll][secAll] = [heroKey]; + // } + // } else { + // cross[firstAll] = { + // [secAll]: [heroKey] + // } + // } + } + + Object.entries(heroes).forEach(([heroKey, hero]) => { + if (hero.draftTier > 0 && hero.keywords) { + const alliances = hero.keywords.split(' ').sort(); + if (alliances.length < 2) { + return; + } + + const [firstAll, ...rest] = alliances; + + rest.forEach((e) => { + addPair(heroKey, firstAll, e); + }) + } + }); + + console.log(cross); + // Check which rows and columns are empty + const emptyRows: number[] = []; + const nonEmptyColumns: number[] = []; + + cross.forEach((row, i) => { + let empty = true; + row.forEach((elem, j) => { + if (elem.length > 0) { + empty = false; + nonEmptyColumns.push(j); + } + }); + if (empty) { + emptyRows.push(i); + } + }) + + setCrossAlliances(cross); + setEmptyRows(emptyRows); + setNonEmptyColumns(nonEmptyColumns); + console.log(emptyRows); + console.log(nonEmptyColumns); + }, []) + + const allianceIndex = Object.keys(alliances); + + return
+ + {crossAlliances && crossAlliances.map((a1: [][], i: number) => { + if (emptyRows && emptyRows.find((e: number) => e === i)) { + return <> + } + + return + {allianceIndex[i]} + { + a1.map((heroes, j) => { + if (nonEmptyColumns && !nonEmptyColumns.find((e: number) => e === j)) { + return <> + } + + return + { i === 0 && allianceIndex[j]} + { heroes && heroes.toString()} + + }) + } + + })} + +
+} \ No newline at end of file From c1eaad12eaa5c734b5085bc715aeba8a0a8b7b32 Mon Sep 17 00:00:00 2001 From: Albert Cui Date: Wed, 31 Jul 2019 13:51:19 -0700 Subject: [PATCH 2/2] slightly better --- .../HeroesCrossTablePage.module.css | 6 ++ .../HeroesCrossTablePage.tsx | 100 +++++++++++++----- 2 files changed, 77 insertions(+), 29 deletions(-) create mode 100644 src/components/HeroesCrossTablePage/HeroesCrossTablePage.module.css diff --git a/src/components/HeroesCrossTablePage/HeroesCrossTablePage.module.css b/src/components/HeroesCrossTablePage/HeroesCrossTablePage.module.css new file mode 100644 index 0000000..4d2bbab --- /dev/null +++ b/src/components/HeroesCrossTablePage/HeroesCrossTablePage.module.css @@ -0,0 +1,6 @@ +.Image { + height: 50px; + width: 50px; + margin: 3px; + cursor: pointer; +} diff --git a/src/components/HeroesCrossTablePage/HeroesCrossTablePage.tsx b/src/components/HeroesCrossTablePage/HeroesCrossTablePage.tsx index 8348be3..185acea 100644 --- a/src/components/HeroesCrossTablePage/HeroesCrossTablePage.tsx +++ b/src/components/HeroesCrossTablePage/HeroesCrossTablePage.tsx @@ -1,12 +1,13 @@ import React, { useEffect, useState } from 'react'; import heroes from 'underlordsconstants/build/underlords_heroes.json'; import commonStyles from '../../common.module.css'; +import styles from './HeroesCrossTablePage.module.css'; import { Hero } from '../../types'; -import HeroCard from '../HeroCard/HeroCard'; import ReactTooltip from 'react-tooltip'; import { alliances, underlordsLoc, strings } from '../Localization/Localization'; import SortButtons from '../SortButtons/SortButtons'; import Helmet from 'react-helmet'; +import { GetHeroImage } from '../../utils'; export default function HeroesCrossTablePage() { @@ -24,40 +25,73 @@ export default function HeroesCrossTablePage() { } } - // const cross: { [index: string]: { [index: string]: string[]}}= {}; - function addPair(heroKey: string, firstAll: string, secAll: string) { const i = allianceIndex.findIndex((e) => e === firstAll); const j = allianceIndex.findIndex((e) => e === secAll); - cross[i][j].push(heroKey); - // if (firstAll in cross) { - // if (secAll in cross[firstAll]) { - // cross[firstAll][secAll].push(heroKey); - // } else { - // cross[firstAll][secAll] = [heroKey]; - // } - // } else { - // cross[firstAll] = { - // [secAll]: [heroKey] - // } - // } - } + // Get number of heroes in this row + const rowCounti = cross[i].reduce((prev, elem) => { + return prev + elem.length; + }, 0); - Object.entries(heroes).forEach(([heroKey, hero]) => { - if (hero.draftTier > 0 && hero.keywords) { - const alliances = hero.keywords.split(' ').sort(); - if (alliances.length < 2) { - return; - } + const columnCounti = cross.reduce((prev, elem) => { + return prev + elem[j].length + }, 0); - const [firstAll, ...rest] = alliances; + const rowCountj = cross[j].reduce((prev, elem) => { + return prev + elem.length; + }, 0); - rest.forEach((e) => { - addPair(heroKey, firstAll, e); + const columnCountj = cross.reduce((prev, elem) => { + return prev + elem[i].length + }, 0); + + if (rowCounti + columnCounti >= rowCountj + columnCountj) { + cross[i][j].push(heroKey); + } else { + cross[j][i].push(heroKey); + } + } + + // sort by alliances with most heroes + const sortedAlliances = Object.keys(alliances).sort((a, b) => { + const first = alliances[a].heroes ? alliances[a].heroes.length : 0; + const second = alliances[b].heroes ? alliances[b].heroes.length : 0; + + if (first === second) { + return 0 + } else { + return first > second ? 1 : -1; + } + }).reverse(); + + const processedHeroes: string[] = []; + + sortedAlliances.forEach((a) => { + const alliance = alliances[a]; + if (alliance.heroes) { + alliance.heroes.forEach((hero: Hero) => { + if (processedHeroes.find((e) => e === hero.key)) { + return; + } + + if (hero.draftTier > 0 && hero.keywords) { + const alliances = hero.keywords.split(' ').sort(); + if (alliances.length < 2) { + return; + } + + const [firstAll, ...rest] = alliances; + + rest.forEach((e: string) => { + addPair(hero.key, firstAll, e); + }) + + processedHeroes.push(hero.key); + } }) } - }); + }) console.log(cross); // Check which rows and columns are empty @@ -86,7 +120,7 @@ export default function HeroesCrossTablePage() { const allianceIndex = Object.keys(alliances); - return
+ return
{crossAlliances && crossAlliances.map((a1: [][], i: number) => { if (emptyRows && emptyRows.find((e: number) => e === i)) { @@ -96,14 +130,22 @@ export default function HeroesCrossTablePage() { return {allianceIndex[i]} { - a1.map((heroes, j) => { + a1.map((heroesArray, j) => { if (nonEmptyColumns && !nonEmptyColumns.find((e: number) => e === j)) { return <> } return { i === 0 && allianceIndex[j]} - { heroes && heroes.toString()} + { heroesArray && heroesArray.map((key: keyof typeof heroes) => { + const hero = heroes[key]; + return {hero.displayName} + })} }) }