-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpda_practice.js
More file actions
107 lines (88 loc) · 3.75 KB
/
Copy pathpda_practice.js
File metadata and controls
107 lines (88 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/**
* pda_practice.js
* Logic for generating PDA exercises and validating user answers.
*/
import { PDA_PRACTICE_BANK } from './pda_practice_bank.js';
import { MACHINE, setMachine, pushUndo } from './pda_state.js';
import { runPdaSimulation } from './pda_simulation.js';
import { addLogMessage, customAlert } from './utils.js';
import { animatePdaDrawing } from './pda_animation.js';
let currentPractice = null;
export function generatePractice(level = 'easy') {
const filtered = PDA_PRACTICE_BANK.filter(p => p.level === level);
const selected = filtered[Math.floor(Math.random() * filtered.length)];
currentPractice = selected;
const display = document.getElementById('practiceBox');
if (display) {
// Apply Content and the PDA indigo glow class
display.innerHTML = `
<div class="practice-card">
<h4>${selected.title}</h4>
<p>${selected.description}</p>
<small><strong>Goal:</strong> ${selected.instruction}</small>
</div>
`;
display.className = 'practice-pda-active';
}
addLogMessage(`New Practice Loaded: ${selected.title}`, 'zap');
}
/**
* pda_practice.js - Enhanced Validation
*/
export async function checkAnswer() {
if (!currentPractice) {
customAlert("No Practice", "Please generate a practice problem first.");
return;
}
addLogMessage("Comparing your PDA with the reference solution...", 'loader');
// Expanded test suite to cover Part 1 through Part 19
const testStrings = [
"", "a", "b", "c", "0", "1", "ab", "ba", "01", "10",
"aabb", "aaabbb", "abc", "aabbcc", "(( ))", "()", "()()",
"0011", "1100", "aba", "a#a", "aa#aa", "[[ ]]", "{[ ]}"
];
const alphabet = currentPractice.solution.alphabet;
let passed = true;
let failString = "";
for (const test of testStrings) {
// Only test strings that fit the specific problem's alphabet
const isValidInput = test.split('').every(char => alphabet.includes(char));
if (isValidInput) {
const userResult = runPdaSimulation(test, MACHINE);
const solResult = runPdaSimulation(test, currentPractice.solution);
if (userResult.success !== solResult.success) {
passed = false;
failString = test;
break;
}
}
}
if (passed) {
customAlert("Success!", `Machine validated for ${currentPractice.title}!`);
addLogMessage("Validation Complete: All internal test cases passed.", 'check-circle');
} else {
customAlert("Incorrect", `Failed on input: "${failString || 'ε'}"`);
addLogMessage(`Mismatch found on "${failString || 'ε'}"`, 'x-circle');
}
}
/**
* Loads the solution for the current practice problem onto the canvas.
*/
export async function showSolution() {
if (!currentPractice) {
customAlert("No Practice", "Please generate a practice problem first.");
return;
}
// Import the animator dynamically to avoid circular dependencies
const { animatePdaDrawing } = await import('./pda_animation.js');
// Save current state to undo stack before overwriting
pushUndo();
// Detailed Logs for the start of the process
addLogMessage(`Initializing solution for: <strong>${currentPractice.title}</strong>`, 'info');
// Start the animated construction
await animatePdaDrawing(currentPractice.solution);
// Final guidance logs
addLogMessage(`Alphabet: {${currentPractice.solution.alphabet.join(', ')}}`, 'list');
addLogMessage("Use the 'Testing' panel to run strings against this solution.", 'help-circle');
customAlert("Solution Loaded", "The reference PDA has been drawn on the canvas.");
}