Skip to content

Commit c0ddb07

Browse files
committed
Enhance board and drag functionality by exposing state getters and improving drop logic
- Added state getters for selectedSquare and possibleMoves in board.js for better access across modules. - Updated drag.js to improve drop handling by verifying piece selection and validating moves before execution. - Ensured drag state management is robust by checking for valid drop targets and maintaining original element visibility during drag operations.
1 parent cc2cd0a commit c0ddb07

3 files changed

Lines changed: 73 additions & 28 deletions

File tree

js/board.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,20 @@ function clearPossibleMoves() {
249249
possibleMoves = [];
250250
}
251251

252-
// Expose board functions globally for drag.js and other modules
252+
// Expose board functions and state globally for drag.js and other modules
253253
if (typeof window !== 'undefined') {
254254
window.clearSelectedSquare = clearSelectedSquare;
255255
window.clearPossibleMoves = clearPossibleMoves;
256256
window.setSelectedSquare = setSelectedSquare;
257257
window.setPossibleMoves = setPossibleMoves;
258258
window.updateBoardVisuals = updateBoardVisuals;
259+
// Expose state getters
260+
Object.defineProperty(window, 'selectedSquare', {
261+
get: function() { return selectedSquare; }
262+
});
263+
Object.defineProperty(window, 'possibleMoves', {
264+
get: function() { return possibleMoves; }
265+
});
259266
}
260267

261268
// Export for Node/Jest tests (CommonJS)

js/drag.js

Lines changed: 63 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -186,39 +186,76 @@ function handleDragMove(event) {
186186
function handleDragEnd(event) {
187187
if (!CONFIG.FEATURES.DRAG_AND_DROP || !dragState.isDragging) return;
188188

189-
// Get drop position
190-
const clientX = event.type === 'touchend' ? (event.changedTouches[0]?.clientX || dragState.currentPos.x) : event.clientX;
191-
const clientY = event.type === 'touchend' ? (event.changedTouches[0]?.clientY || dragState.currentPos.y) : event.clientY;
192-
193-
// Reset position and remove dragging class
194-
dragState.element.style.left = '';
195-
dragState.element.style.top = '';
196-
dragState.element.style.width = '';
197-
dragState.element.style.height = '';
198-
dragState.element.classList.remove('dragging');
199-
200-
// Only process drop if mouse actually moved (was a drag, not just a click)
201-
if (dragState.hasMoved) {
202-
// Find the square element under the drop position
189+
// Get drop position (use currentPos if event coordinates aren't available)
190+
const clientX = event.type === 'touchend'
191+
? (event.changedTouches[0]?.clientX || dragState.currentPos.x)
192+
: (event.clientX || dragState.currentPos.x);
193+
const clientY = event.type === 'touchend'
194+
? (event.changedTouches[0]?.clientY || dragState.currentPos.y)
195+
: (event.clientY || dragState.currentPos.y);
196+
197+
// Store drag state before resetting
198+
const wasDrag = dragState.hasMoved;
199+
const startSquare = dragState.startSquare;
200+
const dragElement = dragState.element;
201+
202+
// Temporarily hide the dragged piece to find the square underneath
203+
const originalDisplay = dragElement.style.display;
204+
dragElement.style.display = 'none';
205+
206+
// Find the square element under the drop position
207+
let targetSquare = null;
208+
if (wasDrag) {
203209
const elementsAtPoint = document.elementsFromPoint(clientX, clientY);
210+
// Find the first square element (the piece is hidden so it won't interfere)
211+
targetSquare = elementsAtPoint.find(el => el.classList.contains('square'));
212+
}
213+
214+
// Restore display and reset styles
215+
dragElement.style.display = originalDisplay;
216+
dragElement.style.left = '';
217+
dragElement.style.top = '';
218+
dragElement.style.width = '';
219+
dragElement.style.height = '';
220+
dragElement.classList.remove('dragging');
221+
222+
// Process drop if it was a drag (not just a click)
223+
if (wasDrag && targetSquare) {
224+
const endRow = parseInt(targetSquare.dataset.row, 10);
225+
const endCol = parseInt(targetSquare.dataset.col, 10);
204226

205-
// Find the first square element in the elements at point
206-
const targetSquare = elementsAtPoint.find(el => el.classList.contains('square'));
227+
debugLog('Dropped at square', endRow, endCol);
207228

208-
if (targetSquare) {
209-
const endRow = parseInt(targetSquare.dataset.row, 10);
210-
const endCol = parseInt(targetSquare.dataset.col, 10);
229+
// Check if the drop square is a valid move (piece is already selected from drag start)
230+
if (typeof window.selectedSquare !== 'undefined' &&
231+
typeof window.possibleMoves !== 'undefined' &&
232+
typeof window.makeMove === 'function') {
211233

212-
debugLog('Dropped at square', endRow, endCol);
234+
// Verify the piece is still selected and this is a valid move
235+
const isPossible = window.possibleMoves.some(pm => pm.row === endRow && pm.col === endCol);
213236

214-
// Select the piece first, then make the move
215-
if (typeof window.handleBoardClick === 'function') {
216-
// Select the starting square
217-
window.handleBoardClick(dragState.startSquare.row, dragState.startSquare.col);
218-
// Make the move to the destination
219-
window.handleBoardClick(endRow, endCol);
237+
if (isPossible && window.selectedSquare &&
238+
window.selectedSquare.row === startSquare.row &&
239+
window.selectedSquare.col === startSquare.col) {
240+
// Make the move directly
241+
window.makeMove(
242+
startSquare.row,
243+
startSquare.col,
244+
endRow,
245+
endCol
246+
);
247+
} else {
248+
debugLog('Invalid drop: not a possible move or selection changed', {
249+
isPossible,
250+
selectedSquare: window.selectedSquare,
251+
startSquare: startSquare,
252+
possibleMoves: window.possibleMoves
253+
});
220254
}
221255
} else {
256+
debugLog('Required functions not available for drop');
257+
}
258+
} else if (wasDrag && !targetSquare) {
222259
// Dropped outside board - ensure no selection
223260
if (typeof window.clearSelectedSquare === 'function') {
224261
window.clearSelectedSquare();

js/game.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,8 @@ if (typeof window !== 'undefined') {
910910
window.handleBoardClick = handleBoardClick;
911911
window.generateLegalMovesForPiece = generateLegalMovesForPiece;
912912
window.findKingInCheck = findKingInCheck;
913-
// Expose state getters
913+
window.makeMove = makeMove;
914+
// Expose state getters (selectedSquare and possibleMoves are in board.js)
914915
Object.defineProperty(window, 'boardState', {
915916
get: function() { return boardState; }
916917
});

0 commit comments

Comments
 (0)