Skip to content

Commit bfc2cd9

Browse files
authored
Merge pull request #295 from ml-research/display-opening-name
The name of the current opening that is being played is shown on screen (only works for normal chess and no other variants).
2 parents 9ccb284 + 4881fed commit bfc2cd9

6 files changed

Lines changed: 61462 additions & 1 deletion

File tree

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"license": "AGPL-3.0",
77
"main": "./dist/electron/main.js",
88
"scripts": {
9-
"build": "node scripts/build.js && electron-builder",
9+
"build:openings": "node tools/build-openings-json.mjs",
10+
"build": "npm run build:openings && node scripts/build.js && electron-builder",
1011
"build:dir": "node scripts/build.js && electron-builder --dir",
1112
"build:clean": "cross-env BUILD_TARGET=clean node scripts/build.js",
1213
"build:web": "cross-env BUILD_TARGET=web node scripts/build.js",

src/renderer/components/GameBoards.vue

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@
6464
:size="setFenSize()"
6565
@change="checkValidFEN"
6666
>
67+
<div
68+
v-if="opening"
69+
class="opening-label"
70+
>
71+
{{ opening.eco }} – {{ opening.name }}
72+
</div>
6773
</div>
6874
<div
6975
v-else
@@ -78,6 +84,12 @@
7884
:size="setFenSize()"
7985
@change="checkValidFEN"
8086
>
87+
<div
88+
v-if="opening"
89+
class="opening-label"
90+
>
91+
{{ opening.eco }} – {{ opening.name }}
92+
</div>
8193
</div>
8294
<div
8395
v-if="QuickTourIndex !== 5"
@@ -139,6 +151,7 @@ import PgnBrowser from './PgnBrowser.vue'
139151
import SettingsTab from './SettingsTab'
140152
import EvalPlotButton from './EvalPlotButton'
141153
import GameInfo from './GameInfo.vue'
154+
import { findBestOpeningForFen } from '../../shared/openingLookup'
142155
import { mapGetters } from 'vuex'
143156
144157
export default {
@@ -178,6 +191,12 @@ export default {
178191
fen () {
179192
return this.$store.getters.fen
180193
},
194+
opening () {
195+
if (!this.fen) return null
196+
// only makes sense for standard chess
197+
if (this.variant && this.variant !== 'chess') return null
198+
return this.findOpeningProgressive()
199+
},
181200
mainFirstMove () {
182201
return this.$store.getters.mainFirstMove
183202
},
@@ -347,6 +366,21 @@ export default {
347366
deselectPocketPieces () {
348367
this.$store.commit('selectPocketPiece', ['boardA', ''])
349368
},
369+
findOpeningProgressive () {
370+
let mov = this.currentMove
371+
// check current position
372+
const opening = findBestOpeningForFen(this.fen)
373+
if (opening) return opening
374+
375+
// if no exact match, backtrack
376+
while (mov && mov.prev) {
377+
mov = mov.prev
378+
const opening = findBestOpeningForFen(mov.fen)
379+
if (opening) return opening
380+
}
381+
382+
return null
383+
},
350384
getBoardPos (event) {
351385
if (event.explicitOriginalTarget.className === 'cg-board' && this.selectedPockedPiece.boardA !== '') {
352386
// get click field
@@ -618,4 +652,21 @@ input {
618652
border-radius: 8px;
619653
}
620654
655+
.opening-label {
656+
margin-top: 4px;
657+
font-size: 11pt;
658+
color: var(--main-text-color);
659+
opacity: 0.9;
660+
}
661+
662+
.opening-label-qt {
663+
margin-top: 4px;
664+
font-size: 11pt;
665+
color: var(--main-text-color);
666+
opacity: 0.9;
667+
border: 5px solid var(--quicktour-highlight);
668+
padding: 2px 4px;
669+
border-radius: 4px;
670+
}
671+
621672
</style>

src/shared/openingLookup.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import openingsData from './openings.json'
2+
3+
const byEpd = openingsData.byEpd || {}
4+
5+
// FEN -> EPD (nur die ersten 4 Felder der FEN)
6+
export function fenToEpd (fen) {
7+
const parts = fen.trim().split(/\s+/)
8+
return parts.slice(0, 4).join(' ')
9+
}
10+
11+
export function findOpeningsForFen (fen) {
12+
const epd = fenToEpd(fen)
13+
return byEpd[epd] || []
14+
}
15+
16+
export function findBestOpeningForFen (fen) {
17+
const candidates = findOpeningsForFen(fen)
18+
if (!candidates.length) return null
19+
return candidates.reduce((best, cur) =>
20+
cur.pgn.split(' ').length > best.pgn.split(' ').length ? cur : best
21+
)
22+
}

0 commit comments

Comments
 (0)