From 3f1daa77bd67cf4c494f0aabc85b91ebf58e1e65 Mon Sep 17 00:00:00 2001 From: Jose Luis Date: Fri, 20 Mar 2026 02:37:59 +0100 Subject: [PATCH] feat: custom scrollbar + expand puzzle levels from 8 to 20 - Custom dark-themed scrollbar (WebKit + Firefox) matching the cyberpunk UI - Added 12 new levels across new categories: - Combinational Logic: MUX, DEMUX, 3-input AND, Majority, Parity - Arithmetic: Half Subtractor, 1-bit Comparator - Decoders & Encoders: 2-to-4 Decoder, 4-to-2 Encoder, 7-Segment - Components: 1-bit ALU - Logic Basics: XNOR Gate Co-Authored-By: Claude Opus 4.6 --- css/style.css | 29 ++++++ js/levels.js | 240 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 249 insertions(+), 20 deletions(-) diff --git a/css/style.css b/css/style.css index d41d6b9..7745be8 100644 --- a/css/style.css +++ b/css/style.css @@ -1,5 +1,34 @@ * { margin: 0; padding: 0; box-sizing: border-box; } +/* ==================== Custom Scrollbar ==================== */ +::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +::-webkit-scrollbar-track { + background: transparent; +} + +::-webkit-scrollbar-thumb { + background: #2a2a3a; + border-radius: 3px; +} + +::-webkit-scrollbar-thumb:hover { + background: #00e59966; +} + +::-webkit-scrollbar-corner { + background: transparent; +} + +/* Firefox */ +* { + scrollbar-width: thin; + scrollbar-color: #2a2a3a transparent; +} + body { font-family: 'Segoe UI', system-ui, sans-serif; background: #0a0a0f; diff --git a/js/levels.js b/js/levels.js index 7ea1044..d9ef128 100644 --- a/js/levels.js +++ b/js/levels.js @@ -75,6 +75,111 @@ export const LEVELS = [ hints: ['XOR = (A NAND B) NAND (NOT(A NAND NOT B) NAND NOT(NOT A NAND B))', 'This requires 4-5 NAND gates.'], difficulty: 3 }, + { + id: 'xnor_gate', + category: 'Logic Basics', + title: 'XNOR Gate', + description: 'Build an XNOR gate. True when both inputs are equal.', + availableGates: ['INPUT', 'OUTPUT', 'NAND'], + testCases: [ + { inputs: { 0: 0, 1: 0 }, outputs: { 0: 1 } }, + { inputs: { 0: 0, 1: 1 }, outputs: { 0: 0 } }, + { inputs: { 0: 1, 1: 0 }, outputs: { 0: 0 } }, + { inputs: { 0: 1, 1: 1 }, outputs: { 0: 1 } } + ], + hints: ['XNOR is the inverse of XOR.', 'Build XOR first, then invert the output with another NAND-as-NOT.'], + difficulty: 3 + }, + // ============ Combinational Logic ============ + { + id: 'mux_2to1', + category: 'Combinational Logic', + title: '2:1 Multiplexer', + description: 'Build a MUX. When SEL=0, output A. When SEL=1, output B. Three inputs: A (0), B (1), SEL (2).', + availableGates: ['INPUT', 'OUTPUT', 'AND', 'OR', 'NOT'], + testCases: [ + { inputs: { 0: 0, 1: 0, 2: 0 }, outputs: { 0: 0 } }, // SEL=0 → A=0 + { inputs: { 0: 1, 1: 0, 2: 0 }, outputs: { 0: 1 } }, // SEL=0 → A=1 + { inputs: { 0: 0, 1: 1, 2: 0 }, outputs: { 0: 0 } }, // SEL=0 → A=0 + { inputs: { 0: 1, 1: 1, 2: 0 }, outputs: { 0: 1 } }, // SEL=0 → A=1 + { inputs: { 0: 0, 1: 0, 2: 1 }, outputs: { 0: 0 } }, // SEL=1 → B=0 + { inputs: { 0: 0, 1: 1, 2: 1 }, outputs: { 0: 1 } }, // SEL=1 → B=1 + { inputs: { 0: 1, 1: 0, 2: 1 }, outputs: { 0: 0 } }, // SEL=1 → B=0 + { inputs: { 0: 1, 1: 1, 2: 1 }, outputs: { 0: 1 } } // SEL=1 → B=1 + ], + hints: ['MUX = (A AND NOT SEL) OR (B AND SEL).', 'You need 1 NOT, 2 AND, and 1 OR gate.'], + difficulty: 2 + }, + { + id: 'demux_1to2', + category: 'Combinational Logic', + title: '1:2 Demultiplexer', + description: 'Route input to one of two outputs based on SEL. Inputs: DATA (0), SEL (1). Outputs: Q0, Q1.', + availableGates: ['INPUT', 'OUTPUT', 'AND', 'NOT'], + testCases: [ + { inputs: { 0: 0, 1: 0 }, outputs: { 0: 0, 1: 0 } }, // DATA=0, SEL=0 → Q0=0, Q1=0 + { inputs: { 0: 1, 1: 0 }, outputs: { 0: 1, 1: 0 } }, // DATA=1, SEL=0 → Q0=1, Q1=0 + { inputs: { 0: 0, 1: 1 }, outputs: { 0: 0, 1: 0 } }, // DATA=0, SEL=1 → Q0=0, Q1=0 + { inputs: { 0: 1, 1: 1 }, outputs: { 0: 0, 1: 1 } } // DATA=1, SEL=1 → Q0=0, Q1=1 + ], + hints: ['Q0 = DATA AND NOT SEL. Q1 = DATA AND SEL.', 'You need 1 NOT and 2 AND gates.'], + difficulty: 2 + }, + { + id: 'and3', + category: 'Combinational Logic', + title: '3-input AND', + description: 'Build a 3-input AND gate. Output is 1 only when all three inputs are 1.', + availableGates: ['INPUT', 'OUTPUT', 'AND'], + testCases: [ + { inputs: { 0: 0, 1: 0, 2: 0 }, outputs: { 0: 0 } }, + { inputs: { 0: 1, 1: 0, 2: 0 }, outputs: { 0: 0 } }, + { inputs: { 0: 1, 1: 1, 2: 0 }, outputs: { 0: 0 } }, + { inputs: { 0: 0, 1: 1, 2: 1 }, outputs: { 0: 0 } }, + { inputs: { 0: 1, 1: 1, 2: 1 }, outputs: { 0: 1 } } + ], + hints: ['Chain two AND gates: (A AND B) AND C.'], + difficulty: 1 + }, + { + id: 'majority', + category: 'Combinational Logic', + title: 'Majority Gate', + description: 'Output 1 if at least two of the three inputs are 1.', + availableGates: ['INPUT', 'OUTPUT', 'AND', 'OR'], + testCases: [ + { inputs: { 0: 0, 1: 0, 2: 0 }, outputs: { 0: 0 } }, + { inputs: { 0: 1, 1: 0, 2: 0 }, outputs: { 0: 0 } }, + { inputs: { 0: 0, 1: 1, 2: 0 }, outputs: { 0: 0 } }, + { inputs: { 0: 0, 1: 0, 2: 1 }, outputs: { 0: 0 } }, + { inputs: { 0: 1, 1: 1, 2: 0 }, outputs: { 0: 1 } }, + { inputs: { 0: 1, 1: 0, 2: 1 }, outputs: { 0: 1 } }, + { inputs: { 0: 0, 1: 1, 2: 1 }, outputs: { 0: 1 } }, + { inputs: { 0: 1, 1: 1, 2: 1 }, outputs: { 0: 1 } } + ], + hints: ['Majority = (A AND B) OR (A AND C) OR (B AND C).', 'You need 3 AND gates and 2 OR gates.'], + difficulty: 2 + }, + { + id: 'parity', + category: 'Combinational Logic', + title: 'Even Parity', + description: 'Output 1 if an even number of inputs are 1 (0 counts as even). Three inputs.', + availableGates: ['INPUT', 'OUTPUT', 'XOR', 'NOT'], + testCases: [ + { inputs: { 0: 0, 1: 0, 2: 0 }, outputs: { 0: 1 } }, // 0 ones = even + { inputs: { 0: 1, 1: 0, 2: 0 }, outputs: { 0: 0 } }, // 1 one = odd + { inputs: { 0: 0, 1: 1, 2: 0 }, outputs: { 0: 0 } }, + { inputs: { 0: 0, 1: 0, 2: 1 }, outputs: { 0: 0 } }, + { inputs: { 0: 1, 1: 1, 2: 0 }, outputs: { 0: 1 } }, // 2 ones = even + { inputs: { 0: 1, 1: 0, 2: 1 }, outputs: { 0: 1 } }, + { inputs: { 0: 0, 1: 1, 2: 1 }, outputs: { 0: 1 } }, + { inputs: { 0: 1, 1: 1, 2: 1 }, outputs: { 0: 0 } } // 3 ones = odd + ], + hints: ['XOR gives odd parity. Invert it for even parity.', 'Chain: NOT(A XOR B XOR C).'], + difficulty: 2 + }, + // ============ Arithmetic ============ { id: 'half_adder', category: 'Arithmetic', @@ -82,10 +187,10 @@ export const LEVELS = [ description: 'Build a half adder. Two outputs: Sum (A XOR B) and Carry (A AND B).', availableGates: ['INPUT', 'OUTPUT', 'NAND'], testCases: [ - { inputs: { 0: 0, 1: 0 }, outputs: { 0: 0, 1: 0 } }, // 0+0: sum=0, carry=0 - { inputs: { 0: 0, 1: 1 }, outputs: { 0: 1, 1: 0 } }, // 0+1: sum=1, carry=0 - { inputs: { 0: 1, 1: 0 }, outputs: { 0: 1, 1: 0 } }, // 1+0: sum=1, carry=0 - { inputs: { 0: 1, 1: 1 }, outputs: { 0: 0, 1: 1 } } // 1+1: sum=0, carry=1 + { inputs: { 0: 0, 1: 0 }, outputs: { 0: 0, 1: 0 } }, + { inputs: { 0: 0, 1: 1 }, outputs: { 0: 1, 1: 0 } }, + { inputs: { 0: 1, 1: 0 }, outputs: { 0: 1, 1: 0 } }, + { inputs: { 0: 1, 1: 1 }, outputs: { 0: 0, 1: 1 } } ], hints: ['Two independent functions: Sum=XOR, Carry=AND.', 'You need 2 OUTPUT gates.'], difficulty: 3 @@ -94,36 +199,131 @@ export const LEVELS = [ id: 'full_adder', category: 'Arithmetic', title: 'Full Adder', - description: 'Build a full adder with carry-in. Outputs: Sum (3-input XOR) and Carry.', + description: 'Build a full adder with carry-in. Outputs: Sum and Carry-out.', availableGates: ['INPUT', 'OUTPUT', 'NAND'], testCases: [ - { inputs: { 0: 0, 1: 0, 2: 0 }, outputs: { 0: 0, 1: 0 } }, // 0+0+0 - { inputs: { 0: 0, 1: 0, 2: 1 }, outputs: { 0: 1, 1: 0 } }, // 0+0+1 - { inputs: { 0: 0, 1: 1, 2: 0 }, outputs: { 0: 1, 1: 0 } }, // 0+1+0 - { inputs: { 0: 0, 1: 1, 2: 1 }, outputs: { 0: 0, 1: 1 } }, // 0+1+1 - { inputs: { 0: 1, 1: 0, 2: 0 }, outputs: { 0: 1, 1: 0 } }, // 1+0+0 - { inputs: { 0: 1, 1: 0, 2: 1 }, outputs: { 0: 0, 1: 1 } }, // 1+0+1 - { inputs: { 0: 1, 1: 1, 2: 0 }, outputs: { 0: 0, 1: 1 } }, // 1+1+0 - { inputs: { 0: 1, 1: 1, 2: 1 }, outputs: { 0: 1, 1: 1 } } // 1+1+1 + { inputs: { 0: 0, 1: 0, 2: 0 }, outputs: { 0: 0, 1: 0 } }, + { inputs: { 0: 0, 1: 0, 2: 1 }, outputs: { 0: 1, 1: 0 } }, + { inputs: { 0: 0, 1: 1, 2: 0 }, outputs: { 0: 1, 1: 0 } }, + { inputs: { 0: 0, 1: 1, 2: 1 }, outputs: { 0: 0, 1: 1 } }, + { inputs: { 0: 1, 1: 0, 2: 0 }, outputs: { 0: 1, 1: 0 } }, + { inputs: { 0: 1, 1: 0, 2: 1 }, outputs: { 0: 0, 1: 1 } }, + { inputs: { 0: 1, 1: 1, 2: 0 }, outputs: { 0: 0, 1: 1 } }, + { inputs: { 0: 1, 1: 1, 2: 1 }, outputs: { 0: 1, 1: 1 } } ], - hints: ['Reuse your half adder logic. A full adder = half adder + half adder + OR.'], + hints: ['A full adder = two half adders + OR for the carry.', 'Sum = A XOR B XOR Cin. Cout = (A AND B) OR (Cin AND (A XOR B)).'], difficulty: 4 }, + { + id: 'half_subtractor', + category: 'Arithmetic', + title: 'Half Subtractor', + description: 'Build A minus B. Outputs: Difference (A XOR B) and Borrow (NOT A AND B).', + availableGates: ['INPUT', 'OUTPUT', 'AND', 'XOR', 'NOT'], + testCases: [ + { inputs: { 0: 0, 1: 0 }, outputs: { 0: 0, 1: 0 } }, // 0-0: diff=0, borrow=0 + { inputs: { 0: 0, 1: 1 }, outputs: { 0: 1, 1: 1 } }, // 0-1: diff=1, borrow=1 + { inputs: { 0: 1, 1: 0 }, outputs: { 0: 1, 1: 0 } }, // 1-0: diff=1, borrow=0 + { inputs: { 0: 1, 1: 1 }, outputs: { 0: 0, 1: 0 } } // 1-1: diff=0, borrow=0 + ], + hints: ['Difference = A XOR B (same as addition!).', 'Borrow = (NOT A) AND B.'], + difficulty: 2 + }, + { + id: 'comparator', + category: 'Arithmetic', + title: '1-bit Comparator', + description: 'Compare A and B. Three outputs: A>B, A=B, A0: GT=1, EQ=0, LT=0 + { inputs: { 0: 1, 1: 1 }, outputs: { 0: 0, 1: 1, 2: 0 } } // 1=1: GT=0, EQ=1, LT=0 + ], + hints: ['A>B = A AND NOT B.', 'A=B = NOT(A XOR B) = XNOR.', 'A