diff --git a/src/components/setup/AutomaSetup.vue b/src/components/setup/AutomaSetup.vue index 2da2aac..7f2bb34 100644 --- a/src/components/setup/AutomaSetup.vue +++ b/src/components/setup/AutomaSetup.vue @@ -4,13 +4,38 @@
  1. -
  2. +
  3. + + +
    1. -
    2. +
    3. + +
      +
      + +
      +
      +
  4. @@ -100,6 +125,7 @@ import Terrain from '@/services/enum/Terrain' export default defineComponent({ name: 'AutomaSetup', emits: { + playerTerrain: (_playerTerrain: (Terrain|undefined)[]) => true, // eslint-disable-line @typescript-eslint/no-unused-vars botTerrain: (_botTerrain: (Terrain|undefined)[]) => true // eslint-disable-line @typescript-eslint/no-unused-vars }, components: { @@ -108,19 +134,21 @@ export default defineComponent({ setup() { const { t } = useI18n() const state = useStateStore() - return { t, state } + const { playerCount, botCount, botFaction } = state.setup.playerSetup + return { t, state, playerCount, botCount, botFaction } }, data() { return { + playerTerrain: [undefined, undefined] as (Terrain|undefined)[], botTerrain: [undefined, undefined] as (Terrain|undefined)[] } }, computed: { palaceTileCount() : number { - return this.state.setup.playerSetup.playerCount + 1 + return this.playerCount + 1 }, bonusCardCount() : number { - return this.state.setup.playerSetup.botCount + this.state.setup.playerSetup.playerCount + 3 + return this.playerCount + this.botCount + 3 }, randomCard(): Card { const allCards = Cards.getAll() @@ -128,23 +156,22 @@ export default defineComponent({ return allCards[index - 1] }, isFactionSymbionts() : boolean { - return this.state.setup.playerSetup.botFaction.includes(BotFaction.SYMBIONTS) + return this.botFaction.includes(BotFaction.SYMBIONTS) }, isFactionBlight() : boolean { - return this.state.setup.playerSetup.botFaction.includes(BotFaction.BLIGHT) + return this.botFaction.includes(BotFaction.BLIGHT) }, isFactionGognomes() : boolean { - return this.state.setup.playerSetup.botFaction.includes(BotFaction.GOGNOMES) + return this.botFaction.includes(BotFaction.GOGNOMES) }, factions() : BotFaction[] { - return this.state.setup.playerSetup.botFaction + return this.botFaction }, isTwoPlayerGame() : boolean { - const { playerCount, botCount } = this.state.setup.playerSetup - return (playerCount + botCount) == 2 + return (this.playerCount + this.botCount) == 2 }, isTwoHumanPlayers() : boolean { - return this.state.setup.playerSetup.playerCount === 2 + return this.playerCount === 2 }, terrains() : Terrain[] { return Object.values(Terrain) @@ -156,7 +183,12 @@ export default defineComponent({ } }, watch: { - // whenever question changes, this function will run + playerTerrain: { + handler(newValue) { + this.$emit('playerTerrain', newValue) + }, + deep: true + }, botTerrain: { handler(newValue) { this.$emit('botTerrain', newValue) diff --git a/src/locales/de.json b/src/locales/de.json index b49cd77..0b292e9 100644 --- a/src/locales/de.json +++ b/src/locales/de.json @@ -12,6 +12,7 @@ "title": "Spieler", "playerCount": "Menschliche Spieler", "playerCountItem": "{count} Spieler", + "player": "Spieler {player}", "botCount": "Automa", "botCountItem": "{count} Automa | {count} Automas (Experimentell)", "botFaction": "Automa Gemeinschaft | Automa {bot} Gemeinschaft", @@ -53,7 +54,7 @@ }, "factionSelectionTwoHumanPlayer": "Wähle deine Gemeinschaft und Rundenbonus nach den üblichen Regeln für ein Spiel mit 3 Spielern.", "chooseAutomaTerrain": "Wähle eine Heimatlandschaft für Automa, die anders ist als deine.", - "invalidTerrainSelection": "Bitte wähle eine Heimatlandschaft für Automa aus.", + "invalidTerrainSelection": "Bitte wähle gültige Heimatlandschaften für dich und für Automa aus.", "automaComponents": { "title": "Verteile Automas Spielsteine wie folgt:", "buildings": "Lege alle Gebäude ihrer Farbe in ihren Bereich.", diff --git a/src/locales/en.json b/src/locales/en.json index cf8f16d..34791f9 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -12,6 +12,7 @@ "title": "Player", "playerCount": "Human Players", "playerCountItem": "{count} Player | {count} Players", + "player": "Player {player}", "botCount": "Automa", "botCountItem": "{count} Automa | {count} Automas (Experimental)", "botFaction": "Automa Faction | Automa {bot} Faction", @@ -53,7 +54,7 @@ }, "factionSelectionTwoHumanPlayer": "Choose your Faction and Round Bonus following the usual rules for a 3-Player game.", "chooseAutomaTerrain": "Choose a Native terrain for Automa different from yours.", - "invalidTerrainSelection": "Please select a terrain for Automa.", + "invalidTerrainSelection": "Please select a terrain for you and for Automa.", "automaComponents": { "title": "Distribute the Automa components as follows:", "buildings": "Place all her buildings in her play area.", diff --git a/src/store/state.ts b/src/store/state.ts index 6ecbea5..d25adcb 100644 --- a/src/store/state.ts +++ b/src/store/state.ts @@ -36,6 +36,8 @@ export const useStateStore = defineStore(`${name}.store`, { resetGame() { this.setup.roundScoreTiles = undefined this.setup.roundScoreFinalTile = undefined + this.setup.playerTerrain = undefined + this.setup.botTerrain = undefined this.setup.setupBookActions = undefined this.setup.setupCompetencyTiles = undefined this.setup.setupInnovationTiles = undefined @@ -57,6 +59,7 @@ export interface Setup { playerSetup: PlayerSetup roundScoreTiles?: number[] roundScoreFinalTile?: number + playerTerrain?: Terrain[] botTerrain?: Terrain[] // parameters not relevant for the application, but persisted for back button support in setup screens setupBookActions?: number[] diff --git a/src/util/NavigationState.ts b/src/util/NavigationState.ts index c369300..1c0865d 100644 --- a/src/util/NavigationState.ts +++ b/src/util/NavigationState.ts @@ -20,6 +20,7 @@ export default class NavigationState { readonly turn : number readonly turnOrderIndex : number readonly player : number + readonly playerTerrain? : Terrain readonly bot : number readonly botFaction? : BotFaction readonly botTerrain? : Terrain @@ -54,6 +55,9 @@ export default class NavigationState { this.preferredScienceDiscipline = roundScoreTile.scienceDiscipline } } + else { + this.playerTerrain = (setup.playerTerrain ?? [])[this.player - 1] + } } } diff --git a/src/views/SetupGameAutoma.vue b/src/views/SetupGameAutoma.vue index 4dedb75..80ad249 100644 --- a/src/views/SetupGameAutoma.vue +++ b/src/views/SetupGameAutoma.vue @@ -2,7 +2,7 @@

    {{t('setupGameAutoma.title')}}

    - +
    @@ -41,16 +41,20 @@ export default defineComponent({ }, data() { return { - botTerrain: [] as (Terrain|undefined)[] + botTerrain: [] as (Terrain|undefined)[], + playerTerrain: [] as (Terrain|undefined)[], } }, computed: { isValidTerrainSelection() : boolean { - if (this.botTerrain[0] === undefined) { + const { playerCount, botCount } = this.state.setup.playerSetup + const allTerrains = [...this.playerTerrain.slice(0, playerCount), ...this.botTerrain.slice(0, botCount)] + // ensure no missing terrain + if (allTerrains.some(terrain => terrain === undefined)) { return false } - if (this.state.setup.playerSetup.botCount === 2 - && (this.botTerrain[1] === undefined || this.botTerrain[1] === this.botTerrain[0])) { + // ensure no duplicate terrain + if (new Set(allTerrains).size !== playerCount + botCount) { return false } return true @@ -58,6 +62,7 @@ export default defineComponent({ }, methods: { startGame() : void { + this.state.setup.playerTerrain = this.playerTerrain.filter(terrain => terrain !== undefined) this.state.setup.botTerrain = this.botTerrain.filter(terrain => terrain !== undefined) // prepare first round with initial player order const { playerCount, botCount } = this.state.setup.playerSetup diff --git a/tests/unit/helper/mockState.ts b/tests/unit/helper/mockState.ts index d5747bd..eeb2294 100644 --- a/tests/unit/helper/mockState.ts +++ b/tests/unit/helper/mockState.ts @@ -16,6 +16,7 @@ export default function (params?: MockStateParams) : State { }, roundScoreTiles: params?.roundScoreTiles, roundScoreFinalTile: params?.roundScoreFinalTile, + playerTerrain: params?.playerTerrain, botTerrain: params?.botTerrain }, rounds: params?.rounds ?? [] @@ -29,6 +30,7 @@ export interface MockStateParams { botFaction?: BotFaction[] roundScoreTiles?: number[] roundScoreFinalTile?: number + playerTerrain?: Terrain[] botTerrain?: Terrain[] rounds?: Round[] } diff --git a/tests/unit/util/NavigationState.spec.ts b/tests/unit/util/NavigationState.spec.ts index 76f10ee..5ec8fac 100644 --- a/tests/unit/util/NavigationState.spec.ts +++ b/tests/unit/util/NavigationState.spec.ts @@ -8,9 +8,11 @@ import { CardDeckPersistence } from '@/store/state' import { RouteParams } from 'vue-router' import NavigationState from '@/util/NavigationState' import ScienceDiscipline from '@/services/enum/ScienceDiscipline' +import Terrain from '@/services/enum/Terrain' const state = mockState({playerCount:1, botCount:2, roundScoreTiles: [1,4,5,9,11,12], roundScoreFinalTile: 2, + playerTerrain: [Terrain.LAKE], botTerrain: [Terrain.DESERT,Terrain.MOUNTAIN], rounds:[ mockRound({round:1, playerOrder:[{player:1},{bot:1},{bot:2}], turns:[ mockTurn({round:1,turn:1,player:1}), @@ -81,6 +83,15 @@ describe('util/NavigationState', () => { expect(navigationState({round:'6',turn:'1',bot:'1'}).passVictoryPoints).to.eq(6) expect(navigationState({round:'6',turn:'1',bot:'1'}).preferredScienceDiscipline).to.eq(ScienceDiscipline.LAW) }) + + it('playerTerrain', () => { + expect(navigationState({round:'1',turn:'1',player:'1'}).playerTerrain).to.eq(Terrain.LAKE) + }) + + it('botTerrain', () => { + expect(navigationState({round:'1',turn:'1',bot:'1'}).botTerrain).to.eq(Terrain.DESERT) + expect(navigationState({round:'1',turn:'1',bot:'2'}).botTerrain).to.eq(Terrain.MOUNTAIN) + }) }) function cardDeck(deck:string[], discard:string[], reserve:string[]) : CardDeckPersistence {