Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fairy adaptation - Draft Request #229

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
47 changes: 47 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Adaptation of Liground for Fairy-Stockfish

### Todo

- [X] Stop being lazy+scared and do something
- [ ] Explore the Chessgroundx 8.3.0 to the point I am comfortable with it
- [ ] Adapt Chessgroundx 8.3.0 for all the possible boards (12 to 1 both files and ranks)
- [ ] Option 1: Caveman code, insert all manually
- [ ] Option 2: Besides the existing code on chessgroundx, add a potential calculator for board size and heights
- [ ] Option 3: Generator of boards in the constructor
- [ ] Option 4: Maybe just add a 12x12 board and fill the void squares with "bricks"
- [X] Merge the changes for the Chessgroundx 8.3.0 adaptation to the current code
- [ ] Figure out a better way of having Fairy-Stockfish only loading the local variants.ini file (Low priority) - and have the engine auto-load the variants
- [X] Reformulate the promotions to be based on legal moves available instead of the pre-programmed promotion tables (this will work nicely with Gating, and perhaps cause troubles to variants such as Kyoto)
- [ ] Have a piece "detector" everytime they're played, e.g. a variant with hidden pieces, the "detector" will add them to the database using the generic graphics, afterwards that piece will be available for customization (graphics)
- [ ] Piece Mapper and dynamic CSS for each variant - Once a new variant is added they will use the generic models (including xiangqi using chess pieces if that's the case, up to the user to gather the required piece)
- [ ] Consider whether or not the promoted piece svgs should be added to the pockets or not
- [ ] Dynamic pocket handler

### Afterwards - variants.ini Workshop
- [ ] Have all the available options from the variants.ini file (Possibly think of a way to dynamically get Fairy's options based on ffish.js or pyffish modifications)
- [ ] Size Validator (a simple operation Rank * File < 128)
- [ ] Check for mutually exclusive options
- [ ] Graphical Board picker (Shogi, Xiangqi, Janggi, Chess, Makruk)
- [ ] Board Tester (Perform a check variants.ini operation before the test)
- [ ] Piece Tester (Create a temp variants.ini file with just the piece on the board, and abuse ffish.js to generate it)
- [ ] Betza reader to Graphics using arrows (Very hard)
- [ ] Betza editor for each custom piece added, the betza editor's idea is to purely add movement based on arrows and pointers from chessground (Very hard and will be looked at the end)
- [ ] Common options for variants

### Ambitious Plans
- [ ] Ability to have a match against the computer (with premoves disabled)

### Graphics
- [X] Get SVGs for the whole alphabet in order to have generic pieces available (Merida only for now as generic)
- [X] Get SVGs for the promoted pieces (whole alphabet)
- [ ] Dig deeper into VUE's graphical abilities

### Technical
- [ ] Possible way to have ffish.js dynamically loaded instead of using the default one (in case of code testing)
- [ ] Look at ffish.js code and try to add PGN Support
- [ ] Definitely work on pyffish' Board support
- [ ] Look into the xboard display (e.g. xboard -> variant shogun displays all the details, pieces) Possibly implement that into ffish.js and pyffish

### Annoyances
- [ ] Figure out why variants with '-' do not work properly

67 changes: 56 additions & 11 deletions src/renderer/components/ChessGround.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="blue merida is2d">
<div class="grid-parent">
<div
v-if="variant==='crazyhouse'|| variant==='shogi' "
v-if="variant==='crazyhouse'|| variant==='shogi' || hasPockets "
ref="pockets"
class="pockets"
:class="{ mirror : $store.getters.orientation === &quot;black&quot;, shogi: variant === &quot;shogi&quot; }"
Expand Down Expand Up @@ -72,10 +72,12 @@ export default {
},
data () {
return {
ranks: ['1', '2', '3', '4', '5', '6', '7', '8'],
files: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'],
ranks: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'],
files: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'],
selectedPiece: null,
piecesToIdx: {
H: 6,
E: 5,
P: 4,
N: 3,
B: 2,
Expand All @@ -85,7 +87,9 @@ export default {
n: 1,
b: 2,
r: 3,
q: 4
q: 4,
e: 5,
h: 6
},
shogiPiecesToIdx: {
P: 6,
Expand Down Expand Up @@ -190,7 +194,7 @@ export default {
return undefined
}
},
...mapGetters(['initialized', 'variant', 'multipv', 'hoveredpv', 'redraw', 'pieceStyle', 'boardStyle', 'fen', 'lastFen', 'orientation', 'moves', 'isPast', 'dimensionNumber', 'analysisMode'])
...mapGetters(['initialized', 'variant', 'hasPockets', 'hasGating', 'multipv', 'hoveredpv', 'redraw', 'pieceStyle', 'boardStyle', 'fen', 'lastFen', 'orientation', 'moves', 'isPast', 'dimensionNumber', 'analysisMode'])
},
watch: {
initialized () {
Expand Down Expand Up @@ -269,8 +273,7 @@ export default {
if (this.variant === 'shogi') {
this.piecesW = this.shogiPiecesW
this.piecesB = this.shogiPiecesB
}
if (this.variant === 'crazyhouse') {
} else if ((this.variant === 'crazyhouse') || this.hasPockets) {
this.piecesW = this.chessPiecesW
this.piecesB = this.chessPiecesB
}
Expand Down Expand Up @@ -302,7 +305,7 @@ export default {

document.body.dispatchEvent(new Event('chessground.resize'))
}
if (this.variant === 'crazyhouse' || this.variant === 'shogi') {
if (this.variant === 'crazyhouse' || this.variant === 'shogi' || this.hasPockets) {
document.body.dispatchEvent(new Event('chessground.resize'))
}
this.board.set({
Expand Down Expand Up @@ -475,7 +478,36 @@ export default {
return false
},
setPromotionOptions (uciMove) {
this.promotions = [];
if (this.$store.getters.isInternational) {
const key = uciMove.substring(2, 4)
const type = this.board.state.pieces[key].role
let num = 0
let promo = false
for (let i = 0; i < this.legalMoves.length; i++) {
if (this.legalMoves[i].includes(uciMove)) {
num = num + 1
if (this.legalMoves[i].includes('+')) {
promo = true
}
}
}
if (num === 1 && promo) {
this.promotions = [ {type: type }, {type: 'p'+type} ]
}
else {
const key = uciMove.substring(2, 4)
const type = this.board.state.pieces[key].role
let num = 0
let promo = false
for (let i = 0; i < this.legalMoves.length; i++) {
if (this.legalMoves[i].includes(uciMove)) {
console.log("Legal moves: ", this.legalMoves[i])
this.promotions[num] = {type : this.legalMoves[i].substring(4,5)+'-piece'}
num = num + 1
}
}
/*
if (this.variant === 'antichess') {
this.promotions = [
{ type: 'k-piece' },
Expand All @@ -491,7 +523,8 @@ export default {
{ type: 'b-piece' },
{ type: 'n-piece' }
]
}
}*/
}
}
if (this.variant === 'shogi') {
const key = uciMove.substring(2, 4)
Expand Down Expand Up @@ -541,6 +574,7 @@ export default {
this.promotions = [this.promotions[1]]
}
}
console.log("Promotions: ", this.promotions)
},
resetPockets (pieces) {
for (let idx = 0; idx < pieces.length; idx++) {
Expand All @@ -549,7 +583,17 @@ export default {
},
afterDrag () {
return (role, key) => {
const pieces = { 'p-piece': 'P', 'n-piece': 'N', 'b-piece': 'B', 'r-piece': 'R', 'q-piece': 'Q', 's-piece': 'S', 'g-piece': 'G', 'l-piece': 'L' }
const pieces = {
'p-piece': 'P',
'n-piece': 'N',
'b-piece': 'B',
'r-piece': 'R',
'q-piece': 'Q',
's-piece': 'S',
'g-piece': 'G',
'h-piece': 'H',
'e-piece': 'E',
'l-piece': 'L' }
const move = pieces[role] + '@' + key
const prevMov = this.currentMove
if (this.$store.getters.legalMoves.includes(move)) {
Expand Down Expand Up @@ -675,7 +719,8 @@ export default {
},
orientation: this.orientation
})
if (this.variant === 'crazyhouse' || this.variant === 'shogi') {

if (this.variant === 'crazyhouse' || this.variant === 'shogi' || this.hasPockets) {
this.updateHand()
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/components/GameBoards.vue
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ export default {
const y = Math.floor(event.layerY / 40)
// var stringPos = y * 9 + x

const letters = { 0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h' }
const letters = { 0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l' }
let pieceCode = Vue.methds.pieceTypeToShort(this.selectedPockedPiece.boardA)
pieceCode = { type: pieceCode, color: this.turnColor.charAt(0) }
this.$store.dispatch('insertPieceAtPosition', ['boardA', pieceCode, letters[x] + (8 - y)])
Expand Down
24 changes: 24 additions & 0 deletions src/renderer/components/MenuBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,13 @@
>
<em class="icon mdi mdi-hammer-screwdriver" /> Settings
</div>
<div
class="item"
@click="addVariantsConfig"
>
<em class="icon mdi mdi-hammer" /> Custom Variants
</div>

<div
class="item"
@click="openExternalBrowser"
Expand Down Expand Up @@ -66,6 +73,23 @@ export default {
console.log(err)
})
},
addVariantsConfig () {
this.$electron.remote.dialog.showOpenDialog({
title: 'Open Variants.ini',
properties: ['openFile'],
filters: [
{ name: 'INI Files', extensions: ['ini'] },
{ name: 'All Files', extensions: ['*'] }
]
}).then(result => {
if (!result.canceled) {
localStorage.INIPath = result.filePaths[0]
this.$store.commit('refreshVariants', result.filePaths[0])
}
}).catch(err => {
console.log(err)
})
},
openPGNFromPath (path) {
const regex = /(?:\[.+ ".*"\]\r?\n)+\r?\n+(?:.+\r?\n)*/gm
let games = []
Expand Down
54 changes: 53 additions & 1 deletion src/renderer/components/PromotionModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,59 @@ export default {
},
data () {
return {
promDir: { 'q-piece': 'q', 'r-piece': 'r', 'b-piece': 'b', 'n-piece': 'n', 'p-piece': 'p', 'k-piece': 'k' },
promDir: {
'-piece': '',
'a-piece': 'a',
'b-piece': 'b',
'c-piece': 'c',
'd-piece': 'd',
'e-piece': 'e',
'f-piece': 'f',
'g-piece': 'g',
'h-piece': 'h',
'i-piece': 'i',
'j-piece': 'j',
'k-piece': 'k',
'l-piece': 'l',
'm-piece': 'm',
'n-piece': 'n',
'o-piece': 'o',
'p-piece': 'p',
'q-piece': 'q',
'r-piece': 'r',
's-piece': 's',
't-piece': 't',
'u-piece': 'u',
'v-piece': 'v',
'x-piece': 'x',
'y-piece': 'y',
'z-piece': 'z',
'pa-piece': '+',
'pb-piece': '+',
'pc-piece': '+',
'pd-piece': '+',
'pe-piece': '+',
'pf-piece': '+',
'pg-piece': '+',
'ph-piece': '+',
'pi-piece': '+',
'pj-piece': '+',
'pk-piece': '+',
'pl-piece': '+',
'pm-piece': '+',
'pn-piece': '+',
'po-piece': '+',
'pp-piece': '+',
'pq-piece': '+',
'pr-piece': '+',
'ps-piece': '+',
'pt-piece': '+',
'pu-piece': '+',
'pv-piece': '+',
'px-piece': '+',
'py-piece': '+',
'pz-piece': '+'
},
shogiPromDir: { 'p-piece': '=', 'l-piece': '=', 'n-piece': '=', 'b-piece': '=', 's-piece': '=', 'r-piece': '=', 'pp-piece': '+', 'pl-piece': '+', 'pn-piece': '+', 'pb-piece': '+', 'ps-piece': '+', 'pr-piece': '+' },
idtocss: {
0: 'one',
Expand Down
17 changes: 17 additions & 0 deletions src/renderer/components/SettingsTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@
>
Cancel
</a>
<a
class="btn blue"
@click="refresh"
> Refresh</a>
<EngineModal
v-if="modal.visible"
:title="modal.title"
Expand Down Expand Up @@ -155,6 +159,12 @@ export default {
this.resetSettings()
this.$store.commit('viewAnalysis', true)
},
refresh () {
this.refreshSettings()
},
refreshSettings () {
this.$store.dispatch('refreshVariants', this.selectedEngine)
},
updateSettings () {
const changed = {}
for (const [name, value] of Object.entries(this.settings)) {
Expand Down Expand Up @@ -313,4 +323,11 @@ input[type=number]::-webkit-inner-spin-button {
.btn.red:hover {
background-color: #8b1919;
}
.btn.blue {
color: white;
background-color: #1e46c9;
}
.btn.blue:hover {
background-color: #2a198b;
}
</style>
5 changes: 5 additions & 0 deletions src/renderer/engine/driver.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,11 @@ export default class EngineDriver {
await this.waitForReady()
}

async uci_only () {
// send "uci" to engine
this._write('uci')
}

/**
* Tell the engine to quit.
*/
Expand Down
Loading