feat: Add configurable win rules (K-in-a-row and no-moves detection)#11
Merged
Conversation
Add two new game rule configurations: 1. **Configurable Win Line Length (K-in-a-row)**: - Players can configure how many consecutive balls are needed to win - Smart default: N-in-a-row for N×N grid (maintains backward compatibility) - UI dropdown allows override from 3 to N - Example: 3-in-a-row on a 5×5 grid instead of requiring 5-in-a-row 2. **No Valid Moves = Loss**: - Player automatically loses if they have no legal moves available - Always enabled (no toggle) - Detects immobilization during movement phase - Shows distinct win message for immobilization victories Core Game Logic (web/js/game.js): - Add winLineLength parameter to constructor with validation (3 ≤ K ≤ N) - Implement sliding window algorithm via checkLineForKConsecutive() method - Refactor checkWinner() to use sliding window for K-in-a-row detection - Add hasValidMoves() method to detect player immobilization - Update getState() to expose winLineLength Game Flow Integration (web/js/main.js): - Read winLineLength config from UI dropdown in initGame() - Add no-moves check after each successful move in movement phase - Handle immobilization win condition for both PvP and PvAI modes UI Updates (web/index.html, web/js/ui.js): - Add Win Condition dropdown with dynamic options based on grid size - Implement showWinnerByImmobilization() for distinct win message - Update rules section to explain new victory conditions - Add JavaScript to dynamically populate dropdown when grid size changes AI Adaptation (web/js/ai.js): - Mirror game.js sliding window logic in checkWinnerFromState() - Refactor evaluateLine() to use sliding window for variable K evaluation - Add immediate win detection in getBestMovement() for optimization - Add no-moves detection to minimax() algorithm - Fix cloneGameState() to preserve winLineLength property Testing (tests/ai.test.js): - Fix "detects winning movement opportunity" test setup - Add Player 1 balls to create valid movement phase scenario - Ensure tests verify AI correctly detects K-in-a-row wins All 130 tests passing with new features fully integrated.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds two new configurable game rules to enhance gameplay flexibility:
Configurable Win Line Length (K-in-a-row)
No Valid Moves = Loss
Implementation Details
Core Game Logic (
web/js/game.js)winLineLengthparameter to constructor with validation (3 ≤ K ≤ N)checkLineForKConsecutive()methodcheckWinner()to use sliding window for K-in-a-row detectionhasValidMoves()method to detect player immobilizationgetState()to exposewinLineLengthGame Flow Integration (
web/js/main.js)initGame()UI Updates (
web/index.html,web/js/ui.js)showWinnerByImmobilization()for distinct win messageAI Adaptation (
web/js/ai.js)checkWinnerFromState()evaluateLine()to use sliding window for variable K evaluationgetBestMovement()for optimizationminimax()algorithmcloneGameState()to preservewinLineLengthpropertyTesting (
tests/ai.test.js)Test Results
All 130 tests passing:
Backward Compatibility
✅ Fully backward compatible: Default behavior (K=N) matches original game
Usage Example
Screenshots
N/A - UI changes are functional (dropdown menu additions)
Related Issues
Addresses user request for configurable win rules to support different game variants and skill levels.