Created
November 8, 2018 17:23
-
-
Save QuentinAndre/f69be9338db73751b27bafaa95bde13d to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| var default_matrix = [ | |
| ['V', 'H', 'W', 'X', 'S', 'C', 'E', 'P', 'T', 'E', 'R', 'C', 'R', 'S', 'P', 'S', 'J', 'T'], | |
| ['S', 'T', 'T', 'T', 'N', 'X', 'D', 'Y', 'D', 'X', 'L', 'M', 'W', 'K', 'A', 'O', 'B', 'C'], | |
| ['G', 'N', 'A', 'R', 'C', 'W', 'O', 'E', 'A', 'Y', 'T', 'R', 'S', 'V', 'L', 'V', 'G', 'J'], | |
| ['C', 'T', 'O', 'D', 'O', 'P', 'O', 'F', 'S', 'N', 'N', 'R', 'A', 'H', 'A', 'E', 'G', 'P'], | |
| ['E', 'O', 'B', 'M', 'R', 'S', 'D', 'R', 'E', 'C', 'O', 'A', 'O', 'E', 'C', 'R', 'I', 'A'], | |
| ['R', 'I', 'L', 'I', 'M', 'F', 'N', 'M', 'C', 'N', 'E', 'U', 'S', 'K', 'E', 'E', 'P', 'A'], | |
| ['J', 'E', 'N', 'O', 'A', 'O', 'N', 'O', 'O', 'M', 'S', 'N', 'I', 'T', 'K', 'I', 'U', 'H'], | |
| ['H', 'C', 'T', 'M', 'N', 'R', 'C', 'H', 'C', 'E', 'O', 'N', 'T', 'N', 'Y', 'G', 'W', 'L'], | |
| ['E', 'T', 'I', 'R', 'E', 'Y', 'H', 'O', 'H', 'M', 'G', 'T', 'I', 'D', 'H', 'N', 'L', 'N'], | |
| ['H', 'L', 'R', 'V', 'A', 'E', 'T', 'O', 'L', 'D', 'L', 'G', 'S', 'L', 'U', 'I', 'K', 'J'], | |
| ['Y', 'T', 'O', 'I', 'A', 'H', 'L', 'I', 'O', 'O', 'H', 'A', 'A', 'U', 'N', 'K', 'V', 'F'], | |
| ['W', 'G', 'L', 'D', 'B', 'D', 'C', 'M', 'I', 'T', 'R', 'W', 'E', 'E', 'C', 'X', 'E', 'W'], | |
| ['L', 'A', 'Y', 'O', 'R', 'B', 'T', 'U', 'K', 'D', 'J', 'D', 'B', 'R', 'T', 'K', 'R', 'A'], | |
| ['S', 'E', 'A', 'L', 'M', 'U', 'C', 'T', 'W', 'I', 'N', 'D', 'S', 'O', 'R', 'C', 'U', 'C'], | |
| ['Z', 'N', 'E', 'T', 'N', 'E', 'M', 'A', 'I', 'L', 'R', 'A', 'P', 'Z', 'M', 'I', 'L', 'B'], | |
| ['Z', 'T', 'H', 'R', 'O', 'N', 'E', 'B', 'P', 'A', 'T', 'R', 'O', 'N', 'A', 'G', 'E', 'W'], | |
| ['V', 'P', 'K', 'M', 'V', 'G', 'F', 'T', 'R', 'A', 'D', 'I', 'T', 'I', 'O', 'N', 'R', 'Q'], | |
| ['O', 'Z', 'A', 'C', 'G', 'R', 'N', 'T', 'A', 'O', 'Y', 'D', 'L', 'G', 'X', 'C', 'M', 'C'] | |
| ]; | |
| var grid1 = [ | |
| ['A', 'I', 'V', 'T', 'A', 'L', 'N', 'I', 'E', 'T', 'S', 'N', 'E', 'T', 'H', 'C', 'E', 'I', 'L'], | |
| ['G', 'N', 'E', 'T', 'H', 'E', 'R', 'L', 'A', 'N', 'D', 'S', 'N', 'P', 'V', 'A', 'A', 'P', 'D'], | |
| ['R', 'O', 'M', 'A', 'N', 'I', 'A', 'T', 'V', 'I', 'S', 'R', 'O', 'I', 'I', 'I', 'O', 'C', 'B'], | |
| ['U', 'T', 'E', 'J', 'V', 'I', 'E', 'T', 'Y', 'C', 'N', 'L', 'E', 'R', 'A', 'R', 'I', 'D', 'I'], | |
| ['O', 'V', 'P', 'M', 'J', 'J', 'S', 'C', 'O', 'B', 'A', 'A', 'T', 'C', 'T', 'P', 'N', 'E', 'G'], | |
| ['B', 'E', 'C', 'I', 'V', 'E', 'S', 'T', 'N', 'N', 'T', 'S', 'U', 'U', 'E', 'A', 'S', 'V', 'Y'], | |
| ['M', 'A', 'E', 'I', 'K', 'A', 'L', 'L', 'D', 'A', 'U', 'W', 'G', 'H', 'L', 'E', 'X', 'C', 'A'], | |
| ['E', 'G', 'J', 'N', 'L', 'A', 'T', 'V', 'O', 'A', 'R', 'A', 'B', 'R', 'T', 'B', 'R', 'Z', 'W'], | |
| ['X', 'E', 'J', 'W', 'N', 'B', 'S', 'L', 'E', 'V', 'L', 'F', 'E', 'N', 'U', 'I', 'V', 'G', 'R'], | |
| ['U', 'Y', 'P', 'D', 'I', 'V', 'U', 'S', 'A', 'E', 'A', 'Z', 'L', 'L', 'R', 'L', 'L', 'S', 'O'], | |
| ['L', 'R', 'R', 'M', 'A', 'C', 'T', 'P', 'N', 'M', 'T', 'K', 'G', 'T', 'N', 'V', 'P', 'N', 'N'], | |
| ['I', 'A', 'A', 'N', 'A', 'O', 'E', 'I', 'E', 'I', 'Y', 'A', 'I', 'J', 'N', 'S', 'K', 'D', 'J'], | |
| ['L', 'G', 'N', 'I', 'N', 'C', 'A', 'L', 'W', 'R', 'R', 'H', 'U', 'A', 'E', 'D', 'R', 'N', 'D'], | |
| ['I', 'N', 'I', 'I', 'T', 'R', 'E', 'S', 'A', 'I', 'H', 'V', 'M', 'L', 'J', 'N', 'A', 'A', 'J'], | |
| ['N', 'U', 'A', 'V', 'K', 'A', 'A', 'D', 'A', 'N', 'P', 'C', 'A', 'O', 'V', 'A', 'M', 'L', 'Y'], | |
| ['U', 'H', 'Z', 'U', 'V', 'J', 'O', 'G', 'O', 'R', 'D', 'W', 'E', 'V', 'J', 'L', 'N', 'G', 'L'], | |
| ['N', 'E', 'D', 'E', 'W', 'S', 'B', 'R', 'N', 'N', 'U', 'V', 'J', 'Z', 'T', 'E', 'E', 'N', 'A'], | |
| ['D', 'S', 'U', 'R', 'A', 'L', 'E', 'B', 'C', 'T', 'I', 'I', 'G', 'I', 'C', 'R', 'D', 'E', 'T'], | |
| ['D', 'N', 'A', 'L', 'N', 'I', 'F', 'G', 'E', 'R', 'M', 'A', 'N', 'Y', 'W', 'I', 'M', 'E', 'I']]; | |
| var words1 = ['AUSTRIA', 'BELARUS', 'BELGIUM', 'BULGARIA', 'CROATIA', 'CZECHREPUBLIC', 'DENMARK', 'ENGLAND', 'ESTONIA', | |
| 'FINLAND', 'FRANCE', 'GERMANY', 'GREECE', 'HUNGARY', 'ICELAND', 'IRELAND', 'ITALY', 'LATVIA', 'LIECHTENSTEIN', | |
| 'LITHUANIA', 'LUXEMBOURG', 'MACEDONIA', 'MALTA', 'NETHERLANDS', 'NORWAY', 'POLAND', 'PORTUGAL', 'ROMANIA', | |
| 'SCOTLAND', 'SLOVAKIA', 'SPAIN', 'SWEDEN', 'SWITZERLAND', 'UKRAINE', 'WALES']; | |
| var grid2 = [ | |
| ['K', 'P', 'E', 'N', 'C', 'I', 'L', 'C', 'A', 'D', 'N', 'E', 'G ', 'A', 'H', 'L', 'B'], | |
| ['Y', 'I', 'L', 'E', 'T', 'T', 'E', 'R', 'S', 'L', 'B', 'M', 'E', 'M', 'O', 'Y', 'T'], | |
| ['E', 'J', 'S', 'J', 'L', 'K', 'I', 'C', 'R', 'P', 'B', 'C', 'C', 'J', 'X', 'R', 'D'], | |
| ['C', 'E', 'G', 'V', 'Y', 'F', 'Q', 'X', 'H', 'L', 'M', 'M', 'O', 'K', 'E', 'A', 'M'], | |
| ['U', 'T', 'N', 'E', 'M', 'U', 'C', 'O', 'D', 'A', 'I', 'A', 'V', 'G', 'M', 'N', 'W'], | |
| ['D', 'M', 'R', 'N', 'T', 'J', 'P', 'R', 'L', 'R', 'I', 'A', 'T', 'K', 'S', 'O', 'T'], | |
| ['I', 'W', 'P', 'E', 'X', 'G', 'A', 'E', 'E', 'W', 'M', 'R', 'M', 'S', 'T', 'I', 'S'], | |
| ['A', 'Z', 'W', 'H', 'P', 'D', 'C', 'T', 'N', 'I', 'E', 'G ', 'A', 'E', 'A', 'T', 'T'], | |
| ['R', 'R', 'U', 'J', 'N', 'A', 'U', 'F', 'R', 'S', 'T', 'E', 'P', 'D', 'P', 'C', 'A'], | |
| ['Y', 'I', 'D', 'E', 'E', 'P', 'P', 'L', 'P', 'R', 'O', 'D', 'P', 'T', 'L', 'I', 'T'], | |
| ['T', 'R', 'L', 'N', 'M', 'P', 'O', 'G', 'U', 'B', 'N', 'N', 'O', 'R', 'E', 'D', 'I'], | |
| ['X', 'A', 'O', 'O', 'L', 'F', 'N', 'L', 'L', 'H', 'R', 'A', 'I', 'A', 'R', 'E', 'O'], | |
| ['C', 'H', 'C', 'V', 'F', 'I', 'E', 'O', 'C', 'X', 'R', 'H', 'N', 'V', 'D', 'T', 'N'], | |
| ['P', 'T', 'S', 'I', 'T', 'R', 'T', 'X', 'S', 'R', 'O', 'T', 'T', 'E', 'L', 'R', 'E'], | |
| ['B', 'A', 'C', 'E', 'G', 'T', 'E', 'T', 'R', 'V', 'I', 'R', 'M', 'L', 'R', 'O', 'R'], | |
| ['K', 'E', 'E', 'O', 'E', 'L', 'X', 'I', 'D', 'H', 'G', 'O', 'E', 'S', 'O', 'P', 'Y'], | |
| ['Y', 'M', 'X', 'R', 'A', 'F', 'X', 'B', 'O', 'S', 'S', 'H', 'N', 'X', 'Z', 'E', 'C'], | |
| ['L', 'X', 'C', 'A', 'V', 'H', 'U', 'A', 'E', 'R', 'I', 'S', 'T', 'B', 'T', 'R', 'X'], | |
| ['G', 'A', 'H', 'J', 'F', 'T', 'O', 'G', 'U', 'N', 'I', 'G ', 'N', 'I', 'L', 'I', 'F'] | |
| ]; | |
| var words2 = ['AGENDA', 'APPOINTMENT', 'BLOTTER', 'BOSS', 'CALENDAR', 'CHAIR', 'COMPUTER', 'DESK', 'DIARY', | |
| 'DICTIONARY', 'DOCUMENT', 'FAX', 'FILING', 'LETTER', 'MAIL', 'MEETING', 'MEMO', 'NOTE', 'OFFICE', 'PAPER', | |
| 'PENCIL', 'PENS', 'PHONE', 'REPORT', 'RULER', 'SHORTHAND', 'STAMPS', 'STATIONERY', 'STAPLER', 'TRAVEL', 'XEROX']; | |
| var default_words = [ | |
| 'throne', | |
| 'palace', | |
| 'tradition', | |
| 'family', | |
| 'descent', | |
| 'royal', | |
| 'kingdom', | |
| 'prince', | |
| 'law', | |
| 'earl', | |
| 'government', | |
| 'charter', | |
| 'sovereign', | |
| 'orb', | |
| 'commons' | |
| ]; | |
| class Chronometer { | |
| constructor() { | |
| this.elapsed = 0; | |
| this.timer = setInterval(() => this.tick(), 1000); | |
| } | |
| tick() { | |
| this.elapsed = this.elapsed + 1; | |
| } | |
| getElapsed() { | |
| return this.elapsed; | |
| } | |
| } | |
| function wordsToUpperCase(words) { | |
| for (var i = 0; i < words.length; i++) { | |
| words[i] = words[i].toUpperCase(); | |
| } | |
| return words; | |
| } | |
| class WordSearch { | |
| constructor(o) { | |
| let obj = o ? o : { | |
| 'words': default_words, | |
| 'wordsGrid': default_matrix, | |
| 'onFindWord': () => null, | |
| 'parentId': "mydiv" | |
| }; | |
| this.wordsGrid = obj.wordsGrid; | |
| this.words = wordsToUpperCase(obj.words); | |
| this.onFindWord = obj.onFindWord; | |
| this.rowSize = this.wordsGrid.length; | |
| this.colSize = this.wordsGrid[0].length; | |
| this.timeToFind = new Array(this.words.length).fill(-1); | |
| this.matrix = this.initMatrix(); | |
| this.parent = document.getElementById(obj.parentId); | |
| this.timer = new Chronometer(); | |
| this.drawGameArea(); | |
| this.displayScore(); | |
| } | |
| drawGameArea() { | |
| var scoreArea = document.createElement("h2"); | |
| var scoreLabel = document.createElement("div"); | |
| scoreLabel.id = "score"; | |
| scoreArea.append(scoreLabel); | |
| this.parent.appendChild(scoreArea); | |
| var gridArea = document.createElement("section"); | |
| gridArea.setAttribute("class", "ws-area"); | |
| this.drawMatrix(gridArea); | |
| this.parent.appendChild(gridArea); | |
| var wordsArea = document.createElement("ul"); | |
| wordsArea.setAttribute("class", "ws-words"); | |
| this.drawWordList(wordsArea); | |
| this.parent.appendChild(wordsArea); | |
| } | |
| getScore() { | |
| return this.timeToFind.map(i => i > 0 ? 1 : 0).reduce((a, b) => a + b); | |
| } | |
| getRemaining() { | |
| return this.timeToFind.map(i => i > 0 ? 0 : 1).reduce((a, b) => a + b); | |
| } | |
| getTiming() { | |
| return this.timeToFind.slice(); | |
| } | |
| displayScore() { | |
| document.getElementById("score").innerHTML = "Found " + this.getScore() + " out of " + this.words.length + " words so far."; | |
| } | |
| initMatrix() { | |
| let matrix = []; | |
| for (var row = 0; row < this.rowSize; row++) { | |
| for (var col = 0; col < this.colSize; col++) { | |
| var item = { | |
| letter: this.wordsGrid[row][col], // Default value | |
| row: row, | |
| col: col | |
| }; | |
| if (!matrix[row]) { | |
| matrix[row] = []; | |
| } | |
| matrix[row][col] = item; | |
| } | |
| } | |
| return matrix; | |
| } | |
| drawWordList(target) { | |
| var words = this.words; | |
| for (var i = 0; i < words.length; i++) { | |
| var liEl = document.createElement('li'); | |
| liEl.id = words[i]; | |
| liEl.setAttribute('class', 'ws-word'); | |
| liEl.setAttribute("text-decoration", "none"); | |
| liEl.innerHTML = words[i]; | |
| target.appendChild(liEl); | |
| } | |
| } | |
| getItem(row, col) { | |
| return (this.matrix[row] ? this.matrix[row][col] : undefined); | |
| } | |
| getItems(rowFrom, colFrom, rowTo, colTo) { | |
| var items = []; | |
| if (rowFrom === rowTo || colFrom === colTo || Math.abs(rowTo - rowFrom) === Math.abs(colTo - colFrom)) { | |
| var shiftY = (rowFrom === rowTo) ? 0 : (rowTo > rowFrom) ? 1 : -1, | |
| shiftX = (colFrom === colTo) ? 0 : (colTo > colFrom) ? 1 : -1, | |
| row = rowFrom, | |
| col = colFrom; | |
| items.push(this.getItem(row, col)); | |
| do { | |
| row += shiftY; | |
| col += shiftX; | |
| items.push(this.getItem(row, col)); | |
| } while (row !== rowTo || col !== colTo); | |
| } | |
| return items; | |
| } | |
| drawMatrix(target) { | |
| var rowcount = this.rowSize; | |
| var columncount = this.colSize; | |
| for (var row = 0; row < rowcount; row++) { | |
| // New row | |
| var divEl = document.createElement('div'); | |
| divEl.setAttribute('class', 'ws-row'); | |
| target.appendChild(divEl); | |
| for (var col = 0; col < columncount; col++) { | |
| var item = this.matrix[row][col]; | |
| var cvEl = document.createElement('canvas'); | |
| cvEl.setAttribute('class', 'ws-col'); | |
| cvEl.setAttribute('width', 25); | |
| cvEl.setAttribute('height', 25); | |
| // Fill text in middle center | |
| var x = cvEl.width / 2, | |
| y = cvEl.height / 2; | |
| var ctx = cvEl.getContext('2d'); | |
| ctx.font = '400 18px Calibri'; | |
| ctx.textAlign = 'center'; | |
| ctx.textBaseline = 'middle'; | |
| ctx.fillStyle = '#333'; // Text color | |
| ctx.fillText(item.letter, x, y); | |
| // Add event listeners | |
| cvEl.addEventListener('mousedown', this.handleMousedown(item)); | |
| cvEl.addEventListener('mouseover', this.handleMouseover(item)); | |
| cvEl.addEventListener('mouseup', this.handleMouseup()); | |
| divEl.appendChild(cvEl); | |
| } | |
| } | |
| } | |
| handleMouseover(item) { | |
| var that = this; | |
| return function () { | |
| if (that.selectFrom) { | |
| that.selected = that.getItems(that.selectFrom.row, that.selectFrom.col, item.row, item.col); | |
| that.clearHighlight(); | |
| for (var i = 0; i < that.selected.length; i++) { | |
| var current = that.selected[i], | |
| row = current.row + 1, | |
| col = current.col + 1, | |
| el = document.querySelector('.ws-row:nth-child(' + row + ') .ws-col:nth-child(' + col + ')'); | |
| el.className += ' ws-selected'; | |
| } | |
| } | |
| } | |
| } | |
| handleMouseup() { | |
| var that = this; | |
| return function () { | |
| that.selectFrom = null; | |
| that.clearHighlight(); | |
| that.validateSelection(that.selected); | |
| that.selected = []; | |
| } | |
| } | |
| handleMousedown(item) { | |
| var that = this; | |
| return function () { | |
| that.selectFrom = item; | |
| } | |
| } | |
| clearHighlight() { | |
| var selectedEls = document.querySelectorAll('.ws-selected'); | |
| for (var i = 0; i < selectedEls.length; i++) { | |
| selectedEls[i].classList.remove('ws-selected'); | |
| } | |
| } | |
| markAsFound(selected) { | |
| for (var i = 0; i < selected.length; i++) { | |
| var row = selected[i].row + 1, | |
| col = selected[i].col + 1, | |
| el = document.querySelector('.ws-row:nth-child(' + row + ') .ws-col:nth-child(' + col + ')'); | |
| el.classList.add('ws-found'); | |
| } | |
| this.displayScore(); | |
| this.onFindWord(); | |
| } | |
| validateSelection(selected) { | |
| var wordSelected = ''; | |
| for (var i = 0; i < selected.length; i++) { | |
| wordSelected += selected[i].letter; | |
| } | |
| var wordSelectedR = wordSelected.split('').reverse().join(''); | |
| var indexOfWord = this.words.indexOf(wordSelected); | |
| var indexOfWordR = this.words.indexOf(wordSelectedR); | |
| if (indexOfWord > -1) { | |
| if (this.timeToFind[indexOfWord] === -1) { | |
| this.timeToFind[indexOfWord] = this.timer.getElapsed(); | |
| var ele = document.getElementById(wordSelected); | |
| ele.style.setProperty("text-decoration", "line-through"); | |
| ele.style.setProperty("color", "red"); | |
| ele.setAttribute("text-decoration", "line-through"); | |
| this.markAsFound(selected); | |
| } | |
| } | |
| if (indexOfWordR > -1) { | |
| if (this.timeToFind[indexOfWordR] === -1) { | |
| this.timeToFind[indexOfWordR] = this.timer.getElapsed(); | |
| var ele = document.getElementById(wordSelectedR); | |
| ele.style.setProperty("text-decoration", "line-through"); | |
| ele.style.setProperty("color", "red"); | |
| ele.setAttribute("text-decoration", "line-through"); | |
| this.markAsFound(selected); | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment