Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 10, 2025

Transform OptiConnect from single-mode AI challenge to dual-mode game with VS AI and Two-Player options, replacing Fischer-style timers (5:00 + 5s increment) with cumulative countdown timers (2:00 total, no increment).

Timer System

  • Cumulative model: Timer counts down only during active turn, preserves remaining time when stopped
  • Visual thresholds: Warning at ≤30s (orange), critical at ≤10s (red pulse)
  • Removed increment system: No time added after moves
// Before: Fischer-style with increment
stopTimer()  addIncrement('player')  playerTime += 5

// After: Cumulative with preserved time
stopTimer() // Preserves remaining time at stoppage

Game Modes

  • VS AI: Human vs depth-9 Elite AI (existing behavior)
  • Two-Player: Local multiplayer with shared device
  • Mode selection panel shown before game start, hidden during play
  • Dynamic labels switch based on mode (YOU/AI ↔ PLAYER 1/PLAYER 2)

Worker Protocol

Added player2-move message type for Two-Player mode alongside existing human-move and computer-move:

// Two-Player mode flow
worker.postMessage({ messageType: 'player2-move', col: columnIndex });
// Handled by makePlayer2Move() in Connect-4.js

Messaging

Mode-specific message variants for appropriate context:

  • Win messages: p1-win (AI mode) vs p1-win-2player
  • Timeout messages: timeout-p1-ai ("You ran out of time") vs timeout-p1-2player ("Player 1 ran out of time")

UI Changes

Mode Selection Panel

Mode selection with visual icons (🤖 VS AI, 👥 2 Player), hover states, and selected styling. Timer panel visibility toggled based on game state.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • code.jquery.com
    • Triggering command: /usr/bin/curl curl -o jquery.min.js REDACTED (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

Overview

Transform OptiConnect into a highly challenging, engaging Connect-4 experience with:

  1. A single powerful Elite AI (no difficulty levels)
  2. Chess-style cumulative timers (2 minutes total per player)
  3. Two game modes: VS AI and Two-Player

Detailed Requirements

1. Remove Difficulty System

Files to modify: index.html, index.js, Connect-4.css

  • Remove the difficulty selection panel (radio buttons 1-5)
  • Remove all difficulty-related code from index.js
  • Replace with game mode selection (VS AI / Two Player)

2. Two Game Modes

Mode Selection UI:

┌──────────────────────┐
│    SELECT MODE       │
│  ┌──────┐ ┌───────┐  │
│  │  🤖  │ │  👥   │  │
│  │VS AI │ │2 PLAYER│ │
│  └──────┘ └───────┘  │
│                      │
│    [Start Game]      │
└──────────────────────┘

VS AI Mode:

  • Human (Player 1 - Red) vs Elite AI (Player 2 - Yellow)
  • AI uses deep search (depth 8-10) for ~80% win rate
  • Human always moves first

Two-Player Mode:

  • Player 1 (Red) vs Player 2 (Yellow)
  • Both players use the same device
  • Player 1 always moves first

3. Chess-Style Cumulative Timer System

IMPORTANT: This is a cumulative timer, NOT per-move reset

Setting Value
Total time per player 2 minutes (120 seconds)
Timer behavior Counts down during your turn, pauses during opponent's turn
Warning threshold 30 seconds remaining (red + pulse)
Critical threshold 10 seconds remaining (faster pulse)
On timeout Immediate loss

How it works:

  1. Game starts: Both players have 2:00
  2. Player 1's turn: Player 1's clock ticks down (e.g., 2:00 → 1:45)
  3. Player 1 makes move: Player 1's clock stops at 1:45
  4. Player 2's turn: Player 2's clock ticks down (e.g., 2:00 → 1:52)
  5. Player 2 makes move: Player 2's clock stops at 1:52
  6. Continue alternating until win/tie/timeout

Timer Display:

┌─────────────────────┐
│  ⏱️ PLAYER 1: 1:45  │  ← Highlighted when active
├─────────────────────┤
│  ⏱️ PLAYER 2: 1:52  │  ← Dimmed when inactive
└─────────────────────┘

In VS AI mode:

┌─────────────────────┐
│  ⏱️ YOU:  1:45      │
├─────────────────────┤
│  ⏱️ AI:   1:52      │
└─────────────────────┘

4. Implement Elite AI (Target: 80% Win Rate)

File to modify: Connect-4.js

The AI should be significantly stronger:

  • Fixed High Search Depth: Use depth 8-10 for the minimax search
  • Advanced Position Evaluation:
    • Center column control (pieces in center columns are more valuable)
    • Threat detection (3-in-a-row with open ends)
    • Blocking opponent threats
    • Potential winning lines available
  • Opening Book: Center column is statistically strongest for first move
  • Move Ordering: Prioritize center columns first for better alpha-beta pruning
  • Leverage existing optimizations: Use alpha-beta pruning and transposition tables from PR Implement AI optimizations: Alpha-Beta Pruning, Bitboards, and Transposition Table #1

5. Timer Implementation

File to modify: index.js

// Timer constants
const TOTAL_TIME = 120; // 2 minutes in seconds
const WARNING_TIME = 30; // Yellow/orange warning
const CRITICAL_TIME = 10; // Red critical warning

// Timer state
let player1Time = TOTAL_TIME;
let player2Time = TOTAL_TIME;
let timerInterval = null;
let activePlayer = null; // 1, 2, or null

function startTimer(player) {
    stopTimer();
    activePlayer = player;
    updateTimerDisplay();
    
    timerInterval = setInterval(() => {
        if (activePlayer === 1) {
            player1Time--;
            if (player1Time <= 0) {
                player1Time = 0;
                stopTimer();
                endGame('timeout-p1');
                return;
            }
        } else if (activePlayer === 2) {
            player2Time--;
            if (player2Time <= 0) {
                player2Time = 0;
                stopTimer();
                endGame('timeout-p2');
                return;
            }
        }
        updateTimerDisplay();
    }, 1000);
}

function stopTimer() {
    if (timerInterval) {
        clearInterval(timerInterval);
        timerInterval = null;
    }
}

function resetTimers() {
    stopTimer();
    player1Time = TOTAL_TIME;
    player2Time = TOTAL_TIME;
    activePlayer = null;
    updateTimerDisplay();
}

function formatTime(seconds) {
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins}:${secs.toString().padStart(2, '0')}`;
}

function updateTimerDisplay() {
    // Update Player 1 timer
    const $timer1 = $('.timer-p1');
    $timer1.find('.timer-value').text(formatTime(player1Time));
    $timer1.toggleClass('active', activePlayer === 1);
    $timer1.toggleClass('warning', player1Time <= WARNING_TIME && player1Time > CRITICAL_TIME);
    $timer1.toggleClass('critical', player1Time <= CRITICAL_TIME);
    
    // Update Player 2 timer
    const $timer2 = $('.timer-p2');
    $timer2.find('.timer-value').text(formatTime(player2Time));
    $timer2.toggleClass('a...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created as a result of the following prompt from Copilot chat.*
> ## Overview
> 
> Transform OptiConnect into a highly challenging, engaging Connect-4 experience with:
> 1. A single powerful Elite AI (no difficulty levels)
> 2. Chess-style cumulative timers (2 minutes total per player)
> 3. Two game modes: VS AI and Two-Player
> 
> ## Detailed Requirements
> 
> ### 1. Remove Difficulty System
> 
> **Files to modify:** `index.html`, `index.js`, `Connect-4.css`
> 
> - Remove the difficulty selection panel (radio buttons 1-5)
> - Remove all difficulty-related code from `index.js`
> - Replace with game mode selection (VS AI / Two Player)
> 
> ### 2. Two Game Modes
> 
> #### Mode Selection UI:
> ```
> ┌──────────────────────┐
> │    SELECT MODE       │
> │  ┌──────┐ ┌───────┐  │
> │  │  🤖  │ │  👥   │  │
> │  │VS AI │ │2 PLAYER│ │
> │  └──────┘ └───────┘  │
> │                      │
> │    [Start Game]      │
> └──────────────────────┘
> ```
> 
> #### VS AI Mode:
> - Human (Player 1 - Red) vs Elite AI (Player 2 - Yellow)
> - AI uses deep search (depth 8-10) for ~80% win rate
> - Human always moves first
> 
> #### Two-Player Mode:
> - Player 1 (Red) vs Player 2 (Yellow)
> - Both players use the same device
> - Player 1 always moves first
> 
> ### 3. Chess-Style Cumulative Timer System
> 
> **IMPORTANT: This is a cumulative timer, NOT per-move reset**
> 
> | Setting | Value |
> |---------|-------|
> | Total time per player | **2 minutes (120 seconds)** |
> | Timer behavior | **Counts down during your turn, pauses during opponent's turn** |
> | Warning threshold | **30 seconds remaining** (red + pulse) |
> | Critical threshold | **10 seconds remaining** (faster pulse) |
> | On timeout | **Immediate loss** |
> 
> #### How it works:
> 1. Game starts: Both players have 2:00
> 2. Player 1's turn: Player 1's clock ticks down (e.g., 2:00  1:45)
> 3. Player 1 makes move: Player 1's clock **stops** at 1:45
> 4. Player 2's turn: Player 2's clock ticks down (e.g., 2:00  1:52)
> 5. Player 2 makes move: Player 2's clock **stops** at 1:52
> 6. Continue alternating until win/tie/timeout
> 
> #### Timer Display:
> ```
> ┌─────────────────────┐
> │  ⏱️ PLAYER 1: 1:45  │  ← Highlighted when active
> ├─────────────────────┤
> │  ⏱️ PLAYER 2: 1:52  │  ← Dimmed when inactive
> └─────────────────────┘
> ```
> 
> In VS AI mode:
> ```
> ┌─────────────────────┐
> │  ⏱️ YOU:  1:45      │
> ├─────────────────────┤
> │  ⏱️ AI:   1:52      │
> └─────────────────────┘
> ```
> 
> ### 4. Implement Elite AI (Target: 80% Win Rate)
> 
> **File to modify:** `Connect-4.js`
> 
> The AI should be significantly stronger:
> 
> - **Fixed High Search Depth**: Use depth 8-10 for the minimax search
> - **Advanced Position Evaluation**: 
>   - Center column control (pieces in center columns are more valuable)
>   - Threat detection (3-in-a-row with open ends)
>   - Blocking opponent threats
>   - Potential winning lines available
> - **Opening Book**: Center column is statistically strongest for first move
> - **Move Ordering**: Prioritize center columns first for better alpha-beta pruning
> - **Leverage existing optimizations**: Use alpha-beta pruning and transposition tables from PR #1
> 
> ### 5. Timer Implementation
> 
> **File to modify:** `index.js`
> 
> ```javascript
> // Timer constants
> const TOTAL_TIME = 120; // 2 minutes in seconds
> const WARNING_TIME = 30; // Yellow/orange warning
> const CRITICAL_TIME = 10; // Red critical warning
> 
> // Timer state
> let player1Time = TOTAL_TIME;
> let player2Time = TOTAL_TIME;
> let timerInterval = null;
> let activePlayer = null; // 1, 2, or null
> 
> function startTimer(player) {
>     stopTimer();
>     activePlayer = player;
>     updateTimerDisplay();
>     
>     timerInterval = setInterval(() => {
>         if (activePlayer === 1) {
>             player1Time--;
>             if (player1Time <= 0) {
>                 player1Time = 0;
>                 stopTimer();
>                 endGame('timeout-p1');
>                 return;
>             }
>         } else if (activePlayer === 2) {
>             player2Time--;
>             if (player2Time <= 0) {
>                 player2Time = 0;
>                 stopTimer();
>                 endGame('timeout-p2');
>                 return;
>             }
>         }
>         updateTimerDisplay();
>     }, 1000);
> }
> 
> function stopTimer() {
>     if (timerInterval) {
>         clearInterval(timerInterval);
>         timerInterval = null;
>     }
> }
> 
> function resetTimers() {
>     stopTimer();
>     player1Time = TOTAL_TIME;
>     player2Time = TOTAL_TIME;
>     activePlayer = null;
>     updateTimerDisplay();
> }
> 
> function formatTime(seconds) {
>     const mins = Math.floor(seconds / 60);
>     const secs = seconds % 60;
>     return `${mins}:${secs.toString().padStart(2, '0')}`;
> }
> 
> function updateTimerDisplay() {
>     // Update Player 1 timer
>     const $timer1 = $('.timer-p1');
>     $timer1.find('.timer-value').text(formatTime(player1Time));
>     $timer1.toggleClass('active', activePlayer === 1);
>     $timer1.toggleClass('warning', player1Time <= WARNING_TIME && player1Time > CRITICAL_TIME);
>     $timer1.toggleClass('critical', player1Time <= CRITICAL_TIME);
>     
>     // Update Player 2 timer
>     const $timer2 = $('.timer-p2');
>     $timer2.find('.timer-value').text(formatTime(player2Time));
>     $timer2.toggleClass('active', activePlayer === 2);
>     $timer2.toggleClass('warning', player2Time <= WARNING_TIME && player2Time > CRITICAL_TIME);
>     $timer2.toggleClass('critical', player2Time <= CRITICAL_TIME);
> }
> ```
> 
> ### 6. Game Flow
> 
> #### Start Game:
> 1. Player selects mode (VS AI or Two Player)
> 2. Clicks "Start Game"
> 3. Board clears, both timers reset to 2:00
> 4. Player 1's timer starts, their turn begins
> 
> #### During Player's Turn:
> 1. Their timer counts down
> 2. They click a column to make a move
> 3. Their timer STOPS (preserves remaining time)
> 4. Check for win/tie
> 5. If game continues, opponent's timer starts
> 
> #### Game End Conditions:
> - **Win**: 4 in a row
> - **Tie**: Board full
> - **Timeout**: Player's timer reaches 0:00
> 
> ### 7. CSS Styling
> 
> **File to modify:** `Connect-4.css`
> 
> ```css
> /* Mode Selection */
> .mode-select {
>     display: flex;
>     gap: 10px;
>     margin-bottom: 15px;
> }
> 
> .mode-btn {
>     flex: 1;
>     padding: 15px 10px;
>     background-color: rgba(255, 255, 255, 0.1);
>     border: 2px solid #666;
>     border-radius: 8px;
>     color: #ccc;
>     cursor: pointer;
>     transition: all 0.3s ease;
>     text-align: center;
> }
> 
> .mode-btn:hover {
>     background-color: rgba(255, 255, 255, 0.2);
>     border-color: #999;
> }
> 
> .mode-btn.selected {
>     background-color: #593f6b;
>     border-color: #fff;
>     color: #fff;
> }
> 
> .mode-btn .icon {
>     font-size: 24px;
>     display: block;
>     margin-bottom: 5px;
> }
> 
> /* Timer Panel */
> .timer-panel {
>     display: flex;
>     flex-direction: column;
>     gap: 8px;
>     margin-bottom: 15px;
> }
> 
> .timer {
>     padding: 12px;
>     background-color: rgba(255, 255, 255, 0.1);
>     border-radius: 8px;
>     border: 2px solid transparent;
>     transition: all 0.3s ease;
>     display: flex;
>     justify-content: space-between;
>     align-items: center;
> }
> 
> .timer-label {
>     font-size: 14px;
>     color: #aaa;
> }
> 
> .timer-value {
>     font-size: 24px;
>     font-family: "Courier New", monospace;
>     color: #fff;
>     font-weight: bold;
> }
> 
> .timer.active {
>     border-color: #4CAF50;
>     box-shadow: 0 0 10px rgba(76, 175, 80, 0.4);
>     background-color: rgba(76, 175, 80, 0.15);
> }
> 
> .timer.active .timer-label {
>     color: #4CAF50;
> }
> 
> .timer.warning {
>     border-color: #ff9800;
>     background-color: rgba(255, 152, 0, 0.15);
> }
> 
> .timer.warning .timer-value {
>     color: #ff9800;
> }
> 
> .timer.critical {
>     border-color: #f44336;
>     background-color: rgba(244, 67, 54, 0.15);
>     animation: pulse-critical 0.5s infinite;
> }
> 
> .timer.critical .timer-value {
>     color: #f44336;
> }
> 
> @keyframes pulse-critical {
>     0%, 100% { opacity: 1; }
>     50% { opacity: 0.7; }
> }
> ```
> 
> ### 8. Updated HTML Structure
> 
> **File to modify:** `index.html`
> 
> ```html
> <div class="sidebar">
>     <h1>Connect-4</h1>
>     
>     <!-- Timer Panel (shown during game) -->
>     <div class="panel timer-panel" style="display: none;">
>         <div class="timer timer-p1">
>             <span class="timer-label">YOU</span>
>             <span class="timer-value">2:00</span>
>         </div>
>         <div class="timer timer-p2">
>             <span class="timer-label">AI</span>
>             <span class="timer-value">2:00</span>
>         </div>
>     </div>
>     
>     <!-- Game Setup Panel (shown before game) -->
>     <div class="panel setup">
>         <h2>Game Mode</h2>
>         <div class="mode-select">
>             <button class="mode-btn selected" data-mode="ai">
>                 <span class="icon">🤖</span>
>                 <span>VS AI</span>
>             </button>
>             <button class="mode-btn" data-mode="2player">
>                 <span class="icon">👥</span>
>                 <span>2 Player</span>
>             </button>
>         </div>
>         <div class="start">
>             <button>Start Game</button>
>         </div>
>     </div>
>     
>     <!-- Info Panel -->
>     <div class="panel info">
>         <h2></h2>
>         <div class="blurb"></div>
>         <div class="outlook"></div>
>     </div>
> </div>
> ```
> 
> ### 9. Updated Messages
> 
> | Situation | Message |
> |-----------|---------|
> | VS AI Start | *"Challenge the Elite AI. Can you be among the 20% who win?"* |
> | Two Player Start | *"Two minds, one board. May the best strategist win!"* |
> | Player 1 Turn | *"Your move. Clock is ticking..."* |
> | Player 2 Turn (2P mode) | *"Player 2's turn. Clock is ticking..."* |
> | AI Turn | *"AI is calculating..."* |
> | Player 1 Wins | *"🏆 Player 1 wins!"* or *"🏆 Incredible! You defeated the AI!"* |
> | Player 2 Wins | *"🏆 Player 2 wins!"* or *"The AI wins. Analyze and try again!"* |
> | Timeout P1 | *"⏱️ Time's up! Player 1 ran out of time."* |
> | Timeout P2 | *"⏱️ Time's up! Player 2 ran out of time."* |
> | Tie | *"It's a draw!"* |
> 
> ### 10. Update README.md
> 
> Update the documentation to reflect:
> - New single Elite AI (no difficulty levels)
> - Two game modes (VS AI, Two Player)
> - Chess-style cumulative timer system (2 min per player)
> - Updated gameplay mechanics
> - Mark "Algorithmic Optimization" as complete in roadmap
> 
> ## Testing Checklist
> 
> - [ ] Mode selection works (VS AI / Two Player)
> - [ ] Game starts with both timers at 2:00
> - [ ] Active player's timer counts down during their turn
> - [ ] Timer stops when move is made
> - [ ] Timer resumes for opponent
> - [ ] Timer displays correctly (mm:ss format)
> - [ ] Warning state at ≤30 seconds (orange)
> - [ ] Critical state at ≤10 seconds (red + pulse)
> - [ ] Timeout correctly ends game
> - [ ] VS AI mode: AI makes strong moves
> - [ ] Two Player mode: Both players can make moves
> - [ ] Win detection works for all directions
> - [ ] Tie detection works
> - [ ] All UI transitions are smooth
> - [ ] Timer pauses during chip drop animations
> - [ ] New game resets everything correctly

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

@vercel
Copy link

vercel bot commented Dec 10, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
opticonnect Ready Ready Preview Comment Dec 10, 2025 10:03pm

Co-authored-by: CodeKunalTomar <111980003+CodeKunalTomar@users.noreply.github.com>
Co-authored-by: CodeKunalTomar <111980003+CodeKunalTomar@users.noreply.github.com>
Copilot AI changed the title [WIP] Remove difficulty selection and add game mode options Add Two Game Modes and Cumulative Chess-Style Timers Dec 10, 2025
Copilot AI requested a review from CodeKunalTomar December 10, 2025 22:07
@CodeKunalTomar CodeKunalTomar marked this pull request as ready for review December 10, 2025 22:12
Copilot AI review requested due to automatic review settings December 10, 2025 22:12
@CodeKunalTomar CodeKunalTomar merged commit 46cd58c into main Dec 10, 2025
2 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request successfully transforms OptiConnect from a single-mode AI challenge into a dual-mode game with two distinct gameplay options. The implementation replaces the Fischer-style timer system (5:00 + 5s increment) with a cumulative countdown timer (2:00 total, no increment) that creates more intense time pressure.

Key Changes:

  • Added two game modes: VS AI (human vs Elite AI) and Two-Player (local multiplayer)
  • Replaced Fischer-style increment timers with cumulative countdown timers (2:00 per player, no increment)
  • Introduced mode-specific messaging and UI labels that adapt based on the selected game mode
  • Added visual timer states: normal, active (green glow), warning (orange ≤30s), and critical (red pulse ≤10s)

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
index.js Implements dual-mode game logic with cumulative timers, mode selection handlers, mode-specific messaging system, and Player 2 turn handling for Two-Player mode
index.html Adds mode selection UI with VS AI and Two-Player buttons, updates timer panel visibility logic, and adjusts initial timer display to 2:00
Connect-4.js Adds player2-move message handler and makePlayer2Move() function in worker to support Two-Player mode alongside existing human and computer move handling
Connect-4.css Adds mode selection button styling with hover/selected states, updates timer styling with warning/critical visual states, and implements pulse-critical animation
README.md Updates documentation to reflect two game modes, cumulative timer system, and removes references to difficulty selection

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

dropCursorChip(coords.row, function() {
if (isWin) {
endGame('p2-win', winningChips);
// In Two-Player mode, use two-player win message; in AI mode, use AI win message
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment mentions "Two-Player mode" but should use the actual mode value '2player' (without the dash) for consistency with how the mode is checked elsewhere in the code. The logic is correct but the comment could confuse future maintainers.

Suggested change
// In Two-Player mode, use two-player win message; in AI mode, use AI win message
// If gameMode is '2player', use two-player win message; otherwise, use AI win message

Copilot uses AI. Check for mistakes.
Comment on lines +156 to +162
// Update warning and critical states for Player 1
$player1Timer.removeClass('warning critical');
if (player1Time > 0 && player1Time <= CRITICAL_TIME) {
$player1Timer.addClass('critical');
} else if (player1Time > 0 && player1Time <= WARNING_TIME) {
$player1Timer.addClass('warning');
}
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The warning state condition checks player1Time > 0 && player1Time <= WARNING_TIME, but the critical state also checks player1Time > 0 && player1Time <= CRITICAL_TIME. Since CRITICAL_TIME (10) is less than WARNING_TIME (30), when time is at or below CRITICAL_TIME, both conditions could be true before removeClass is called. However, this is handled correctly by removing both classes first (line 157), then applying the appropriate one. The logic works as intended but could be clearer by using player1Time <= CRITICAL_TIME for critical and player1Time > CRITICAL_TIME && player1Time <= WARNING_TIME for warning to make the mutual exclusivity explicit.

Copilot uses AI. Check for mistakes.
Comment on lines +17 to 24
<div class = "timer timer-p1" id = "player-timer">
<div class = "timer-label">YOU</div>
<div class = "timer-value">5:00</div>
<div class = "timer-value">2:00</div>
</div>
<div class = "timer" id = "ai-timer">
<div class = "timer timer-p2" id = "ai-timer">
<div class = "timer-label">AI</div>
<div class = "timer-value">5:00</div>
<div class = "timer-value">2:00</div>
</div>
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The timer elements have both class-based selectors (timer-p1, timer-p2) and ID attributes (player-timer, ai-timer) from the old implementation. While the JavaScript correctly uses the class selectors, the IDs are now obsolete and should be removed to avoid confusion and maintain cleaner markup.

Copilot uses AI. Check for mistakes.
}

.mode-btn:focus {
outline: none;
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing outline on focus creates an accessibility issue for keyboard users who need visual indication of which element has focus. Consider using a custom focus style instead of removing it entirely.

Suggested change
outline: none;
outline: none;
box-shadow: 0 0 0 3px #fff, 0 0 8px 2px #593f6b;
border-color: #fff;

Copilot uses AI. Check for mistakes.
Comment on lines +371 to +407
function startPlayer2Turn() {
setBlurb('p2-turn-2player');
$('.click-columns div').addClass('hover');

// Start player 2 timer
startTimer(2);

// if mouse is already over a column, show cursor chip there
const col = $('.click-columns div:hover').index();
if(col !== -1) {
createCursorChip(2, col);
}

$('.click-columns')
.on('mouseenter', function() {
const col = $('.click-columns div:hover').index();
createCursorChip(2, col);
})
.on('mouseleave', function() {
destroyCursorChip();
});

$('.click-columns div')
.on('mouseenter', function() {
const col = $(this).index();
moveCursorChip(col);
})
.on('click', function() {
$('.click-columns, .click-columns div').off();

const col = $(this).index();
worker.postMessage({
messageType: 'player2-move',
col: col
});
});
}
Copy link

Copilot AI Dec 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The functions startHumanTurn and startPlayer2Turn have significant code duplication (lines 257-290 vs 373-406). The only differences are the player number (1 vs 2) passed to createCursorChip/startTimer and the message type sent to the worker. Consider refactoring into a single function that accepts player number and message type as parameters to reduce duplication and improve maintainability.

Copilot uses AI. Check for mistakes.
@CodeKunalTomar CodeKunalTomar deleted the copilot/remove-difficulty-system branch December 12, 2025 17:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants