From eab3d5ad598edbe670f1adc12ce53b51a7c1624c Mon Sep 17 00:00:00 2001 From: tjonesdev Date: Thu, 20 Nov 2025 18:56:50 -0600 Subject: [PATCH 01/10] feat(fen): add working fen input Branch: DEV-5-add-fen-input --- index.html | 2 +- src/client/App.vue | 95 +++++++++------------------- src/client/components/BaseButton.vue | 2 +- src/client/components/BaseInput.vue | 48 ++++++++++++++ src/client/components/FENInput.vue | 29 +++++++++ 5 files changed, 108 insertions(+), 68 deletions(-) create mode 100644 src/client/components/BaseInput.vue create mode 100644 src/client/components/FENInput.vue diff --git a/index.html b/index.html index 257b092..5150490 100644 --- a/index.html +++ b/index.html @@ -5,7 +5,7 @@ Rookie GUI -
+
diff --git a/src/client/App.vue b/src/client/App.vue index 99f4ea4..f2e515a 100644 --- a/src/client/App.vue +++ b/src/client/App.vue @@ -2,6 +2,7 @@ import {computed, onMounted, ref} from 'vue'; import {TheChessboard} from 'vue3-chessboard'; import BaseButton from '@/client/components/BaseButton.vue'; + import FENInput from '@/client/components/FENInput.vue'; import 'vue3-chessboard/style.css'; const port = ref(null); @@ -145,75 +146,21 @@ theme.value = await window.darkMode.toggle() ? 'dark' : 'light'; }; - let boardAPI; + const boardAPI = ref(); + const fen = ref(''); // Access the boardAPI in the onMounted hook onMounted(() => { - // Console.log(boardAPI?.getBoardPosition()); - // Console.log(boardAPI?.getFen()); + fen.value = boardAPI.value?.getFen(); }); const boardConfig = { coordinates: true, - // AutoCastle: true, - // ViewOnly: false, - // DisableContextMenu: false, - // AddPieceZIndex: false, - // BlockTouchScroll: false, - highlight: { - lastMove: true, - check: true, - }, - animation: { - enabled: true, - duration: 300, - }, - // LastMove: undefined, - // Movable: { - // Free: false, - // Color: 'white', - // ShowDests: true, - // Dests: possibleMovesWhite, - // // We need to specify movable.events.after as an empty function so that we always have something to patch - // // BoardApi.changeTurn onto. Other functions need to be specifed as undefined so that BoardApi.setConfig - // // can reset values back to undefined, eg. if the user calls BoardApi.setConfig({}, true). - // // - // // eslint-disable-next-line @typescript-eslint/no-empty-function - // Events: {after: () => {}, afterNewPiece: undefined}, - // RookCastle: true, - // }, - premovable: { - enabled: false, - showDests: false, - castle: false, - events: { - set: undefined, - unset: undefined, - }, - }, - predroppable: { - enabled: false, - events: { - set: undefined, - unset: undefined, - }, - }, draggable: { - enabled: false, - distance: 3, - autoDistance: false, - showGhost: false, - deleteOnDropOff: false, + enabled: true, }, selectable: { - enabled: false, - }, - events: { - change: undefined, - move: undefined, - dropNewPiece: undefined, - select: undefined, - insert: undefined, + enabled: true, }, drawable: { enabled: false, @@ -242,13 +189,20 @@ diff --git a/src/client/components/BaseButton.vue b/src/client/components/BaseButton.vue index 55964fe..392af6a 100644 --- a/src/client/components/BaseButton.vue +++ b/src/client/components/BaseButton.vue @@ -21,7 +21,7 @@ font-size: 1rem; font-weight: 600; border: 0; - border-radius: 4px; + border-radius: 6px; line-height: 1; cursor: pointer; background-color: var(--color-bg-brand); diff --git a/src/client/components/BaseInput.vue b/src/client/components/BaseInput.vue new file mode 100644 index 0000000..f963924 --- /dev/null +++ b/src/client/components/BaseInput.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/src/client/components/FENInput.vue b/src/client/components/FENInput.vue new file mode 100644 index 0000000..ad93703 --- /dev/null +++ b/src/client/components/FENInput.vue @@ -0,0 +1,29 @@ + + + -- GitLab From ed4d78dab6a82466070d4d9754de5d38f3b30065 Mon Sep 17 00:00:00 2001 From: tjonesdev Date: Thu, 20 Nov 2025 18:57:04 -0600 Subject: [PATCH 02/10] chore(readme): add info on gui features Branch: DEV-5-add-fen-input --- README.md | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 211bab6..846d63b 100644 --- a/README.md +++ b/README.md @@ -17,14 +17,14 @@ This project is the middleware that links the chess board arduino and the chess 1. Arduino B constantly reads from arduino A for the "state change" and "board state" flags and writes the data it receives serially. 1. GUI constantly reads from arduino B for the "state change" (used for both user and robot moves) and "board state" flags. Data comes serially and needs to be converted to array. 1. GUI writes back to arduino B with "acknowledge" flag (note to self: this flag might be unnecessary and end up not being used). -1. GUI converts the board state bytes to a move list (algerbraic notation, matthew needs to determine what this will look like exactly) and updates the visual board state to match. +1. GUI converts the board state bytes to a move list (algerbraic notation, matthew needs to determine what this will look like exactly) and updates the visual board state to match. 1. The GUI sends the move list to the engine (HTTP request?). 1. Engine reads the move list with the user's move from the GUI (HTTP request?) and updates it with the move the robot should make. Sends the updated move list back to the GUI (HTTP request?). -1. GUI fetches (HTTP request?) updated move list from engine. Converts the move list to array with "move"/"capture"/etc flags and starting and destination positions and writes the data serially. +1. GUI fetches (HTTP request?) updated move list from engine. Converts the move list to array with "move"/"capture"/etc flags and starting and destination positions and writes the data serially. 1. Arduino B constantly reading from GUI for new writes (with "move"/"capture"/etc flags). Picks up the write and converts the serial data to a byte array. Sends the data on to arduino A (Matthew handles this). 1. Arduino A communicates with the robot arm to physically move piece from starting position to destination position (+ perform "capture"/"castle"/"promotion" based on flags, if needed). Writes the updated board state bytes when complete. 1. Arduino B reads the new board state as bytes, writes it serially from byte array with "state change" and "board state" flags. -1. GUI reads the data from arduino B and writes back with "acknowledge" flag set. +1. GUI reads the data from arduino B and writes back with "acknowledge" flag set. 1. GUI updates the visual board state. Nothing needs to be passed on to the engine because the engine was the last to make a move. Waits for another write from the arduino. 1. Arduino A detects a user move with sensors, passes the data to Arduino B, and etc... @@ -34,8 +34,8 @@ This project is the middleware that links the chess board arduino and the chess - GUI needs to keep track of which move is made by who in local storage to determine which side is moving/capturing/etc. - GUI never sends "board state" or "state change" flags or board state bytes to arduino B, always the other way around. - GUI only actually keeps the data it reads from arduino B if the "state change" or "board state" flags are set. -- User can click button in GUI to ask arduino B for the current board state. - 1. This will cause the GUI to write data serially with the "ask" flag. +- User can click button in GUI to ask arduino B for the current board state. + 1. This will cause the GUI to write data serially with the "ask" flag. 1. Arduino B will read the "ask" flag from the GUI and write the board state bytes serially with the "board state" flag set (but NOT the "state change" flag). 1. The GUI will read the updated board state and update the visual board state (if needed). It will then write an "acknowledge" flag serially. - User can click button in GUI to end/reset the game state. @@ -44,7 +44,7 @@ This project is the middleware that links the chess board arduino and the chess 1. The user would be expected to manually move the pieces back to their original positions instead of the robot arm. - User can click button in GUI to pause game. 1. Would work same as ending the game but instead of resetting state, would just disable serial communication but maintain existing state in local storage. - 1. Start button would be changed to "resume" and would just reopen serial communication with existing state when clicked. + 1. Start button would be changed to "resume" and would just reopen serial communication with existing state when clicked. ## Data @@ -88,10 +88,22 @@ Arduino B sends this to GUI: `[start word, header, ...board state]` (total of 10 - GUI to engine: fastcgi?? GUI features to include: -- FEN box -- sidebar area for rating (or just the number) -- no click, drag, etc. - all moves should be handled programatically -- Start, reset, pause buttons. +- FEN box (manual fen NOT ALLOWED with custom engine/rookie) +- visual red light/green light indicating connection to arduino (and engine?) +- sidebar area for rating (like chess.com, not lichess -- wants the number to display as well as the visual) (note to self: white is pos num, black is neg num) +- button to export pgn (dont display the textbox like lichess does) +- move list sidebar (note to self: this info is what gets passed to engine, NOT pgn) +- some visual to display pieces that have been captured +- no click, drag, etc. - all moves should be handled programatically (can add toggle to enable/disable moveability) +- Start, reset, pause buttons for connection with arduino. +- buttons to differentiate reset, resign, and force rookie to resign (they will all functionally do the same thing -- cut arduino communication and reset the board -- but will be logged to db differently for indicating who won/lost). should have a confirm modal for these. +- Database to store all games with columns for who won/lost. +- user name option (for storing in database) +- history viewer (low priority) +- stockfish engine support with and without rookie (low priority) +- toggle for engines (stockfish or custom) and toggle for type (robot or gui) (low priority) +- no undo move options +- no time controls with robot (can optionally add when playing in gui but low priority) ## Local Development -- GitLab From 7ec37e11ed732a20e5e1893d30d288c7956e965a Mon Sep 17 00:00:00 2001 From: tjonesdev Date: Sun, 23 Nov 2025 16:30:24 -0600 Subject: [PATCH 03/10] chore(vite): add aliases Branch: DEV-5-add-fen-input --- vite.client.config.js | 7 +++++-- vite.ipc.config.js | 12 +++++++++--- vite.server.config.js | 12 +++++++++--- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/vite.client.config.js b/vite.client.config.js index 24f2b16..0a45672 100644 --- a/vite.client.config.js +++ b/vite.client.config.js @@ -2,10 +2,11 @@ import {fileURLToPath, URL} from 'node:url'; import {defineConfig} from 'vite'; import vue from '@vitejs/plugin-vue'; -export default defineConfig({ +const entryName = 'client'; +const config = defineConfig({ resolve: { alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)), + '@': fileURLToPath(new URL(`./src/${entryName}`, import.meta.url)), }, }, plugins: [vue()], @@ -17,3 +18,5 @@ export default defineConfig({ transformer: 'lightningcss', }, }); + +export default config; diff --git a/vite.ipc.config.js b/vite.ipc.config.js index 27d87bc..eb65a76 100644 --- a/vite.ipc.config.js +++ b/vite.ipc.config.js @@ -1,9 +1,13 @@ +import {fileURLToPath, URL} from 'node:url'; import {defineConfig} from 'vite'; const entryName = 'ipc'; - -// https://vitejs.dev/config -export default defineConfig({ +const config = defineConfig({ + resolve: { + alias: { + '@': fileURLToPath(new URL(`./src/${entryName}`, import.meta.url)), + }, + }, build: { rollupOptions: { output: { @@ -14,3 +18,5 @@ export default defineConfig({ }, }, }); + +export default config; diff --git a/vite.server.config.js b/vite.server.config.js index d448375..020698c 100644 --- a/vite.server.config.js +++ b/vite.server.config.js @@ -1,9 +1,13 @@ +import {fileURLToPath, URL} from 'node:url'; import {defineConfig} from 'vite'; const entryName = 'server'; - -// https://vitejs.dev/config -export default defineConfig({ +const config = defineConfig({ + resolve: { + alias: { + '@': fileURLToPath(new URL(`./src/${entryName}`, import.meta.url)), + }, + }, build: { lib: { formats: ['es'], @@ -12,3 +16,5 @@ export default defineConfig({ }, }, }); + +export default config; -- GitLab From ab2fff62675e2d3b9294d3e3235af598a66ecd43 Mon Sep 17 00:00:00 2001 From: tjonesdev Date: Sun, 23 Nov 2025 16:31:51 -0600 Subject: [PATCH 04/10] chore(eslint): tweak array and object rules Branch: DEV-5-add-fen-input --- eslint.config.js | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/eslint.config.js b/eslint.config.js index ad615cd..6d7fffd 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -244,7 +244,7 @@ const config = defineConfig([ 'error', { consistent: true, - multiline: false, + multiline: true, minItems: 4, }, ], @@ -333,8 +333,8 @@ const config = defineConfig([ 'error', { ObjectExpression: { - minProperties: 1, consistent: true, + minProperties: 1, }, ObjectPattern: { consistent: true, @@ -526,7 +526,7 @@ const config = defineConfig([ 'error', { consistent: true, - multiline: false, + multiline: true, minItems: 4, }, ], @@ -583,18 +583,23 @@ const config = defineConfig([ 'vue/object-curly-newline': [ 'error', { - ObjectExpression: 'always', + ObjectExpression: { + consistent: true, + minProperties: 1, + }, ObjectPattern: { - multiline: true, + consistent: true, minProperties: 4, + multiline: true, }, ImportDeclaration: { - multiline: true, + consistent: true, minProperties: 4, + multiline: true, }, ExportDeclaration: { - multiline: true, - minProperties: 4, + consistent: true, + minProperties: 1, }, }, ], @@ -634,13 +639,15 @@ const config = defineConfig([ */ ...{ 'jsdoc/check-indentation': [ - 'error', { + 'error', + { excludeTags: ['example'], }, ], 'jsdoc/check-line-alignment': ['error', 'always'], 'jsdoc/check-param-names': [ - 'error', { + 'error', + { disableMissingParamChecks: true, }, ], @@ -651,12 +658,14 @@ const config = defineConfig([ 'jsdoc/require-asterisk-prefix': 'error', 'jsdoc/require-description-complete-sentence': 'error', 'jsdoc/require-description': [ - 'error', { + 'error', + { exemptedBy: ['inheritdoc'], }, ], 'jsdoc/require-jsdoc': [ - 'error', { + 'error', + { checkGetters: false, checkSetters: false, enableFixer: false, @@ -667,15 +676,19 @@ const config = defineConfig([ FunctionExpression: true, MethodDefinition: true, }, + contexts: [':not(Property) > FunctionExpression'], }, ], 'jsdoc/sort-tags': [ - 'error', { + 'error', + { reportIntraTagGroupSpacing: false, }, ], 'jsdoc/tag-lines': [ - 'error', 'any', { + 'error', + 'any', + { applyToEndTag: false, startLines: 1, }, -- GitLab From 73e383cf6618ef8256ae20bf60da95f15aa56e41 Mon Sep 17 00:00:00 2001 From: tjonesdev Date: Sun, 23 Nov 2025 16:32:17 -0600 Subject: [PATCH 05/10] refactor(fonts): move files to src dir Branch: DEV-5-add-fen-input --- .../fonts/Montserrat-Italic-VariableFont_wght.woff2 | Bin .../assets/fonts/Montserrat-VariableFont_wght.woff2 | Bin 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{ => client}/assets/fonts/Montserrat-Italic-VariableFont_wght.woff2 (100%) rename src/{ => client}/assets/fonts/Montserrat-VariableFont_wght.woff2 (100%) diff --git a/src/assets/fonts/Montserrat-Italic-VariableFont_wght.woff2 b/src/client/assets/fonts/Montserrat-Italic-VariableFont_wght.woff2 similarity index 100% rename from src/assets/fonts/Montserrat-Italic-VariableFont_wght.woff2 rename to src/client/assets/fonts/Montserrat-Italic-VariableFont_wght.woff2 diff --git a/src/assets/fonts/Montserrat-VariableFont_wght.woff2 b/src/client/assets/fonts/Montserrat-VariableFont_wght.woff2 similarity index 100% rename from src/assets/fonts/Montserrat-VariableFont_wght.woff2 rename to src/client/assets/fonts/Montserrat-VariableFont_wght.woff2 -- GitLab From e6072c01c98fd33afb1039622108286231817193 Mon Sep 17 00:00:00 2001 From: tjonesdev Date: Sun, 23 Nov 2025 16:34:09 -0600 Subject: [PATCH 06/10] refactor(components): factor out input into multiple components, move to base dir Branch: DEV-5-add-fen-input --- src/client/components/BaseInput.vue | 48 ------------------- .../components/{ => base}/BaseButton.vue | 2 +- src/client/components/base/BaseInput.vue | 20 ++++++++ src/client/components/base/BaseInputGroup.vue | 18 +++++++ src/client/components/base/BaseLabel.vue | 15 ++++++ 5 files changed, 54 insertions(+), 49 deletions(-) delete mode 100644 src/client/components/BaseInput.vue rename src/client/components/{ => base}/BaseButton.vue (93%) create mode 100644 src/client/components/base/BaseInput.vue create mode 100644 src/client/components/base/BaseInputGroup.vue create mode 100644 src/client/components/base/BaseLabel.vue diff --git a/src/client/components/BaseInput.vue b/src/client/components/BaseInput.vue deleted file mode 100644 index f963924..0000000 --- a/src/client/components/BaseInput.vue +++ /dev/null @@ -1,48 +0,0 @@ - - - - - diff --git a/src/client/components/BaseButton.vue b/src/client/components/base/BaseButton.vue similarity index 93% rename from src/client/components/BaseButton.vue rename to src/client/components/base/BaseButton.vue index 392af6a..54a4694 100644 --- a/src/client/components/BaseButton.vue +++ b/src/client/components/base/BaseButton.vue @@ -3,7 +3,7 @@ diff --git a/src/client/components/base/BaseInput.vue b/src/client/components/base/BaseInput.vue new file mode 100644 index 0000000..08c2fdd --- /dev/null +++ b/src/client/components/base/BaseInput.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/src/client/components/base/BaseInputGroup.vue b/src/client/components/base/BaseInputGroup.vue new file mode 100644 index 0000000..a00aae1 --- /dev/null +++ b/src/client/components/base/BaseInputGroup.vue @@ -0,0 +1,18 @@ + + + + + diff --git a/src/client/components/base/BaseLabel.vue b/src/client/components/base/BaseLabel.vue new file mode 100644 index 0000000..d729cd7 --- /dev/null +++ b/src/client/components/base/BaseLabel.vue @@ -0,0 +1,15 @@ + + + + + -- GitLab From c09e0c5fa0e328deda767172c8cb8a4f70df01c1 Mon Sep 17 00:00:00 2001 From: tjonesdev Date: Sun, 23 Nov 2025 16:35:31 -0600 Subject: [PATCH 07/10] refactor(components): create playgame view and move some app logic to it Branch: DEV-5-add-fen-input --- src/client/App.vue | 59 ++---------------------- src/client/components/FENInput.vue | 29 ------------ src/client/components/views/PlayGame.vue | 59 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 84 deletions(-) delete mode 100644 src/client/components/FENInput.vue create mode 100644 src/client/components/views/PlayGame.vue diff --git a/src/client/App.vue b/src/client/App.vue index f2e515a..321689e 100644 --- a/src/client/App.vue +++ b/src/client/App.vue @@ -1,9 +1,7 @@