Last active
March 7, 2022 12:49
-
-
Save shubanker/afd98af53dab59e0966091ba42766004 to your computer and use it in GitHub Desktop.
wordleunlimited AutoSolver
This file contains 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
// ==UserScript== | |
// @name wordleunlimited autoMate | |
// @namespace https://www.wordleunlimited.com/ | |
// @version 0.4 | |
// @description Auto Solve Wordle Unlimited | |
// @author Shubanker Chourasia | |
// @match https://www.wordleunlimited.com/* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=wordleunlimited.com | |
// @grant none | |
// @require https://cdn.jsdelivr.net/gh/pieroxy/lz-string/libs/lz-string.min.js | |
// ==/UserScript== | |
const sleep = (ms = 500) => new Promise((resolve) => setTimeout(resolve, ms)); | |
class WordleSolver { | |
static wordsList = []; | |
static fetchWords = async () => { | |
const localJSON = localStorage.getItem("wordsList.min"); | |
if (localJSON) { | |
try { | |
WordleSolver.wordsList = LZString.decompressFromBase64(localJSON).split(','); | |
return; | |
} catch (error) {} | |
} | |
const response = await fetch("https://api.npoint.io/3338e6baccc78823690d"); | |
const words = await response.json(); | |
WordleSolver.wordsList = words; | |
localStorage.setItem("wordsList.min", LZString.compressToBase64(words.join(','))); | |
//clearing older storages: | |
['wordsList2','wordsList'].forEach(k=>localStorage.removeItem(k)); | |
}; | |
static initialised = false; | |
/** @type Record<string,HTMLElement> */ | |
static buttonMap = {}; | |
/** @type String[] */ | |
filteredList = []; | |
length = document.querySelector(".RowL").childNodes.length; | |
blackListChars = new Set(); | |
/** @type Map<string,Set<Number> */ | |
incorrectPositionsList = new Map(); | |
identifiedPositionsMap = new Map(); | |
identifiedIndexes = new Set(); | |
checkedWords = new Set(); | |
filledRowsCount = 0; | |
solveWordle = async () => { | |
await WordleSolver.initialise(); | |
this.filteredList = WordleSolver.wordsList; | |
this.nextStep(); | |
}; | |
processEnteredRows = (startIndex = this.filledRowsCount) => { | |
const filledRows = document.querySelectorAll(".RowL-locked-in"); | |
for (let i = startIndex; i < filledRows.length; i++) { | |
this.processesEnteredWordResults(filledRows[i].childNodes); | |
} | |
this.filterWordsList(); | |
this.filledRowsCount = filledRows.length; | |
}; | |
nextStep = async () => { | |
this.processEnteredRows(); | |
const word = | |
this.filteredList[Math.floor(Math.random() * this.filteredList.length)]; | |
WordleSolver.inputWord(word); | |
this.checkedWords.add(word); | |
await sleep(); | |
if ( | |
this.identifiedIndexes.size === this.length || | |
document.querySelectorAll(".RowL-locked-in").length > 5 || | |
this.filteredList.length === 0 | |
) { | |
return this.done(); | |
} | |
}; | |
static inputWord = (word, pressEnter = true) => { | |
if (word) { | |
for (let i = 0; i < word.length; i++) { | |
WordleSolver.buttonMap[word[i]].click(); | |
} | |
} | |
pressEnter && WordleSolver.buttonMap["enter"].click(); | |
}; | |
static async initialise() { | |
if (!WordleSolver.initialised) { | |
nextButton.disabled = true; | |
await WordleSolver.fetchWords(); | |
WordleSolver.initialised = true; | |
nextButton.disabled = false; | |
} | |
} | |
/** | |
* | |
* @param {NodeListOf<ChildNode>} enteredChars | |
*/ | |
processesEnteredWordResults(enteredChars) { | |
enteredChars.forEach((charNode, i) => { | |
const classes = [...charNode.classList]; | |
const char = charNode.innerText.toLowerCase(); | |
if (classes.includes("letter-elsewhere")) { | |
if (!this.incorrectPositionsList.has(char)) { | |
this.incorrectPositionsList.set(char, new Set()); | |
} | |
this.incorrectPositionsList.get(char).add(i); | |
} | |
if (classes.includes("letter-correct")) { | |
if (!this.identifiedPositionsMap.has(char)) { | |
this.identifiedPositionsMap.set(char, new Set()); | |
} | |
this.identifiedPositionsMap.get(char).add(i); | |
this.identifiedIndexes.add(i); | |
} | |
if (classes.includes("letter-absent")) { | |
this.blackListChars.add(char); | |
} | |
}); | |
// for repeting chars, 2nd char is marked as absent. | |
for (const char of [ | |
...this.incorrectPositionsList.keys(), | |
...this.identifiedPositionsMap.keys(), | |
]) { | |
this.blackListChars.delete(char); | |
} | |
} | |
filterWordsList() { | |
this.filteredList = this.filteredList.filter((word) => { | |
if (word.length !== this.length || this.checkedWords.has(word)) { | |
return false; | |
} | |
for (let i = 0; i < word.length; i++) { | |
const char = word[i]; | |
if (this.blackListChars.has(char)) { | |
return false; | |
} | |
if ( | |
this.identifiedIndexes.has(i) && | |
!this.identifiedPositionsMap.get(char)?.has(i) | |
) { | |
return false; | |
} | |
if ( | |
this.incorrectPositionsList.has(char) && | |
this.incorrectPositionsList.get(char)?.has(i) | |
) { | |
return false; | |
} | |
} | |
const charSet = new Set(word); | |
for (const char of this.incorrectPositionsList.keys()) { | |
if (!charSet.has(char)) { | |
return false; | |
} | |
} | |
return true; | |
}); | |
} | |
done() { | |
solveButton.hidden = false; | |
nextButton.hidden = true; | |
} | |
} | |
var solveButton = document.createElement("button"); | |
var nextButton = document.createElement("button"); | |
var revealAnswer = document.createElement("button"); | |
(function () { | |
"use strict"; | |
solveButton.innerHTML = "Auto Solve"; | |
nextButton.innerHTML = "Next Step"; | |
revealAnswer.innerHTML = "Reveal Answer"; | |
nextButton.hidden = true; | |
document.querySelector(".game-icons.right-icons").appendChild(solveButton); | |
document.querySelector(".game-icons.right-icons").appendChild(nextButton); | |
document.querySelector(".Game").appendChild(revealAnswer); | |
var currentSolverObj = null; | |
solveButton.addEventListener("click", () => { | |
currentSolverObj = new WordleSolver(); | |
nextButton.hidden = false; | |
solveButton.hidden = true; | |
currentSolverObj.solveWordle(); | |
}); | |
nextButton.addEventListener("click", () => { | |
currentSolverObj.nextStep(); | |
}); | |
revealAnswer.addEventListener("click", () => { | |
WordleSolver.inputWord( | |
atob(document.querySelector(".game-id").childNodes[1].textContent), | |
false | |
); | |
}); | |
document.querySelectorAll(".Game-keyboard-button").forEach((button) => { | |
WordleSolver.buttonMap[button.textContent.toLowerCase()] = button; | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment