Week 4 Sec 1 – 1 (Branch 1475)
✨ นายภานุวัฒน์ ก้องจันทร์สว่าง
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device=width, initial-scale=1.0"> <meta http-equiv="equiv="X-Ua-Compatible" content="ie-edge"> <title>24 Game</title> <style> @import url('https://fonts.googleapis.com/css?family=Copse&display=swap'); *, *::before, *::after { box-sizing: border-box; } :root { --card-height: 80vh; -webkit-tap-highlight-color: transparent; } body { margin: 0; width: 100vw; height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; background-color: rgba(0,0,256,0.8); overflow: hidden; } .card { width: var(--card-height); height: var(--card-height); justify-items: center; align-items: center; display: grid; grid-template-columns: repeat(3, calc(var(--card-height) / 3)); grid-template-rows: repeat(3, calc(var(--card-height) / 3)); background-color: orange; border-radius: 50%; } .check-box { cursor: pointer; position: absolute; display: grid; justify-items: center; align-items: center; top: 1.5vh; width: calc(var(--card-height) * 1.1); height: calc(var(--card-height) * 1.15); font-size: 15vh; color: rgba(256, 256, 256, 0.8); background-color: rgba(0,0,0,0.8); border-radius: 5vh; z-index: 20; } .check-box::selection { cursor: none; } .check { margin-top: -20%; width: calc(var(--card-height) * 0.5); height: calc(var(--card-height) * 0.9); transform: rotate(45deg); border-bottom: calc(var(--card-height) * 0.15) solid greenyellow; border-right: calc(var(--card-height) * 0.15) solid greenyellow; } .dummy { position: absolute; display: none; } .corner { width: calc(var(--card-height) * 0.5); height: calc(var(--card-height) * 0.5); } .top-left-corner { background: repeating-linear-gradient(45deg, red, red 1vh, white 1vh, white 1.5vh); clip-path: polygon(0% 0%, 40% 0, 100% 100%, 0 40%); margin-top: 75%; margin-left: 75%; } .top-right-corner { background: repeating-linear-gradient(-45deg, red, red 1vh, white 1vh, white 1.5vh); clip-path: polygon(60% 0, 100% 0%, 100% 40%, 0 100%); margin-top: 75%; margin-right: 75%; } .bottom-left-corner { background: repeating-linear-gradient(-45deg, red, red 1vh, white 1vh, white 1.5vh); clip-path: polygon(0% 60%, 100% 0, 40% 100%, 0 100%); margin-bottom: 75%; margin-left: 75%; } .bottom-right-corner { background: repeating-linear-gradient(45deg, red, red 1vh, white 1vh, white 1.5vh); clip-path: polygon(0% 0%, 100% 60%, 100% 100%, 60% 100%); margin-bottom: 75%; margin-right: 75%; } .number-button { font-family: "Copse"; text-align: center; cursor: pointer; line-height: calc(var(--card-height) / 3);; width: calc(var(--card-height) / 3); height: calc(var(--card-height) / 3); border-radius: 50%; } .number-button.selected { color: pink; text-shadow: 0 0 5px black; } .button::selection{ color: none; } .empty { color: none; pointer-events: none; } .center { width: calc(var(--card-height) / 6); height: calc(var(--card-height) / 6); background-color: white; border: 0.3vh solid red; z-index: 10; text-align: center; align-content: center; justify-content: center; display: grid; grid-gap: 1vh; grid-template-columns: repeat(2, auto) } .addition, .subtraction, .multiplication, .division { cursor: pointer; font-family: "Copse"; font-size: calc(var(--card-height) * 0.045); width: calc(var(--card-height) / 16); height: calc(var(--card-height) / 16); background-color: rgba(256,0,0,0.5); border: 0.2vh solid black; border-radius: 50%; z-index: 15; } .addition.selected, .subtraction.selected, .multiplication.selected, .division.selected { background-color: pink; } .controls { margin-top: 2vh; display: grid; grid-template-columns: repeat(4, calc(var(--card-height) * 0.24)); grid-gap: 1vw; text-align: center; align-items: center; } .rules, .answer, .hint, .reset { cursor: pointer; font-size: 3vh; border: 0.3vh solid black; border-radius: 1000px; background-color: orange; } .text-box { cursor: default; visibility: visible; grid-column: 1 / 5; font-size: calc(var(--card-height) * 0.05); height: calc(var(--card-height) * 0.1); line-height: calc(var(--card-height) * 0.1); color: rgba(255,255,255,0.8); background-color: rgba(0,0,0,0.5); border-radius: 1000px; } .text-box::selection { color: none; } .hidden { visibility: hidden; } @media (max-width: 500px) { :root { --card-height: 100vw; } .center { width: calc(var(--card-height) / 4); height: calc(var(--card-height) / 4); grid-gap: 1vw; } .addition, .subtraction, .multiplication, .division { cursor: pointer; font-family: "Copse"; font-size: calc(var(--card-height) * 0.075); width: calc(var(--card-height) / 10); height: calc(var(--card-height) / 10); background-color: rgba(256,0,0,0.5); border: 0.2vh solid black; border-radius: 50%; z-index: 15; } .check-box { top: 12%; width: calc(var(--card-height)); height: 70vh; } .text-box { width: 99vw; } } </style> </head> <body> <div class="card"> <div class="check-box hidden" checkBox> <div class="check"></div> Again? </div> <div class="corner top-left-corner"></div> <div class="number-button button span-three" numberButton></div> <div class="corner top-right-corner"></div> <div class="number-button button" numberButton></div> <div class="center"> <div class="addition button" operationButton></div> <div class="subtraction button" operationButton></div> <div class="multiplication button" operationButton></div> <div class="division button" operationButton></div> </div> <div class="number-button button" numberButton></div> <div class="corner bottom-left-corner"></div> <div class="number-button button span-three" numberButton></div> <div class="corner bottom-right-corner"></div> <div class="dummy" dummy></div> </div> <div class="controls"> <div class="answer button" answerButton></div> <div class="hint button" hintButton></div> <div class="rules button" rulesButton></div> <div class="reset button" resetButton></div> <div class="text-box hidden" textBox></div> </div> </body> <script> class twentyFourGame { constructor() { this.dummyOperand = document.querySelector('[dummy]') this.dummyOperation = document.querySelector('[dummy]') this.newNumbers() } clear() { this.firstOperand = this.dummyOperand this.secondOperand = this.dummyOperand this.activeOperation = this.dummyOperation } newNumbers() { this.clear() this.randomizeNumbers() this.populateNumbers() } randomizeNumbers() { let base = 24 answerArray.splice(0, answerArray.length) for (let i = 0; i < 3; i++) { let operation = Math.floor((Math.random() * 6)) % 4 let nextNumber = Math.floor((Math.random() * 10)) + 2 if (operation === 3) { if ((base + nextNumber) > 24) { i-- continue } answerArray.push(nextNumber) answerArray.push(' − ') base = base + nextNumber } else if (operation === 2) { if ((base - nextNumber) < 1) { i-- continue } answerArray.push(nextNumber) answerArray.push(' + ') base = base - nextNumber } else if (operation === 1) { if ((base * nextNumber) > 32) { i-- continue } answerArray.push(nextNumber) answerArray.push(' ÷ ') base = base * nextNumber } else { if (base % nextNumber !== 0) { i-- continue } answerArray.push(nextNumber) answerArray.push(' × ') base = base / nextNumber } operationsArray[i] = operationLib[operation] } if (base > 16) { this.randomizeNumbers() } else { answerArray.push(base) answerArray.reverse() } } populateNumbers() { let randomOrder = Math.floor(Math.random() * 4) numberButtonElements.forEach((number, index) => { number.innerText = `${answerArray[2*((randomOrder + index) % 4)]}` number.classList.remove('empty') number.classList.remove('selected') number.style.fontSize = `calc(var(--card-height) / (${answerArray[2*((randomOrder + index) % 4)].toString().length} + 3.5)` }) } chooseOperation(operation) { if (this.activeOperation === operation) { this.activeOperation.classList.remove('selected') this.activeOperation = this.dummyOperation return } else { this.activeOperation.classList.remove('selected') this.activeOperation = operation this.activeOperation.classList.add('selected') } } chooseNumber(number) { if (this.firstOperand === number) { this.firstOperand.classList.remove('selected') this.firstOperand = this.dummyOperand return } else if (this.secondOperand === number) { this.secondOperand.classList.remove('selected') this.secondOperand = this.dummyOperand return } else if (this.firstOperand !== this.dummyOperation) { this.secondOperand.classList.remove('selected') this.secondOperand = number this.secondOperand.classList.add('selected') } else { this.firstOperand.classList.remove('selected') this.firstOperand = number this.firstOperand.classList.add('selected') } } compute() { if (this.firstOperand === this.dummyOperand || this.secondOperand === this.dummyOperand || this.activeOperation === this.dummyOperation){ return } let computation const first = parseInt(this.firstOperand.innerText) const second = parseInt(this.secondOperand.innerText) textBoxElement.classList.add('hidden') textBoxElement.innerText = '' switch (this.activeOperation.innerText) { case '+': computation = first + second break case '−': computation = Math.abs(first - second) break case '×': computation = first * second break case '÷': if (first % second === 0) { computation = first / second } else if (second % first === 0) { computation = second / first } else { this.firstOperand.classList.remove('selected') this.secondOperand.classList.remove('selected') this.activeOperation.classList.remove('selected') textBoxElement.innerText = 'The quotient is not a whole number' textBoxElement.classList.remove('hidden') this.clear() return } break default: this.clear() return } this.firstOperand.innerText = '' this.firstOperand.classList.add('empty') this.secondOperand.innerText = `${computation}` this.secondOperand.style.fontSize = `calc(var(--card-height) / (${computation.toString().length} + 3.5)` this.secondOperand.classList.remove('selected') this.activeOperation.classList.remove('selected') this.clear() this.victory() } victory() { let victoryCount = 0 numberButtonElements.forEach(number => { if (number.innerText === '' || number.innerText === '24') victoryCount++ }) if (victoryCount === 4) { checkBoxElement.classList.toggle('hidden') } } } const operationButtonElements = document.querySelectorAll('[operationButton]') const numberButtonElements = document.querySelectorAll('[numberButton]') const answerButtonElement = document.querySelector('[answerButton]') const hintButtonElement = document.querySelector('[hintButton]') const rulesButtonElement = document.querySelector('[rulesButton]') const resetButtonElement = document.querySelector('[resetButton]') const textBoxElement = document.querySelector('[textBox]') const checkBoxElement = document.querySelector('[checkBox]') const operationLib = ['Multiplication', 'Division', 'Addition', 'Subtraction'] const operationsArray = [], answerArray = [] const newGame = new twentyFourGame() let operationSymbols = '+−×÷' operationButtonElements.forEach((operation,index) => { operation.innerText = `${operationSymbols[index]}` operation.addEventListener('click', () => { newGame.chooseOperation(operation) newGame.compute() }) }) numberButtonElements.forEach(number => { number.addEventListener('click', () => { newGame.chooseNumber(number) newGame.compute() }) }) answerButtonElement.innerText = 'Answer' answerButtonElement.addEventListener('click', () => { let answerText = '' answerArray.forEach(index => { answerText += `${index}` }) if (textBoxElement.innerText === answerText) { textBoxElement.classList.add('hidden') textBoxElement.innerText = '' } else { textBoxElement.innerText = answerText textBoxElement.classList.remove('hidden') } }) hintButtonElement.innerText = 'Hints' hintButtonElement.addEventListener('click', () => { let hintText = '' operationsArray.forEach(element => { hintText += `${element} ` }) hintText = hintText.slice(0,-1) if (textBoxElement.innerText === hintText) { textBoxElement.classList.add('hidden') textBoxElement.innerText = '' } else { textBoxElement.innerText = hintText textBoxElement.classList.remove('hidden') } }) rulesButtonElement.innerText = 'Rules' rulesButtonElement.addEventListener('click', () => { let rulesText = 'Reach 24 using all numbers' if (textBoxElement.innerText === rulesText) { textBoxElement.classList.add('hidden') textBoxElement.innerText = '' } else { textBoxElement.innerText = rulesText textBoxElement.classList.remove('hidden') } }) resetButtonElement.innerText = 'Reset' resetButtonElement.addEventListener('click', () => { textBoxElement.classList.add('hidden') newGame.activeOperation.classList.remove('selected') newGame.clear() newGame.populateNumbers() }) checkBoxElement.addEventListener('click', () => { newGame.newNumbers() checkBoxElement.classList.toggle('hidden') }) </script> </html>