Repository: brdgm/seti-solo-helper
Pull request #15: Prefill data gained from game board for telescope action
Author: login: stefanseifert
Created: 2025-05-12T20:52:27Z | Merged: 2025-05-12T21:03:31Z

- most likely the bot will actually gain 1 data per sector scanned
- it may scan the same sector multiple times, and in this case does not get a data for each scan


Diff:
diff --git a/src/util/getInitialBotGameBoardResources.ts b/src/util/getInitialBotGameBoardResources.ts
new file mode 100644
index 0000000..1307867
--- /dev/null
+++ b/src/util/getInitialBotGameBoardResources.ts
@@ -0,0 +1,25 @@
+import BotGameBoardResources from '@/services/BotGameBoardResources'
+import { CardAction } from '@/services/Card'
+import Action from '@/services/enum/Action'
+import TechType from '@/services/enum/TechType'
+
+/**
+ * Initialize resources the bot will gain from the game board for a given action.
+ * Those resources may be different in certain edge cases, so the values here only pre-populate the input
+ * fields and can be changed by the user.
+ * @param action The action the bot is taking.
+ * @param techType The tech type the bot is using.
+ * @returns The resources the bot will gain from the game board.
+ */
+export default function getInitialBotGameBoardResources(action: CardAction, techType?: TechType) : BotGameBoardResources {
+  if (action.action == Action.TELESCOPE) {
+    // most likely the bot will actually gain 1 data per sector scanned
+    // it may scan the same sector multiple times, and in this case does not get a data for each scan
+    let data = action.scanSector.length
+    if (techType === TechType.TELESCOPE) {
+      data += 1
+    }
+    return { data }
+  }
+  return {}
+}
diff --git a/src/views/RoundTurnBot.vue b/src/views/RoundTurnBot.vue
index 503d909..2d0110f 100644
--- a/src/views/RoundTurnBot.vue
+++ b/src/views/RoundTurnBot.vue
@@ -14,7 +14,7 @@
     <p v-if="isFirstPass" class="mt-2">
       <AppIcon name="rotate-solar-system" class="icon"/>
     </p>
-    <BotResources v-model="botGameBoardResources"/>
+    <BotResources v-model="botGameBoardResources" :key="JSON.stringify(botGameBoardResources)"/>
     <BotReachedMilestones :navigationState="navigationState" :botGameBoardResources="botGameBoardResources"/>
     <button class="btn btn-primary btn-lg mt-4 me-2" @click="next()">
       {{t('action.next')}}
@@ -25,7 +25,7 @@
     <BotAction :action="currentAction" :currentCard="botActions.currentCard" :navigationState="navigationState" :botGameBoardResources="botGameBoardResources"
         :key="JSON.stringify(state.alienDiscovery.species)" @ready="ready"/>
 
-    <BotResources v-if="showBotResources" v-model="botGameBoardResources"/>
+    <BotResources v-if="showBotResources" v-model="botGameBoardResources" :key="JSON.stringify(botGameBoardResources)"/>
     <BotReachedMilestones :navigationState="navigationState" :botGameBoardResources="botGameBoardResources"/>
 
     <button class="btn btn-success btn-lg mt-4 me-2" @click="executed()" v-if="actionReady">
@@ -76,6 +76,7 @@ import BotAction from '@/components/round/BotAction.vue'
 import ModalDialog from '@brdgm/brdgm-commons/src/components/structure/ModalDialog.vue'
 import showModal from '@brdgm/brdgm-commons/src/util/modal/showModal'
 import hasBotGameBoardResources from '@/util/hasBotGameBoardResources'
+import getInitialBotGameBoardResources from '@/util/getInitialBotGameBoardResources'
 
 export default defineComponent({
   name: 'RoundTurnBot',
@@ -180,6 +181,7 @@ export default defineComponent({
     ready(techType?: TechType) : void {
       this.actionReady = true
       this.actionTechType = techType
+      this.botGameBoardResources = getInitialBotGameBoardResources(this.currentAction, techType)
       this.navigationState.botActionResources.applyAction(this.currentAction, techType, this.botActions.currentCard?.alienSpecies)
     }
   },
diff --git a/tests/unit/util/getInitialBotGameBoardResources.spec.ts b/tests/unit/util/getInitialBotGameBoardResources.spec.ts
new file mode 100644
index 0000000..96d20a2
--- /dev/null
+++ b/tests/unit/util/getInitialBotGameBoardResources.spec.ts
@@ -0,0 +1,22 @@
+import { expect } from 'chai'
+import getInitialBotGameBoardResources from '@/util/getInitialBotGameBoardResources'
+import Action from '@/services/enum/Action'
+import ScanSector from '@/services/enum/ScanSector'
+import TechType from '@/services/enum/TechType'
+
+describe('util/getInitialBotGameBoardResources', () => {
+  it('telescope', () => {
+    const resources = getInitialBotGameBoardResources({action:Action.TELESCOPE, scanSector: [ScanSector.EARTH,ScanSector.CARD]})
+    expect(resources).to.eql({data: 2})
+  })
+
+  it('telescope-tech', () => {
+    const resources = getInitialBotGameBoardResources({action:Action.TELESCOPE, scanSector: [ScanSector.EARTH,ScanSector.CARD]}, TechType.TELESCOPE)
+    expect(resources).to.eql({data: 3})
+  })
+
+  it('other', () => {
+    const resources = getInitialBotGameBoardResources({action:Action.ANALYZE, victoryPoints: 1}, TechType.COMPUTER)
+    expect(resources).to.eql({})
+  })
+})


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR aims to prefill the bot’s game board resources for telescope actions based on the scanned sectors and tech type.  
- Adds unit tests for getInitialBotGameBoardResources  
- Updates RoundTurnBot.vue to force component re-render when botGameBoardResources change  
- Implements getInitialBotGameBoardResources to adjust data based on the action and optional tech type

### Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

| File | Description |
| ---- | ----------- |
| tests/unit/util/getInitialBotGameBoardResources.spec.ts | Added unit tests covering telescope actions and non-telescope actions |
| src/views/RoundTurnBot.vue | Updated BotResources component to use a key based on botGameBoardResources for re-rendering, and prefilled resources in the ready method |
| src/util/getInitialBotGameBoardResources.ts | New utility to initialize bot resources based on action and tech type |




state: COMMENTED
author_association: NONE
submitted_at: 2025-05-12T20:55:06Z

Review comments:
diff_hunk: @@ -14,7 +14,7 @@
     <p v-if="isFirstPass" class="mt-2">
       <AppIcon name="rotate-solar-system" class="icon"/>
     </p>
-    <BotResources v-model="botGameBoardResources"/>
+    <BotResources v-model="botGameBoardResources" :key="JSON.stringify(botGameBoardResources)"/>
path: src/views/RoundTurnBot.vue
user: login: Copilot
body: [nitpick] Consider using a computed property or a lightweight hash function for the key instead of JSON.stringify directly, to reduce potential performance overhead if botGameBoardResources grows in complexity.
created_at: 2025-05-12T20:55:05Z
author_association: NONE
diff_hunk: @@ -0,0 +1,27 @@
+import BotGameBoardResources from '@/services/BotGameBoardResources'
+import { CardAction } from '@/services/Card'
+import Action from '@/services/enum/Action'
+import TechType from '@/services/enum/TechType'
+
+/**
+ * Initialize resources the bot will gain from the game board for a given action.
+ * Those resources may be different in certain edge cases, so the values here only pre-populate the input
+ * fields and can be changed by the user.
+ * @param action The action the bot is taking.
+ * @param techType The tech type the bot is using.
+ * @returns The resources the bot will gain from the game board.
+ */
+export default function getInitialBotGameBoardResources(action: CardAction, techType?: TechType) : BotGameBoardResources {
+  switch (action.action) {
+    // most likely the bot will actually gain 1 data per sector scanned
+    // it may he scans the same sector multiple times, and in this case does not get a data for each scan
path: src/util/getInitialBotGameBoardResources.ts
user: login: Copilot
body: [nitpick] There appears to be a typo in the comment ('he scans'); consider rephrasing it to 'it may scan the same sector multiple times, and in that case, it does not gain additional data for each duplicate scan.'
```suggestion
    // it may scan the same sector multiple times, and in that case, it does not gain additional data for each duplicate scan
```
created_at: 2025-05-12T20:55:05Z
author_association: NONE

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-05-12T21:02:30Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=brdgm_seti-solo-helper&pullRequest=15) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 New issues](https://sonarcloud.io/project/issues?id=brdgm_seti-solo-helper&pullRequest=15&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=brdgm_seti-solo-helper&pullRequest=15&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=brdgm_seti-solo-helper&pullRequest=15&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [100.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=brdgm_seti-solo-helper&pullRequest=15&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=brdgm_seti-solo-helper&pullRequest=15&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=brdgm_seti-solo-helper&pullRequest=15)


author_association: NONE