-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a6d28df
commit ec00748
Showing
8 changed files
with
190 additions
and
7 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { TechCardSelectionPersistence } from '@/store/state' | ||
import Tech from './enum/Tech' | ||
import TechPlaceholder from './enum/TechPlaceholder' | ||
import { ref } from 'vue' | ||
import { cloneDeep, shuffle } from 'lodash' | ||
import getAllEnumValues from '@brdgm/brdgm-commons/src/util/enum/getAllEnumValues' | ||
import DraftingRowCard from './DraftingRowCard' | ||
import DraftingPriorityCard from './DraftingPriorityCard' | ||
import TechMatch from './enum/TechMatch' | ||
import getTechDuration from '@/util/getTechDuration' | ||
|
||
/** | ||
* Manages the drafting of tech cards. | ||
*/ | ||
export default class TechCardSelection { | ||
|
||
private readonly _techs | ||
private readonly _round : number | ||
|
||
private constructor(techs: (Tech|TechPlaceholder)[][], round: number) { | ||
this._techs = ref(techs) | ||
this._round = round | ||
} | ||
|
||
public get techs() : readonly (Tech|TechPlaceholder)[][] { | ||
return this._techs.value | ||
} | ||
|
||
/** | ||
* Gets persistence view. | ||
*/ | ||
public toPersistence() : TechCardSelectionPersistence { | ||
return { | ||
techs: this._techs.value | ||
} | ||
} | ||
|
||
/** | ||
* Determines the tech card to be drafted by Automa. | ||
* @param row Row selection | ||
* @param priority Priority selection | ||
* @param prosperityTechs Prosperity techs | ||
*/ | ||
public determineTech(rowCard: DraftingRowCard, priorityCard: DraftingPriorityCard, prosperityTechs: Tech[]) : Tech { | ||
for (const row of rowCard.rows) { | ||
const rowTechs = this._techs.value[row - 1] | ||
if (this.getOnlyTechs(rowTechs).length > 2) { | ||
for (const priority of priorityCard.priority) { | ||
const matchingIndexes = this.findMatchingIndexes(rowTechs, priority, prosperityTechs) | ||
for (const column of rowCard.columns) { | ||
if (matchingIndexes.includes(column - 1)) { | ||
return rowTechs[column - 1] as Tech | ||
} | ||
} | ||
} | ||
} | ||
} | ||
throw new Error('Not matching tech card found.') | ||
} | ||
|
||
private getOnlyTechs(techs: (Tech|TechPlaceholder)[]) : Tech[] { | ||
return techs.filter(tech => tech != TechPlaceholder.PLACEHOLDER && tech != TechPlaceholder.EMPTY) as Tech[] | ||
} | ||
|
||
private findMatchingIndexes(techs: (Tech|TechPlaceholder)[], priority: (Tech|TechMatch), prosperityTechs: Tech[]) : number[] { | ||
const onlyTechs = this.getOnlyTechs(techs) | ||
const maxAge = onlyTechs.map(tech => getTechDuration(tech, this._round)).reduce((a,b) => Math.max(a,b)) | ||
let matchingTechs | ||
if (priority == TechMatch.MAX_AGE) { | ||
matchingTechs = onlyTechs.filter(tech => getTechDuration(tech, this._round) == maxAge) | ||
} | ||
else if (priority == TechMatch.PROSPERITY) { | ||
matchingTechs = onlyTechs.filter(tech => prosperityTechs.includes(tech)) | ||
} | ||
else { | ||
matchingTechs = onlyTechs.filter(tech => tech == priority) | ||
} | ||
return matchingTechs.map(tech => techs.indexOf(tech)) | ||
} | ||
|
||
/** | ||
* Removes a tech card. | ||
* @param tech Tech card. | ||
*/ | ||
public remove(tech: Tech) : void { | ||
this._techs.value.forEach((row,index) => { | ||
this._techs.value[index] = row.map(item => item == tech ? TechPlaceholder.EMPTY : item) | ||
}) | ||
} | ||
|
||
/** | ||
* Creates a selection of techs in 4 ros respecting the placeholder rows. | ||
*/ | ||
public static new(placeholderRows: number[], round: number) : TechCardSelection { | ||
const allTechs = shuffle(getAllEnumValues(Tech)) | ||
const techs : (Tech|TechPlaceholder)[][] = [] | ||
for (let row = 1; row <= 4; row++) { | ||
if (placeholderRows.includes(row)) { | ||
techs.push([...allTechs.splice(0, 3), TechPlaceholder.PLACEHOLDER]) | ||
} | ||
else { | ||
techs.push(allTechs.splice(0, 4)) | ||
} | ||
} | ||
return new TechCardSelection(techs, round) | ||
} | ||
|
||
/** | ||
* Re-creates from persistence. | ||
*/ | ||
public static fromPersistence(persistence : TechCardSelectionPersistence, round: number) : TechCardSelection { | ||
return new TechCardSelection(cloneDeep(persistence.techs), round) | ||
} | ||
|
||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
/** | ||
* Tech placeholder | ||
*/ | ||
enum TechPlaceholder { | ||
PLACEHOLDER = 'placeholder', | ||
EMPTY = 'empty' | ||
} | ||
export default TechPlaceholder |
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import { expect } from 'chai' | ||
import Tech from '@/services/enum/Tech' | ||
import TechCardSelection from '@/services/TechCardSelection' | ||
import TechPlaceholder from '@/services/enum/TechPlaceholder' | ||
import DraftingRowCards from '@/services/DraftingRowCards' | ||
import DraftingPriorityCards from '@/services/DraftingPriorityCards' | ||
|
||
describe('services/TechCardSelection', () => { | ||
it('new', () => { | ||
const techCardSelection = TechCardSelection.new([1,4], 1) | ||
|
||
expect(techCardSelection.techs.length).to.eq(4) | ||
expect(techCardSelection.techs.flat().length).to.eq(16) | ||
|
||
const persistence = techCardSelection.toPersistence() | ||
expect(persistence.techs.length).to.eq(4) | ||
expect(persistence.techs.flat().length).to.eq(16) | ||
}) | ||
|
||
it('remove', () => { | ||
const techCardSelection = TechCardSelection.fromPersistence({ | ||
techs: [ | ||
[Tech.COMMUNICATION, Tech.ECONOMICS, Tech.ENERGY, Tech.ENGINEERING], | ||
[Tech.GOVERNMENT, Tech.MEDICINE, Tech.SCIENCE, TechPlaceholder.PLACEHOLDER], | ||
[Tech.SOCIAL_SCIENCE, Tech.TRANSPORTATION, Tech.ARTS, TechPlaceholder.PLACEHOLDER], | ||
[Tech.ARMY, Tech.MILITARY, Tech.WEAPONRY, Tech.AGRICULTURE] | ||
] | ||
}, 1) | ||
expect(techCardSelection.techs.flat().length).to.eq(16) | ||
|
||
techCardSelection.remove(Tech.TRANSPORTATION) | ||
expect(techCardSelection.techs.flat().length).to.eq(16) | ||
expect(techCardSelection.techs[2]).to.eql([Tech.SOCIAL_SCIENCE, TechPlaceholder.EMPTY, Tech.ARTS, TechPlaceholder.PLACEHOLDER]) | ||
}) | ||
|
||
it('determineTech', () => { | ||
const techCardSelection = TechCardSelection.fromPersistence({ | ||
techs: [ | ||
[Tech.WEAPONRY, TechPlaceholder.EMPTY, TechPlaceholder.EMPTY, Tech.ENGINEERING], | ||
[Tech.GOVERNMENT, Tech.MEDICINE, Tech.SCIENCE, TechPlaceholder.PLACEHOLDER], | ||
[Tech.SOCIAL_SCIENCE, Tech.TRANSPORTATION, Tech.ARTS, TechPlaceholder.PLACEHOLDER], | ||
[Tech.ARMY, Tech.MILITARY, Tech.AGRICULTURE, Tech.COMMUNICATION] | ||
] | ||
}, 2) | ||
const prosperityTechs = [Tech.ECONOMICS, Tech.MEDICINE, Tech.SCIENCE, Tech.TRANSPORTATION] | ||
|
||
// rows [4,3,2,1] priority [MAX_AGE, PROSPERITY,ENGINEERING,ARMY] columns [1,2,3,4] | ||
expect(techCardSelection.determineTech(DraftingRowCards.get(1), DraftingPriorityCards.get(1), prosperityTechs)).to.eq(Tech.AGRICULTURE) | ||
|
||
// rows [1,4,3,2], priority [PROSPERITY,ENGINEERING,COMMUNICATION,MAX_AGE] columns [1,2,4,3] | ||
expect(techCardSelection.determineTech(DraftingRowCards.get(2), DraftingPriorityCards.get(3), prosperityTechs)).to.eq(Tech.COMMUNICATION) | ||
|
||
// rows [2,1,4,3], priority [PROSPERITY,ENGINEERING,COMMUNICATION,MAX_AGE] columns [1,3,2,4] | ||
expect(techCardSelection.determineTech(DraftingRowCards.get(3), DraftingPriorityCards.get(3), prosperityTechs)).to.eq(Tech.SCIENCE) | ||
}) | ||
}) |
This file contains 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