├── LICENSE ├── README.md ├── instructions ├── instructionsA.png ├── instructionsB.png ├── instructionsC.png └── instructionsD.png ├── main.js ├── package.json ├── token.json ├── wordlist_0.txt └── wordlist_1.txt /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 carykh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WordleEdit 2 | WordleEdit is a multiplayer version of Wordle (created by Josh Wardle) where players can edit their own words as they go. It runs as a Discord bot! I programmed the bot in February 2022 and played it with friends in March 2022, but for some reason I never released the source code until now. Well, here it is! 3 | 4 | ![](https://github.com/carykh/WordleEdit/blob/main/instructions/instructionsA.png) 5 | 6 | ![](https://github.com/carykh/WordleEdit/blob/main/instructions/instructionsB.png) 7 | 8 | ![](https://github.com/carykh/WordleEdit/blob/main/instructions/instructionsC.png) 9 | 10 | ![](https://github.com/carykh/WordleEdit/blob/main/instructions/instructionsD.png) 11 | -------------------------------------------------------------------------------- /instructions/instructionsA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/carykh/WordleEdit/47b3bc2a7493b71331787f57d9482dee11548069/instructions/instructionsA.png -------------------------------------------------------------------------------- /instructions/instructionsB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/carykh/WordleEdit/47b3bc2a7493b71331787f57d9482dee11548069/instructions/instructionsB.png -------------------------------------------------------------------------------- /instructions/instructionsC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/carykh/WordleEdit/47b3bc2a7493b71331787f57d9482dee11548069/instructions/instructionsC.png -------------------------------------------------------------------------------- /instructions/instructionsD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/carykh/WordleEdit/47b3bc2a7493b71331787f57d9482dee11548069/instructions/instructionsD.png -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | const { Client, Intents } = require('discord.js'); 2 | const prefix = '!'; 3 | var pingCount = 0; 4 | var MILLI = 1000; 5 | var ZERO = 48; // char code of '0'. 6 | var CHAR_CODE_A = 97; // char code of 'a'. 7 | var frillPiece = ":blue_heart: :purple_heart: :orange_heart: "; 8 | var frill = frillPiece+frillPiece; 9 | var skullPiece = ":skull: "; 10 | var skulls = skullPiece+skullPiece+skullPiece; 11 | var thought = ":thought_balloon: "; 12 | 13 | const client = new Client({ 14 | intents: [ 15 | Intents.FLAGS.DIRECT_MESSAGE_REACTIONS, 16 | Intents.FLAGS.DIRECT_MESSAGES, 17 | Intents.FLAGS.DIRECT_MESSAGE_TYPING, 18 | Intents.FLAGS.GUILDS, 19 | Intents.FLAGS.GUILD_MESSAGES 20 | ], 21 | 22 | partials: [ 23 | 'CHANNEL', // Required to receive DMs 24 | ] 25 | }); 26 | 27 | var fs = require("fs"); 28 | 29 | var wordListFile = fs.readFileSync("./wordlist_1.txt", 'utf-8'); 30 | var wordList = wordListFile.split("\r\n"); 31 | 32 | var wordListEasyFile = fs.readFileSync("./wordlist_0.txt", 'utf-8'); 33 | var wordListEasy = wordListEasyFile.split("\r\n"); 34 | 35 | var intervalFunc = null; 36 | 37 | var game = newClearGame("", new Array(0)); 38 | 39 | client.once('ready',() => { 40 | console.log(`WordleEdit bot is online as ${client.user.tag}!`); 41 | client.user.setActivity('!create, !join', { type: 'WATCHING' }); 42 | }); 43 | 44 | client.on("messageCreate", (message) => { 45 | if (message.author.bot) { 46 | return; 47 | } else if (message.channel.type == "DM") { 48 | var player_index = getPlayerIndex(message.author); 49 | if (player_index < 0) { 50 | message.author.send("Sorry, you aren't in a current WordleEdit game. Join the game using \"`!join`\" or \"`!create`\" a new game."); 51 | } else { 52 | if (game["stage"] == 2) { 53 | var wc = game["word_count"]; 54 | if (game["words"][player_index].length == wc) { 55 | message.author.send("You have already written enough words for this game ("+wc+")."); 56 | } else { 57 | processWritingSubmission(game, player_index, message.content); 58 | if (hasEveryoneFinishedWriting(game)) { 59 | startGuessingStage(game); 60 | } 61 | } 62 | } else if (game["stage"] == 3) { 63 | if (message.content.length >= 10 && message.content.includes(' ')) { // The player initiated an "Edit"! 64 | processEditingSubmission(game, player_index, message.content); 65 | } else { 66 | var gc = game["guesses"][player_index].length; 67 | if (gc == game["round_count"]) { 68 | message.author.send("You've already submitted a guess for this turn! Wait for the turn to finish."); 69 | } else { 70 | processGuessingSubmission(game, player_index, message.content); 71 | if (hasEveryoneFinishedGuessing(game)) { 72 | finishGuessingTurn(game); 73 | } 74 | } 75 | } 76 | } 77 | } 78 | return; 79 | } else if (!message.content.startsWith(prefix)) { 80 | return; 81 | } 82 | 83 | const args = message.content.slice(prefix.length).split(" "); 84 | const command = args.shift().toLowerCase(); 85 | if (command === 'ping') { 86 | pingCount++; 87 | message.channel.send("PONG!!! "+pingCount+' pings have been said since I last started up.'); 88 | } else if (command === 'getreply') { 89 | message.author.send("Here is your reply"); 90 | } else if (game["stage"] >= 1) { 91 | if (message.channel == game["channel"]) { 92 | handleGameMessage(message); 93 | } else { 94 | message.channel.send("There's a WordleEdit game going on in a different channel right now. Please wait for that to finish first."); 95 | } 96 | } else if (command == 'create') { 97 | game = newClearGame(message.channel, args); 98 | game["stage"] = 1 99 | message.channel.send(announceStringOf(game,1)); 100 | } 101 | }); 102 | 103 | function processWritingSubmission(game, player_index, receivedMessage) { 104 | var response = parseSubmittedWord(game, player_index, receivedMessage, game["allow_hard_words"]); 105 | var word = response[0]; 106 | var alert_ = response[1]; 107 | if (word.length == 5) { // The player submitted a successful word. 108 | game["words"][player_index].push(word); 109 | } 110 | game["player_list"][player_index].send(alert_); 111 | } 112 | 113 | function processGuessingSubmission(game, player_index, receivedMessage) { 114 | var response = parseSubmittedWord(game, player_index, receivedMessage, true); 115 | var word = response[0]; 116 | var _alert = response[1]; 117 | 118 | if (word.length == 5) { // The player submitted a successful word. 119 | game["guesses"][player_index].push(word); 120 | if (!hasEveryoneFinishedGuessing(game)) { 121 | game["player_list"][player_index].send(_alert).then(message => { 122 | game["waiting_messages_to_delete"].push(message); 123 | }); 124 | } 125 | } else { 126 | game["player_list"][player_index].send(_alert); 127 | } 128 | } 129 | 130 | function processEditingSubmission(game, player_index, receivedMessage) { 131 | var parts = receivedMessage.split(" "); 132 | var nextI = (player_index+1)%game["player_list"].length; 133 | var wordOn = game["word_on"][nextI]; 134 | var origWord = game["words"][player_index][wordOn]; 135 | if (parts[0].toLowerCase() != origWord) { 136 | game["player_list"][player_index].send("If you're trying to initiate an edit, the first word must be the word your opponent is trying to guess. Right now, that's "+formatWord(origWord,true,false)+"."); 137 | return; 138 | } 139 | 140 | var response = parseSubmittedWord(game, player_index, parts[1], game["allow_hard_words"]); 141 | var newWord = response[0]; 142 | var _alert = response[1]; 143 | if(newWord == origWord){ 144 | game["player_list"][player_index].send("Edit at least one letter of the word."); 145 | return; 146 | } 147 | if (newWord.length == 5) { // The player submitted a successful word to edit into. 148 | var editCost = getEditCost(origWord,newWord); 149 | 150 | if (editCost > game["edits"][player_index]) { // you don't have enough money for that. 151 | game["player_list"][player_index].send("TOO POOR. You only have "+pluralize(game["edits"][player_index],"edit")+" in the bank, but editing your "+rankify(wordOn)+" word from "+formatWord(origWord, true, false)+" to "+formatWord(newWord, true, false)+" would cost you "+pluralize(editCost,"edit")+"."); 152 | } else { 153 | game["words"][player_index][wordOn] = newWord; 154 | game["most_recent_edit"][player_index] = game["round_count"]; 155 | game["edits"][player_index] -= editCost; 156 | 157 | var appendix = ""; 158 | if (game["guesses"][player_index].length < game["round_count"]) { 159 | appendix = "\nDon't forget to write a guess for YOUR word, though!"; 160 | } 161 | game["player_list"][player_index].send("SUCCESS! Your "+rankify(wordOn)+" word was successfully edited from "+formatWord(origWord, true, false)+" to "+formatWord(newWord, true, false)+"! That cost you "+pluralize(editCost,"edit")+", leaving you with "+pluralize(game["edits"][player_index],"edit")+" left."+appendix); 162 | } 163 | } else { 164 | game["player_list"][player_index].send(_alert); 165 | } 166 | } 167 | 168 | function getEditCost(a, b) { 169 | var count = 0; 170 | for (var i = 0; i < 5; i++) { 171 | if (a.charAt(i) != b.charAt(i)) { 172 | count += 1; 173 | } 174 | } 175 | return count; 176 | } 177 | 178 | function pluralize(n, stri) { 179 | if (n == 1) { 180 | return n+" "+stri; 181 | } else { 182 | return n+" "+stri+"s"; 183 | } 184 | } 185 | 186 | function hasEveryoneFinishedWriting(game) { 187 | var LEN = game["player_list"].length; 188 | for (var i = 0; i < LEN; i++) { 189 | if (game["words"][i].length < game["word_count"]) { 190 | return false; 191 | } 192 | } 193 | return true; 194 | } 195 | function hasEveryoneFinishedGuessing(game) { 196 | var LEN = game["player_list"].length; 197 | for (var i = 0; i < LEN; i++) { 198 | if (game["guesses"][i].length < game["round_count"]) { 199 | return false; 200 | } 201 | } 202 | return true; 203 | } 204 | 205 | 206 | function getPlayerIndex(author) { 207 | var LEN = game["player_list"].length; 208 | for (var i = 0; i < LEN; i++) { 209 | if (author == game["player_list"][i]) { 210 | return i; 211 | } 212 | } 213 | return -1; 214 | } 215 | 216 | function parseSubmittedWord(game, player_index, message, allow_hard_words) { 217 | var word = message.toLowerCase().replace(/[^a-z]/gi,''); 218 | if (word.length < 5) { 219 | return ["","That word is not long enough."]; 220 | } else { 221 | word = word.substring(0,5); 222 | var thisWordList = allow_hard_words ? wordList : wordListEasy; 223 | if (thisWordList.includes(word)) { 224 | var alert_ = ""; 225 | if (game["stage"] == 2) { 226 | var wordCountSoFar = game["words"][player_index].length; 227 | alert_ = "Word # "+(wordCountSoFar+1)+" of "+game["word_count"]+" successfully received as "+formatWord(word,true, false); 228 | if (wordCountSoFar == game["word_count"]-1) { 229 | alert_ += ". You have finished submitting all words for this game."; 230 | } 231 | } else if (game["stage"] == 3) { 232 | var guessCount = game["guesses"][player_index].length; 233 | alert_ = "Guess # "+(guessCount+1)+" successfully received as "+formatWord(word, true, false)+". Waiting for the round to finish."; 234 | } 235 | return [word,alert_]; 236 | } else { 237 | return ["","That word isn't in Wordle's dictionary, try again."]; 238 | } 239 | } 240 | } 241 | 242 | function getCode(guess, answer) { 243 | var LEN = 5; 244 | 245 | var guessArr = new Array(LEN); 246 | var answerArr = new Array(LEN); 247 | var result = new Array(LEN); 248 | for (var pos = 0; pos < LEN; pos++) { 249 | guessArr[pos] = guess.charCodeAt(pos)-CHAR_CODE_A; 250 | answerArr[pos] = answer.charCodeAt(pos)-CHAR_CODE_A; 251 | result[pos] = 0; 252 | } 253 | 254 | for (var pos = 0; pos < LEN; pos++) { 255 | var g = guessArr[pos]; 256 | if (answerArr[pos] == g) { 257 | result[pos] = 2; 258 | guessArr[pos] = -1; // ensure that letter can't be used again. (Like if the word is 'CLERK' and you guess 'STEEP', the first E uses up the E, so the second E can't claim it.) 259 | answerArr[pos] = -1; 260 | } 261 | } 262 | var resultString = ""; 263 | for (var pos = 0; pos < LEN; pos++) { 264 | if (result[pos] == 0) { 265 | for (var apos = 0; apos < LEN; apos++) { 266 | if (answerArr[apos] == guessArr[pos]) { 267 | result[pos] = 1; 268 | guessArr[pos] = -1; // ensure that letter can't be used again. 269 | answerArr[apos] = -1; 270 | } 271 | } 272 | } 273 | resultString += String.fromCharCode(result[pos] + CHAR_CODE_A); 274 | } 275 | return resultString; 276 | } 277 | 278 | 279 | function handleGameMessage(message) { 280 | var mc = message.channel; 281 | const args = message.content.slice(prefix.length).split(" "); 282 | const command = args.shift().toLowerCase(); 283 | var author = message.author; 284 | if (command == 'join') { 285 | if (game["stage"] == 1) { 286 | if (game["player_list"].includes(author)) { 287 | mc.send(author.username+", you're already in this game. Don't try to join twice."); 288 | } else { 289 | game["player_list"].push(author); 290 | 291 | var words = new Array(0); 292 | game["words"].push(words); 293 | var guesses = new Array(0); 294 | game["guesses"].push(guesses); 295 | var codes = new Array(0); 296 | game["codes"].push(codes); 297 | 298 | game["word_on"].push(0); 299 | game["edits"].push(0); 300 | game["max_greens"].push(0); 301 | game["most_recent_edit"].push(-1); 302 | game["most_recent_new_word"].push(-1); 303 | mc.send(author.username+" just joined the game. "+ 304 | "\nPlayer count: "+game["player_list"].length); 305 | } 306 | } else { 307 | mc.send("It's the wrong stage of game for that."); 308 | } 309 | } else if (command == 'start') { 310 | if (game["stage"] == 1) { 311 | var PLAYER_COUNT = game["player_list"].length; 312 | if (PLAYER_COUNT < 1) { 313 | message.channel.send("There are only "+PLAYER_COUNT+" players. Not enough."); 314 | } else { 315 | startGame(game, args); 316 | } 317 | } else { 318 | mc.send("It's the wrong stage of game for that."); 319 | } 320 | } else if (command == 'create') { 321 | mc.send("It's the wrong stage of game for that."); 322 | } else if (command == 'abort') { 323 | abort(game, "This WordleEdit game has been aborted."); 324 | game["stage"] = 0; 325 | } 326 | } 327 | 328 | function abort(game, message) { 329 | if (intervalFunc != null) { 330 | deleteMessages(game, "timer_messages_to_edit"); 331 | clearInterval(intervalFunc); 332 | } 333 | alertChannelAndPlayers(game, message); 334 | } 335 | 336 | function alertChannelAndPlayers(game, stri) { 337 | game["channel"].send(stri); 338 | var LEN = game["player_list"].length; 339 | for (var i = 0; i < LEN; i++) { 340 | game["player_list"][i].send(stri); 341 | } 342 | } 343 | 344 | function startGame(game, args) { 345 | var mc = game["channel"]; 346 | game["stage"] = 2; 347 | mc.send(frill+" **STARTING THE WORDLEEDIT GAME NOW!** "+frill); 348 | mc.send(announceStringOf(game,2)+"\nPlayers, go into your DMs with this bot to play the remainder of this game."); 349 | 350 | game["timer"] = game["writing_stage_time"]; 351 | game["timer_messages_to_edit"] = new Array(0); 352 | 353 | setTimersAndMessagePlayerList(game); 354 | 355 | intervalFunc = setInterval(function() { 356 | updateAllTimers(game); 357 | if (game["timer"] <= 0) { 358 | wrapUpWritingStageBecauseTimeRanOut(game); 359 | startGuessingStage(game); 360 | } 361 | }, 2000); 362 | } 363 | 364 | function wrapUpWritingStageBecauseTimeRanOut(game) { 365 | var LEN = game["player_list"].length; 366 | var wc = game["word_count"]; 367 | for (var p_i = 0; p_i < LEN; p_i++) { 368 | var swc = game["words"][p_i].length; 369 | var pc = game["player_list"][p_i]; // player channel 370 | if (swc == wc) { 371 | pc.send("Congrats! You submitted all your words on time."); 372 | } else { 373 | var rwc = wc-swc; 374 | var messageString = "You only submitted "+pluralize(swc,"word")+" on time. So, the final "+pluralize(rwc,"word")+" have been randomly chosen by the bot (me) to be:" 375 | for (var w_i = 0; w_i < rwc; w_i++) { 376 | var word = getRandomWord(game); 377 | messageString += "\n"+formatWord(word, true, false); 378 | game["words"][p_i].push(word); 379 | } 380 | pc.send(messageString); 381 | } 382 | } 383 | } 384 | 385 | function deleteMessages(game, list) { 386 | var LEN = game[list].length; 387 | for (var i = 0; i < LEN; i++) { 388 | var m = game[list][i]; 389 | if (m != null) { 390 | m.delete(); 391 | } 392 | } 393 | game[list] = new Array(0); 394 | } 395 | 396 | function startGuessingStage(game) { 397 | deleteMessages(game, "timer_messages_to_edit"); 398 | clearInterval(intervalFunc); 399 | 400 | game["stage"] = 3; 401 | game["round_count"] = 1; 402 | alertChannelAndPlayers(game, "All players have submitted their words. Time for the guessing stage to begin."); 403 | 404 | startGuessingTurn(game); 405 | } 406 | 407 | function startGuessingTurn(game) { 408 | game["timer"] = game["guessing_stage_time"]; 409 | game["timer_messages_to_edit"] = new Array(0); 410 | 411 | setTimersAndMessagePlayerList(game); 412 | 413 | intervalFunc = setInterval(function() { 414 | updateAllTimers(game); 415 | if (game["timer"] <= 0) { 416 | finishGuessingTurn(game); 417 | } 418 | }, 2000); 419 | } 420 | 421 | function getRandomWord(game) { 422 | var thisGamesWordList = game["allow_hard_words"] ? wordList : wordListEasy; 423 | var choice = Math.floor(Math.random()*thisGamesWordList.length); 424 | return thisGamesWordList[choice]; 425 | } 426 | 427 | function countGreens(code) { 428 | var count = 0; 429 | for (var i = 0; i < code.length; i++) { 430 | if (code.charCodeAt(i) == 2+CHAR_CODE_A) { 431 | count += 1; 432 | } 433 | } 434 | return count; 435 | } 436 | 437 | function calculatePlayersRoundPerformance(game, p_i, r, LEN) { 438 | var pgc = game["guesses"][p_i].length; 439 | var pc = game["player_list"][p_i]; // player channel 440 | if (pgc < game["round_count"]) { 441 | if (game["auto_guess"]) { 442 | var word = getRandomWord(game); 443 | game["guesses"][p_i].push(word); 444 | pc.send("You didn't guess in time. So, your guess will be randomly chosen by the bot (me) to be:\n"+formatWord(word,true, false)); 445 | } else { 446 | var word = "*****"; 447 | game["guesses"][p_i].push(word); 448 | pc.send("You didn't guess in time, so we're going to skip your turn! Better luck next time."); 449 | } 450 | } 451 | var prevI = (p_i+LEN-1)%LEN; 452 | var wordOn = game["word_on"][p_i]; 453 | var guess = game["guesses"][p_i][r]; 454 | var answer = game["words"][prevI][wordOn]; 455 | var code = getCode(guess, answer); 456 | game["codes"][p_i].push(code); 457 | 458 | var greenCount = countGreens(code); 459 | var diff = greenCount-game["max_greens"][p_i]; 460 | if (diff > 0) { 461 | if (diff >= game["greens_needed_for_an_edit"]) { 462 | game["edits"][p_i] = Math.min(game["edits"][p_i]+1,game["max_edits"]); 463 | // you get one edit if you uncover 2+ green tiles. 464 | } 465 | game["max_greens"][p_i] = greenCount; 466 | } 467 | 468 | if (countLetters(code, 'a') >= game["grays_needed_for_an_edit"]) { 469 | var prevI = (p_i+LEN-1)%LEN; 470 | game["edits"][prevI] = Math.min(game["edits"][prevI]+1,game["max_edits"]); // you get one edit if your opponent gets 5 grays on your word. 471 | } 472 | } 473 | 474 | function countLetters(stri, ch) { 475 | var count = 0; 476 | for (var i = 0; i < stri.length; i++) { 477 | if (stri.charAt(i) == ch) { 478 | count += 1; 479 | } 480 | } 481 | return count; 482 | } 483 | 484 | 485 | function finishGuessingTurn(game) { 486 | var r = game["round_count"]-1; // the index of the round we're on. 487 | var LEN = game["player_list"].length; 488 | for (var p_i = 0; p_i < LEN; p_i++) { 489 | calculatePlayersRoundPerformance(game, p_i, r, LEN); 490 | } 491 | deleteMessages(game, "timer_messages_to_edit"); 492 | deleteMessages(game, "waiting_messages_to_delete"); 493 | 494 | game["channel"].send(formatRoundResult(game, r, -1)); 495 | for (var p_i = 0; p_i < LEN; p_i++) { 496 | game["player_list"][p_i].send(formatRoundResult(game, r, p_i)); 497 | } 498 | 499 | var finishers = new Array(0); 500 | for (var p_i = 0; p_i < LEN; p_i++) { 501 | if (game["codes"][p_i][r] === "ccccc") { 502 | var prevI = (p_i+LEN-1)%LEN; 503 | var prevP = game["player_list"][prevI]; 504 | var wordOn = game["word_on"][p_i]; 505 | if (wordOn >= game["word_count"]-1) { 506 | finishers.push(p_i); 507 | } 508 | if (game["word_on"][p_i] < game["word_count"]-1) { 509 | game["player_list"][p_i].send("Congrats, you solved "+prevP.username+"'s "+rankify(wordOn)+" word! Guess their "+ rankify(wordOn+1)+" one."); 510 | } 511 | 512 | game["word_on"][p_i] += 1; 513 | game["max_greens"][p_i] = 0; 514 | game["most_recent_new_word"][p_i] = r+1; 515 | } 516 | } 517 | 518 | if (finishers.length >= 1) { // someone finished the game. 519 | if (finishers.length == 1) { 520 | var f = finishers[0]; 521 | var winner = game["player_list"][f]; 522 | var prevI = (f+LEN-1)%LEN; 523 | var prevP = game["player_list"][prevI]; 524 | 525 | winner.send(frill+"YOU WON! Congrats, you solved "+prevP.username+"'s final word, so you've won. "+frill); 526 | for (var p_i = 0; p_i < LEN; p_i++) { 527 | if (p_i != f) { 528 | game["player_list"][p_i].send(skulls+"YOU LOST. "+winner.username+" just solved "+prevP.username+"'s final word, so they won. "+skulls); 529 | } 530 | } 531 | game["channel"].send(frill+winner.username+" WON! They solved "+prevP.username+"'s final word. "+frill); 532 | } else { 533 | for (var f_i = 0; f_i < finishers.length; f_i++) { 534 | var f = finishers[f_i]; 535 | var winner = game["player_list"][f]; 536 | var prevI = (f+LEN-1)%LEN; 537 | var prevP = game["player_list"][prevI]; 538 | winner.send(frill+" YOU TIED! Congrats, you solved "+prevP.username+"'s final word, so you've completed the game! You finished on the same turn as "+getTiedString(game, finishers, f_i)+"."+frill); 539 | } 540 | 541 | game["channel"].send(frill+getTiedString(game, finishers, -1)+" TIED! They solved their final words on the same turn. "+frill); 542 | } 543 | abort(game, "This WordleEdit game has ended."); 544 | game["stage"] = 0; 545 | } else { 546 | game["round_count"]++; 547 | clearInterval(intervalFunc); 548 | startGuessingTurn(game); 549 | } 550 | } 551 | 552 | function getTiedString(game, finishers, exclude) { 553 | var tiedString = ""; 554 | for (var f_j = 0; f_j < finishers.length; f_j++) { 555 | if (f_j != exclude) { 556 | tiedString += game["player_list"][finishers[f_j]].username+" and "; 557 | } 558 | } 559 | return tiedString.substring(0,tiedString.length-5); // remove the final " and ". 560 | } 561 | 562 | function formatRoundResult(game, round_i, player_i) { 563 | var black = ":black_large_square: "; 564 | var boom = ":boom: "; 565 | var pencil = ":pencil: "; 566 | var puzzle = ":jigsaw: "; 567 | var questWord = ""; 568 | for (var i = 0; i < 5; i++) { 569 | questWord += ":question: "; 570 | } 571 | 572 | var LEN = game["player_list"].length; 573 | 574 | var guesses_string = ". "; 575 | var codes_string = ". "; 576 | var truth_string = ". "; 577 | for (var pseudo_i = 0; pseudo_i < LEN; pseudo_i++) { 578 | var p_i = pseudo_i; 579 | if (player_i >= 0) { 580 | p_i = (pseudo_i+player_i)%LEN; 581 | } 582 | var prevI = (p_i+LEN-1)%LEN; 583 | var tile = black; 584 | if (game["most_recent_edit"][prevI] == game["round_count"]) { // this person's word was edited. Ooooh. 585 | tile = boom; 586 | } 587 | var wordOn = game["word_on"][p_i]; 588 | 589 | guesses_string += tile+puzzle+formatWord(game["guesses"][p_i][round_i], true, true)+pencil+tile; 590 | var w = (game["word_on"][p_i]+1)%10; 591 | var e = game["edits"][p_i]%10; 592 | codes_string += tile+formatNumber(w)+formatCode(game["codes"][p_i][round_i], true, true)+formatNumber(e)+tile; 593 | 594 | var truth_piece = questWord; 595 | if (player_i == prevI || game["codes"][p_i][round_i] === "ccccc") { // you know the answer word, since you chose it. OR it's solved! 596 | truth_piece = formatWord(game["words"][prevI][wordOn], true, true); 597 | } 598 | truth_string += tile+tile+truth_piece+tile+tile; 599 | } 600 | 601 | 602 | if (player_i >= 0 && game["show_keyboard"]) { // this is a human player, not the spectator 603 | var remainingCharacters = getRemainingCharacters(game, player_i); 604 | 605 | var rows = new Array(3); 606 | for (var r = 0; r < 3; r++) { 607 | rows[r] = black+black+black+thought; 608 | } 609 | var perRow = Math.ceil(remainingCharacters.length/3); 610 | 611 | for (var ch_i = 0; ch_i < remainingCharacters.length; ch_i++) { 612 | var ch = remainingCharacters[ch_i]; 613 | var character_block = formatLetter(ch); 614 | var row = Math.floor(ch_i/perRow); 615 | rows[row] += character_block; 616 | } 617 | guesses_string += rows[0]; 618 | codes_string += rows[1]; 619 | truth_string += rows[2]; 620 | } 621 | 622 | var result = ""; 623 | if (player_i >= 0) { // This is a player DM, so we have to put the username list each time. 624 | result += playerListToString(game, player_i)+"\n"; 625 | } else if (round_i == 0) { // It's round 1 and publicly being shown, so we have to put the username list each time. 626 | result += playerListToString(game, 0)+"\n"; 627 | } 628 | result += guesses_string+"\n"+codes_string; 629 | if (player_i >= 0) { 630 | result += "\n"+truth_string; 631 | } 632 | return result; 633 | } 634 | 635 | function getRemainingCharacters(game, player_i) { 636 | var LEN = game["player_list"].length; 637 | var remainingCharacterIndices = new Array(26); 638 | for (var i = 0; i < 26; i++) { 639 | remainingCharacterIndices[i] = true; 640 | } 641 | var prevI = (player_i+LEN-1)%LEN; 642 | 643 | var firstUsefulRound = Math.max(game["most_recent_edit"][prevI],game["most_recent_new_word"][player_i],0); 644 | 645 | for (var round = firstUsefulRound; round < game["round_count"]; round++) { 646 | var guess = game["guesses"][player_i][round]; 647 | var code = game["codes"][player_i][round]; 648 | for (var i = 0; i < 5; i++) { 649 | if (code.charAt(i) == 'a') { 650 | var DQedLetter = guess.charCodeAt(i)-CHAR_CODE_A; 651 | remainingCharacterIndices[DQedLetter] = false; 652 | } 653 | } 654 | for (var i = 0; i < 5; i++) { // in case the word is something like 'CHEER', and one 'E' is gray and the other is yellow, the first for-loop will see the gray E and kick E off the keyboard, but it shouldn't be removed since the yellow E proves it's there. 655 | if (code.charAt(i) != 'a') { 656 | var approvedLetter = guess.charCodeAt(i)-CHAR_CODE_A; 657 | remainingCharacterIndices[approvedLetter] = true; 658 | } 659 | } 660 | } 661 | 662 | var remainingCharacters = new Array(0); 663 | for (var i = 0; i < 26; i++) { 664 | if (remainingCharacterIndices[i]) { 665 | remainingCharacters.push(String.fromCharCode(i + CHAR_CODE_A)); 666 | } 667 | } 668 | return remainingCharacters; 669 | } 670 | 671 | function updateAllTimers(game) { 672 | game["timer"] -= 2; 673 | if (game["timer"] >= 2) { 674 | var editedStri = formatTime(game["timer"]); 675 | var LEN = game["timer_messages_to_edit"].length; 676 | for (var i = 0; i < LEN; i++) { 677 | var mess = game["timer_messages_to_edit"][i]; 678 | if (mess != null) { 679 | mess.edit(editedStri); 680 | } 681 | } 682 | } 683 | } 684 | 685 | function setTimersAndMessagePlayerList(game) { 686 | game["channel"].send(formatTime(game["timer"])).then(message => { 687 | game["timer_messages_to_edit"].push(message); 688 | }); 689 | 690 | var LEN = game["player_list"].length; 691 | for (var i = 0; i < LEN; i++) { 692 | var prevI = (i+LEN-1)%LEN; 693 | var nextI = (i+1)%LEN; 694 | var p = game["player_list"][i]; 695 | var nextP = game["player_list"][nextI]; 696 | var prevP = game["player_list"][prevI]; 697 | 698 | if (game["stage"] == 2) { 699 | game["player_list"][i].send("Hello, "+p.username+"! In this WordleEdit game, you are Player #"+(i+1)+" of "+LEN+". Please type "+pluralize(game["word_count"], "word")+" for Player #"+(nextI+1)+" ("+nextP.username+") to guess."); 700 | } else if (game["stage"] == 3 && game["round_count"] == 1) { 701 | var wordOn = game["word_on"][i]; 702 | game["player_list"][i].send("Please guess "+prevP.username+"'s "+rankify(wordOn)+" word."); 703 | } 704 | 705 | game["player_list"][i].send(formatTime(game["timer"])).then(message => { 706 | game["timer_messages_to_edit"].push(message); 707 | }); 708 | } 709 | } 710 | function rankify(n) { 711 | var modN = (n%100)+1; 712 | var suffix = ""; 713 | if (modN >= 10 && modN < 20) { 714 | suffix = "th"; 715 | } else { 716 | if (modN%10 == 1) { 717 | suffix = "st"; 718 | } else if (modN%10 == 2) { 719 | suffix = "nd"; 720 | } else if (modN%10 == 3) { 721 | suffix = "rd"; 722 | } else { 723 | suffix = "th"; 724 | } 725 | } 726 | return (n+1)+suffix; 727 | } 728 | 729 | function playerListToString(game, indexShift) { 730 | var RESULT_STR = ""; 731 | var LEN = game["player_list"].length; 732 | for (var i = 0; i < LEN; i++) { 733 | if (i == 1 && LEN == 2) { 734 | RESULT_STR += " <---> "; 735 | } else { 736 | if (i >= 1) { 737 | RESULT_STR += " ----> "; 738 | } 739 | } 740 | if (i == game["position"]) { 741 | RESULT_STR += ":arrow_right:"; 742 | } 743 | RESULT_STR += game["player_list"][(i-indexShift+LEN)%LEN].username; 744 | } 745 | return RESULT_STR; 746 | } 747 | 748 | function formatWord(word, emojify, finalSpace) { 749 | if (emojify) { 750 | var result = ""; 751 | for (var i = 0; i < 5; i++) { 752 | var toAdd = (word.charAt(i) == '*') ? ":question:" : ":regional_indicator_"+word.charAt(i)+":"; 753 | result += toAdd; 754 | if (finalSpace || i < 4) { 755 | result += " "; 756 | } 757 | } 758 | return result; 759 | } else { 760 | return word.toUpperCase(); 761 | } 762 | } 763 | 764 | function formatLetter(ch) { 765 | return ":regional_indicator_"+ch+": "; 766 | } 767 | 768 | function formatCode(code, emojify, finalSpace) { 769 | if (emojify) { 770 | var emojis = [":white_large_square:",":yellow_square:",":green_square:",":green_heart:"] 771 | var result = ""; 772 | for (var i = 0; i < 5; i++) { 773 | if (code === "ccccc") { 774 | result += emojis[3]; 775 | } else { 776 | result += emojis[code.charCodeAt(i)-CHAR_CODE_A]; 777 | } 778 | if (finalSpace || i < 4) { 779 | result += " "; 780 | } 781 | } 782 | return result; 783 | } else { 784 | return code.toUpperCase(); 785 | } 786 | } 787 | 788 | function formatTime(timer) { 789 | return "Time left: "+formatNumber(timer); 790 | } 791 | 792 | function formatNumber(number) { 793 | var sNumber = number+""; 794 | var numberNames = ["zero","one","two","three","four","five","six","seven","eight","nine"]; 795 | var LEN = sNumber.length; 796 | var result = ""; 797 | for (var i = 0; i < LEN; i++) { 798 | result += ":"+numberNames[sNumber.charCodeAt(i)-ZERO]+": "; 799 | } 800 | return result; 801 | } 802 | 803 | function announceStringOf(game,stage) { 804 | var ANNOUNCE_STR = "We're creating a brand new game of WordleEdit!"; 805 | if (stage == 1) { 806 | ANNOUNCE_STR += "\nType \"`!join`\" to join this game." 807 | } else if (stage == 2) { 808 | ANNOUNCE_STR += "\n\nPlayer list: " 809 | for (var i = 0; i < game["player_list"].length; i++) { 810 | ANNOUNCE_STR += "\n"+game["player_list"][i].username; 811 | } 812 | } 813 | return ANNOUNCE_STR; 814 | } 815 | 816 | function newClearGame(mc, args) { 817 | var thisGame = []; 818 | thisGame["player_list"] = []; 819 | 820 | thisGame["words"] = new Array(0); 821 | thisGame["guesses"] = new Array(0); 822 | thisGame["codes"] = new Array(0); 823 | thisGame["word_on"] = new Array(0); 824 | thisGame["timer_messages_to_edit"] = new Array(0); 825 | thisGame["max_greens"] = new Array(0); 826 | thisGame["edits"] = new Array(0); 827 | thisGame["most_recent_edit"] = new Array(0); 828 | thisGame["most_recent_new_word"] = new Array(0); 829 | 830 | thisGame["word_count"] = defaultValue(args,0,3); 831 | thisGame["greens_needed_for_an_edit"] = defaultValue(args,1,2); 832 | thisGame["grays_needed_for_an_edit"] = defaultValue(args,2,5); 833 | thisGame["writing_stage_time"] = defaultValue(args,3,180); 834 | thisGame["guessing_stage_time"] = defaultValue(args,4,60); 835 | thisGame["allow_hard_words"] = yesNoValue(args,5,false); 836 | thisGame["auto_guess"] = yesNoValue(args,6,true); 837 | thisGame["show_keyboard"] = yesNoValue(args,7,true); 838 | 839 | thisGame["channel"] = mc; 840 | thisGame["stage"] = 0; 841 | thisGame["timer"] = 0; 842 | thisGame["round_count"] = 0; 843 | thisGame["waiting_messages_to_delete"] = new Array(0); 844 | 845 | thisGame["max_edits"] = 9; 846 | 847 | return thisGame; 848 | } 849 | 850 | function defaultValue(arr, index, def) { 851 | if (index >= arr.length) { 852 | return def; 853 | } else { 854 | return arr[index]*1; 855 | } 856 | } 857 | 858 | function yesNoValue(arr, index, def) { 859 | if (index >= arr.length) { 860 | return def; 861 | } else { 862 | return (arr[index] === "y"); 863 | } 864 | } 865 | 866 | client.login(require("./token.json").token); 867 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WordleEdit", 3 | "version": "1.0.0", 4 | "description": "WordleEdit is a multiplayer version of Wordle (created by Josh Wardle) where players can edit their own words as they go.", 5 | "main": "main.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "discord.js": "13.12.0" 14 | } 15 | } -------------------------------------------------------------------------------- /token.json: -------------------------------------------------------------------------------- 1 | { 2 | "token": "INSERT YOUR DISCORD BOT'S TOKEN HERE" 3 | } 4 | -------------------------------------------------------------------------------- /wordlist_0.txt: -------------------------------------------------------------------------------- 1 | aback 2 | abase 3 | abate 4 | abbey 5 | abbot 6 | abhor 7 | abide 8 | abled 9 | abode 10 | abort 11 | about 12 | above 13 | abuse 14 | abyss 15 | acorn 16 | acrid 17 | actor 18 | acute 19 | adage 20 | adapt 21 | adept 22 | admin 23 | admit 24 | adobe 25 | adopt 26 | adore 27 | adorn 28 | adult 29 | affix 30 | afire 31 | afoot 32 | afoul 33 | after 34 | again 35 | agape 36 | agate 37 | agent 38 | agile 39 | aging 40 | aglow 41 | agony 42 | agora 43 | agree 44 | ahead 45 | aider 46 | aisle 47 | alarm 48 | album 49 | alert 50 | algae 51 | alibi 52 | alien 53 | align 54 | alike 55 | alive 56 | allay 57 | alley 58 | allot 59 | allow 60 | alloy 61 | aloft 62 | alone 63 | along 64 | aloof 65 | aloud 66 | alpha 67 | altar 68 | alter 69 | amass 70 | amaze 71 | amber 72 | amble 73 | amend 74 | amiss 75 | amity 76 | among 77 | ample 78 | amply 79 | amuse 80 | angel 81 | anger 82 | angle 83 | angry 84 | angst 85 | anime 86 | ankle 87 | annex 88 | annoy 89 | annul 90 | anode 91 | antic 92 | anvil 93 | aorta 94 | apart 95 | aphid 96 | aping 97 | apnea 98 | apple 99 | apply 100 | apron 101 | aptly 102 | arbor 103 | ardor 104 | arena 105 | argue 106 | arise 107 | armor 108 | aroma 109 | arose 110 | array 111 | arrow 112 | arson 113 | artsy 114 | ascot 115 | ashen 116 | aside 117 | askew 118 | assay 119 | asset 120 | atoll 121 | atone 122 | attic 123 | audio 124 | audit 125 | augur 126 | aunty 127 | avail 128 | avert 129 | avian 130 | avoid 131 | await 132 | awake 133 | award 134 | aware 135 | awash 136 | awful 137 | awoke 138 | axial 139 | axiom 140 | axion 141 | azure 142 | bacon 143 | badge 144 | badly 145 | bagel 146 | baggy 147 | baker 148 | baler 149 | balmy 150 | banal 151 | banjo 152 | barge 153 | baron 154 | basal 155 | basic 156 | basil 157 | basin 158 | basis 159 | baste 160 | batch 161 | bathe 162 | baton 163 | batty 164 | bawdy 165 | bayou 166 | beach 167 | beady 168 | beard 169 | beast 170 | beech 171 | beefy 172 | befit 173 | began 174 | begat 175 | beget 176 | begin 177 | begun 178 | being 179 | belch 180 | belie 181 | belle 182 | belly 183 | below 184 | bench 185 | beret 186 | berry 187 | berth 188 | beset 189 | betel 190 | bevel 191 | bezel 192 | bible 193 | bicep 194 | biddy 195 | bigot 196 | bilge 197 | billy 198 | binge 199 | bingo 200 | biome 201 | birch 202 | birth 203 | bison 204 | bitty 205 | black 206 | blade 207 | blame 208 | bland 209 | blank 210 | blare 211 | blast 212 | blaze 213 | bleak 214 | bleat 215 | bleed 216 | bleep 217 | blend 218 | bless 219 | blimp 220 | blind 221 | blink 222 | bliss 223 | blitz 224 | bloat 225 | block 226 | bloke 227 | blond 228 | blood 229 | bloom 230 | blown 231 | bluer 232 | bluff 233 | blunt 234 | blurb 235 | blurt 236 | blush 237 | board 238 | boast 239 | bobby 240 | boney 241 | bongo 242 | bonus 243 | booby 244 | boost 245 | booth 246 | booty 247 | booze 248 | boozy 249 | borax 250 | borne 251 | bosom 252 | bossy 253 | botch 254 | bough 255 | boule 256 | bound 257 | bowel 258 | boxer 259 | brace 260 | braid 261 | brain 262 | brake 263 | brand 264 | brash 265 | brass 266 | brave 267 | bravo 268 | brawl 269 | brawn 270 | bread 271 | break 272 | breed 273 | briar 274 | bribe 275 | brick 276 | bride 277 | brief 278 | brine 279 | bring 280 | brink 281 | briny 282 | brisk 283 | broad 284 | broil 285 | broke 286 | brood 287 | brook 288 | broom 289 | broth 290 | brown 291 | brunt 292 | brush 293 | brute 294 | buddy 295 | budge 296 | buggy 297 | bugle 298 | build 299 | built 300 | bulge 301 | bulky 302 | bully 303 | bunch 304 | bunny 305 | burly 306 | burnt 307 | burst 308 | bused 309 | bushy 310 | butch 311 | butte 312 | buxom 313 | buyer 314 | bylaw 315 | cabal 316 | cabby 317 | cabin 318 | cable 319 | cacao 320 | cache 321 | cacti 322 | caddy 323 | cadet 324 | cagey 325 | cairn 326 | camel 327 | cameo 328 | canal 329 | candy 330 | canny 331 | canoe 332 | canon 333 | caper 334 | caput 335 | carat 336 | cargo 337 | carol 338 | carry 339 | carve 340 | caste 341 | catch 342 | cater 343 | catty 344 | caulk 345 | cause 346 | cavil 347 | cease 348 | cedar 349 | cello 350 | chafe 351 | chaff 352 | chain 353 | chair 354 | chalk 355 | champ 356 | chant 357 | chaos 358 | chard 359 | charm 360 | chart 361 | chase 362 | chasm 363 | cheap 364 | cheat 365 | check 366 | cheek 367 | cheer 368 | chess 369 | chest 370 | chick 371 | chide 372 | chief 373 | child 374 | chili 375 | chill 376 | chime 377 | china 378 | chirp 379 | chock 380 | choir 381 | choke 382 | chord 383 | chore 384 | chose 385 | chuck 386 | chump 387 | chunk 388 | churn 389 | chute 390 | cider 391 | cigar 392 | cinch 393 | circa 394 | civic 395 | civil 396 | clack 397 | claim 398 | clamp 399 | clang 400 | clank 401 | clash 402 | clasp 403 | class 404 | clean 405 | clear 406 | cleat 407 | cleft 408 | clerk 409 | click 410 | cliff 411 | climb 412 | cling 413 | clink 414 | cloak 415 | clock 416 | clone 417 | close 418 | cloth 419 | cloud 420 | clout 421 | clove 422 | clown 423 | cluck 424 | clued 425 | clump 426 | clung 427 | coach 428 | coast 429 | cobra 430 | cocoa 431 | colon 432 | color 433 | comet 434 | comfy 435 | comic 436 | comma 437 | conch 438 | condo 439 | conic 440 | copse 441 | coral 442 | corer 443 | corny 444 | couch 445 | cough 446 | could 447 | count 448 | coupe 449 | court 450 | coven 451 | cover 452 | covet 453 | covey 454 | cower 455 | coyly 456 | crack 457 | craft 458 | cramp 459 | crane 460 | crank 461 | crash 462 | crass 463 | crate 464 | crave 465 | crawl 466 | craze 467 | crazy 468 | creak 469 | cream 470 | credo 471 | creed 472 | creek 473 | creep 474 | creme 475 | crepe 476 | crept 477 | cress 478 | crest 479 | crick 480 | cried 481 | crier 482 | crime 483 | crimp 484 | crisp 485 | croak 486 | crock 487 | crone 488 | crony 489 | crook 490 | cross 491 | croup 492 | crowd 493 | crown 494 | crude 495 | cruel 496 | crumb 497 | crump 498 | crush 499 | crust 500 | crypt 501 | cubic 502 | cumin 503 | curio 504 | curly 505 | curry 506 | curse 507 | curve 508 | curvy 509 | cutie 510 | cyber 511 | cycle 512 | cynic 513 | daddy 514 | daily 515 | dairy 516 | daisy 517 | dally 518 | dance 519 | dandy 520 | datum 521 | daunt 522 | dealt 523 | death 524 | debar 525 | debit 526 | debug 527 | debut 528 | decal 529 | decay 530 | decor 531 | decoy 532 | decry 533 | defer 534 | deign 535 | deity 536 | delay 537 | delta 538 | delve 539 | demon 540 | demur 541 | denim 542 | dense 543 | depot 544 | depth 545 | derby 546 | deter 547 | detox 548 | deuce 549 | devil 550 | diary 551 | dicey 552 | digit 553 | dilly 554 | dimly 555 | diner 556 | dingo 557 | dingy 558 | diode 559 | dirge 560 | dirty 561 | disco 562 | ditch 563 | ditto 564 | ditty 565 | diver 566 | dizzy 567 | dodge 568 | dodgy 569 | dogma 570 | doing 571 | dolly 572 | donor 573 | donut 574 | dopey 575 | doubt 576 | dough 577 | dowdy 578 | dowel 579 | downy 580 | dowry 581 | dozen 582 | draft 583 | drain 584 | drake 585 | drama 586 | drank 587 | drape 588 | drawl 589 | drawn 590 | dread 591 | dream 592 | dress 593 | dried 594 | drier 595 | drift 596 | drill 597 | drink 598 | drive 599 | droit 600 | droll 601 | drone 602 | drool 603 | droop 604 | dross 605 | drove 606 | drown 607 | druid 608 | drunk 609 | dryer 610 | dryly 611 | duchy 612 | dully 613 | dummy 614 | dumpy 615 | dunce 616 | dusky 617 | dusty 618 | dutch 619 | duvet 620 | dwarf 621 | dwell 622 | dwelt 623 | dying 624 | eager 625 | eagle 626 | early 627 | earth 628 | easel 629 | eaten 630 | eater 631 | ebony 632 | eclat 633 | edict 634 | edify 635 | eerie 636 | egret 637 | eight 638 | eject 639 | eking 640 | elate 641 | elbow 642 | elder 643 | elect 644 | elegy 645 | elfin 646 | elide 647 | elite 648 | elope 649 | elude 650 | email 651 | embed 652 | ember 653 | emcee 654 | empty 655 | enact 656 | endow 657 | enema 658 | enemy 659 | enjoy 660 | ennui 661 | ensue 662 | enter 663 | entry 664 | envoy 665 | epoch 666 | epoxy 667 | equal 668 | equip 669 | erase 670 | erect 671 | erode 672 | error 673 | erupt 674 | essay 675 | ester 676 | ether 677 | ethic 678 | ethos 679 | etude 680 | evade 681 | event 682 | every 683 | evict 684 | evoke 685 | exact 686 | exalt 687 | excel 688 | exert 689 | exile 690 | exist 691 | expel 692 | extol 693 | extra 694 | exult 695 | eying 696 | fable 697 | facet 698 | faint 699 | fairy 700 | faith 701 | false 702 | fancy 703 | fanny 704 | farce 705 | fatal 706 | fatty 707 | fault 708 | fauna 709 | favor 710 | feast 711 | fecal 712 | feign 713 | fella 714 | felon 715 | femme 716 | femur 717 | fence 718 | feral 719 | ferry 720 | fetal 721 | fetch 722 | fetid 723 | fetus 724 | fever 725 | fewer 726 | fiber 727 | fibre 728 | ficus 729 | field 730 | fiend 731 | fiery 732 | fifth 733 | fifty 734 | fight 735 | filer 736 | filet 737 | filly 738 | filmy 739 | filth 740 | final 741 | finch 742 | finer 743 | first 744 | fishy 745 | fixer 746 | fizzy 747 | fjord 748 | flack 749 | flail 750 | flair 751 | flake 752 | flaky 753 | flame 754 | flank 755 | flare 756 | flash 757 | flask 758 | fleck 759 | fleet 760 | flesh 761 | flick 762 | flier 763 | fling 764 | flint 765 | flirt 766 | float 767 | flock 768 | flood 769 | floor 770 | flora 771 | floss 772 | flour 773 | flout 774 | flown 775 | fluff 776 | fluid 777 | fluke 778 | flume 779 | flung 780 | flunk 781 | flush 782 | flute 783 | flyer 784 | foamy 785 | focal 786 | focus 787 | foggy 788 | foist 789 | folio 790 | folly 791 | foray 792 | force 793 | forge 794 | forgo 795 | forte 796 | forth 797 | forty 798 | forum 799 | found 800 | foyer 801 | frail 802 | frame 803 | frank 804 | fraud 805 | freak 806 | freed 807 | freer 808 | fresh 809 | friar 810 | fried 811 | frill 812 | frisk 813 | fritz 814 | frock 815 | frond 816 | front 817 | frost 818 | froth 819 | frown 820 | froze 821 | fruit 822 | fudge 823 | fugue 824 | fully 825 | fungi 826 | funky 827 | funny 828 | furor 829 | furry 830 | fussy 831 | fuzzy 832 | gaffe 833 | gaily 834 | gamer 835 | gamma 836 | gamut 837 | gassy 838 | gaudy 839 | gauge 840 | gaunt 841 | gauze 842 | gavel 843 | gawky 844 | gayer 845 | gayly 846 | gazer 847 | gecko 848 | geeky 849 | geese 850 | genie 851 | genre 852 | ghost 853 | ghoul 854 | giant 855 | giddy 856 | gipsy 857 | girly 858 | girth 859 | given 860 | giver 861 | glade 862 | gland 863 | glare 864 | glass 865 | glaze 866 | gleam 867 | glean 868 | glide 869 | glint 870 | gloat 871 | globe 872 | gloom 873 | glory 874 | gloss 875 | glove 876 | glyph 877 | gnash 878 | gnome 879 | godly 880 | going 881 | golem 882 | golly 883 | gonad 884 | goner 885 | goody 886 | gooey 887 | goofy 888 | goose 889 | gorge 890 | gouge 891 | gourd 892 | grace 893 | grade 894 | graft 895 | grail 896 | grain 897 | grand 898 | grant 899 | grape 900 | graph 901 | grasp 902 | grass 903 | grate 904 | grave 905 | gravy 906 | graze 907 | great 908 | greed 909 | green 910 | greet 911 | grief 912 | grill 913 | grime 914 | grimy 915 | grind 916 | gripe 917 | groan 918 | groin 919 | groom 920 | grope 921 | gross 922 | group 923 | grout 924 | grove 925 | growl 926 | grown 927 | gruel 928 | gruff 929 | grunt 930 | guard 931 | guava 932 | guess 933 | guest 934 | guide 935 | guild 936 | guile 937 | guilt 938 | guise 939 | gulch 940 | gully 941 | gumbo 942 | gummy 943 | guppy 944 | gusto 945 | gusty 946 | gypsy 947 | habit 948 | hairy 949 | halve 950 | handy 951 | happy 952 | hardy 953 | harem 954 | harpy 955 | harry 956 | harsh 957 | haste 958 | hasty 959 | hatch 960 | hater 961 | haunt 962 | haute 963 | haven 964 | havoc 965 | hazel 966 | heady 967 | heard 968 | heart 969 | heath 970 | heave 971 | heavy 972 | hedge 973 | hefty 974 | heist 975 | helix 976 | hello 977 | hence 978 | heron 979 | hilly 980 | hinge 981 | hippo 982 | hippy 983 | hitch 984 | hoard 985 | hobby 986 | hoist 987 | holly 988 | homer 989 | honey 990 | honor 991 | horde 992 | horny 993 | horse 994 | hotel 995 | hotly 996 | hound 997 | house 998 | hovel 999 | hover 1000 | howdy 1001 | human 1002 | humid 1003 | humor 1004 | humph 1005 | humus 1006 | hunch 1007 | hunky 1008 | hurry 1009 | husky 1010 | hussy 1011 | hutch 1012 | hydro 1013 | hyena 1014 | hymen 1015 | hyper 1016 | icily 1017 | icing 1018 | ideal 1019 | idiom 1020 | idiot 1021 | idler 1022 | idyll 1023 | igloo 1024 | iliac 1025 | image 1026 | imbue 1027 | impel 1028 | imply 1029 | inane 1030 | inbox 1031 | incur 1032 | index 1033 | inept 1034 | inert 1035 | infer 1036 | ingot 1037 | inlay 1038 | inlet 1039 | inner 1040 | input 1041 | inter 1042 | intro 1043 | ionic 1044 | irate 1045 | irony 1046 | islet 1047 | issue 1048 | itchy 1049 | ivory 1050 | jaunt 1051 | jazzy 1052 | jelly 1053 | jerky 1054 | jetty 1055 | jewel 1056 | jiffy 1057 | joint 1058 | joist 1059 | joker 1060 | jolly 1061 | joust 1062 | judge 1063 | juice 1064 | juicy 1065 | jumbo 1066 | jumpy 1067 | junta 1068 | junto 1069 | juror 1070 | kappa 1071 | karma 1072 | kayak 1073 | kebab 1074 | khaki 1075 | kinky 1076 | kiosk 1077 | kitty 1078 | knack 1079 | knave 1080 | knead 1081 | kneed 1082 | kneel 1083 | knelt 1084 | knife 1085 | knock 1086 | knoll 1087 | known 1088 | koala 1089 | krill 1090 | label 1091 | labor 1092 | laden 1093 | ladle 1094 | lager 1095 | lance 1096 | lanky 1097 | lapel 1098 | lapse 1099 | large 1100 | larva 1101 | lasso 1102 | latch 1103 | later 1104 | lathe 1105 | latte 1106 | laugh 1107 | layer 1108 | leach 1109 | leafy 1110 | leaky 1111 | leant 1112 | leapt 1113 | learn 1114 | lease 1115 | leash 1116 | least 1117 | leave 1118 | ledge 1119 | leech 1120 | leery 1121 | lefty 1122 | legal 1123 | leggy 1124 | lemon 1125 | lemur 1126 | leper 1127 | level 1128 | lever 1129 | libel 1130 | liege 1131 | light 1132 | liken 1133 | lilac 1134 | limbo 1135 | limit 1136 | linen 1137 | liner 1138 | lingo 1139 | lipid 1140 | lithe 1141 | liver 1142 | livid 1143 | llama 1144 | loamy 1145 | loath 1146 | lobby 1147 | local 1148 | locus 1149 | lodge 1150 | lofty 1151 | logic 1152 | login 1153 | loopy 1154 | loose 1155 | lorry 1156 | loser 1157 | louse 1158 | lousy 1159 | lover 1160 | lower 1161 | lowly 1162 | loyal 1163 | lucid 1164 | lucky 1165 | lumen 1166 | lumpy 1167 | lunar 1168 | lunch 1169 | lunge 1170 | lupus 1171 | lurch 1172 | lurid 1173 | lusty 1174 | lying 1175 | lymph 1176 | lynch 1177 | lyric 1178 | macaw 1179 | macho 1180 | macro 1181 | madam 1182 | madly 1183 | mafia 1184 | magic 1185 | magma 1186 | maize 1187 | major 1188 | maker 1189 | mambo 1190 | mamma 1191 | mammy 1192 | manga 1193 | mange 1194 | mango 1195 | mangy 1196 | mania 1197 | manic 1198 | manly 1199 | manor 1200 | maple 1201 | march 1202 | marry 1203 | marsh 1204 | mason 1205 | masse 1206 | match 1207 | matey 1208 | mauve 1209 | maxim 1210 | maybe 1211 | mayor 1212 | mealy 1213 | meant 1214 | meaty 1215 | mecca 1216 | medal 1217 | media 1218 | medic 1219 | melee 1220 | melon 1221 | mercy 1222 | merge 1223 | merit 1224 | merry 1225 | metal 1226 | meter 1227 | metro 1228 | micro 1229 | midge 1230 | midst 1231 | might 1232 | milky 1233 | mimic 1234 | mince 1235 | miner 1236 | minim 1237 | minor 1238 | minty 1239 | minus 1240 | mirth 1241 | miser 1242 | missy 1243 | mocha 1244 | modal 1245 | model 1246 | modem 1247 | mogul 1248 | moist 1249 | molar 1250 | moldy 1251 | money 1252 | month 1253 | moody 1254 | moose 1255 | moral 1256 | moron 1257 | morph 1258 | mossy 1259 | motel 1260 | motif 1261 | motor 1262 | motto 1263 | moult 1264 | mound 1265 | mount 1266 | mourn 1267 | mouse 1268 | mouth 1269 | mover 1270 | movie 1271 | mower 1272 | mucky 1273 | mucus 1274 | muddy 1275 | mulch 1276 | mummy 1277 | munch 1278 | mural 1279 | murky 1280 | mushy 1281 | music 1282 | musky 1283 | musty 1284 | myrrh 1285 | nadir 1286 | naive 1287 | nanny 1288 | nasal 1289 | nasty 1290 | natal 1291 | naval 1292 | navel 1293 | needy 1294 | neigh 1295 | nerdy 1296 | nerve 1297 | never 1298 | newer 1299 | newly 1300 | nicer 1301 | niche 1302 | niece 1303 | night 1304 | ninja 1305 | ninny 1306 | ninth 1307 | noble 1308 | nobly 1309 | noise 1310 | noisy 1311 | nomad 1312 | noose 1313 | north 1314 | nosey 1315 | notch 1316 | novel 1317 | nudge 1318 | nurse 1319 | nutty 1320 | nylon 1321 | nymph 1322 | oaken 1323 | obese 1324 | occur 1325 | ocean 1326 | octal 1327 | octet 1328 | odder 1329 | oddly 1330 | offal 1331 | offer 1332 | often 1333 | olden 1334 | older 1335 | olive 1336 | ombre 1337 | omega 1338 | onion 1339 | onset 1340 | opera 1341 | opine 1342 | opium 1343 | optic 1344 | orbit 1345 | order 1346 | organ 1347 | other 1348 | otter 1349 | ought 1350 | ounce 1351 | outdo 1352 | outer 1353 | outgo 1354 | ovary 1355 | ovate 1356 | overt 1357 | ovine 1358 | ovoid 1359 | owing 1360 | owner 1361 | oxide 1362 | ozone 1363 | paddy 1364 | pagan 1365 | paint 1366 | paler 1367 | palsy 1368 | panel 1369 | panic 1370 | pansy 1371 | papal 1372 | paper 1373 | parer 1374 | parka 1375 | parry 1376 | parse 1377 | party 1378 | pasta 1379 | paste 1380 | pasty 1381 | patch 1382 | patio 1383 | patsy 1384 | patty 1385 | pause 1386 | payee 1387 | payer 1388 | peace 1389 | peach 1390 | pearl 1391 | pecan 1392 | pedal 1393 | penal 1394 | pence 1395 | penne 1396 | penny 1397 | perch 1398 | peril 1399 | perky 1400 | pesky 1401 | pesto 1402 | petal 1403 | petty 1404 | phase 1405 | phone 1406 | phony 1407 | photo 1408 | piano 1409 | picky 1410 | piece 1411 | piety 1412 | piggy 1413 | pilot 1414 | pinch 1415 | piney 1416 | pinky 1417 | pinto 1418 | piper 1419 | pique 1420 | pitch 1421 | pithy 1422 | pivot 1423 | pixel 1424 | pixie 1425 | pizza 1426 | place 1427 | plaid 1428 | plain 1429 | plait 1430 | plane 1431 | plank 1432 | plant 1433 | plate 1434 | plaza 1435 | plead 1436 | pleat 1437 | plied 1438 | plier 1439 | pluck 1440 | plumb 1441 | plume 1442 | plump 1443 | plunk 1444 | plush 1445 | poesy 1446 | point 1447 | poise 1448 | poker 1449 | polar 1450 | polka 1451 | polyp 1452 | pooch 1453 | poppy 1454 | porch 1455 | poser 1456 | posit 1457 | posse 1458 | pouch 1459 | pound 1460 | pouty 1461 | power 1462 | prank 1463 | prawn 1464 | preen 1465 | press 1466 | price 1467 | prick 1468 | pride 1469 | pried 1470 | prime 1471 | primo 1472 | print 1473 | prior 1474 | prism 1475 | privy 1476 | prize 1477 | probe 1478 | prone 1479 | prong 1480 | proof 1481 | prose 1482 | proud 1483 | prove 1484 | prowl 1485 | proxy 1486 | prude 1487 | prune 1488 | psalm 1489 | pubic 1490 | pudgy 1491 | puffy 1492 | pulpy 1493 | pulse 1494 | punch 1495 | pupal 1496 | pupil 1497 | puppy 1498 | puree 1499 | purer 1500 | purge 1501 | purse 1502 | pushy 1503 | putty 1504 | pygmy 1505 | quack 1506 | quail 1507 | quake 1508 | qualm 1509 | quark 1510 | quart 1511 | quash 1512 | quasi 1513 | queen 1514 | queer 1515 | quell 1516 | query 1517 | quest 1518 | queue 1519 | quick 1520 | quiet 1521 | quill 1522 | quilt 1523 | quirk 1524 | quite 1525 | quota 1526 | quote 1527 | quoth 1528 | rabbi 1529 | rabid 1530 | racer 1531 | radar 1532 | radii 1533 | radio 1534 | rainy 1535 | raise 1536 | rajah 1537 | rally 1538 | ralph 1539 | ramen 1540 | ranch 1541 | randy 1542 | range 1543 | rapid 1544 | rarer 1545 | raspy 1546 | ratio 1547 | ratty 1548 | raven 1549 | rayon 1550 | razor 1551 | reach 1552 | react 1553 | ready 1554 | realm 1555 | rearm 1556 | rebar 1557 | rebel 1558 | rebus 1559 | rebut 1560 | recap 1561 | recur 1562 | recut 1563 | reedy 1564 | refer 1565 | refit 1566 | regal 1567 | rehab 1568 | reign 1569 | relax 1570 | relay 1571 | relic 1572 | remit 1573 | renal 1574 | renew 1575 | repay 1576 | repel 1577 | reply 1578 | rerun 1579 | reset 1580 | resin 1581 | retch 1582 | retro 1583 | retry 1584 | reuse 1585 | revel 1586 | revue 1587 | rhino 1588 | rhyme 1589 | rider 1590 | ridge 1591 | rifle 1592 | right 1593 | rigid 1594 | rigor 1595 | rinse 1596 | ripen 1597 | riper 1598 | risen 1599 | riser 1600 | risky 1601 | rival 1602 | river 1603 | rivet 1604 | roach 1605 | roast 1606 | robin 1607 | robot 1608 | rocky 1609 | rodeo 1610 | roger 1611 | rogue 1612 | roomy 1613 | roost 1614 | rotor 1615 | rouge 1616 | rough 1617 | round 1618 | rouse 1619 | route 1620 | rover 1621 | rowdy 1622 | rower 1623 | royal 1624 | ruddy 1625 | ruder 1626 | rugby 1627 | ruler 1628 | rumba 1629 | rumor 1630 | rupee 1631 | rural 1632 | rusty 1633 | sadly 1634 | safer 1635 | saint 1636 | salad 1637 | sally 1638 | salon 1639 | salsa 1640 | salty 1641 | salve 1642 | salvo 1643 | sandy 1644 | saner 1645 | sappy 1646 | sassy 1647 | satin 1648 | satyr 1649 | sauce 1650 | saucy 1651 | sauna 1652 | saute 1653 | savor 1654 | savoy 1655 | savvy 1656 | scald 1657 | scale 1658 | scalp 1659 | scaly 1660 | scamp 1661 | scant 1662 | scare 1663 | scarf 1664 | scary 1665 | scene 1666 | scent 1667 | scion 1668 | scoff 1669 | scold 1670 | scone 1671 | scoop 1672 | scope 1673 | score 1674 | scorn 1675 | scour 1676 | scout 1677 | scowl 1678 | scram 1679 | scrap 1680 | scree 1681 | screw 1682 | scrub 1683 | scrum 1684 | scuba 1685 | sedan 1686 | seedy 1687 | segue 1688 | seize 1689 | semen 1690 | sense 1691 | sepia 1692 | serif 1693 | serum 1694 | serve 1695 | setup 1696 | seven 1697 | sever 1698 | sewer 1699 | shack 1700 | shade 1701 | shady 1702 | shaft 1703 | shake 1704 | shaky 1705 | shale 1706 | shall 1707 | shalt 1708 | shame 1709 | shank 1710 | shape 1711 | shard 1712 | share 1713 | shark 1714 | sharp 1715 | shave 1716 | shawl 1717 | shear 1718 | sheen 1719 | sheep 1720 | sheer 1721 | sheet 1722 | sheik 1723 | shelf 1724 | shell 1725 | shied 1726 | shift 1727 | shine 1728 | shiny 1729 | shire 1730 | shirk 1731 | shirt 1732 | shoal 1733 | shock 1734 | shone 1735 | shook 1736 | shoot 1737 | shore 1738 | shorn 1739 | short 1740 | shout 1741 | shove 1742 | shown 1743 | showy 1744 | shrew 1745 | shrub 1746 | shrug 1747 | shuck 1748 | shunt 1749 | shush 1750 | shyly 1751 | siege 1752 | sieve 1753 | sight 1754 | sigma 1755 | silky 1756 | silly 1757 | since 1758 | sinew 1759 | singe 1760 | siren 1761 | sissy 1762 | sixth 1763 | sixty 1764 | skate 1765 | skier 1766 | skiff 1767 | skill 1768 | skimp 1769 | skirt 1770 | skulk 1771 | skull 1772 | skunk 1773 | slack 1774 | slain 1775 | slang 1776 | slant 1777 | slash 1778 | slate 1779 | slave 1780 | sleek 1781 | sleep 1782 | sleet 1783 | slept 1784 | slice 1785 | slick 1786 | slide 1787 | slime 1788 | slimy 1789 | sling 1790 | slink 1791 | sloop 1792 | slope 1793 | slosh 1794 | sloth 1795 | slump 1796 | slung 1797 | slunk 1798 | slurp 1799 | slush 1800 | slyly 1801 | smack 1802 | small 1803 | smart 1804 | smash 1805 | smear 1806 | smell 1807 | smelt 1808 | smile 1809 | smirk 1810 | smite 1811 | smith 1812 | smock 1813 | smoke 1814 | smoky 1815 | smote 1816 | snack 1817 | snail 1818 | snake 1819 | snaky 1820 | snare 1821 | snarl 1822 | sneak 1823 | sneer 1824 | snide 1825 | sniff 1826 | snipe 1827 | snoop 1828 | snore 1829 | snort 1830 | snout 1831 | snowy 1832 | snuck 1833 | snuff 1834 | soapy 1835 | sober 1836 | soggy 1837 | solar 1838 | solid 1839 | solve 1840 | sonar 1841 | sonic 1842 | sooth 1843 | sooty 1844 | sorry 1845 | sound 1846 | south 1847 | sower 1848 | space 1849 | spade 1850 | spank 1851 | spare 1852 | spark 1853 | spasm 1854 | spawn 1855 | speak 1856 | spear 1857 | speck 1858 | speed 1859 | spell 1860 | spelt 1861 | spend 1862 | spent 1863 | sperm 1864 | spice 1865 | spicy 1866 | spied 1867 | spiel 1868 | spike 1869 | spiky 1870 | spill 1871 | spilt 1872 | spine 1873 | spiny 1874 | spire 1875 | spite 1876 | splat 1877 | split 1878 | spoil 1879 | spoke 1880 | spoof 1881 | spook 1882 | spool 1883 | spoon 1884 | spore 1885 | sport 1886 | spout 1887 | spray 1888 | spree 1889 | sprig 1890 | spunk 1891 | spurn 1892 | spurt 1893 | squad 1894 | squat 1895 | squib 1896 | stack 1897 | staff 1898 | stage 1899 | staid 1900 | stain 1901 | stair 1902 | stake 1903 | stale 1904 | stalk 1905 | stall 1906 | stamp 1907 | stand 1908 | stank 1909 | stare 1910 | stark 1911 | start 1912 | stash 1913 | state 1914 | stave 1915 | stead 1916 | steak 1917 | steal 1918 | steam 1919 | steed 1920 | steel 1921 | steep 1922 | steer 1923 | stein 1924 | stern 1925 | stick 1926 | stiff 1927 | still 1928 | stilt 1929 | sting 1930 | stink 1931 | stint 1932 | stock 1933 | stoic 1934 | stoke 1935 | stole 1936 | stomp 1937 | stone 1938 | stony 1939 | stood 1940 | stool 1941 | stoop 1942 | store 1943 | stork 1944 | storm 1945 | story 1946 | stout 1947 | stove 1948 | strap 1949 | straw 1950 | stray 1951 | strip 1952 | strut 1953 | stuck 1954 | study 1955 | stuff 1956 | stump 1957 | stung 1958 | stunk 1959 | stunt 1960 | style 1961 | suave 1962 | sugar 1963 | suing 1964 | suite 1965 | sulky 1966 | sully 1967 | sumac 1968 | sunny 1969 | super 1970 | surer 1971 | surge 1972 | surly 1973 | sushi 1974 | swami 1975 | swamp 1976 | swarm 1977 | swash 1978 | swath 1979 | swear 1980 | sweat 1981 | sweep 1982 | sweet 1983 | swell 1984 | swept 1985 | swift 1986 | swill 1987 | swine 1988 | swing 1989 | swirl 1990 | swish 1991 | swoon 1992 | swoop 1993 | sword 1994 | swore 1995 | sworn 1996 | swung 1997 | synod 1998 | syrup 1999 | tabby 2000 | table 2001 | taboo 2002 | tacit 2003 | tacky 2004 | taffy 2005 | taint 2006 | taken 2007 | taker 2008 | tally 2009 | talon 2010 | tamer 2011 | tango 2012 | tangy 2013 | taper 2014 | tapir 2015 | tardy 2016 | tarot 2017 | taste 2018 | tasty 2019 | tatty 2020 | taunt 2021 | tawny 2022 | teach 2023 | teary 2024 | tease 2025 | teddy 2026 | teeth 2027 | tempo 2028 | tenet 2029 | tenor 2030 | tense 2031 | tenth 2032 | tepee 2033 | tepid 2034 | terra 2035 | terse 2036 | testy 2037 | thank 2038 | theft 2039 | their 2040 | theme 2041 | there 2042 | these 2043 | theta 2044 | thick 2045 | thief 2046 | thigh 2047 | thing 2048 | think 2049 | third 2050 | thong 2051 | thorn 2052 | those 2053 | three 2054 | threw 2055 | throb 2056 | throw 2057 | thrum 2058 | thumb 2059 | thump 2060 | thyme 2061 | tiara 2062 | tibia 2063 | tidal 2064 | tiger 2065 | tight 2066 | tilde 2067 | timer 2068 | timid 2069 | tipsy 2070 | titan 2071 | tithe 2072 | title 2073 | toast 2074 | today 2075 | toddy 2076 | token 2077 | tonal 2078 | tonga 2079 | tonic 2080 | tooth 2081 | topaz 2082 | topic 2083 | torch 2084 | torso 2085 | torus 2086 | total 2087 | totem 2088 | touch 2089 | tough 2090 | towel 2091 | tower 2092 | toxic 2093 | toxin 2094 | trace 2095 | track 2096 | tract 2097 | trade 2098 | trail 2099 | train 2100 | trait 2101 | tramp 2102 | trash 2103 | trawl 2104 | tread 2105 | treat 2106 | trend 2107 | triad 2108 | trial 2109 | tribe 2110 | trice 2111 | trick 2112 | tried 2113 | tripe 2114 | trite 2115 | troll 2116 | troop 2117 | trope 2118 | trout 2119 | trove 2120 | truce 2121 | truck 2122 | truer 2123 | truly 2124 | trump 2125 | trunk 2126 | truss 2127 | trust 2128 | truth 2129 | tryst 2130 | tubal 2131 | tuber 2132 | tulip 2133 | tulle 2134 | tumor 2135 | tunic 2136 | turbo 2137 | tutor 2138 | twang 2139 | tweak 2140 | tweed 2141 | tweet 2142 | twice 2143 | twine 2144 | twirl 2145 | twist 2146 | twixt 2147 | tying 2148 | udder 2149 | ulcer 2150 | ultra 2151 | umbra 2152 | uncle 2153 | uncut 2154 | under 2155 | undid 2156 | undue 2157 | unfed 2158 | unfit 2159 | unify 2160 | union 2161 | unite 2162 | unity 2163 | unlit 2164 | unmet 2165 | unset 2166 | untie 2167 | until 2168 | unwed 2169 | unzip 2170 | upper 2171 | upset 2172 | urban 2173 | urine 2174 | usage 2175 | usher 2176 | using 2177 | usual 2178 | usurp 2179 | utile 2180 | utter 2181 | vague 2182 | valet 2183 | valid 2184 | valor 2185 | value 2186 | valve 2187 | vapid 2188 | vapor 2189 | vault 2190 | vaunt 2191 | vegan 2192 | venom 2193 | venue 2194 | verge 2195 | verse 2196 | verso 2197 | verve 2198 | vicar 2199 | video 2200 | vigil 2201 | vigor 2202 | villa 2203 | vinyl 2204 | viola 2205 | viper 2206 | viral 2207 | virus 2208 | visit 2209 | visor 2210 | vista 2211 | vital 2212 | vivid 2213 | vixen 2214 | vocal 2215 | vodka 2216 | vogue 2217 | voice 2218 | voila 2219 | vomit 2220 | voter 2221 | vouch 2222 | vowel 2223 | vying 2224 | wacky 2225 | wafer 2226 | wager 2227 | wagon 2228 | waist 2229 | waive 2230 | waltz 2231 | warty 2232 | waste 2233 | watch 2234 | water 2235 | waver 2236 | waxen 2237 | weary 2238 | weave 2239 | wedge 2240 | weedy 2241 | weigh 2242 | weird 2243 | welch 2244 | welsh 2245 | wench 2246 | whack 2247 | whale 2248 | wharf 2249 | wheat 2250 | wheel 2251 | whelp 2252 | where 2253 | which 2254 | whiff 2255 | while 2256 | whine 2257 | whiny 2258 | whirl 2259 | whisk 2260 | white 2261 | whole 2262 | whoop 2263 | whose 2264 | widen 2265 | wider 2266 | widow 2267 | width 2268 | wield 2269 | wight 2270 | willy 2271 | wimpy 2272 | wince 2273 | winch 2274 | windy 2275 | wiser 2276 | wispy 2277 | witch 2278 | witty 2279 | woken 2280 | woman 2281 | women 2282 | woody 2283 | wooer 2284 | wooly 2285 | woozy 2286 | wordy 2287 | world 2288 | worry 2289 | worse 2290 | worst 2291 | worth 2292 | would 2293 | wound 2294 | woven 2295 | wrack 2296 | wrath 2297 | wreak 2298 | wreck 2299 | wrest 2300 | wring 2301 | wrist 2302 | write 2303 | wrong 2304 | wrote 2305 | wrung 2306 | wryly 2307 | yacht 2308 | yearn 2309 | yeast 2310 | yield 2311 | young 2312 | youth 2313 | zebra 2314 | zesty 2315 | zonal 2316 | --------------------------------------------------------------------------------