Skip to content

Commit

Permalink
round start
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanseifert committed Oct 19, 2024
1 parent d807a35 commit 20398ab
Show file tree
Hide file tree
Showing 10 changed files with 298 additions and 18 deletions.
24 changes: 24 additions & 0 deletions src/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,37 @@
"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."
},
"roundStart": {
"title": "Beginn der Epoche",
"newCards": {
"title": "1) Neue Karten",
"playAsUsual": "Keine Anpassungen."
},
"newGoals": {
"title": "2) Neue Ziele",
"playerTakeGoal": "Nehme eine Zielplatine (optional).",
"botDetermine": "Bestimme eine Zielplatine für V.I.C.I.",
"botTakeGoal": "Entferne Zielplatine <b>{goalChip}</b> (wenn verfügbar).",
"botNoGoal": "Es wird keine Zielplatine entfernt."
},
"extraFind": {
"title": "3) Sonderfund",
"playAsUsual": "Keine Anpassungen. V.I.C.I macht keinen Sonderfund."
}
},
"turnPlayer": {
"title": "Spieler",
"takeTurn": "Führe deinen Zug aus."
},
"turnBot": {
"title": "V.I.C.I"
},
"roundEnd": {
"title": "Ende der Epoche"
},
"gameEnd": {
"title": "Spielende"
},
"sideBar": {
"round": "Epoche {round}"
},
Expand Down
24 changes: 24 additions & 0 deletions src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,37 @@
"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."
},
"roundStart": {
"title": "Era Start",
"newCards": {
"title": "1) New Cards",
"playAsUsual": "Play as usual."
},
"newGoals": {
"title": "2) New goals",
"playerTakeGoal": "Take a goal chip (optional).",
"botDetermine": "Determine goal chip for V.I.C.I.",
"botTakeGoal": "Remove goal chip <b>{goalChip}</b> (if available).",
"botNoGoal": "No goal chip is removed."
},
"extraFind": {
"title": "3) Extra find",
"playAsUsual": "Play as usual, V.I.C.I makes no extra find."
}
},
"turnPlayer": {
"title": "Player",
"takeTurn": "Take your turn."
},
"turnBot": {
"title": "V.I.C.I"
},
"roundEnd": {
"title": "Era End"
},
"gameEnd": {
"title": "Game End"
},
"sideBar": {
"round": "Era {round}"
},
Expand Down
18 changes: 18 additions & 0 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import SetupGame from '@/views/SetupGame.vue'
import SetupBot from '@/views/SetupBot.vue'
import TurnPlayer from '@/views/TurnPlayer.vue'
import TurnBot from '@/views/TurnBot.vue'
import RoundStart from '@/views/RoundStart.vue'
import RoundEnd from '@/views/RoundEnd.vue'
import GameEnd from '@/views/GameEnd.vue'

const LOCALSTORAGE_KEY = `${name}.route`

Expand All @@ -26,6 +29,11 @@ const routes: Array<RouteRecordRaw> = [
name: 'SetupBot',
component: SetupBot
},
{
path: '/round/:round/start',
name: 'RoundStart',
component: RoundStart
},
{
path: '/round/:round/turn/:turn/player',
name: 'TurnPlayer',
Expand All @@ -36,6 +44,16 @@ const routes: Array<RouteRecordRaw> = [
name: 'TurnBot',
component: TurnBot
},
{
path: '/round/:round/end',
name: 'RoundEnd',
component: RoundEnd
},
{
path: '/gameEnd',
name: 'GameEnd',
component: GameEnd
},
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
Expand Down
45 changes: 38 additions & 7 deletions src/util/NavigationState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import CardDeck from '@/services/CardDeck'
import Card from '@/services/Card'
import Cards from '@/services/Cards'
import rollDice from '@brdgm/brdgm-commons/src/util/random/rollDice'
import Player from '@/services/enum/Player'

export default class NavigationState {

readonly round : number
readonly turn : number

readonly startPlayer : Player
readonly player : Player

readonly cardDeck : CardDeck
readonly evolutionCount : number
readonly prosperityCount : number
Expand All @@ -21,7 +24,15 @@ export default class NavigationState {

constructor(route: RouteLocation, state: State) {
this.round = getIntRouteParam(route, 'round')
this.turn = getIntRouteParam(route, 'turn')
if (route.name == 'RoundEnd' || route.name == 'GameEnd') {
this.turn = MAX_TURN
}
else {
this.turn = getIntRouteParam(route, 'turn')
}

this.startPlayer = getStartPlayer(state, this.round)
this.player = getPlayer(route, this.startPlayer)

// try to load persistence with rolled die values for current turns
const botPersistence = getBotPersistence(state, this.round, this.turn)
Expand Down Expand Up @@ -52,13 +63,33 @@ export default class NavigationState {

}

const MAX_TURN = 999

function getStartPlayer(state: State, round: number) : Player {
const roundData = state.rounds.find(item => item.round == round)
if (roundData) {
return roundData.startPlayer
}
return Player.PLAYER
}

function getPlayer(route: RouteLocation, startPlayer: Player) : Player {
if (route.name == 'TurnPlayer') {
return Player.PLAYER
}
else if (route.name == 'TurnBot') {
return Player.BOT
}
else {
return startPlayer
}
}

function getBotPersistence(state: State, round: number, turn: number) : BotPersistence|undefined {
const roundData = state.rounds.find(item => item.round == round)
if (roundData) {
const turnData = roundData.turns.find(item => item.turn == turn)
if (turnData && turnData.botPersistence) {
return turnData.botPersistence
}
return turnData?.botPersistence
}
return undefined
}
Expand All @@ -67,7 +98,7 @@ function getPreviousBotPersistence(state: State, round: number, turn: number) :
const roundData = state.rounds.find(item => item.round == round)
if (roundData) {
const lastBotPersistence = roundData.turns
.filter(item => (item.turn < turn) || turn == 0)
.filter(item => item.turn < turn)
.toSorted((a,b) => a.turn - b.turn)
.map(item => item.botPersistence)
.find(item => item != undefined)
Expand All @@ -78,7 +109,7 @@ function getPreviousBotPersistence(state: State, round: number, turn: number) :

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

// get initial card deck
Expand Down
41 changes: 41 additions & 0 deletions src/views/GameEnd.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<template>
<SideBar :navigationState="navigationState"/>

<h1 class="mb-3">{{t('gameEnd.title')}}</h1>

<p>...</p>

<FooterButtons :backButtonRouteTo="backButtonRouteTo" endGameButtonType="endGame"/>
</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: 'GameEnd',
components: {
FooterButtons,
SideBar
},
setup() {
const { t } = useI18n()
const route = useRoute()
const state = useStateStore()
const navigationState = new NavigationState(route, state)
return { t, state, navigationState }
},
computed: {
backButtonRouteTo() : string {
return '/round/4/end'
}
}
})
</script>
69 changes: 69 additions & 0 deletions src/views/RoundEnd.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<template>
<SideBar :navigationState="navigationState"/>

<h1 class="mb-3">{{t('roundEnd.title')}}</h1>

<h3>5) Site phase</h3>

<h3>6) Feeding phase</h3>

<h3>7) Event phase</h3>

<h3>8) Income phase</h3>

<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: 'RoundStart',
components: {
FooterButtons,
SideBar
},
setup() {
const { t } = useI18n()
const route = useRoute()
const state = useStateStore()
const navigationState = new NavigationState(route, state)
const { round } = navigationState
return { t, state, navigationState, round }
},
computed: {
backButtonRouteTo() : string {
const roundData = this.state.rounds.find(item => item.round === this.round)
if (roundData) {
const lastTurn = roundData.turns.toSorted((a,b) => a.turn - b.turn)[0]
if (lastTurn) {
return `/round/${lastTurn.round}/turn/${lastTurn.turn}/${lastTurn.player}`
}
}
return ''
}
},
methods: {
next() : void {
if (this.round < 4) {
this.$router.push(`/round/${this.round+1}/start`)
}
else {
this.$router.push(`/gameEnd`)
}
}
}
})
</script>
80 changes: 80 additions & 0 deletions src/views/RoundStart.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<template>
<SideBar :navigationState="navigationState"/>

<h1 class="mb-3">{{t('roundStart.title')}}</h1>

<h3 v-html="t('roundStart.newCards.title')"></h3>
<p v-html="t('roundStart.newCards.playAsUsual')"></p>

<h3 v-html="t('roundStart.newGoals.title')"></h3>
<ol>
<li v-if="isPlayerStartPlayer" v-html="t('roundStart.newGoals.playerTakeGoal')"></li>
<li v-if="goalChip && goalChip > 4" v-html="t('roundStart.newGoals.botNoGoal')"></li>
<li v-else-if="goalChip" v-html="t('roundStart.newGoals.botTakeGoal', {goalChip})"></li>
<li v-else><button class="btn btn-sm btn-secondary" @click="determineGoalChip" v-html="t('roundStart.newGoals.botDetermine')"></button></li>
<li v-if="!isPlayerStartPlayer" v-html="t('roundStart.newGoals.playerTakeGoal')"></li>
</ol>

<h3 v-html="t('roundStart.extraFind.title')"></h3>
<p v-html="t('roundStart.extraFind.playAsUsual')"></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'
import rollDice from '@brdgm/brdgm-commons/src/util/random/rollDice'
import Player from '@/services/enum/Player'
export default defineComponent({
name: 'RoundStart',
components: {
FooterButtons,
SideBar
},
setup() {
const { t } = useI18n()
const route = useRoute()
const state = useStateStore()
const navigationState = new NavigationState(route, state)
const { round, startPlayer } = navigationState
return { t, state, navigationState, round, startPlayer }
},
data() {
return {
goalChip: undefined as number|undefined
}
},
computed: {
backButtonRouteTo() : string {
if (this.round > 1) {
return `/round/${this.round-1}/end`
}
return ''
},
isPlayerStartPlayer() : boolean {
return this.startPlayer == Player.PLAYER
}
},
methods: {
next() : void {
this.$router.push(`/round/${this.round}/turn/1/${this.startPlayer}`)
},
determineGoalChip() : void {
this.goalChip = rollDice(6)
}
}
})
</script>
Loading

0 comments on commit 20398ab

Please sign in to comment.