Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions ChromeExtensions/Masyu/manifest.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"manifest_version": 3,
"name": "Masyu Solver WASM",
"version": "1.0",
"description": "Solves Masyu puzzles on gridpuzzle.com using Python and WASM.",
"name": "Masyu Solver Z3",
"version": "3.0",
"description": "Solves Masyu puzzles on gridpuzzle.com using Vanilla JS and Z3 WASM.",
"permissions": [
"activeTab",
"scripting"
Expand All @@ -26,11 +26,16 @@
],
"web_accessible_resources": [
{
"resources": ["solver.py", "solver_logic.py"],
"resources": [
"z3-built.js",
"z3-built.wasm",
"z3-built.worker.js",
"solver.js"
],
"matches": ["<all_urls>"]
}
],
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval' https://cdn.jsdelivr.net; object-src 'self'"
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'"
}
}
72 changes: 31 additions & 41 deletions ChromeExtensions/Masyu/popup.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,46 @@

// Popup script
// Popup script for Masyu Z3 Solver
const statusDiv = document.getElementById('status');
const solveBtn = document.getElementById('solveBtn');

let pyodide = null;

async function initPyodide() {
if (pyodide) return;
statusDiv.textContent = "Loading Python...";
pyodide = await loadPyodide();
// Load local python files
const files = [
'solver_logic.py',
'solver.py'
];
// Initialize Z3 worker or load script
// Since z3-built.js puts Z3 on window, we can load it dynamically or via script tag.
// For extension, better to load explicitly.

async function loadScript(url) {
return new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = url;
script.onload = resolve;
script.onerror = reject;
document.head.appendChild(script);
});
}

for (const file of files) {
const response = await fetch(file);
const text = await response.text();
const filename = file.split('/').pop();
pyodide.FS.writeFile(filename, text);
async function initSolver() {
statusDiv.textContent = "Loading Z3...";
if (!window.Z3) {
await loadScript('z3-built.js');
}
if (!window.solveMasyu) {
await loadScript('solver.js');
}
statusDiv.textContent = "Python Ready.";
statusDiv.textContent = "Z3 Ready.";
}

solveBtn.addEventListener('click', async () => {
try {
statusDiv.textContent = "Initializing...";
await initPyodide();
await initSolver();

statusDiv.textContent = "Scraping Grid...";
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

chrome.tabs.sendMessage(tab.id, { action: "getGrid" }, async (response) => {
if (chrome.runtime.lastError) {
statusDiv.textContent = "Error: " + chrome.runtime.lastError.message;
return;
}
if (!response || !response.grid) {
statusDiv.textContent = "Error: No grid found.";
return;
Expand All @@ -41,34 +49,16 @@ solveBtn.addEventListener('click', async () => {
statusDiv.textContent = "Solving...";
const grid = response.grid;

// Run Python Solver
// Pass grid as list of lists
pyodide.globals.set("grid_data", grid);

const pythonCode = `
import solver
import js

solution = solver.solve_masyu(grid_data.to_py())
solution
`;

const solution = await pyodide.runPythonAsync(pythonCode);
// Call solver
const solution = await window.solveMasyu(grid);

if (!solution) {
statusDiv.textContent = "No solution found.";
statusDiv.textContent = "No Solution Found";
return;
}

const solObj = solution.toJs();
// Map comes as Map, convert to obj
const result = {
h: solObj.get('h'),
v: solObj.get('v')
};

statusDiv.textContent = "Applying...";
chrome.tabs.sendMessage(tab.id, { action: "applySolution", solution: result });
chrome.tabs.sendMessage(tab.id, { action: "applySolution", solution: solution });
statusDiv.textContent = "Done!";
});

Expand Down
Loading
Loading