Skip to content

Commit

Permalink
navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanseifert committed Oct 19, 2024
1 parent a407946 commit d807a35
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 51 deletions.
45 changes: 45 additions & 0 deletions src/components/turn/SideBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<template>
<div class="sidebar">
{{t('sideBar.round', {round:navigationState.round})}}<br/>
</div>
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue'
import { useI18n } from 'vue-i18n'
import { useStateStore } from '@/store/state'
import NavigationState from '@/util/NavigationState'
export default defineComponent({
name: 'SideBar',
setup() {
const { t } = useI18n()
const state = useStateStore()
return { t, state }
},
props: {
navigationState: {
type: Object as PropType<NavigationState>,
required: true
}
}
})
</script>

<style lang="scss" scoped>
.sidebar {
float: right;
width: 145px;
margin-left: 15px;
margin-bottom: 10px;
margin-right: -12px;
padding: 15px 10px 15px 15px;
background-color: #ddd;
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
@media (max-width: 600px) {
font-size: 0.8rem;
width: 120px;
}
}
</style>
10 changes: 10 additions & 0 deletions src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@
"diceNotice": "Diese Würfel werden nicht gewürfelt - sie dienen dazu, die Anzahl von V.I.C.Is Würfeln zu ermitteln.",
"noOtherComponents": "Anderes Spielmaterial wird für V.I.C.I nicht benötigt."
},
"turnPlayer": {
"title": "Spieler",
"takeTurn": "Führe deinen Zug aus."
},
"turnBot": {
"title": "V.I.C.I"
},
"sideBar": {
"round": "Epoche {round}"
},
"difficultyLevel": {
"1": "Einstieg",
"2": "Moderat",
Expand Down
10 changes: 10 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@
"diceNotice": "You do not roll them, they are used to count the number of V.I.C.I's dice.",
"noOtherComponents": "Other components are not used for V.I.C.I."
},
"turnPlayer": {
"title": "Player",
"takeTurn": "Take your turn."
},
"turnBot": {
"title": "V.I.C.I"
},
"sideBar": {
"round": "Era {round}"
},
"difficultyLevel": {
"1": "Beginner",
"2": "Moderate",
Expand Down
12 changes: 12 additions & 0 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import AppHome from '@/views/AppHome.vue'
import NotFound from '@/views/NotFound.vue'
import SetupGame from '@/views/SetupGame.vue'
import SetupBot from '@/views/SetupBot.vue'
import TurnPlayer from '@/views/TurnPlayer.vue'
import TurnBot from '@/views/TurnBot.vue'

const LOCALSTORAGE_KEY = `${name}.route`

Expand All @@ -24,6 +26,16 @@ const routes: Array<RouteRecordRaw> = [
name: 'SetupBot',
component: SetupBot
},
{
path: '/round/:round/turn/:turn/player',
name: 'TurnPlayer',
component: TurnPlayer
},
{
path: '/round/:round/turn/:turn/bot',
name: 'TurnBot',
component: TurnBot
},
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
Expand Down
2 changes: 2 additions & 0 deletions src/store/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ export interface Turn {
}
export interface BotPersistence {
cardDeck: CardDeckPersistence
evolutionCount: number
prosperityCount: number
actionRoll: number
territoryRoll: number
beaconRoll: number
Expand Down
17 changes: 0 additions & 17 deletions src/util/AbstractNavigationState.ts

This file was deleted.

63 changes: 41 additions & 22 deletions src/util/BotNavigationState.ts → src/util/NavigationState.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,47 @@
import { BotPersistence, CardDeckPersistence, State } from '@/store/state'
import { BotPersistence, State } from '@/store/state'
import { RouteLocation } from 'vue-router'
import AbstractNavigationState from './AbstractNavigationState'
import getIntRouteParam from '@brdgm/brdgm-commons/src/util/router/getIntRouteParam'
import CardDeck from '@/services/CardDeck'
import Card from '@/services/Card'
import rollDice from '@brdgm/brdgm-commons/src/util/random/rollDice'
import Cards from '@/services/Cards'
import rollDice from '@brdgm/brdgm-commons/src/util/random/rollDice'

export default class BotNavigationState extends AbstractNavigationState {
export default class NavigationState {

private readonly cardDeck : CardDeck
private readonly currentCard : Card
private readonly actionRoll : number
private readonly territoryRoll : number
private readonly beaconRoll : number
readonly round : number
readonly turn : number

constructor(route : RouteLocation, state : State) {
super(route, state)
readonly cardDeck : CardDeck
readonly evolutionCount : number
readonly prosperityCount : number
readonly currentCard : Card
readonly actionRoll : number
readonly territoryRoll : number
readonly beaconRoll : number

constructor(route: RouteLocation, state: State) {
this.round = getIntRouteParam(route, 'round')
this.turn = getIntRouteParam(route, 'turn')

// try to load persistence with rolled die values for current turns
const botPersistence = getBotPersistence(state, this.round, this.turn)
if (botPersistence) {
this.cardDeck = CardDeck.fromPersistence(botPersistence.cardDeck)
this.evolutionCount = botPersistence.evolutionCount
this.prosperityCount = botPersistence.prosperityCount
this.actionRoll = botPersistence.actionRoll
this.territoryRoll = botPersistence.territoryRoll
this.beaconRoll = botPersistence.beaconRoll
}
// otherwise prepare new turn based on previous card deck
else {
this.cardDeck = CardDeck.fromPersistence(getCardDeckFromPreviousTurn(state, this.round, this.turn))
const previousBotPersistence = getPreviousBotPersistence(state, this.round, this.turn)
this.cardDeck = CardDeck.fromPersistence(previousBotPersistence.cardDeck)
// draw next card
this.cardDeck.draw()
// counters
this.evolutionCount = previousBotPersistence.evolutionCount
this.prosperityCount = previousBotPersistence.prosperityCount
// roll dice for action selection
this.actionRoll = rollDice(6)
this.territoryRoll = rollDice(6)
Expand All @@ -51,28 +63,35 @@ function getBotPersistence(state: State, round: number, turn: number) : BotPersi
return undefined
}

function getCardDeckFromPreviousTurn(state: State, round: number, turn: number) : CardDeckPersistence {
function getPreviousBotPersistence(state: State, round: number, turn: number) : BotPersistence {
const roundData = state.rounds.find(item => item.round == round)
if (roundData) {
const lastTurnCardDeck = roundData.turns
const lastBotPersistence = roundData.turns
.filter(item => (item.turn < turn) || turn == 0)
.toSorted((a,b) => a.turn - b.turn)
.map(item => item.botPersistence?.cardDeck)
.map(item => item.botPersistence)
.find(item => item != undefined)
if (lastTurnCardDeck) {
return lastTurnCardDeck
if (lastBotPersistence) {
return lastBotPersistence
}
}

// check previous round
if (round > 1) {
return getCardDeckFromPreviousTurn(state, round - 1, 0)
return getPreviousBotPersistence(state, round - 1, 0)
}

// get initial card deck
const initialCardDeck = state.setup.initialCardDeck
if (initialCardDeck) {
return initialCardDeck
let initialCardDeck = state.setup.initialCardDeck
if (!initialCardDeck) {
initialCardDeck = CardDeck.new().toPersistence() // should never happen
}
return {
cardDeck: initialCardDeck,
evolutionCount: 0,
prosperityCount: 0,
actionRoll: 0,
territoryRoll: 0,
beaconRoll: 0
}
return CardDeck.new().toPersistence() // should never happen
}
11 changes: 0 additions & 11 deletions src/util/PlayerNavigationState.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/views/SetupBot.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export default defineComponent({
turns: []
}
this.state.storeRound(round)
this.$router.push('/round/1/turn/1')
this.$router.push('/round/1/turn/1/player')
}
}
})
Expand Down
65 changes: 65 additions & 0 deletions src/views/TurnBot.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<template>
<SideBar :navigationState="navigationState"/>

<h1>
<img src="@/assets/vici.webp" class="vici" alt=""/>
{{t('turnBot.title')}}
</h1>

<button class="btn btn-primary btn-lg mt-4 me-2" @click="next()">
{{t('action.next')}}
</button>

<FooterButtons :backButtonRouteTo="backButtonRouteTo" endGameButtonType="abortGame"/>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { useI18n } from 'vue-i18n'
import FooterButtons from '@/components/structure/FooterButtons.vue'
import { useStateStore } from '@/store/state'
import { useRoute } from 'vue-router'
import SideBar from '@/components/turn/SideBar.vue'
import NavigationState from '@/util/NavigationState'
export default defineComponent({
name: 'TurnBot',
components: {
FooterButtons,
SideBar
},
setup() {
const { t } = useI18n()
const route = useRoute()
const state = useStateStore()
const navigationState = new NavigationState(route, state)
const { round, turn } = navigationState
return { t, state, navigationState, round, turn }
},
computed: {
backButtonRouteTo() : string {
if (this.turn > 1) {
return `/round/${this.round}/turn/${this.turn-1}/player`
}
if (this.round > 1) {
return `/round/${this.round-1}/end`
}
return ''
}
},
methods: {
next() : void {
this.$router.push(`/round/${this.round}/turn/${this.turn+1}/player`)
}
}
})
</script>

<style lang="scss" scoped>
.vici {
height: 3rem;
margin-top: -0.5rem;
}
</style>
59 changes: 59 additions & 0 deletions src/views/TurnPlayer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<template>
<SideBar :navigationState="navigationState"/>

<h1>
{{t('turnPlayer.title')}}
</h1>

<p v-html="t('turnPlayer.takeTurn')" class="mt-4 mb-4"></p>

<button class="btn btn-primary btn-lg mt-4" @click="next()">
{{t('action.next')}}
</button>

<FooterButtons :backButtonRouteTo="backButtonRouteTo" endGameButtonType="abortGame"/>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
import { useI18n } from 'vue-i18n'
import FooterButtons from '@/components/structure/FooterButtons.vue'
import { useRoute } from 'vue-router'
import { useStateStore } from '@/store/state'
import SideBar from '@/components/turn/SideBar.vue'
import NavigationState from '@/util/NavigationState'
export default defineComponent({
name: 'TurnPlayer',
components: {
FooterButtons,
SideBar
},
setup() {
const { t } = useI18n()
const route = useRoute()
const state = useStateStore()
const navigationState = new NavigationState(route, state)
const { round, turn } = navigationState
return { t, state, navigationState, round, turn }
},
computed: {
backButtonRouteTo() : string {
if (this.turn > 1) {
return `/round/${this.round}/turn/${this.turn-1}/bot`
}
if (this.round > 1) {
return `/round/${this.round-1}/end`
}
return ''
}
},
methods: {
next() : void {
this.$router.push(`/round/${this.round}/turn/${this.turn+1}/bot`)
}
}
})
</script>

0 comments on commit d807a35

Please sign in to comment.