From 7afdaba39d2cc46673b3e08dd18f5b3e1bc4128f Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 12 Aug 2024 09:46:52 +1000 Subject: [PATCH 01/93] add virtual keybroad --- 21-2048-Game/index.html | 98 +++++++++++++++++++++++++++++++---------- 21-2048-Game/script.js | 12 +---- 21-2048-Game/style.css | 32 ++++++++++++++ 3 files changed, 108 insertions(+), 34 deletions(-) diff --git a/21-2048-Game/index.html b/21-2048-Game/index.html index c2c9e50..0a96012 100644 --- a/21-2048-Game/index.html +++ b/21-2048-Game/index.html @@ -1,31 +1,83 @@ - - - Talha - 2048 Game + + + Talha - 2048 Game - + - - - + + + - - - - - -
-
-

2048

-
-
score
- 0 -
+ + + + + +
+
+

2048

+
+
score
+ 0
- Join the numbers and get to the 2048 tile! -
- - + Join the numbers and get to the 2048 tile! +
+
+
+
+
+ + + + + + +
+
+
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + + \ No newline at end of file diff --git a/21-2048-Game/script.js b/21-2048-Game/script.js index 91b58c2..01ea965 100644 --- a/21-2048-Game/script.js +++ b/21-2048-Game/script.js @@ -1,10 +1,3 @@ -document.addEventListener("DOMContentLoaded", () => { - const gridDisplay = document.querySelector(".grid"); - const scoreDisplay = document.getElementById("score"); - const resultDisplay = document.getElementById("result"); - let squares = []; - const width = 4; - let score = 0; //create the playing board function createBoard() { @@ -17,7 +10,6 @@ document.addEventListener("DOMContentLoaded", () => { generate(); generate(); } - createBoard(); //generate a new number function generate() { @@ -263,7 +255,5 @@ document.addEventListener("DOMContentLoaded", () => { squares[i].style.backgroundColor = "#d7d4f0"; } } - addColours(); - var myTimer = setInterval(addColours, 50); -}); + diff --git a/21-2048-Game/style.css b/21-2048-Game/style.css index 91ee9e2..18d5f7d 100644 --- a/21-2048-Game/style.css +++ b/21-2048-Game/style.css @@ -1,6 +1,7 @@ body { background-color: #faf8ef; display: flex; + flex-direction: column; justify-content: center; font-family: "Clear Sans", "Helvetica Neue"; } @@ -63,3 +64,34 @@ h1 { .score-title { font-size: 16px; } + +.arrow_button { + background-color: #8f7a663b; + color: #ffffff; + border-radius: 3px; + border: 1px solid #8f7a66; + outline: 1px solid #8f7a66; + box-shadow: 1px 1px 5px #8f7a66; + width: 10%; + text-align: center; + padding: 2% +} + +.first_line_virtual_keybroad { + display: flex; + justify-content: space-evenly; + margin-bottom: 20px; +} + +.second_line_virtual_keybroad { + display: flex; + justify-content: space-between; +} + +.virtual_keybroad { + color: #ffffff; + position: absolute; + width: 85%; + top: 60%; + height: 20%; +} \ No newline at end of file From aa1347227af3778d490b00b0c025e98946d0f23b Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 12 Aug 2024 09:55:21 +1000 Subject: [PATCH 02/93] auto show/hide virtual keybroad --- 21-2048-Game/index.html | 11 ++++++++++- 21-2048-Game/script.js | 6 +++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/21-2048-Game/index.html b/21-2048-Game/index.html index 0a96012..bfba00e 100644 --- a/21-2048-Game/index.html +++ b/21-2048-Game/index.html @@ -27,7 +27,7 @@

2048

Join the numbers and get to the 2048 tile!
-
+
@@ -78,6 +78,15 @@

2048

//create the playing board addColours(); var myTimer = setInterval(addColours, 50); + if (hasPhysicalKeyboard()) { + console.log("Physical keyboard likely present"); + // Hide virtual keyboard + document.getElementById("virtual_keybroad").style.display = "none"; + } else { + console.log("Physical keyboard likely not present"); + // Show virtual keyboard + document.getElementById("virtual_keybroad").style.display = "block"; + } \ No newline at end of file diff --git a/21-2048-Game/script.js b/21-2048-Game/script.js index 01ea965..6c4b077 100644 --- a/21-2048-Game/script.js +++ b/21-2048-Game/script.js @@ -256,4 +256,8 @@ } } - + function hasPhysicalKeyboard() { + return !('ontouchstart' in window) || // works on most browsers + (navigator.maxTouchPoints === 0) || // works on IE10/11 and Surface + (navigator.msMaxTouchPoints === 0); // works on IE10/11 and Surface +} From 24c76efbc9a3f028e3a1b0d2c53a19c164e3e6eb Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 12 Aug 2024 10:42:39 +1000 Subject: [PATCH 03/93] add virtual keybroad --- 18-Hangman-Game/index.html | 2 ++ 18-Hangman-Game/script.js | 58 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/18-Hangman-Game/index.html b/18-Hangman-Game/index.html index 86cca97..1337606 100644 --- a/18-Hangman-Game/index.html +++ b/18-Hangman-Game/index.html @@ -54,6 +54,8 @@

You have already entered this letter

+
+
diff --git a/18-Hangman-Game/script.js b/18-Hangman-Game/script.js index 68dfb0f..6c818e6 100644 --- a/18-Hangman-Game/script.js +++ b/18-Hangman-Game/script.js @@ -87,10 +87,8 @@ function showNotification() { notification.classList.remove("show"); }, 2000); } - -window.addEventListener("keypress", (e) => { +function press(letter){ if (playable) { - const letter = e.key.toLowerCase(); if (letter >= "a" && letter <= "z") { if (selectedWord.includes(letter)) { if (!correctLetters.includes(letter)) { @@ -109,6 +107,10 @@ window.addEventListener("keypress", (e) => { } } } +} + +window.addEventListener("keypress", (e) => { + press (e.key.toLowerCase()); }); playAgainButton.addEventListener("click", () => { @@ -123,3 +125,53 @@ playAgainButton.addEventListener("click", () => { // Init displayWord(); +function hasPhysicalKeyboard() { + return !('ontouchstart' in window) || // works on most browsers + (navigator.maxTouchPoints === 0) || // works on IE10/11 and Surface + (navigator.msMaxTouchPoints === 0); // works on IE10/11 and Surface +} +function virtualKeyEvent(key) { + //console.log(`Key pressed: ${key}`); + press (key.toLowerCase()); + // Add your custom logic here for handling virtual key presses +} +function createVirtualKeyboard(divElement) { + // Check if a physical keyboard is present + if (!hasPhysicalKeyboard()) { + // Physical keyboard is not present, create virtual keyboard + const keyboard = document.createElement('div'); + keyboard.style.display = 'flex'; + keyboard.style.flexWrap = 'wrap'; + keyboard.style.justifyContent = 'center'; + keyboard.style.padding = '10px'; + keyboard.style.position = 'absolute'; + keyboard.style.top = '75%'; + keyboard.style.width = '100%'; + keyboard.style.left = '0'; + const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + letters.split('').forEach(letter => { + const button = document.createElement('button'); + button.textContent = letter; + button.style.margin = '5px'; + button.style.padding = '10px 15px'; + button.style.fontSize = '18px'; + button.style.backgroundColor = 'rgba(255, 255, 255, 0.25)'; + button.style.border = 'none'; + button.style.borderRadius = '5px'; + button.style.boxShadow = '0 0 0 1px rgba(0, 0, 0, 0.25)'; + button.style.cursor = 'pointer'; + + + button.addEventListener('click', () => { + virtualKeyEvent(letter); + }); + + keyboard.appendChild(button); + }); + + divElement.appendChild(keyboard); + } else { + console.log('Physical keyboard detected. Virtual keyboard not created.'); + } +} +createVirtualKeyboard(document.getElementById('virtual_keyboard')); From 076b6e1d92b22738f701b8a357b66daef90b93f5 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 12 Aug 2024 11:30:31 +1000 Subject: [PATCH 04/93] update readme,change the link to my page and update 2048 to use oriantation sensor --- 21-2048-Game/index.html | 32 ++++++++++- 21-2048-Game/script.js | 119 +++++++++++++++++++++++++++++++++++++++- 21-2048-Game/style.css | 8 ++- README.md | 58 ++++++++++---------- 4 files changed, 182 insertions(+), 35 deletions(-) diff --git a/21-2048-Game/index.html b/21-2048-Game/index.html index bfba00e..46a2c57 100644 --- a/21-2048-Game/index.html +++ b/21-2048-Game/index.html @@ -27,7 +27,15 @@

2048

Join the numbers and get to the 2048 tile!
-
+
+
+ Reset Oriantation +
+
+ Use virtual keybroad +
+
+
@@ -82,11 +90,29 @@

2048

console.log("Physical keyboard likely present"); // Hide virtual keyboard document.getElementById("virtual_keybroad").style.display = "none"; + toggleOrientationListener(false); } else { console.log("Physical keyboard likely not present"); - // Show virtual keyboard - document.getElementById("virtual_keybroad").style.display = "block"; + + + if (hasOrientationSensor()) { + console.log("Device has an orientation sensor"); + document.getElementById("oriantationCtl").style.display = "flex"; + document.getElementById("virtual_keybroad").style.display = "none"; + toggleOrientationListener(true); + } else { + console.log("Device does not have an orientation sensor"); + // You can add code here for devices without an orientation sensor + document.getElementById("virtual_keybroad").style.display = "block"; + document.getElementById("oriantationCtl").style.display = "none"; + toggleOrientationListener(false); + } + + + } + + \ No newline at end of file diff --git a/21-2048-Game/script.js b/21-2048-Game/script.js index 6c4b077..39545c3 100644 --- a/21-2048-Game/script.js +++ b/21-2048-Game/script.js @@ -1,4 +1,4 @@ - +var ori_threashold = 15; //create the playing board function createBoard() { for (let i = 0; i < width * width; i++) { @@ -261,3 +261,120 @@ (navigator.maxTouchPoints === 0) || // works on IE10/11 and Surface (navigator.msMaxTouchPoints === 0); // works on IE10/11 and Surface } +function hasOrientationSensor() { + return new Promise((resolve) => { + if (window.DeviceOrientationEvent) { + // For iOS 13+ devices + if (typeof DeviceOrientationEvent.requestPermission === 'function') { + DeviceOrientationEvent.requestPermission() + .then(permissionState => { + if (permissionState === 'granted') { + window.addEventListener('deviceorientation', function(event) { + // Remove the event listener immediately after it fires + window.removeEventListener('deviceorientation', arguments.callee); + resolve(true); + }); + // If the event doesn't fire within 1 second, assume no orientation sensor + setTimeout(() => resolve(false), 1000); + } else { + resolve(false); + } + }) + .catch(console.error); + } else { + // For non-iOS devices or older iOS versions + window.addEventListener('deviceorientation', function(event) { + // Remove the event listener immediately after it fires + window.removeEventListener('deviceorientation', arguments.callee); + resolve(event.alpha !== null && event.beta !== null && event.gamma !== null); + }); + // If the event doesn't fire within 1 second, assume no orientation sensor + setTimeout(() => resolve(false), 1000); + } + } else { + resolve(false); + } + }); +} + +function toggleOrientationListener(switchOn ) { + if (isOrientationListenerActive && !switchOn) { + window.removeEventListener('deviceorientation', handleOrientation); + isOrientationListenerActive = false; + console.log("Orientation listener turned off"); + } else { + resetOrientation().then(() => { + window.addEventListener('deviceorientation', handleOrientation); + isOrientationListenerActive = true; + console.log("Orientation listener turned on"); + }); + } +} +function showKeybroad(){ + toggleOrientationListener(false); + document.getElementById("virtual_keybroad").style.display = "block"; + document.getElementById("oriantationCtl").style.display = "none"; +} +let baseAlpha = 0; +let baseBeta = 0; +let baseGamma = 0; +let isOrientationListenerActive = false; + +function resetOrientation() { + return new Promise((resolve) => { + if (window.DeviceOrientationEvent) { + const orientationHandler = function(event) { + baseAlpha = event.alpha || 0; + baseBeta = event.beta || 0; + baseGamma = event.gamma || 0; + + window.removeEventListener('deviceorientation', orientationHandler); + console.log("Orientation reset. Base values:", {alpha: baseAlpha, beta: baseBeta, gamma: baseGamma}); + resolve(); + }; + + window.addEventListener('deviceorientation', orientationHandler, { once: true }); + + // If no orientation event fires within 1 second, resolve anyway + setTimeout(() => { + window.removeEventListener('deviceorientation', orientationHandler); + console.log("No orientation event detected. Using default values."); + resolve(); + }, 1000); + } else { + console.log("DeviceOrientationEvent is not supported"); + resolve(); + } + }); +} + +function handleOrientation(event) { + let relativeAlpha = event.alpha - baseAlpha; + let relativeBeta = event.beta - baseBeta; + let relativeGamma = event.gamma - baseGamma; + + // Normalize values + relativeAlpha = (relativeAlpha + 180) % 360 - 180; + relativeBeta = Math.max(-90, Math.min(90, relativeBeta)); + relativeGamma = Math.max(-90, Math.min(90, relativeGamma)); + + console.log("Relative orientation:", {alpha: relativeAlpha, beta: relativeBeta, gamma: relativeGamma}); + + // Here you can add code to control your game based on these values + // For example: + if (Math.abs(relativeGamma) > ori_threashold) { + if (relativeGamma > 0) { + keyRight(); // Assuming keyRight is your function to move right in the game + } else { + keyLeft(); // Assuming keyLeft is your function to move left in the game + } + } + + if (Math.abs(relativeBeta) > ori_threashold) { + if (relativeBeta > 0) { + keyDown(); // Assuming keyDown is your function to move down in the game + } else { + keyUp(); // Assuming keyUp is your function to move up in the game + } + } +} \ No newline at end of file diff --git a/21-2048-Game/style.css b/21-2048-Game/style.css index 18d5f7d..f3fa929 100644 --- a/21-2048-Game/style.css +++ b/21-2048-Game/style.css @@ -67,14 +67,15 @@ h1 { .arrow_button { background-color: #8f7a663b; - color: #ffffff; + color: black; border-radius: 3px; border: 1px solid #8f7a66; outline: 1px solid #8f7a66; box-shadow: 1px 1px 5px #8f7a66; width: 10%; text-align: center; - padding: 2% + padding: 2%; + font-size: 1em; } .first_line_virtual_keybroad { @@ -94,4 +95,7 @@ h1 { width: 85%; top: 60%; height: 20%; +} +.ctrl{ + display: none; } \ No newline at end of file diff --git a/README.md b/README.md index cd7759c..122110f 100644 --- a/README.md +++ b/README.md @@ -4,35 +4,35 @@ This repository contains a collection of HTML, CSS, and JavaScript games. ๐ŸŽฏ | # | Game | Live Demo | | :-: | ---------------------------------------------- | --------- | -| 01 | [Candy Crush Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/01-Candy-Crush-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/01-Candy-Crush-Game/) | -| 02 | [Archery Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/02-Archery-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/02-Archery-Game/) | -| 03 | [Speed Typing Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/03-Speed-Typing-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/03-Speed-Typing-Game/) | -| 04 | [Breakout Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/04-Breakout-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/04-Breakout-Game/) | -| 05 | [Minesweeper Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/05-Minesweeper-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/05-Minesweeper-Game/) | -| 06 | [Tower Blocks Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/06-Tower-Blocks) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/06-Tower-Blocks/) | -| 07 | [Ping Pong Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/07-Ping-Pong-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/07-Ping-Pong-Game/) | -| 08 | [Tetris Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/08-Tetris-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/08-Tetris-Game/) | -| 09 | [Tilting Maze Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/09-Tilting-Maze-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/09-Tilting-Maze-Game/) | -| 10 | [Memory Card Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/10-Memory-Card-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/10-Memory-Card-Game/) | -| 11 | [Rock Paper Scissors Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/11-Rock-Paper-Scissors) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/11-Rock-Paper-Scissors/) | -| 12 | [Type Number Guessing Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/12-Type-Number-Guessing-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/12-Type-Number-Guessing-Game/) | -| 13 | [Tic Tac Toe Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/13-Tic-Tac-Toe) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/13-Tic-Tac-Toe/) | -| 14 | [Snake Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/14-Snake-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/14-Snake-Game/) | -| 15 | [Connect Four Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/15-Connect-Four-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/15-Connect-Four-Game/) | -| 16 | [Insect Catch Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/16-Insect-Catch-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/16-Insect-Catch-Game/) | -| 17 | [Typing Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/17-Typing-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/17-Typing-Game/) | -| 18 | [Hangman Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/18-Hangman-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/18-Hangman-Game/) | -| 19 | [Flappy Bird Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/19-Flappy-Bird-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/19-Flappy-Bird-Game/) | -| 20 | [Crossy Road Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/20-Crossy-Road-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/20-Crossy-Road-Game/) | -| 21 | [2048 Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/21-2048-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/21-2048-Game/) | -| 22 | [Dice Roll Simulator](https://github.com/he-is-talha/html-css-javascript-games/tree/main/22-Dice-Roll-Simulator) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/22-Dice-Roll-Simulator/) | -| 23 | [Shape Clicker Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/23-Shape-Clicker-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/23-Shape-Clicker-Game/) | -| 24 | [Typing Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/24-Typing-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/24-Typing-Game/) | -| 25 | [Speak Number Guessing Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/25-Speak-Number-Guessing-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/25-Speak-Number-Guessing-Game/) | -| 26 | [Fruit Slicer Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/26-Fruit-Slicer-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/26-Fruit-Slicer-Game/) | -| 27 | [Quiz Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/27-Quiz-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/27-Quiz-Game/) | -| 28 | [Emoji Catcher Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/28-Emoji-Catcher-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/28-Emoji-Catcher-Game/) | -| 29 | [Whack A Mole Game](https://github.com/he-is-talha/html-css-javascript-games/tree/main/29-Whack-A-Mole-Game) | [Live Demo](https://he-is-talha.github.io/html-css-javascript-games/29-Whack-A-Mole-Game/) | +| 01 | [Candy Crush Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/01-Candy-Crush-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/01-Candy-Crush-Game/) | +| 02 | [Archery Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/02-Archery-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/02-Archery-Game/) | +| 03 | [Speed Typing Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/03-Speed-Typing-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/03-Speed-Typing-Game/) | +| 04 | [Breakout Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/04-Breakout-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/04-Breakout-Game/) | +| 05 | [Minesweeper Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/05-Minesweeper-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/05-Minesweeper-Game/) | +| 06 | [Tower Blocks Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/06-Tower-Blocks) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/06-Tower-Blocks/) | +| 07 | [Ping Pong Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/07-Ping-Pong-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/07-Ping-Pong-Game/) | +| 08 | [Tetris Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/08-Tetris-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/08-Tetris-Game/) | +| 09 | [Tilting Maze Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/09-Tilting-Maze-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/09-Tilting-Maze-Game/) | +| 10 | [Memory Card Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/10-Memory-Card-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/10-Memory-Card-Game/) | +| 11 | [Rock Paper Scissors Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/11-Rock-Paper-Scissors) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/11-Rock-Paper-Scissors/) | +| 12 | [Type Number Guessing Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/12-Type-Number-Guessing-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/12-Type-Number-Guessing-Game/) | +| 13 | [Tic Tac Toe Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/13-Tic-Tac-Toe) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/13-Tic-Tac-Toe/) | +| 14 | [Snake Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/14-Snake-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/14-Snake-Game/) | +| 15 | [Connect Four Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/15-Connect-Four-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/15-Connect-Four-Game/) | +| 16 | [Insect Catch Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/16-Insect-Catch-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/16-Insect-Catch-Game/) | +| 17 | [Typing Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/17-Typing-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/17-Typing-Game/) | +| 18 | [Hangman Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/18-Hangman-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/18-Hangman-Game/) | +| 19 | [Flappy Bird Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/19-Flappy-Bird-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/19-Flappy-Bird-Game/) | +| 20 | [Crossy Road Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/20-Crossy-Road-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/20-Crossy-Road-Game/) | +| 21 | [2048 Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/21-2048-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/21-2048-Game/) | +| 22 | [Dice Roll Simulator](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/22-Dice-Roll-Simulator) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/22-Dice-Roll-Simulator/) | +| 23 | [Shape Clicker Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/23-Shape-Clicker-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/23-Shape-Clicker-Game/) | +| 24 | [Typing Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/24-Typing-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/24-Typing-Game/) | +| 25 | [Speak Number Guessing Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/25-Speak-Number-Guessing-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/25-Speak-Number-Guessing-Game/) | +| 26 | [Fruit Slicer Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/26-Fruit-Slicer-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/26-Fruit-Slicer-Game/) | +| 27 | [Quiz Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/27-Quiz-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/27-Quiz-Game/) | +| 28 | [Emoji Catcher Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/28-Emoji-Catcher-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/28-Emoji-Catcher-Game/) | +| 29 | [Whack A Mole Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/29-Whack-A-Mole-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/29-Whack-A-Mole-Game/) | ## Games Description From 04e573a29e37c6a7a68e4caac8bd27f95072e9f8 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 12 Aug 2024 11:39:35 +1000 Subject: [PATCH 05/93] fix bug --- 21-2048-Game/script.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/21-2048-Game/script.js b/21-2048-Game/script.js index 39545c3..6de9777 100644 --- a/21-2048-Game/script.js +++ b/21-2048-Game/script.js @@ -347,6 +347,7 @@ function resetOrientation() { } }); } +var lockout = false; function handleOrientation(event) { let relativeAlpha = event.alpha - baseAlpha; @@ -362,6 +363,7 @@ function handleOrientation(event) { // Here you can add code to control your game based on these values // For example: + if(!lockout){ if (Math.abs(relativeGamma) > ori_threashold) { if (relativeGamma > 0) { keyRight(); // Assuming keyRight is your function to move right in the game @@ -377,4 +379,12 @@ function handleOrientation(event) { keyUp(); // Assuming keyUp is your function to move up in the game } } + lockout = true; + // Lock out for 2 second to prevent accidental movement,reset the lockout after 1 second + setTimeout(() => lockout = false, 2000); + } + //reset the lockout when return to initial position + if(Math.abs(relativeGamma) < ori_threashold && Math.abs(relativeBeta) < ori_threashold){ + lockout = false; + } } \ No newline at end of file From 52556ccf2d3d1cbf678fd25521c27b87a0dfe5a0 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 12 Aug 2024 12:26:08 +1000 Subject: [PATCH 06/93] fixbugs --- 21-2048-Game/script.js | 604 +++++++++++++++++++++-------------------- 1 file changed, 309 insertions(+), 295 deletions(-) diff --git a/21-2048-Game/script.js b/21-2048-Game/script.js index 6de9777..67fa227 100644 --- a/21-2048-Game/script.js +++ b/21-2048-Game/script.js @@ -1,316 +1,321 @@ var ori_threashold = 15; - //create the playing board - function createBoard() { - for (let i = 0; i < width * width; i++) { - square = document.createElement("div"); - square.innerHTML = 0; - gridDisplay.appendChild(square); - squares.push(square); - } - generate(); - generate(); - } - - //generate a new number - function generate() { - randomNumber = Math.floor(Math.random() * squares.length); - if (squares[randomNumber].innerHTML == 0) { - squares[randomNumber].innerHTML = 2; - checkForGameOver(); - } else generate(); - } - - function moveRight() { - for (let i = 0; i < 16; i++) { - if (i % 4 === 0) { - let totalOne = squares[i].innerHTML; - let totalTwo = squares[i + 1].innerHTML; - let totalThree = squares[i + 2].innerHTML; - let totalFour = squares[i + 3].innerHTML; - let row = [ - parseInt(totalOne), - parseInt(totalTwo), - parseInt(totalThree), - parseInt(totalFour), - ]; - - let filteredRow = row.filter((num) => num); - let missing = 4 - filteredRow.length; - let zeros = Array(missing).fill(0); - let newRow = zeros.concat(filteredRow); - - squares[i].innerHTML = newRow[0]; - squares[i + 1].innerHTML = newRow[1]; - squares[i + 2].innerHTML = newRow[2]; - squares[i + 3].innerHTML = newRow[3]; - } - } +//create the playing board +function createBoard() { + for (let i = 0; i < width * width; i++) { + square = document.createElement("div"); + square.innerHTML = 0; + gridDisplay.appendChild(square); + squares.push(square); } + generate(); + generate(); +} - function moveLeft() { - for (let i = 0; i < 16; i++) { - if (i % 4 === 0) { - let totalOne = squares[i].innerHTML; - let totalTwo = squares[i + 1].innerHTML; - let totalThree = squares[i + 2].innerHTML; - let totalFour = squares[i + 3].innerHTML; - let row = [ - parseInt(totalOne), - parseInt(totalTwo), - parseInt(totalThree), - parseInt(totalFour), - ]; - - let filteredRow = row.filter((num) => num); - let missing = 4 - filteredRow.length; - let zeros = Array(missing).fill(0); - let newRow = filteredRow.concat(zeros); - - squares[i].innerHTML = newRow[0]; - squares[i + 1].innerHTML = newRow[1]; - squares[i + 2].innerHTML = newRow[2]; - squares[i + 3].innerHTML = newRow[3]; - } - } - } +//generate a new number +function generate() { + randomNumber = Math.floor(Math.random() * squares.length); + if (squares[randomNumber].innerHTML == 0) { + squares[randomNumber].innerHTML = 2; + checkForGameOver(); + } else generate(); +} - function moveUp() { - for (let i = 0; i < 4; i++) { +function moveRight() { + for (let i = 0; i < 16; i++) { + if (i % 4 === 0) { let totalOne = squares[i].innerHTML; - let totalTwo = squares[i + width].innerHTML; - let totalThree = squares[i + width * 2].innerHTML; - let totalFour = squares[i + width * 3].innerHTML; - let column = [ + let totalTwo = squares[i + 1].innerHTML; + let totalThree = squares[i + 2].innerHTML; + let totalFour = squares[i + 3].innerHTML; + let row = [ parseInt(totalOne), parseInt(totalTwo), parseInt(totalThree), parseInt(totalFour), ]; - let filteredColumn = column.filter((num) => num); - let missing = 4 - filteredColumn.length; + let filteredRow = row.filter((num) => num); + let missing = 4 - filteredRow.length; let zeros = Array(missing).fill(0); - let newColumn = filteredColumn.concat(zeros); + let newRow = zeros.concat(filteredRow); - squares[i].innerHTML = newColumn[0]; - squares[i + width].innerHTML = newColumn[1]; - squares[i + width * 2].innerHTML = newColumn[2]; - squares[i + width * 3].innerHTML = newColumn[3]; + squares[i].innerHTML = newRow[0]; + squares[i + 1].innerHTML = newRow[1]; + squares[i + 2].innerHTML = newRow[2]; + squares[i + 3].innerHTML = newRow[3]; } } +} - function moveDown() { - for (let i = 0; i < 4; i++) { +function moveLeft() { + for (let i = 0; i < 16; i++) { + if (i % 4 === 0) { let totalOne = squares[i].innerHTML; - let totalTwo = squares[i + width].innerHTML; - let totalThree = squares[i + width * 2].innerHTML; - let totalFour = squares[i + width * 3].innerHTML; - let column = [ + let totalTwo = squares[i + 1].innerHTML; + let totalThree = squares[i + 2].innerHTML; + let totalFour = squares[i + 3].innerHTML; + let row = [ parseInt(totalOne), parseInt(totalTwo), parseInt(totalThree), parseInt(totalFour), ]; - let filteredColumn = column.filter((num) => num); - let missing = 4 - filteredColumn.length; + let filteredRow = row.filter((num) => num); + let missing = 4 - filteredRow.length; let zeros = Array(missing).fill(0); - let newColumn = zeros.concat(filteredColumn); + let newRow = filteredRow.concat(zeros); - squares[i].innerHTML = newColumn[0]; - squares[i + width].innerHTML = newColumn[1]; - squares[i + width * 2].innerHTML = newColumn[2]; - squares[i + width * 3].innerHTML = newColumn[3]; + squares[i].innerHTML = newRow[0]; + squares[i + 1].innerHTML = newRow[1]; + squares[i + 2].innerHTML = newRow[2]; + squares[i + 3].innerHTML = newRow[3]; } } +} - function combineRow() { - for (let i = 0; i < 15; i++) { - if (squares[i].innerHTML === squares[i + 1].innerHTML) { - let combinedTotal = - parseInt(squares[i].innerHTML) + parseInt(squares[i + 1].innerHTML); - squares[i].innerHTML = combinedTotal; - squares[i + 1].innerHTML = 0; - score += combinedTotal; - scoreDisplay.innerHTML = score; - } - } - checkForWin(); +function moveUp() { + for (let i = 0; i < 4; i++) { + let totalOne = squares[i].innerHTML; + let totalTwo = squares[i + width].innerHTML; + let totalThree = squares[i + width * 2].innerHTML; + let totalFour = squares[i + width * 3].innerHTML; + let column = [ + parseInt(totalOne), + parseInt(totalTwo), + parseInt(totalThree), + parseInt(totalFour), + ]; + + let filteredColumn = column.filter((num) => num); + let missing = 4 - filteredColumn.length; + let zeros = Array(missing).fill(0); + let newColumn = filteredColumn.concat(zeros); + + squares[i].innerHTML = newColumn[0]; + squares[i + width].innerHTML = newColumn[1]; + squares[i + width * 2].innerHTML = newColumn[2]; + squares[i + width * 3].innerHTML = newColumn[3]; } +} - function combineColumn() { - for (let i = 0; i < 12; i++) { - if (squares[i].innerHTML === squares[i + width].innerHTML) { - let combinedTotal = - parseInt(squares[i].innerHTML) + - parseInt(squares[i + width].innerHTML); - squares[i].innerHTML = combinedTotal; - squares[i + width].innerHTML = 0; - score += combinedTotal; - scoreDisplay.innerHTML = score; - } - } - checkForWin(); +function moveDown() { + for (let i = 0; i < 4; i++) { + let totalOne = squares[i].innerHTML; + let totalTwo = squares[i + width].innerHTML; + let totalThree = squares[i + width * 2].innerHTML; + let totalFour = squares[i + width * 3].innerHTML; + let column = [ + parseInt(totalOne), + parseInt(totalTwo), + parseInt(totalThree), + parseInt(totalFour), + ]; + + let filteredColumn = column.filter((num) => num); + let missing = 4 - filteredColumn.length; + let zeros = Array(missing).fill(0); + let newColumn = zeros.concat(filteredColumn); + + squares[i].innerHTML = newColumn[0]; + squares[i + width].innerHTML = newColumn[1]; + squares[i + width * 2].innerHTML = newColumn[2]; + squares[i + width * 3].innerHTML = newColumn[3]; } +} - //assign functions to keyCodes - function control(e) { - if (e.keyCode === 37) { - keyLeft(); - } else if (e.keyCode === 38) { - keyUp(); - } else if (e.keyCode === 39) { - keyRight(); - } else if (e.keyCode === 40) { - keyDown(); +function combineRow() { + for (let i = 0; i < 15; i++) { + if (squares[i].innerHTML === squares[i + 1].innerHTML) { + let combinedTotal = + parseInt(squares[i].innerHTML) + parseInt(squares[i + 1].innerHTML); + squares[i].innerHTML = combinedTotal; + squares[i + 1].innerHTML = 0; + score += combinedTotal; + scoreDisplay.innerHTML = score; } } - document.addEventListener("keyup", control); + checkForWin(); +} - function keyRight() { - moveRight(); - combineRow(); - moveRight(); - generate(); +function combineColumn() { + for (let i = 0; i < 12; i++) { + if (squares[i].innerHTML === squares[i + width].innerHTML) { + let combinedTotal = + parseInt(squares[i].innerHTML) + + parseInt(squares[i + width].innerHTML); + squares[i].innerHTML = combinedTotal; + squares[i + width].innerHTML = 0; + score += combinedTotal; + scoreDisplay.innerHTML = score; + } } + checkForWin(); +} - function keyLeft() { - moveLeft(); - combineRow(); - moveLeft(); - generate(); +//assign functions to keyCodes +function control(e) { + if (e.keyCode === 37) { + keyLeft(); + } else if (e.keyCode === 38) { + keyUp(); + } else if (e.keyCode === 39) { + keyRight(); + } else if (e.keyCode === 40) { + keyDown(); } +} +document.addEventListener("keyup", control); - function keyUp() { - moveUp(); - combineColumn(); - moveUp(); - generate(); - } +function keyRight() { + moveRight(); + combineRow(); + moveRight(); + generate(); +} - function keyDown() { - moveDown(); - combineColumn(); - moveDown(); - generate(); - } +function keyLeft() { + moveLeft(); + combineRow(); + moveLeft(); + generate(); +} - //check for the number 2048 in the squares to win - function checkForWin() { - for (let i = 0; i < squares.length; i++) { - if (squares[i].innerHTML == 2048) { - resultDisplay.innerHTML = "You WIN"; - document.removeEventListener("keyup", control); - setTimeout(() => clear(), 3000); - } - } - } +function keyUp() { + moveUp(); + combineColumn(); + moveUp(); + generate(); +} - //check if there are no zeros on the board to lose - function checkForGameOver() { - let zeros = 0; - for (let i = 0; i < squares.length; i++) { - if (squares[i].innerHTML == 0) { - zeros++; - } - } - if (zeros === 0) { - resultDisplay.innerHTML = "You LOSE"; +function keyDown() { + moveDown(); + combineColumn(); + moveDown(); + generate(); +} + +//check for the number 2048 in the squares to win +function checkForWin() { + for (let i = 0; i < squares.length; i++) { + if (squares[i].innerHTML == 2048) { + resultDisplay.innerHTML = "You WIN"; document.removeEventListener("keyup", control); setTimeout(() => clear(), 3000); } } +} + +//check if there are no zeros on the board to lose +function checkForGameOver() { + let zeros = 0; + for (let i = 0; i < squares.length; i++) { + if (squares[i].innerHTML == 0) { + zeros++; + } + } + if (zeros === 0) { + resultDisplay.innerHTML = "You LOSE"; + document.removeEventListener("keyup", control); + lockout = true; + lockoutInterval = null; + myTimer = setTimeout(() => clear(), 3000); + } +} - //clear timer - function clear() { +//clear timer +function clear() { + if (myTimer != null) { clearInterval(myTimer); + lockout = false; } +} - //add colours - function addColours() { - for (let i = 0; i < squares.length; i++) { - if (squares[i].innerHTML == 0) - squares[i].style.backgroundColor = "#afa192"; - else if (squares[i].innerHTML == 2) - squares[i].style.backgroundColor = "#eee4da"; - else if (squares[i].innerHTML == 4) - squares[i].style.backgroundColor = "#ede0c8"; - else if (squares[i].innerHTML == 8) - squares[i].style.backgroundColor = "#f2b179"; - else if (squares[i].innerHTML == 16) - squares[i].style.backgroundColor = "#ffcea4"; - else if (squares[i].innerHTML == 32) - squares[i].style.backgroundColor = "#e8c064"; - else if (squares[i].innerHTML == 64) - squares[i].style.backgroundColor = "#ffab6e"; - else if (squares[i].innerHTML == 128) - squares[i].style.backgroundColor = "#fd9982"; - else if (squares[i].innerHTML == 256) - squares[i].style.backgroundColor = "#ead79c"; - else if (squares[i].innerHTML == 512) - squares[i].style.backgroundColor = "#76daff"; - else if (squares[i].innerHTML == 1024) - squares[i].style.backgroundColor = "#beeaa5"; - else if (squares[i].innerHTML == 2048) - squares[i].style.backgroundColor = "#d7d4f0"; - } +//add colours +function addColours() { + for (let i = 0; i < squares.length; i++) { + if (squares[i].innerHTML == 0) + squares[i].style.backgroundColor = "#afa192"; + else if (squares[i].innerHTML == 2) + squares[i].style.backgroundColor = "#eee4da"; + else if (squares[i].innerHTML == 4) + squares[i].style.backgroundColor = "#ede0c8"; + else if (squares[i].innerHTML == 8) + squares[i].style.backgroundColor = "#f2b179"; + else if (squares[i].innerHTML == 16) + squares[i].style.backgroundColor = "#ffcea4"; + else if (squares[i].innerHTML == 32) + squares[i].style.backgroundColor = "#e8c064"; + else if (squares[i].innerHTML == 64) + squares[i].style.backgroundColor = "#ffab6e"; + else if (squares[i].innerHTML == 128) + squares[i].style.backgroundColor = "#fd9982"; + else if (squares[i].innerHTML == 256) + squares[i].style.backgroundColor = "#ead79c"; + else if (squares[i].innerHTML == 512) + squares[i].style.backgroundColor = "#76daff"; + else if (squares[i].innerHTML == 1024) + squares[i].style.backgroundColor = "#beeaa5"; + else if (squares[i].innerHTML == 2048) + squares[i].style.backgroundColor = "#d7d4f0"; } +} - function hasPhysicalKeyboard() { - return !('ontouchstart' in window) || // works on most browsers - (navigator.maxTouchPoints === 0) || // works on IE10/11 and Surface - (navigator.msMaxTouchPoints === 0); // works on IE10/11 and Surface +function hasPhysicalKeyboard() { + return !('ontouchstart' in window) || // works on most browsers + (navigator.maxTouchPoints === 0) || // works on IE10/11 and Surface + (navigator.msMaxTouchPoints === 0); // works on IE10/11 and Surface } function hasOrientationSensor() { return new Promise((resolve) => { - if (window.DeviceOrientationEvent) { - // For iOS 13+ devices - if (typeof DeviceOrientationEvent.requestPermission === 'function') { - DeviceOrientationEvent.requestPermission() - .then(permissionState => { - if (permissionState === 'granted') { - window.addEventListener('deviceorientation', function(event) { - // Remove the event listener immediately after it fires - window.removeEventListener('deviceorientation', arguments.callee); - resolve(true); - }); - // If the event doesn't fire within 1 second, assume no orientation sensor - setTimeout(() => resolve(false), 1000); - } else { - resolve(false); - } - }) - .catch(console.error); - } else { - // For non-iOS devices or older iOS versions - window.addEventListener('deviceorientation', function(event) { - // Remove the event listener immediately after it fires - window.removeEventListener('deviceorientation', arguments.callee); - resolve(event.alpha !== null && event.beta !== null && event.gamma !== null); + if (window.DeviceOrientationEvent) { + // For iOS 13+ devices + if (typeof DeviceOrientationEvent.requestPermission === 'function') { + DeviceOrientationEvent.requestPermission() + .then(permissionState => { + if (permissionState === 'granted') { + window.addEventListener('deviceorientation', function (event) { + // Remove the event listener immediately after it fires + window.removeEventListener('deviceorientation', arguments.callee); + resolve(true); }); // If the event doesn't fire within 1 second, assume no orientation sensor setTimeout(() => resolve(false), 1000); - } + } else { + resolve(false); + } + }) + .catch(console.error); } else { - resolve(false); + // For non-iOS devices or older iOS versions + window.addEventListener('deviceorientation', function (event) { + // Remove the event listener immediately after it fires + window.removeEventListener('deviceorientation', arguments.callee); + resolve(event.alpha !== null && event.beta !== null && event.gamma !== null); + }); + // If the event doesn't fire within 1 second, assume no orientation sensor + setTimeout(() => resolve(false), 1000); } + } else { + resolve(false); + } }); } -function toggleOrientationListener(switchOn ) { +function toggleOrientationListener(switchOn) { if (isOrientationListenerActive && !switchOn) { - window.removeEventListener('deviceorientation', handleOrientation); - isOrientationListenerActive = false; - console.log("Orientation listener turned off"); + window.removeEventListener('deviceorientation', handleOrientation); + isOrientationListenerActive = false; + console.log("Orientation listener turned off"); } else { - resetOrientation().then(() => { - window.addEventListener('deviceorientation', handleOrientation); - isOrientationListenerActive = true; - console.log("Orientation listener turned on"); - }); + resetOrientation().then(() => { + window.addEventListener('deviceorientation', handleOrientation); + isOrientationListenerActive = true; + console.log("Orientation listener turned on"); + }); } } -function showKeybroad(){ +function showKeybroad() { toggleOrientationListener(false); document.getElementById("virtual_keybroad").style.display = "block"; document.getElementById("oriantationCtl").style.display = "none"; @@ -321,70 +326,79 @@ let baseGamma = 0; let isOrientationListenerActive = false; function resetOrientation() { - return new Promise((resolve) => { - if (window.DeviceOrientationEvent) { - const orientationHandler = function(event) { - baseAlpha = event.alpha || 0; - baseBeta = event.beta || 0; - baseGamma = event.gamma || 0; - - window.removeEventListener('deviceorientation', orientationHandler); - console.log("Orientation reset. Base values:", {alpha: baseAlpha, beta: baseBeta, gamma: baseGamma}); - resolve(); - }; - - window.addEventListener('deviceorientation', orientationHandler, { once: true }); - - // If no orientation event fires within 1 second, resolve anyway - setTimeout(() => { - window.removeEventListener('deviceorientation', orientationHandler); - console.log("No orientation event detected. Using default values."); - resolve(); - }, 1000); - } else { - console.log("DeviceOrientationEvent is not supported"); - resolve(); - } - }); + return new Promise((resolve) => { + if (window.DeviceOrientationEvent) { + const orientationHandler = function (event) { + baseAlpha = event.alpha || 0; + baseBeta = event.beta || 0; + baseGamma = event.gamma || 0; + + window.removeEventListener('deviceorientation', orientationHandler); + console.log("Orientation reset. Base values:", { alpha: baseAlpha, beta: baseBeta, gamma: baseGamma }); + resolve(); + }; + + window.addEventListener('deviceorientation', orientationHandler, { once: true }); + + // If no orientation event fires within 1 second, resolve anyway + setTimeout(() => { + window.removeEventListener('deviceorientation', orientationHandler); + console.log("No orientation event detected. Using default values."); + resolve(); + }, 1000); + } else { + console.log("DeviceOrientationEvent is not supported"); + resolve(); + } + }); } var lockout = false; - +var lockoutInterval; function handleOrientation(event) { - let relativeAlpha = event.alpha - baseAlpha; - let relativeBeta = event.beta - baseBeta; - let relativeGamma = event.gamma - baseGamma; + let relativeAlpha = event.alpha - baseAlpha; + let relativeBeta = event.beta - baseBeta; + let relativeGamma = event.gamma - baseGamma; - // Normalize values - relativeAlpha = (relativeAlpha + 180) % 360 - 180; - relativeBeta = Math.max(-90, Math.min(90, relativeBeta)); - relativeGamma = Math.max(-90, Math.min(90, relativeGamma)); + // Normalize values + relativeAlpha = (relativeAlpha + 180) % 360 - 180; + relativeBeta = Math.max(-90, Math.min(90, relativeBeta)); + relativeGamma = Math.max(-90, Math.min(90, relativeGamma)); - console.log("Relative orientation:", {alpha: relativeAlpha, beta: relativeBeta, gamma: relativeGamma}); + console.log("Relative orientation:", { alpha: relativeAlpha, beta: relativeBeta, gamma: relativeGamma }); - // Here you can add code to control your game based on these values - // For example: - if(!lockout){ + // Here you can add code to control your game based on these values + // For example: + if (!lockout) { if (Math.abs(relativeGamma) > ori_threashold) { - if (relativeGamma > 0) { - keyRight(); // Assuming keyRight is your function to move right in the game - } else { - keyLeft(); // Assuming keyLeft is your function to move left in the game - } + if (relativeGamma > 0) { + keyRight(); // Assuming keyRight is your function to move right in the game + } else { + keyLeft(); // Assuming keyLeft is your function to move left in the game + } } if (Math.abs(relativeBeta) > ori_threashold) { - if (relativeBeta > 0) { - keyDown(); // Assuming keyDown is your function to move down in the game - } else { - keyUp(); // Assuming keyUp is your function to move up in the game - } + if (relativeBeta > 0) { + keyDown(); // Assuming keyDown is your function to move down in the game + } else { + keyUp(); // Assuming keyUp is your function to move up in the game + } } lockout = true; // Lock out for 2 second to prevent accidental movement,reset the lockout after 1 second - setTimeout(() => lockout = false, 2000); + lockoutInterval = setInterval(() => { + lockout = false; + clearInterval(lockoutInterval); + }, 2000); + + } + //reset the lockout when return to initial position - if(Math.abs(relativeGamma) < ori_threashold && Math.abs(relativeBeta) < ori_threashold){ + if (Math.abs(relativeGamma) < ori_threashold && Math.abs(relativeBeta) < ori_threashold) { lockout = false; + if (lockoutInterval != null) { + clearInterval(lockoutInterval); + } } } \ No newline at end of file From 63d09c8dd085000fee3b47ae807d4e67e20002f9 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 12 Aug 2024 12:56:12 +1000 Subject: [PATCH 07/93] update icon,add index --- 01-Candy-Crush-Game/index.html | 2 +- 02-Archery-Game/index.html | 2 +- 03-Speed-Typing-Game/index.html | 2 +- 04-Breakout-Game/index.html | 2 +- 10-Memory-Card-Game/index.html | 2 +- 11-Rock-Paper-Scissors/index.html | 2 +- 12-Type-Number-Guessing-Game/index.html | 2 +- 13-Tic-Tac-Toe/index.html | 2 +- 14-Snake-Game/index.html | 2 +- 15-Connect-Four-Game/index.html | 2 +- 16-Insect-Catch-Game/index.html | 2 +- 17-Typing-Game/index.html | 2 +- 22-Dice-Roll-Simulator/index.html | 2 +- 23-Shape-Clicker-Game/index.html | 2 +- 24-Typing-Game/index.html | 2 +- 25-Speak-Number-Guessing-Game/index.html | 2 +- 28-Emoji-Catcher-Game/index.html | 2 +- index.html | 202 +++++++++++++++++++++++ 18 files changed, 219 insertions(+), 17 deletions(-) create mode 100644 index.html diff --git a/01-Candy-Crush-Game/index.html b/01-Candy-Crush-Game/index.html index 20454e5..5dfef9c 100644 --- a/01-Candy-Crush-Game/index.html +++ b/01-Candy-Crush-Game/index.html @@ -12,7 +12,7 @@ - + diff --git a/02-Archery-Game/index.html b/02-Archery-Game/index.html index 485b967..ba1ad63 100644 --- a/02-Archery-Game/index.html +++ b/02-Archery-Game/index.html @@ -15,7 +15,7 @@ - + diff --git a/03-Speed-Typing-Game/index.html b/03-Speed-Typing-Game/index.html index f28b696..7f88154 100644 --- a/03-Speed-Typing-Game/index.html +++ b/03-Speed-Typing-Game/index.html @@ -15,7 +15,7 @@ - + diff --git a/04-Breakout-Game/index.html b/04-Breakout-Game/index.html index 2261583..2b5dfc0 100644 --- a/04-Breakout-Game/index.html +++ b/04-Breakout-Game/index.html @@ -13,7 +13,7 @@ - +

Breakout!

diff --git a/10-Memory-Card-Game/index.html b/10-Memory-Card-Game/index.html index 2e6318d..4e002a9 100644 --- a/10-Memory-Card-Game/index.html +++ b/10-Memory-Card-Game/index.html @@ -12,7 +12,7 @@ - + diff --git a/11-Rock-Paper-Scissors/index.html b/11-Rock-Paper-Scissors/index.html index 32df139..0d48ae8 100644 --- a/11-Rock-Paper-Scissors/index.html +++ b/11-Rock-Paper-Scissors/index.html @@ -15,7 +15,7 @@ - + diff --git a/12-Type-Number-Guessing-Game/index.html b/12-Type-Number-Guessing-Game/index.html index 0cb07e1..1590c5f 100644 --- a/12-Type-Number-Guessing-Game/index.html +++ b/12-Type-Number-Guessing-Game/index.html @@ -15,7 +15,7 @@ - + diff --git a/13-Tic-Tac-Toe/index.html b/13-Tic-Tac-Toe/index.html index 25c582f..da1bb42 100644 --- a/13-Tic-Tac-Toe/index.html +++ b/13-Tic-Tac-Toe/index.html @@ -15,7 +15,7 @@ - + diff --git a/14-Snake-Game/index.html b/14-Snake-Game/index.html index a9e2e7b..902dd8d 100644 --- a/14-Snake-Game/index.html +++ b/14-Snake-Game/index.html @@ -12,7 +12,7 @@ - + diff --git a/15-Connect-Four-Game/index.html b/15-Connect-Four-Game/index.html index d5056b8..9caa6a6 100644 --- a/15-Connect-Four-Game/index.html +++ b/15-Connect-Four-Game/index.html @@ -13,7 +13,7 @@ - + diff --git a/16-Insect-Catch-Game/index.html b/16-Insect-Catch-Game/index.html index 1ad0f14..2da8fcd 100644 --- a/16-Insect-Catch-Game/index.html +++ b/16-Insect-Catch-Game/index.html @@ -14,7 +14,7 @@ - + diff --git a/17-Typing-Game/index.html b/17-Typing-Game/index.html index 2f64320..faf2d9d 100644 --- a/17-Typing-Game/index.html +++ b/17-Typing-Game/index.html @@ -20,7 +20,7 @@ - +
+ diff --git a/04-Breakout-Game/script.js b/04-Breakout-Game/script.js index 5df25e0..6d0ce51 100644 --- a/04-Breakout-Game/script.js +++ b/04-Breakout-Game/script.js @@ -168,12 +168,12 @@ function showAllBricks() { } // Handle Key Events -function keyDown(e) { +function keyPressDown(e) { if (e.key === "Right" || e.key === "ArrowRight") paddle.dx = paddle.speed; else if (e.key === "Left" || e.key === "ArrowLeft") paddle.dx = -paddle.speed; } -function keyUp(e) { +function keyPressUp(e) { if ( e.key === "Right" || e.key === "ArrowRight" || @@ -195,10 +195,119 @@ function update() { } // Event Listeners -document.addEventListener("keydown", keyDown); -document.addEventListener("keyup", keyUp); +document.addEventListener("keydown", keyPressDown); +document.addEventListener("keyup", keyPressUp); rulesButton.addEventListener("click", () => rules.classList.add("show")); closeButton.addEventListener("click", () => rules.classList.remove("show")); // Init update(); + +var downLock = false; +function keyDown() {// pressed down arrow key + if (downLock) { + var event = new KeyboardEvent('keyup', { + bubbles: true, + cancelable: true, + key: 'ArrowDown', // or any other key you want to simulate + keyCode: 40, // or any other key code you want to simulate + which: 40, // or any other key code you want to simulate + }); + document.dispatchEvent(event); + downLock = false; + document.getElementById("down_arrow").style.transform = "scale(1)"; + } else { + var event = new KeyboardEvent('keydown', { + bubbles: true, + cancelable: true, + key: 'ArrowDown', // or any other key you want to simulate + keyCode: 40, // or any other key code you want to simulate + which: 40, // or any other key code you want to simulate + }); + document.dispatchEvent(event); + downLock = true; + document.getElementById("down_arrow").style.transform = "scale(0.9)"; + } +} + +var upLock = false; +function keyUp() {// pressed up arrow key + if (upLock) { + var event = new KeyboardEvent('keyup', { + bubbles: true, + cancelable: true, + key: 'ArrowUp', // or any other key you want to simulate + keyCode: 38, // or any other key code you want to simulate + which: 38, // or any other key code you want to simulate + }); + document.dispatchEvent(event); + upLock = false; + document.getElementById("up_arrow").style.transform = "scale(1)"; + } else { + var event = new KeyboardEvent('keydown', { + bubbles: true, + cancelable: true, + key: 'ArrowUp', // or any other key you want to simulate + keyCode: 38, // or any other key code you want to simulate + which: 38, // or any other key code you want to simulate + }); + document.dispatchEvent(event); + upLock = true; + document.getElementById("up_arrow").style.transform = "scale(0.9)"; + } +} + +var leftLock = false; +function keyLeft() {// pressed left arrow key + if (leftLock) { + var event = new KeyboardEvent('keyup', { + bubbles: true, + cancelable: true, + key: 'ArrowLeft', // or any other key you want to simulate + keyCode: 37, // or any other key code you want to simulate + which: 37, // or any other key code you want to simulate + }); + document.dispatchEvent(event); + leftLock = false; + document.getElementById("left_arrow").style.transform = "scale(1)"; + } else { + var event = new KeyboardEvent('keydown', { + bubbles: true, + cancelable: true, + key: 'ArrowLeft', // or any other key you want to simulate + keyCode: 37, // or any other key code you want to simulate + which: 37, // or any other key code you want to simulate + }); + document.dispatchEvent(event); + leftLock = true; + document.getElementById("left_arrow").style.transform = "scale(0.9)"; + } +} + +var rightLock = false; +function keyRight() {// pressed right arrow key + if (rightLock) { + var event = new KeyboardEvent('keyup', { + bubbles: true, + cancelable: true, + key: 'ArrowRight', // or any other key you want to simulate + keyCode: 39, // or any other key code you want to simulate + which: 39, // or any other key code you want to simulate + }); + document.dispatchEvent(event); + rightLock = false; + document.getElementById("right_arrow").style.transform = "scale(1)"; + } else { + var event = new KeyboardEvent('keydown', { + bubbles: true, + cancelable: true, + key: 'ArrowRight', // or any other key you want to simulate + keyCode: 39, // or any other key code you want to simulate + which: 39, // or any other key code you want to simulate + }); + document.dispatchEvent(event); + rightLock = true; + document.getElementById("right_arrow").style.transform = "scale(0.9)"; + } +} + From 8c9dd3d0b2419ce5161a4852a0a5a5322796d883 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 15 Aug 2024 00:36:30 +1000 Subject: [PATCH 38/93] update index --- index.html | 104 +++++++++++++++++++---------------------------------- 1 file changed, 37 insertions(+), 67 deletions(-) diff --git a/index.html b/index.html index 0ee6789..092ad32 100644 --- a/index.html +++ b/index.html @@ -1,10 +1,10 @@ - + - - ๆธธๆˆๅˆ—่กจ + + Game List -

ๆธธๆˆๅˆ—่กจ


- fork from https://github.com/he-is-talha/html-css-javascript-games +

Game List


+ Github address: leoncoolmoon/html-css-javascript-games + ; Fork from: he-is-talha - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - +
#ๆธธๆˆๅœจ็บฟๆผ”็คบGame: description
01Candy Crush GameLive DemoCandy Crush Game: Enjoy the classic match-three puzzle game where you swap colored candies to create matches and clear levels. ๐Ÿฌ๐Ÿญ
02Archery GameLive DemoArchery Game: Test your aim in this challenging archery game where precision and timing are key to hitting the bullseye. ๐Ÿน
03Speed Typing GameLive DemoSpeed Typing Game: Improve your typing speed and accuracy with this game that challenges you to type words quickly under time pressure. โŒจ๏ธ
04Breakout GameLive DemoBreakout Game: Relive the arcade classic where you use a paddle to bounce a ball and break bricks, aiming for a high score. ๐ŸŽฎ
05Minesweeper GameLive DemoMinesweeper Game: Exercise your logical thinking with this puzzle game where you avoid hidden mines and uncover safe tiles. ๐Ÿ’ฃ
06Tower Blocks GameLive DemoTower Blocks Game: Build a tower by stacking blocks as high as possible without letting them topple over in this physics-based game. ๐Ÿ—๏ธ
07Ping Pong GameLive DemoPing Pong Game: Experience the thrill of table tennis as you compete against an AI opponent in this classic sports game. ๐Ÿ“
08Tetris GameLive DemoTetris Game: Arrange falling tetrominoes to create complete lines and score points in this addictive puzzle game. ๐Ÿงฑ
09Tilting Maze GameLive DemoTilting Maze Game: Navigate a ball through a tilting maze, avoiding traps and reaching the goal in this challenging game of skill. ๐ŸŒ€
10Memory Card GameLive DemoMemory Card Game: Test your memory by matching pairs of cards in this classic concentration game. ๐Ÿƒ
11Rock Paper Scissors GameLive DemoRock Paper Scissors Game: lay the timeless hand game against the computer and see who comes out victorious. โœ‚๏ธ
12Type Number Guessing GameLive DemoType Number Guessing Game: Guess the hidden number based on clues provided after each guess in this number guessing game. ๐Ÿ”ข
13Tic Tac Toe GameLive DemoTic Tac Toe Game: Challenge a friend or AI in this simple yet strategic game of placing Xs and Os in a 3x3 grid. โญ•โŒ
14Snake GameLive DemoSnake Game: Control a growing snake, eat food, and avoid collisions with walls and your own tail in this nostalgic arcade game. ๐Ÿ
15Connect Four GameLive DemoConnect Four Game: Strategically drop colored discs to connect four in a row vertically, horizontally, or diagonally in this classic board game. ๐Ÿ”ต๐Ÿ”ด
16Insect Catch GameLive DemoInsect Catch Game: Test your reflexes by clicking on randomly appearing insects to catch them before they disappear. ๐Ÿž
17Typing GameLive DemoTyping Game: Sharpen your typing skills by typing specific words or sentences as quickly and accurately as possible. โŒจ๏ธ
18Hangman GameLive DemoHangman Game: Guess the hidden word by suggesting letters within a certain number of guesses in this word-guessing game. ๐ŸŽฉ
19Flappy Bird GameLive DemoFlappy Bird Game: Guide a bird through gaps in pipes by tapping to flap its wings, avoiding obstacles and aiming for a high score. ๐Ÿฆ
20Crossy Road GameLive DemoCrossy Road Game: Help a character cross roads, rivers, and other obstacles in this endless hopping game with a retro arcade feel. ๐Ÿšฆ
212048 GameLive Demo2048 Game: Slide numbered tiles on a grid to combine them and create a tile with the number 2048 in this addictive puzzle game. ๐Ÿงฉ
22Dice Roll SimulatorLive DemoDice Roll Simulator: Simulate rolling dice to achieve different combinations or outcomes in this virtual dice rolling game. ๐ŸŽฒ
23Shape Clicker GameLive DemoShape Clicker Game: Click on various shapes appearing on the screen within a time limit to score points in this clicker game. ๐Ÿ”ท๐Ÿ”ถ
24Typing GameLive DemoTyping Game: Improve your typing speed and accuracy by typing specific words or sentences under time pressure. โŒจ๏ธ
25Speak Number Guessing GameLive DemoSpeak Number Guessing Game: Guess the hidden number by speaking your guesses aloud in this voice-activated number guessing game. ๐Ÿ—ฃ๏ธ๐Ÿ”ข
26Fruit Slicer GameLive DemoFruit Slicer Game: Swipe across the screen to slice falling fruits while avoiding bombs in this fast-paced fruit-slicing game. ๐Ÿ‰๐Ÿ”ช
27Quiz GameLive DemoQuiz Game: Test your knowledge on various topics by answering trivia questions and aiming for a high score in this quiz game. ๐Ÿง ๐Ÿ“š
28Emoji Catcher GameLive DemoEmoji Catcher Game: Catch falling emojis with a basket or container while avoiding bombs and other obstacles in this emoji-catching game. ๐ŸŽฏ๐Ÿ˜„
29Whack A Mole GameLive DemoWhack A Mole Game: Test your reaction speed by hitting randomly appearing moles with a mallet before they disappear in this classic arcade game. ๐Ÿ•น๏ธ
30Guess Number GameLive DemoGuess Number Game: Guess a 4-digit number with A for right position and B for right number. Only eight chances. A good game for logical thinking.๐Ÿง ๐Ÿค–
From ad2b10d16ecd214d90143322aaf5d0d504cb08a0 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 15 Aug 2024 08:37:30 +1000 Subject: [PATCH 39/93] =?UTF-8?q?add=20=E4=B8=AD=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 61 +++++++++--------- indexCN.html | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+), 30 deletions(-) create mode 100644 indexCN.html diff --git a/index.html b/index.html index 092ad32..6da4b3c 100644 --- a/index.html +++ b/index.html @@ -42,6 +42,7 @@

Game List


+ ไธญๆ–‡
Github address: leoncoolmoon/html-css-javascript-games ; Fork from: he-is-talha @@ -54,123 +55,123 @@

Game List


- + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - +
01Candy Crush Game: Enjoy the classic match-three puzzle game where you swap colored candies to create matches and clear levels. ๐Ÿฌ๐ŸญCandy Crush Game: Enjoy the classic match-three puzzle game where you swap colored candies to create matches and clear levels. ๐Ÿฌ๐Ÿญ
02Archery Game: Test your aim in this challenging archery game where precision and timing are key to hitting the bullseye. ๐ŸนArchery Game: Test your aim in this challenging archery game where precision and timing are key to hitting the bullseye. ๐Ÿน
03Speed Typing Game: Improve your typing speed and accuracy with this game that challenges you to type words quickly under time pressure. โŒจ๏ธSpeed Typing Game: Improve your typing speed and accuracy with this game that challenges you to type words quickly under time pressure. โŒจ๏ธ
04Breakout Game: Relive the arcade classic where you use a paddle to bounce a ball and break bricks, aiming for a high score. ๐ŸŽฎBreakout Game: Relive the arcade classic where you use a paddle to bounce a ball and break bricks, aiming for a high score. ๐ŸŽฎ
05Minesweeper Game: Exercise your logical thinking with this puzzle game where you avoid hidden mines and uncover safe tiles. ๐Ÿ’ฃMinesweeper Game: Exercise your logical thinking with this puzzle game where you avoid hidden mines and uncover safe tiles. ๐Ÿ’ฃ
06Tower Blocks Game: Build a tower by stacking blocks as high as possible without letting them topple over in this physics-based game. ๐Ÿ—๏ธTower Blocks Game: Build a tower by stacking blocks as high as possible without letting them topple over in this physics-based game. ๐Ÿ—๏ธ
07Ping Pong Game: Experience the thrill of table tennis as you compete against an AI opponent in this classic sports game. ๐Ÿ“Ping Pong Game: Experience the thrill of table tennis as you compete against an AI opponent in this classic sports game. ๐Ÿ“
08Tetris Game: Arrange falling tetrominoes to create complete lines and score points in this addictive puzzle game. ๐ŸงฑTetris Game: Arrange falling tetrominoes to create complete lines and score points in this addictive puzzle game. ๐Ÿงฑ
09Tilting Maze Game: Navigate a ball through a tilting maze, avoiding traps and reaching the goal in this challenging game of skill. ๐ŸŒ€Tilting Maze Game: Navigate a ball through a tilting maze, avoiding traps and reaching the goal in this challenging game of skill. ๐ŸŒ€
10Memory Card Game: Test your memory by matching pairs of cards in this classic concentration game. ๐ŸƒMemory Card Game: Test your memory by matching pairs of cards in this classic concentration game. ๐Ÿƒ
11Rock Paper Scissors Game: lay the timeless hand game against the computer and see who comes out victorious. โœ‚๏ธRock Paper Scissors Game: lay the timeless hand game against the computer and see who comes out victorious. โœ‚๏ธ
12Type Number Guessing Game: Guess the hidden number based on clues provided after each guess in this number guessing game. ๐Ÿ”ขType Number Guessing Game: Guess the hidden number based on clues provided after each guess in this number guessing game. ๐Ÿ”ข
13Tic Tac Toe Game: Challenge a friend or AI in this simple yet strategic game of placing Xs and Os in a 3x3 grid. โญ•โŒTic Tac Toe Game: Challenge a friend or AI in this simple yet strategic game of placing Xs and Os in a 3x3 grid. โญ•โŒ
14Snake Game: Control a growing snake, eat food, and avoid collisions with walls and your own tail in this nostalgic arcade game. ๐ŸSnake Game: Control a growing snake, eat food, and avoid collisions with walls and your own tail in this nostalgic arcade game. ๐Ÿ
15Connect Four Game: Strategically drop colored discs to connect four in a row vertically, horizontally, or diagonally in this classic board game. ๐Ÿ”ต๐Ÿ”ดConnect Four Game: Strategically drop colored discs to connect four in a row vertically, horizontally, or diagonally in this classic board game. ๐Ÿ”ต๐Ÿ”ด
16Insect Catch Game: Test your reflexes by clicking on randomly appearing insects to catch them before they disappear. ๐ŸžInsect Catch Game: Test your reflexes by clicking on randomly appearing insects to catch them before they disappear. ๐Ÿž
17Typing Game: Sharpen your typing skills by typing specific words or sentences as quickly and accurately as possible. โŒจ๏ธTyping Game: Sharpen your typing skills by typing specific words or sentences as quickly and accurately as possible. โŒจ๏ธ
18Hangman Game: Guess the hidden word by suggesting letters within a certain number of guesses in this word-guessing game. ๐ŸŽฉHangman Game: Guess the hidden word by suggesting letters within a certain number of guesses in this word-guessing game. ๐ŸŽฉ
19Flappy Bird Game: Guide a bird through gaps in pipes by tapping to flap its wings, avoiding obstacles and aiming for a high score. ๐ŸฆFlappy Bird Game: Guide a bird through gaps in pipes by tapping to flap its wings, avoiding obstacles and aiming for a high score. ๐Ÿฆ
20Crossy Road Game: Help a character cross roads, rivers, and other obstacles in this endless hopping game with a retro arcade feel. ๐ŸšฆCrossy Road Game: Help a character cross roads, rivers, and other obstacles in this endless hopping game with a retro arcade feel. ๐Ÿšฆ
212048 Game: Slide numbered tiles on a grid to combine them and create a tile with the number 2048 in this addictive puzzle game. ๐Ÿงฉ2048 Game: Slide numbered tiles on a grid to combine them and create a tile with the number 2048 in this addictive puzzle game. ๐Ÿงฉ
22Dice Roll Simulator: Simulate rolling dice to achieve different combinations or outcomes in this virtual dice rolling game. ๐ŸŽฒDice Roll Simulator: Simulate rolling dice to achieve different combinations or outcomes in this virtual dice rolling game. ๐ŸŽฒ
23Shape Clicker Game: Click on various shapes appearing on the screen within a time limit to score points in this clicker game. ๐Ÿ”ท๐Ÿ”ถShape Clicker Game: Click on various shapes appearing on the screen within a time limit to score points in this clicker game. ๐Ÿ”ท๐Ÿ”ถ
24Typing Game: Improve your typing speed and accuracy by typing specific words or sentences under time pressure. โŒจ๏ธTyping Game: Improve your typing speed and accuracy by typing specific words or sentences under time pressure. โŒจ๏ธ
25Speak Number Guessing Game: Guess the hidden number by speaking your guesses aloud in this voice-activated number guessing game. ๐Ÿ—ฃ๏ธ๐Ÿ”ขSpeak Number Guessing Game: Guess the hidden number by speaking your guesses aloud in this voice-activated number guessing game. ๐Ÿ—ฃ๏ธ๐Ÿ”ข
26Fruit Slicer Game: Swipe across the screen to slice falling fruits while avoiding bombs in this fast-paced fruit-slicing game. ๐Ÿ‰๐Ÿ”ชFruit Slicer Game: Swipe across the screen to slice falling fruits while avoiding bombs in this fast-paced fruit-slicing game. ๐Ÿ‰๐Ÿ”ช
27Quiz Game: Test your knowledge on various topics by answering trivia questions and aiming for a high score in this quiz game. ๐Ÿง ๐Ÿ“šQuiz Game: Test your knowledge on various topics by answering trivia questions and aiming for a high score in this quiz game. ๐Ÿง ๐Ÿ“š
28Emoji Catcher Game: Catch falling emojis with a basket or container while avoiding bombs and other obstacles in this emoji-catching game. ๐ŸŽฏ๐Ÿ˜„Emoji Catcher Game: Catch falling emojis with a basket or container while avoiding bombs and other obstacles in this emoji-catching game. ๐ŸŽฏ๐Ÿ˜„
29Whack A Mole Game: Test your reaction speed by hitting randomly appearing moles with a mallet before they disappear in this classic arcade game. ๐Ÿ•น๏ธWhack A Mole Game: Test your reaction speed by hitting randomly appearing moles with a mallet before they disappear in this classic arcade game. ๐Ÿ•น๏ธ
30Guess Number Game: Guess a 4-digit number with A for right position and B for right number. Only eight chances. A good game for logical thinking.๐Ÿง ๐Ÿค–Guess Number Game: Guess a 4-digit number with A for right position and B for right number. Only eight chances. A good game for logical thinking.๐Ÿง ๐Ÿค–
diff --git a/indexCN.html b/indexCN.html new file mode 100644 index 0000000..575d52e --- /dev/null +++ b/indexCN.html @@ -0,0 +1,179 @@ + + + + + + + ๆธธๆˆๅˆ—่กจ + + + +

ๆธธๆˆๅˆ—่กจ


+ English
+ Github ๅœฐๅ€: leoncoolmoon/html-css-javascript-games + ; ๅˆ†ๅ‰่‡ช: he-is-talha + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#ๆธธๆˆ๏ผšๆ่ฟฐ
01็ณ–ๆžœไผ ๅฅ‡ๆธธๆˆ๏ผšไบซๅ—็ปๅ…ธ็š„ไธ‰ๆถˆ็›Šๆ™บๆธธๆˆ๏ผŒไบคๆขๅฝฉ่‰ฒ็ณ–ๆžœไปฅๅˆ›ๅปบๅŒน้…ๅนถๅฎŒๆˆๅ…ณๅกใ€‚ ๐Ÿฌ๐Ÿญ
02ๅฐ„็ฎญๆธธๆˆ๏ผšๅœจ่ฟ™ไธชๅ…ทๆœ‰ๆŒ‘ๆˆ˜ๆ€ง็š„ๅฐ„็ฎญๆธธๆˆไธญๆต‹่ฏ•ไฝ ็š„็ž„ๅ‡†่ƒฝๅŠ›๏ผŒ็ฒพๅ‡†ๅ’Œๆ—ถๆœบๆ˜ฏๅ‡ปไธญ้ถๅฟƒ็š„ๅ…ณ้”ฎใ€‚ ๐Ÿน
03ๆ‰“ๅญ—้€Ÿๅบฆๆธธๆˆ๏ผš้€š่ฟ‡่ฟ™ไธชๆธธๆˆๆ้ซ˜ไฝ ็š„ๆ‰“ๅญ—้€Ÿๅบฆๅ’Œๅ‡†็กฎๆ€ง๏ผŒๆŒ‘ๆˆ˜ไฝ ๅœจๆ—ถ้—ดๅŽ‹ๅŠ›ไธ‹ๅฟซ้€Ÿ่พ“ๅ…ฅๅ•่ฏใ€‚ โŒจ๏ธ
04ๆ‰“็ –ๅ—ๆธธๆˆ๏ผš้‡ๆธฉ็ปๅ…ธ่ก—ๆœบๆธธๆˆ๏ผŒไฝฟ็”จไธ€ไธช็ƒๆ‹ๅ‡ปๆ‰“็ƒๅนถๆ‰“็ ด็ –ๅ—๏ผŒไบ‰ๅ–้ซ˜ๅˆ†ใ€‚ ๐ŸŽฎ
05ๆ‰ซ้›ทๆธธๆˆ๏ผšๅœจ่ฟ™ไธช็›Šๆ™บๆธธๆˆไธญ้”ป็‚ผไฝ ็š„้€ป่พ‘ๆ€็ปด๏ผŒ้ฟๅ…้š่—็š„ๅœฐ้›ท๏ผŒๆญๅผ€ๅฎ‰ๅ…จ็š„ๆ–นๅ—ใ€‚ ๐Ÿ’ฃ
06ๅก”ๆฅผๆธธๆˆ๏ผšๅœจ่ฟ™ไธช็‰ฉ็†ๅŸบ็ก€็š„ๆธธๆˆไธญ๏ผŒ้€š่ฟ‡ๅ †ๅ ๆ–นๅ—ๅฐฝๅฏ่ƒฝ้ซ˜ๅœฐๅปบ้€ ไธ€ๅบงๅก”๏ผŒ่€Œไธ่ฎฉๅฎƒไปฌๅ€’ไธ‹ใ€‚ ๐Ÿ—๏ธ
07ไน’ไน“็ƒๆธธๆˆ๏ผšๅœจ่ฟ™ไธช็ปๅ…ธ่ฟๅŠจๆธธๆˆไธญไธŽ AI ๅฏนๆ‰‹็ซžไบ‰๏ผŒไฝ“้ชŒไน’ไน“็ƒ็š„ๅˆบๆฟ€ใ€‚ ๐Ÿ“
08ไฟ„็ฝ—ๆ–ฏๆ–นๅ—ๆธธๆˆ๏ผšๆŽ’ๅˆ—ไธ‹่ฝ็š„ๆ–นๅ—ไปฅๅˆ›ๅปบๅฎŒๆ•ด็š„่กŒๅนถๅœจ่ฟ™ไธชไธŠ็˜พ็š„็›Šๆ™บๆธธๆˆไธญๅพ—ๅˆ†ใ€‚ ๐Ÿงฑ
09ๅ€พๆ–œ่ฟทๅฎซๆธธๆˆ๏ผšๅœจ่ฟ™ไธชๆŠ€่ƒฝๆŒ‘ๆˆ˜ๆธธๆˆไธญ๏ผŒๅฏผ่ˆชไธ€ไธช็ƒ้€š่ฟ‡ๅ€พๆ–œ็š„่ฟทๅฎซ๏ผŒ้ฟๅผ€้™ท้˜ฑๅนถ่พพๅˆฐ็›ฎๆ ‡ใ€‚ ๐ŸŒ€
10่ฎฐๅฟ†ๅก็‰‡ๆธธๆˆ๏ผšๅœจ่ฟ™ไธช็ปๅ…ธ็š„่ฎฐๅฟ†ๆธธๆˆไธญ๏ผŒ้€š่ฟ‡ๅŒน้…ๆˆๅฏน็š„ๅก็‰‡ๆฅๆต‹่ฏ•ไฝ ็š„่ฎฐๅฟ†ๅŠ›ใ€‚ ๐Ÿƒ
11ๅ‰ชๅˆ€็Ÿณๅคดๅธƒๆธธๆˆ๏ผšไธŽ่ฎก็ฎ—ๆœบ่ฟ›่กŒ่ฟ™ไธช็ปๅ…ธๆ‰‹ๅŠฟๆธธๆˆ๏ผŒ็œ‹็œ‹่ฐๅฐ†่Žท่ƒœใ€‚ โœ‚๏ธ
12่พ“ๅ…ฅๆ•ฐๅญ—็Œœ่ฐœๆธธๆˆ๏ผšๆ นๆฎๆฏๆฌก็Œœๆต‹ๅŽๆไพ›็š„็บฟ็ดขๆฅ็Œœๆต‹้š่—็š„ๆ•ฐๅญ—ใ€‚ ๐Ÿ”ข
13ไบ•ๅญ—ๆฃ‹ๆธธๆˆ๏ผšๅœจ่ฟ™ไธช็ฎ€ๅ•่€Œๆˆ˜็•ฅๆ€ง็š„ๆธธๆˆไธญๆŒ‘ๆˆ˜ๆœ‹ๅ‹ๆˆ– AI๏ผŒๅœจ 3x3 ็ฝ‘ๆ ผไธญๆ”พ็ฝฎ X ๅ’Œ Oใ€‚ โญ•โŒ
14่ดชๅƒ่›‡ๆธธๆˆ๏ผšๆŽงๅˆถไธ€ๆกไธๆ–ญ็”Ÿ้•ฟ็š„่›‡๏ผŒๅƒ้ฃŸ็‰ฉ๏ผŒ้ฟๅ…ไธŽๅข™ๅฃๅ’Œ่‡ชๅทฑ็š„ๅฐพๅทดๅ‘็”Ÿ็ขฐๆ’ž๏ผŒๅœจ่ฟ™ไธชๆ€€ๆ—ง็š„่ก—ๆœบๆธธๆˆไธญใ€‚ ๐Ÿ
15ๅ››ๅญ่ฟž็ ๆธธๆˆ๏ผšๆˆ˜็•ฅๆ€งๅœฐๆŠ•ๆ”พๅฝฉ่‰ฒๅœ†็›˜๏ผŒไปฅ็บตๅ‘ใ€ๆจชๅ‘ๆˆ–ๅฏน่ง’็บฟ่ฟžๆŽฅๅ››ไธชๅœจ่ฟ™ไธช็ปๅ…ธๆฃ‹็›˜ๆธธๆˆไธญใ€‚ ๐Ÿ”ต๐Ÿ”ด
16ๆ•่™ซๆธธๆˆ๏ผš้€š่ฟ‡็‚นๅ‡ป้šๆœบๅ‡บ็Žฐ็š„ๆ˜†่™ซๆฅๆต‹่ฏ•ไฝ ็š„ๅๅบ”่ƒฝๅŠ›๏ผŒๅฐฝ้‡ๅœจๅฎƒไปฌๆถˆๅคฑไน‹ๅ‰ๆ•ๆ‰ๅˆฐๅฎƒไปฌใ€‚ ๐Ÿž
17ๆ‰“ๅญ—ๆธธๆˆ๏ผš้€š่ฟ‡ๅฐฝๅฏ่ƒฝๅฟซ้€Ÿๅ‡†็กฎๅœฐ่พ“ๅ…ฅ็‰นๅฎš็š„ๅ•่ฏๆˆ–ๅฅๅญๆฅๆ้ซ˜ไฝ ็š„ๆ‰“ๅญ—ๆŠ€่ƒฝใ€‚ โŒจ๏ธ
18็ปžๅˆ‘ๆžถๆธธๆˆ๏ผšๅœจ่ฟ™ไธช็Œœๅญ—ๆธธๆˆไธญ๏ผŒ้€š่ฟ‡ๅœจๆœ‰้™็š„็Œœๆต‹ๆฌกๆ•ฐๅ†…ๅปบ่ฎฎๅญ—ๆฏๆฅ็Œœๆต‹้š่—็š„ๅ•่ฏใ€‚ ๐ŸŽฉ
19Flappy Bird ๆธธๆˆ๏ผš้€š่ฟ‡็‚นๅ‡ปๆฅๅผ•ๅฏผ้ธŸๅ„ฟ็ฉฟ่ฟ‡็ฎก้“้—ด้š™๏ผŒ้ฟๅ…้šœ็ข็‰ฉๅนถไบ‰ๅ–้ซ˜ๅˆ†ใ€‚ ๐Ÿฆ
20่ฟ‡้ฉฌ่ทฏๆธธๆˆ๏ผšๅธฎๅŠฉ่ง’่‰ฒ็ฉฟ่ถŠ้“่ทฏใ€ๆฒณๆตๅ’Œๅ…ถไป–้šœ็ข๏ผŒๅœจ่ฟ™ไธชๅ…ทๆœ‰ๅคๅค่ก—ๆœบ้ฃŽๆ ผ็š„ๆ— ๅฐฝ่ทณ่ทƒๆธธๆˆไธญใ€‚ ๐Ÿšฆ
212048 ๆธธๆˆ๏ผšๅœจ่ฟ™ไธชไธŠ็˜พ็š„็›Šๆ™บๆธธๆˆไธญ๏ผŒๆป‘ๅŠจๆ•ฐๅญ—ๆ–นๅ—ไปฅ็ป„ๅˆๅฎƒไปฌๅนถๅˆ›ๅปบไธ€ไธชๆ•ฐๅญ—ไธบ 2048 ็š„ๆ–นๅ—ใ€‚ ๐Ÿงฉ
22้ชฐๅญๆŠ•ๆŽทๆจกๆ‹Ÿๅ™จ๏ผšๆจกๆ‹ŸๆŽท้ชฐๅญไปฅๅœจ่ฟ™ไธช่™šๆ‹Ÿ้ชฐๅญๆŠ•ๆŽทๆธธๆˆไธญ่Žทๅพ—ไธๅŒ็š„็ป„ๅˆๆˆ–็ป“ๆžœใ€‚ ๐ŸŽฒ
23ๅฝข็Šถ็‚นๅ‡ปๆธธๆˆ๏ผšๅœจๆ—ถ้—ด้™ๅˆถๅ†…็‚นๅ‡ปๅฑๅน•ไธŠๅ‡บ็Žฐ็š„ๅ„็งๅฝข็Šถ๏ผŒไปฅๅœจ่ฟ™ไธช็‚นๅ‡ปๆธธๆˆไธญๅพ—ๅˆ†ใ€‚ ๐Ÿ”ท๐Ÿ”ถ
24ๆ‰“ๅญ—ๆธธๆˆ๏ผš้€š่ฟ‡ๅœจๆ—ถ้—ดๅŽ‹ๅŠ›ไธ‹่พ“ๅ…ฅ็‰นๅฎš็š„ๅ•่ฏๆˆ–ๅฅๅญๆฅๆ้ซ˜ไฝ ็š„ๆ‰“ๅญ—้€Ÿๅบฆๅ’Œๅ‡†็กฎๆ€งใ€‚ โŒจ๏ธ
25่ฏดๅ‡บๆ•ฐๅญ—็Œœ่ฐœๆธธๆˆ๏ผš้€š่ฟ‡ๅคงๅฃฐ่ฏดๅ‡บไฝ ็š„็Œœๆต‹ๆฅ็Œœๆต‹้š่—็š„ๆ•ฐๅญ—๏ผŒๅ‚ไธŽ่ฟ™ไธช่ฏญ้Ÿณๆฟ€ๆดป็š„ๆ•ฐๅญ—็Œœๆต‹ๆธธๆˆใ€‚ ๐Ÿ—ฃ๏ธ๐Ÿ”ข
26ๆฐดๆžœๅˆ‡ๅ‰ฒๆธธๆˆ๏ผšๅœจ่ฟ™ไธชๅฟซ่Š‚ๅฅ็š„ๆฐดๆžœๅˆ‡ๅ‰ฒๆธธๆˆไธญ๏ผŒๅˆ’่ฟ‡ๅฑๅน•ๅˆ‡ๅ‰ฒๆމไธ‹ๆฅ็š„ๆฐดๆžœ๏ผŒๅŒๆ—ถ้ฟๅ…็‚ธๅผนใ€‚ ๐Ÿ‰๐Ÿ”ช
27ๆต‹้ชŒๆธธๆˆ๏ผš้€š่ฟ‡ๅ›ž็ญ”ๅ„็งไธป้ข˜็š„็ไบ‹้—ฎ้ข˜ๆฅๆต‹่ฏ•ไฝ ็š„็Ÿฅ่ฏ†๏ผŒๅœจ่ฟ™ไธชๆต‹้ชŒๆธธๆˆไธญไบ‰ๅ–้ซ˜ๅˆ†ใ€‚ ๐Ÿง ๐Ÿ“š
28่กจๆƒ…็ฌฆๅทๆ•ๆ‰ๆธธๆˆ๏ผšๅœจ่ฟ™ไธช่กจๆƒ…ๆ•ๆ‰ๆธธๆˆไธญ๏ผŒ็”จ็ฏฎๅญๆˆ–ๅฎนๅ™จๆ•ๆ‰ๆމไธ‹ๆฅ็š„่กจๆƒ…็ฌฆๅท๏ผŒๅŒๆ—ถ้ฟๅผ€็‚ธๅผนๅ’Œๅ…ถไป–้šœ็ข็‰ฉใ€‚ ๐ŸŽฏ๐Ÿ˜„
29ๆ‰“ๅœฐ้ผ ๆธธๆˆ๏ผš้€š่ฟ‡ๅœจ่ฟ™ไธช็ปๅ…ธ่ก—ๆœบๆธธๆˆไธญ็”จ้”คๅญๅ‡ปๆ‰“้šๆœบๅ‡บ็Žฐ็š„ๅœฐ้ผ ๆฅๆต‹่ฏ•ไฝ ็š„ๅๅบ”้€Ÿๅบฆใ€‚ ๐Ÿ•น๏ธ
30็Œœๆ•ฐๅญ—ๆธธๆˆ๏ผš็Œœๆต‹ไธ€ไธช 4 ไฝๆ•ฐๅญ—๏ผŒA ่กจ็คบไฝ็ฝฎๆญฃ็กฎ๏ผŒB ่กจ็คบๆ•ฐๅญ—ๆญฃ็กฎใ€‚ๅชๆœ‰ๅ…ซๆฌกๆœบไผšใ€‚ไธ€ไธช้”ป็‚ผ้€ป่พ‘ๆ€็ปด็š„ๅฅฝๆธธๆˆใ€‚๐Ÿง ๐Ÿค–
+ + From df6068f4699cb18cb372c3fff5177810bd287e0e Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 15 Aug 2024 08:40:06 +1000 Subject: [PATCH 40/93] fix index bug --- index.html | 6 +++--- indexCN.html | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index 6da4b3c..8ca7aaa 100644 --- a/index.html +++ b/index.html @@ -42,9 +42,9 @@

Game List


- ไธญๆ–‡
- Github address: leoncoolmoon/html-css-javascript-games - ; Fork from: he-is-talha + ไธญๆ–‡
+ Github address: leoncoolmoon/html-css-javascript-games;
+ Fork from: he-is-talha diff --git a/indexCN.html b/indexCN.html index 575d52e..5eb6fa3 100644 --- a/indexCN.html +++ b/indexCN.html @@ -42,9 +42,9 @@

ๆธธๆˆๅˆ—่กจ


- English
- Github ๅœฐๅ€: leoncoolmoon/html-css-javascript-games - ; ๅˆ†ๅ‰่‡ช: he-is-talha + English
+ Github ๅœฐๅ€: leoncoolmoon/html-css-javascript-games;
+ ๅˆ†ๅ‰่‡ช: he-is-talha
From 5d2a74cd3fd62db4a0cd58fa1ca09e8b996fcb6e Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 15 Aug 2024 08:50:55 +1000 Subject: [PATCH 41/93] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E4=BF=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 2 +- indexCN.html | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/index.html b/index.html index 8ca7aaa..ca7eee0 100644 --- a/index.html +++ b/index.html @@ -42,7 +42,7 @@

Game List


- ไธญๆ–‡
+ ไธญๆ–‡
Github address: leoncoolmoon/html-css-javascript-games;
Fork from: he-is-talha
diff --git a/indexCN.html b/indexCN.html index 5eb6fa3..c265693 100644 --- a/indexCN.html +++ b/indexCN.html @@ -42,7 +42,7 @@

ๆธธๆˆๅˆ—่กจ


- English
+ English
Github ๅœฐๅ€: leoncoolmoon/html-css-javascript-games;
ๅˆ†ๅ‰่‡ช: he-is-talha
@@ -71,7 +71,7 @@

ๆธธๆˆๅˆ—่กจ


- + @@ -83,7 +83,7 @@

ๆธธๆˆๅˆ—่กจ


- + @@ -107,11 +107,11 @@

ๆธธๆˆๅˆ—่กจ


- + - + @@ -163,7 +163,7 @@

ๆธธๆˆๅˆ—่กจ


- + From 1a6ab005f33851ff1d8506349b2192a401cdfc70 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 15 Aug 2024 10:57:47 +1000 Subject: [PATCH 42/93] add virtual keybroad to pingpong, fix some bugs --- 04-Breakout-Game/index.html | 68 +++++++++-------- 04-Breakout-Game/script.js | 108 ++++++++++++++------------- 07-Ping-Pong-Game/index.html | 141 +++++++++++++++++++++-------------- 07-Ping-Pong-Game/script.js | 121 ++++++++++++++++++++++++++++++ index.html | 2 +- indexCN.html | 2 +- 6 files changed, 304 insertions(+), 138 deletions(-) diff --git a/04-Breakout-Game/index.html b/04-Breakout-Game/index.html index 3f6eba1..11e1e45 100644 --- a/04-Breakout-Game/index.html +++ b/04-Breakout-Game/index.html @@ -1,34 +1,42 @@ - - - - - Breakout Game - - - - - - + + + + + Breakout Game + + + - - - -

Breakout!

- -
-

How To Play:

-

- Use your right and left keys to move the paddle to bounce the ball up - and break the blocks. -

-

If you miss the ball, your score and the blocks will reset.

- -
- - - - - + + + + + + + + +

Breakout!

+ +
+

How To Play:

+

+ Use your right and left keys to move the paddle to bounce the ball up + and break the blocks. +

+

If you miss the ball, your score and the blocks will reset.

+ +
+ + + + + + + \ No newline at end of file diff --git a/04-Breakout-Game/script.js b/04-Breakout-Game/script.js index 6d0ce51..72a008d 100644 --- a/04-Breakout-Game/script.js +++ b/04-Breakout-Game/script.js @@ -202,63 +202,66 @@ closeButton.addEventListener("click", () => rules.classList.remove("show")); // Init update(); +function keyDown() {} +function keyUp() {} -var downLock = false; -function keyDown() {// pressed down arrow key - if (downLock) { - var event = new KeyboardEvent('keyup', { - bubbles: true, - cancelable: true, - key: 'ArrowDown', // or any other key you want to simulate - keyCode: 40, // or any other key code you want to simulate - which: 40, // or any other key code you want to simulate - }); - document.dispatchEvent(event); - downLock = false; - document.getElementById("down_arrow").style.transform = "scale(1)"; - } else { - var event = new KeyboardEvent('keydown', { - bubbles: true, - cancelable: true, - key: 'ArrowDown', // or any other key you want to simulate - keyCode: 40, // or any other key code you want to simulate - which: 40, // or any other key code you want to simulate - }); - document.dispatchEvent(event); - downLock = true; - document.getElementById("down_arrow").style.transform = "scale(0.9)"; - } -} +// var downLock = false; +// function keyDown() {// pressed down arrow key +// if (downLock) { +// var event = new KeyboardEvent('keyup', { +// bubbles: true, +// cancelable: true, +// key: 'ArrowDown', // or any other key you want to simulate +// keyCode: 40, // or any other key code you want to simulate +// which: 40, // or any other key code you want to simulate +// }); +// document.dispatchEvent(event); +// downLock = false; +// document.getElementById("down_arrow").style.transform = "scale(1)"; +// } else { +// var event = new KeyboardEvent('keydown', { +// bubbles: true, +// cancelable: true, +// key: 'ArrowDown', // or any other key you want to simulate +// keyCode: 40, // or any other key code you want to simulate +// which: 40, // or any other key code you want to simulate +// }); +// document.dispatchEvent(event); +// downLock = true; +// document.getElementById("down_arrow").style.transform = "scale(0.9)"; +// } +// } -var upLock = false; -function keyUp() {// pressed up arrow key - if (upLock) { - var event = new KeyboardEvent('keyup', { - bubbles: true, - cancelable: true, - key: 'ArrowUp', // or any other key you want to simulate - keyCode: 38, // or any other key code you want to simulate - which: 38, // or any other key code you want to simulate - }); - document.dispatchEvent(event); - upLock = false; - document.getElementById("up_arrow").style.transform = "scale(1)"; - } else { - var event = new KeyboardEvent('keydown', { - bubbles: true, - cancelable: true, - key: 'ArrowUp', // or any other key you want to simulate - keyCode: 38, // or any other key code you want to simulate - which: 38, // or any other key code you want to simulate - }); - document.dispatchEvent(event); - upLock = true; - document.getElementById("up_arrow").style.transform = "scale(0.9)"; - } -} +// var upLock = false; +// function keyUp() {// pressed up arrow key +// if (upLock) { +// var event = new KeyboardEvent('keyup', { +// bubbles: true, +// cancelable: true, +// key: 'ArrowUp', // or any other key you want to simulate +// keyCode: 38, // or any other key code you want to simulate +// which: 38, // or any other key code you want to simulate +// }); +// document.dispatchEvent(event); +// upLock = false; +// document.getElementById("up_arrow").style.transform = "scale(1)"; +// } else { +// var event = new KeyboardEvent('keydown', { +// bubbles: true, +// cancelable: true, +// key: 'ArrowUp', // or any other key you want to simulate +// keyCode: 38, // or any other key code you want to simulate +// which: 38, // or any other key code you want to simulate +// }); +// document.dispatchEvent(event); +// upLock = true; +// document.getElementById("up_arrow").style.transform = "scale(0.9)"; +// } +// } var leftLock = false; function keyLeft() {// pressed left arrow key + if(rightLock) keyRight(); if (leftLock) { var event = new KeyboardEvent('keyup', { bubbles: true, @@ -286,6 +289,7 @@ function keyLeft() {// pressed left arrow key var rightLock = false; function keyRight() {// pressed right arrow key + if(leftLock) keyLeft(); if (rightLock) { var event = new KeyboardEvent('keyup', { bubbles: true, diff --git a/07-Ping-Pong-Game/index.html b/07-Ping-Pong-Game/index.html index ab5db40..9ed5d03 100644 --- a/07-Ping-Pong-Game/index.html +++ b/07-Ping-Pong-Game/index.html @@ -1,65 +1,98 @@ - - Ping Pong Game - - - + + Ping Pong Game + + + - - - + - - - + + + - + + + - - - - -
- -
-
- - - -
-

Control: Player Left(W and S) | Player Right(โ†‘ and โ†“)

- -
05ๆ‰ซ้›ทๆธธๆˆ๏ผšๅœจ่ฟ™ไธช็›Šๆ™บๆธธๆˆไธญ้”ป็‚ผไฝ ็š„้€ป่พ‘ๆ€็ปด๏ผŒ้ฟๅ…้š่—็š„ๅœฐ้›ท๏ผŒๆญๅผ€ๅฎ‰ๅ…จ็š„ๆ–นๅ—ใ€‚ ๐Ÿ’ฃๆ‰ซ้›ทๆธธๆˆ๏ผš็ปๅ…ธ็š„ๆ‰ซ้›ทๆธธๆˆ๏ผŒๅทฆ้”ฎๆ‰“ๅผ€ๆ–นๅ—๏ผŒๅณ้”ฎ๏ผˆ้•ฟๆŒ‰๏ผ‰ๆ ‡่ฎฐๆ–นๅ—๏ผŒๅŒๅ‡ปๆ‰“ๅผ€ๅ‘จๅ›ด็š„ๆ–นๅ—ใ€‚ ๐Ÿ’ฃ
06
08ไฟ„็ฝ—ๆ–ฏๆ–นๅ—ๆธธๆˆ๏ผšๆŽ’ๅˆ—ไธ‹่ฝ็š„ๆ–นๅ—ไปฅๅˆ›ๅปบๅฎŒๆ•ด็š„่กŒๅนถๅœจ่ฟ™ไธชไธŠ็˜พ็š„็›Šๆ™บๆธธๆˆไธญๅพ—ๅˆ†ใ€‚ ๐Ÿงฑไฟ„็ฝ—ๆ–ฏๆ–นๅ—ๆธธๆˆ๏ผšๆŽ’ๅˆ—ไธ‹่ฝ็š„ๆ–นๅ—ไปฅๅˆ›ๅปบๅฎŒๆ•ด็š„่กŒๅนถๅœจ่ฟ™ไธชไธŠ็˜พ็š„็›Šๆ™บๆธธๆˆไธญๅพ—ๅˆ†๏ผŒๆ”ฏๆŒ้‡ๅŠ›ๆ„Ÿๅบ”ใ€‚ ๐Ÿงฑ
09
14่ดชๅƒ่›‡ๆธธๆˆ๏ผšๆŽงๅˆถไธ€ๆกไธๆ–ญ็”Ÿ้•ฟ็š„่›‡๏ผŒๅƒ้ฃŸ็‰ฉ๏ผŒ้ฟๅ…ไธŽๅข™ๅฃๅ’Œ่‡ชๅทฑ็š„ๅฐพๅทดๅ‘็”Ÿ็ขฐๆ’ž๏ผŒๅœจ่ฟ™ไธชๆ€€ๆ—ง็š„่ก—ๆœบๆธธๆˆไธญใ€‚ ๐Ÿ่ดชๅƒ่›‡ๆธธๆˆ๏ผšๆŽงๅˆถไธ€ๆกไธๆ–ญ็”Ÿ้•ฟ็š„่›‡๏ผŒๅƒ้ฃŸ็‰ฉ๏ผŒ้ฟๅ…ไธŽ่‡ชๅทฑ็š„ๅฐพๅทดๅ‘็”Ÿ็ขฐๆ’ž๏ผŒๅœจ่ฟ™ไธชๆ€€ๆ—ง็š„่ก—ๆœบๆธธๆˆไธญ๏ผŒๆ”ฏๆŒ้‡ๅŠ›ๆ„Ÿๅบ”ใ€‚ ๐Ÿ
15ๅ››ๅญ่ฟž็ ๆธธๆˆ๏ผšๆˆ˜็•ฅๆ€งๅœฐๆŠ•ๆ”พๅฝฉ่‰ฒๅœ†็›˜๏ผŒไปฅ็บตๅ‘ใ€ๆจชๅ‘ๆˆ–ๅฏน่ง’็บฟ่ฟžๆŽฅๅ››ไธชๅœจ่ฟ™ไธช็ปๅ…ธๆฃ‹็›˜ๆธธๆˆไธญใ€‚ ๐Ÿ”ต๐Ÿ”ดๅ››/ไบ”ๅญ่ฟž็ ๆธธๆˆ๏ผšๆˆ˜็•ฅๆ€งๅœฐๆŠ•ๆ”พๅฝฉ่‰ฒๅœ†็›˜๏ผŒไปฅ็บตๅ‘ใ€ๆจชๅ‘ๆˆ–ๅฏน่ง’็บฟ่ฟžๆŽฅๅ››ไธชๅœจ่ฟ™ไธช็ปๅ…ธๆฃ‹็›˜ๆธธๆˆไธญใ€‚ ๐Ÿ”ต๐Ÿ”ด
16
28่กจๆƒ…็ฌฆๅทๆ•ๆ‰ๆธธๆˆ๏ผšๅœจ่ฟ™ไธช่กจๆƒ…ๆ•ๆ‰ๆธธๆˆไธญ๏ผŒ็”จ็ฏฎๅญๆˆ–ๅฎนๅ™จๆ•ๆ‰ๆމไธ‹ๆฅ็š„่กจๆƒ…็ฌฆๅท๏ผŒๅŒๆ—ถ้ฟๅผ€็‚ธๅผนๅ’Œๅ…ถไป–้šœ็ข็‰ฉใ€‚ ๐ŸŽฏ๐Ÿ˜„่กจๆƒ…็ฌฆๅทๆ•ๆ‰ๆธธๆˆ๏ผš่กจๆƒ…ๅŒ…็‰ˆ็š„ๆ‰“ๅœฐ้ผ ๆธธๆˆใ€‚ ๐ŸŽฏ๐Ÿ˜„
29
diff --git a/indexCN.html b/indexCN.html index c265693..993e5e6 100644 --- a/indexCN.html +++ b/indexCN.html @@ -42,7 +42,7 @@

ๆธธๆˆๅˆ—่กจ


- English
+ English
Github ๅœฐๅ€: leoncoolmoon/html-css-javascript-games;
ๅˆ†ๅ‰่‡ช: he-is-talha
From 0773925a558ff0ff287453914b9f788e76c42caf Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 15 Aug 2024 12:04:52 +1000 Subject: [PATCH 43/93] modify the ctrl for the game --- 04-Breakout-Game/index.html | 4 ++-- 04-Breakout-Game/script.js | 46 +++++++++++++++++++++++++++++++++++++ indexCN.html | 2 +- 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/04-Breakout-Game/index.html b/04-Breakout-Game/index.html index 11e1e45..cd6660c 100644 --- a/04-Breakout-Game/index.html +++ b/04-Breakout-Game/index.html @@ -31,12 +31,12 @@

How To Play:

- + \ No newline at end of file diff --git a/04-Breakout-Game/script.js b/04-Breakout-Game/script.js index 72a008d..a79bff9 100644 --- a/04-Breakout-Game/script.js +++ b/04-Breakout-Game/script.js @@ -314,4 +314,50 @@ function keyRight() {// pressed right arrow key document.getElementById("right_arrow").style.transform = "scale(0.9)"; } } +//ๅขžๅŠ ไธ€ไธช่งฆๆ‘ธๅฑๅน•ไบ‹ไปถ๏ผŒ่ฎฉPaddleๆฐดๅนณ็งปๅŠจ่ท็ฆปๅ’Œ่งฆๆ‘ธ็‚นๆฐดๅนณ็งปๅŠจ่ท็ฆปไธ€่‡ด +var touchXstart = null; +function actionStart(e){ + e.preventDefault(); + //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ + + if(e.touches && touchXstart == null){//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ touchXstart็ญ‰ไบŽ็ฌฌไธ€ไธชtouch็‚น็š„xๅๆ ‡ + touchXstart = e.touches[0].pageX; + }else{//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ touchXstart็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡ + touchXstart = e.pageX; + } + + +} +function actionEnd(e){ + e.preventDefault(); + touchXstart = null; +} +function actionMove(e){ + //e.preventDefault(); + var dist; + //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ + if(touchXstart != null){ + if(e.touches ){//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ dist็ญ‰ไบŽ็ฌฌไธ€ไธชtouch็‚น็š„xๅๆ ‡x็›ธๅฏนtouchXstart็š„็งปๅŠจ่ท็ฆป + dist = e.touches[0].pageX - touchXstart; + }else{//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ dist็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡x็›ธๅฏนtouchXstart็š„็งปๅŠจ่ท็ฆป + dist = e.pageX - touchXstart; + } + // dist ๆŒ‰็…ง็”ปๅธƒ็š„ๆ”พๅคงๆฏ”ไพ‹็ผฉๆ”พ + var canvasS = document.getElementById("canvas"); + dist = dist / canvas.width *canvasS.clientWidth /2; + + paddle.x = paddle.x + dist; + if (paddle.x + paddle.w > canvas.width) paddle.x = canvas.width - paddle.w; + if (paddle.x < 0) paddle.x = 0; + } + } + + +document.addEventListener('touchstart', actionStart); +document.addEventListener('touchend', actionEnd); +document.addEventListener('touchmove', actionMove); +//็›ธๅบ”้ผ ๆ ‡็‚นๅ‡ปๅŽ็งปๅŠจ็š„ไบ‹ไปถ +document.addEventListener('mousedown', actionStart); +document.addEventListener('mouseup', actionEnd); +document.addEventListener('mousemove', actionMove); diff --git a/indexCN.html b/indexCN.html index 993e5e6..3833f40 100644 --- a/indexCN.html +++ b/indexCN.html @@ -42,7 +42,7 @@

ๆธธๆˆๅˆ—่กจ


- English
+ English
Github ๅœฐๅ€: leoncoolmoon/html-css-javascript-games;
ๅˆ†ๅ‰่‡ช: he-is-talha
From d8cbbddc08185ea55f8a4d195a9911d1dd52f9e9 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 15 Aug 2024 23:36:57 +1000 Subject: [PATCH 44/93] improve positioning for the mouse --- 04-Breakout-Game/script.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/04-Breakout-Game/script.js b/04-Breakout-Game/script.js index a79bff9..35a7b11 100644 --- a/04-Breakout-Game/script.js +++ b/04-Breakout-Game/script.js @@ -316,21 +316,20 @@ function keyRight() {// pressed right arrow key } //ๅขžๅŠ ไธ€ไธช่งฆๆ‘ธๅฑๅน•ไบ‹ไปถ๏ผŒ่ฎฉPaddleๆฐดๅนณ็งปๅŠจ่ท็ฆปๅ’Œ่งฆๆ‘ธ็‚นๆฐดๅนณ็งปๅŠจ่ท็ฆปไธ€่‡ด var touchXstart = null; +var previousPosition = canvas.width/2-paddle.w/2; function actionStart(e){ e.preventDefault(); //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ - if(e.touches && touchXstart == null){//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ touchXstart็ญ‰ไบŽ็ฌฌไธ€ไธชtouch็‚น็š„xๅๆ ‡ touchXstart = e.touches[0].pageX; }else{//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ touchXstart็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡ touchXstart = e.pageX; } - - } function actionEnd(e){ e.preventDefault(); touchXstart = null; + previousPosition = paddle.x; } function actionMove(e){ //e.preventDefault(); @@ -343,10 +342,9 @@ function actionMove(e){ dist = e.pageX - touchXstart; } // dist ๆŒ‰็…ง็”ปๅธƒ็š„ๆ”พๅคงๆฏ”ไพ‹็ผฉๆ”พ - var canvasS = document.getElementById("canvas"); - dist = dist / canvas.width *canvasS.clientWidth /2; + - paddle.x = paddle.x + dist; + paddle.x = previousPosition + dist; if (paddle.x + paddle.w > canvas.width) paddle.x = canvas.width - paddle.w; if (paddle.x < 0) paddle.x = 0; } From b8f9e5dc1faf475eb6cd0087542444173af3b61d Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 15 Aug 2024 23:42:21 +1000 Subject: [PATCH 45/93] improve movement --- 04-Breakout-Game/script.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/04-Breakout-Game/script.js b/04-Breakout-Game/script.js index 35a7b11..8b69eec 100644 --- a/04-Breakout-Game/script.js +++ b/04-Breakout-Game/script.js @@ -318,7 +318,7 @@ function keyRight() {// pressed right arrow key var touchXstart = null; var previousPosition = canvas.width/2-paddle.w/2; function actionStart(e){ - e.preventDefault(); + // e.preventDefault(); //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ if(e.touches && touchXstart == null){//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ touchXstart็ญ‰ไบŽ็ฌฌไธ€ไธชtouch็‚น็š„xๅๆ ‡ touchXstart = e.touches[0].pageX; @@ -327,7 +327,7 @@ function actionStart(e){ } } function actionEnd(e){ - e.preventDefault(); + //e.preventDefault(); touchXstart = null; previousPosition = paddle.x; } @@ -337,7 +337,7 @@ function actionMove(e){ //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ if(touchXstart != null){ if(e.touches ){//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ dist็ญ‰ไบŽ็ฌฌไธ€ไธชtouch็‚น็š„xๅๆ ‡x็›ธๅฏนtouchXstart็š„็งปๅŠจ่ท็ฆป - dist = e.touches[0].pageX - touchXstart; + dist =( e.touches[0].pageX - touchXstart)*2; }else{//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ dist็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡x็›ธๅฏนtouchXstart็š„็งปๅŠจ่ท็ฆป dist = e.pageX - touchXstart; } From 658be378f44d7c4a923225ea8f7d16bc2522f312 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 15 Aug 2024 23:47:20 +1000 Subject: [PATCH 46/93] try faster --- 04-Breakout-Game/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/04-Breakout-Game/script.js b/04-Breakout-Game/script.js index 8b69eec..94dd2bf 100644 --- a/04-Breakout-Game/script.js +++ b/04-Breakout-Game/script.js @@ -337,7 +337,7 @@ function actionMove(e){ //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ if(touchXstart != null){ if(e.touches ){//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ dist็ญ‰ไบŽ็ฌฌไธ€ไธชtouch็‚น็š„xๅๆ ‡x็›ธๅฏนtouchXstart็š„็งปๅŠจ่ท็ฆป - dist =( e.touches[0].pageX - touchXstart)*2; + dist =( e.touches[0].pageX - touchXstart)*4; }else{//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ dist็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡x็›ธๅฏนtouchXstart็š„็งปๅŠจ่ท็ฆป dist = e.pageX - touchXstart; } From 2297276e1f1a0673b6903a177ca229001fd8a9f4 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 16 Aug 2024 00:00:57 +1000 Subject: [PATCH 47/93] fix movement --- 04-Breakout-Game/index.html | 2 +- 04-Breakout-Game/style.css | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/04-Breakout-Game/index.html b/04-Breakout-Game/index.html index cd6660c..053e18f 100644 --- a/04-Breakout-Game/index.html +++ b/04-Breakout-Game/index.html @@ -3,7 +3,7 @@ - + Breakout Game diff --git a/04-Breakout-Game/style.css b/04-Breakout-Game/style.css index 64b7bd4..95d58a2 100644 --- a/04-Breakout-Game/style.css +++ b/04-Breakout-Game/style.css @@ -41,7 +41,8 @@ canvas { display: block; border-radius: 5px; width: 800px; - max-width: 96%; + max-width: 70vw; + max-height: 70vh; } .btn { From 5c54c3873df964003709eed5e73b3433a948771c Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 16 Aug 2024 00:08:21 +1000 Subject: [PATCH 48/93] done with it --- 04-Breakout-Game/style.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/04-Breakout-Game/style.css b/04-Breakout-Game/style.css index 95d58a2..bfb3bab 100644 --- a/04-Breakout-Game/style.css +++ b/04-Breakout-Game/style.css @@ -29,6 +29,7 @@ body { justify-content: center; min-height: 100vh; margin: 0; + overscroll-behavior: contain; } h1 { @@ -40,9 +41,8 @@ canvas { background-color: var(--canvas-color); display: block; border-radius: 5px; - width: 800px; - max-width: 70vw; - max-height: 70vh; + max-width: 90vw; + max-height: 60vh; } .btn { From 31c23ba249b2d6b3dd7f8e6f974113bcaa4f6123 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 16 Aug 2024 11:33:56 +1000 Subject: [PATCH 49/93] change pingPong to mouse/touch ctrl --- 04-Breakout-Game/style.css | 2 +- 07-Ping-Pong-Game/index.html | 4 +- 07-Ping-Pong-Game/script.js | 110 ++++++++++++++++++++++++++++++++++- 3 files changed, 110 insertions(+), 6 deletions(-) diff --git a/04-Breakout-Game/style.css b/04-Breakout-Game/style.css index bfb3bab..a862695 100644 --- a/04-Breakout-Game/style.css +++ b/04-Breakout-Game/style.css @@ -29,7 +29,7 @@ body { justify-content: center; min-height: 100vh; margin: 0; - overscroll-behavior: contain; + overscroll-behavior-y: contain; } h1 { diff --git a/07-Ping-Pong-Game/index.html b/07-Ping-Pong-Game/index.html index 9ed5d03..edc1e05 100644 --- a/07-Ping-Pong-Game/index.html +++ b/07-Ping-Pong-Game/index.html @@ -56,7 +56,7 @@
- + \ No newline at end of file diff --git a/07-Ping-Pong-Game/script.js b/07-Ping-Pong-Game/script.js index eb473d9..ebc94b4 100644 --- a/07-Ping-Pong-Game/script.js +++ b/07-Ping-Pong-Game/script.js @@ -148,9 +148,11 @@ function update() { } else if (rightPlayerScore === maxScore) { playerWin("Right player"); } + } function playerWin(player) { + gameRunning = false; var message = "Congratulations! " + player + " win!"; $("#message").text(message); // Set the message text $("#message-modal").modal("show"); // Display the message modal @@ -215,7 +217,7 @@ $("#message-modal-close").on("click", function () { var downLock = false; function keyDown() {// pressed down arrow key - if(upLock) { keyUp(); } + if (upLock) { keyUp(); } if (downLock) { var event = new KeyboardEvent('keyup', { bubbles: true, @@ -279,7 +281,7 @@ function keyRight() {// pressed right arrow key var wLock = false; function keyW() {// pressed w key - if (sLock) {keyS();} + if (sLock) { keyS(); } if (wLock) { var event = new KeyboardEvent('keyup', { bubbles: true, @@ -308,7 +310,7 @@ function keyW() {// pressed w key var sLock = false; function keyS() {// pressed s key - if (wLock) {keyW();} + if (wLock) { keyW(); } if (sLock) { var event = new KeyboardEvent('keyup', { bubbles: true, @@ -333,3 +335,105 @@ function keyS() {// pressed s key document.getElementById("right_arrow").style.transform = "scale(0.9)rotate(90deg)"; } } + +//ๅขžๅŠ ไธ€ไธช่งฆๆ‘ธๅฑๅน•ไบ‹ไปถ๏ผŒ่ฎฉPaddleๆฐดๅนณ็งปๅŠจ่ท็ฆปๅ’Œ่งฆๆ‘ธ็‚นๆฐดๅนณ็งปๅŠจ่ท็ฆปไธ€่‡ด +var touchYstartLeft = null; +var previousPositionLeft = canvas.height / 2 - paddleHeight; +var touchYstartRight = null; +var previousPositionRight = canvas.height / 2 - paddleHeight; +function actionStart(e) { + //e.preventDefault(); + //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ + var leftPt = { pageX: canvas.width, pageY: 0 }, rightPt = { pageX: 0, pageY: 0 }; + + if (e.touches) {//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ + e.touches.forEach(element => {//่ฎฐๅฝ•ๅทฆๅŠ่พน๏ผŒๆœ€ๅทฆ่พน็š„็‚น + if (element.pageX - canvas.offsetLeft < canvas.width / 2) { + leftPt = element.pageX < leftPt.pageX ? element : leftPt; + } else {//่ฎฐๅฝ•ๅณๅŠ่พน๏ผŒๆœ€ๅณ่พน็š„็‚น + rightPt = element.pageX > rightPt.pageX ? element : rightPt; + } + }); + if (touchYstartLeft == null) { touchYstartLeft = leftPt.pageY; } + if (touchYstartRight == null) { touchYstartRight = rightPt.pageY; } + return; + } else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ touchXstart็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡ + if (e.pageX - canvas.offsetLeft < canvas.width / 2) { + if (touchYstartLeft == null) { touchYstartLeft = e.pageY; } + } else { + if (touchYstartRight == null) { touchYstartRight = e.pageY; } + } + } + + + + +} +function actionEnd(e) { + //e.preventDefault(); + if (touchYstartRight != null) { + touchYstartRight = null; + previousPositionRight = rightPaddleY; + } + if (touchYstartLeft != null) { + touchYstartLeft = null; + previousPositionLeft = leftPaddleY; + } +} +function actionMove(e) { + //e.preventDefault(); + var distLeft, distRight, leftPt, rightPt; + //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ + if (e.touches) { + e.touches.forEach(element => { + if (element.pageX - canvas.offsetLeft < canvas.width / 2) { + leftPt = element.pageX < leftPt.pageX ? element : leftPt; + } else {//่ฎฐๅฝ•ๅณๅŠ่พน๏ผŒๆœ€ๅณ่พน็š„็‚น + rightPt = element.pageX > rightPt.pageX ? element : rightPt; + } + }); + if (touchYstartLeft != null) { + distLeft = leftPt.pageY - touchYstartLeft; + leftPaddleY = previousPositionLeft + distLeft; + if (leftPaddleY + paddleHeight > canvas.height) leftPaddleY = canvas.height - paddleHeight; + if (leftPaddleY < 0) leftPaddleY = 0; + } + if (touchYstartRight != null) { + distRight = rightPt.pageY - touchYstartRight; + rightPaddleY = previousPositionRight + distRight; + if (rightPaddleY + paddleHeight > canvas.height) rightPaddleY = canvas.height - paddleHeight; + if (rightPaddleY < 0) rightPaddleY = 0; + } + + } else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ dist็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡x็›ธๅฏนtouchXstart็š„็งปๅŠจ่ท็ฆป + if (e.pageX - canvas.offsetLeft < canvas.width / 2) { + if (touchYstartLeft != null) { + distLeft = e.pageY - touchYstartLeft; + leftPaddleY = previousPositionLeft + distLeft; + if (leftPaddleY + paddleHeight > canvas.height) leftPaddleY = canvas.height - paddleHeight; + if (leftPaddleY < 0) leftPaddleY = 0; + } + } else { + if (touchYstartRight != null) { + distRight = e.pageY - touchYstartRight; + rightPaddleY = previousPositionRight + distRight; + if (rightPaddleY + paddleHeight > canvas.height) rightPaddleY = canvas.height - paddleHeight; + if (rightPaddleY < 0) rightPaddleY = 0; + } + } + } + + + + + +} + + +document.addEventListener('touchstart', actionStart); +document.addEventListener('touchend', actionEnd); +document.addEventListener('touchmove', actionMove); +//็›ธๅบ”้ผ ๆ ‡็‚นๅ‡ปๅŽ็งปๅŠจ็š„ไบ‹ไปถ +document.addEventListener('mousedown', actionStart); +document.addEventListener('mouseup', actionEnd); +document.addEventListener('mousemove', actionMove); \ No newline at end of file From 0b83af39e19ec5b60e951829e321238a591c50a6 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 16 Aug 2024 13:21:26 +1000 Subject: [PATCH 50/93] random words definiation of words --- 18-Hangman-Game/index.html | 118 ++++++++++++++++++++----------------- 18-Hangman-Game/script.js | 57 ++++++++++++++++-- 18-Hangman-Game/style.css | 31 +++++++++- 3 files changed, 145 insertions(+), 61 deletions(-) diff --git a/18-Hangman-Game/index.html b/18-Hangman-Game/index.html index ef8d967..3d93e72 100644 --- a/18-Hangman-Game/index.html +++ b/18-Hangman-Game/index.html @@ -1,61 +1,71 @@ - - - - - Hangman - - - + + + + + Hangman - - - + + + - - - -

Hangman

-

Find the hidden word - Press a letter

-
- - - - - - - - - - - - - - - - - -
-
-
-
-
- - - -
-

You have already entered this letter

+ + + + + + + + +

Hangman

+

Find the hidden word - Press a letter

+
+ + + + + + + + + + + + + + + + + +
+
-
+
+
+ + + +
+

You have already entered this letter

+
+
+
+ + + + + \ No newline at end of file diff --git a/18-Hangman-Game/script.js b/18-Hangman-Game/script.js index 6c818e6..aa84d10 100644 --- a/18-Hangman-Game/script.js +++ b/18-Hangman-Game/script.js @@ -1,6 +1,7 @@ const wordElement = document.getElementById("word"); const wrongLettersElement = document.getElementById("wrong-letters"); const playAgainButton = document.getElementById("play-button"); +const definitionButton = document.getElementById("def-button"); const popup = document.getElementById("popup-container"); const notification = document.getElementById("notification-container"); const finalMessage = document.getElementById("final-message"); @@ -34,12 +35,15 @@ const words = [ "node", ]; let selectedWord = words[Math.floor(Math.random() * words.length)]; - let playable = true; const correctLetters = []; const wrongLetters = []; - +async function fetchRandomWord() { + const response = await fetch('https://random-word-api.herokuapp.com/word'); + const randomWord = await response.json(); + return randomWord[0]; // ่ฟ”ๅ›ž้šๆœบๅ•่ฏ +} function displayWord() { wordElement.innerHTML = ` ${selectedWord @@ -113,16 +117,57 @@ window.addEventListener("keypress", (e) => { press (e.key.toLowerCase()); }); -playAgainButton.addEventListener("click", () => { +playAgainButton.addEventListener("click", async () => { playable = true; correctLetters.splice(0); wrongLetters.splice(0); - selectedWord = words[Math.floor(Math.random() * words.length)]; + //selectedWord = words[Math.floor(Math.random() * words.length)]; + selectedWord = await fetchRandomWord(); displayWord(); updateWrongLettersElement(); popup.style.display = "none"; }); +definitionButton.addEventListener("click", async () => { + const word = selectedWord; + if (!word) return; + + const response = await fetch(`https://api.dictionaryapi.dev/api/v2/entries/en/${word}`); + const data = await response.json(); + const resultContent = document.getElementById('resultContent'); + resultContent.innerHTML = formatResult(data); + + document.getElementById('resultContainer').classList.remove('hidden'); + document.body.classList.remove('hidden-result'); +}); +function formatResult(data) { + if (!data || data.length === 0 || data.title === 'No Definitions Found') return 'No results found.'; + + const wordData = data[0]; + let resultHTML = `

${wordData.word}

`; + resultHTML += `

Phonetic: ${wordData.phonetic || 'N/A'}

`; + + if (wordData.origin) { + resultHTML += `

Origin: ${wordData.origin}

`; + } + + resultHTML += '

Meanings:

'; + wordData.meanings.forEach(meaning => { + resultHTML += `

${meaning.partOfSpeech}

`; + meaning.definitions.forEach(def => { + resultHTML += `

- ${def.definition}

`; + if (def.example) { + resultHTML += `

Example: ${def.example}

`; + } + }); + }); + + return resultHTML; +} +document.getElementById('closeButton').addEventListener('click', () => { + document.getElementById('resultContainer').classList.add('hidden'); + document.body.classList.add('hidden-result'); +}); // Init displayWord(); function hasPhysicalKeyboard() { @@ -145,8 +190,8 @@ function createVirtualKeyboard(divElement) { keyboard.style.justifyContent = 'center'; keyboard.style.padding = '10px'; keyboard.style.position = 'absolute'; - keyboard.style.top = '75%'; - keyboard.style.width = '100%'; + keyboard.style.top = '60vh'; + keyboard.style.width = '100vw'; keyboard.style.left = '0'; const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; letters.split('').forEach(letter => { diff --git a/18-Hangman-Game/style.css b/18-Hangman-Game/style.css index 25c42d7..85d9392 100644 --- a/18-Hangman-Game/style.css +++ b/18-Hangman-Game/style.css @@ -18,7 +18,7 @@ body { flex-direction: column; align-items: center; justify-content: center; - height: 80vh; + height: 60vh; overflow: hidden; margin: 0; } @@ -99,6 +99,7 @@ h3 { display: none; align-items: center; justify-content: center; + z-index: 500; } .popup { @@ -145,3 +146,31 @@ h3 { .notification-container p { margin: 0; } +#resultContainer { + position: fixed; + top: 50px; + left: 50%; + transform: translateX(-50%); + background-color: #224ca4; + border: 1px solid #ccc; + padding: 20px; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); + max-width: 500px; + width: 80%; + z-index: 1000; + +} + +.hidden { + display: none; +} + +#resultContent { + text-align: left; + max-height: 70vh; + overflow-y: auto; +} + +body.hidden-result #resultContainer { + display: none; +} \ No newline at end of file From 41e6e00702187476a832880e27b56c198a4bd1e4 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 17 Aug 2024 00:14:37 +1000 Subject: [PATCH 51/93] fix page --- 07-Ping-Pong-Game/index.html | 3 ++- 07-Ping-Pong-Game/script.js | 31 +++++++++++++++++++++++++++---- 07-Ping-Pong-Game/style.css | 5 +++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/07-Ping-Pong-Game/index.html b/07-Ping-Pong-Game/index.html index edc1e05..917104c 100644 --- a/07-Ping-Pong-Game/index.html +++ b/07-Ping-Pong-Game/index.html @@ -3,7 +3,8 @@ Ping Pong Game - + + diff --git a/07-Ping-Pong-Game/script.js b/07-Ping-Pong-Game/script.js index ebc94b4..2e43721 100644 --- a/07-Ping-Pong-Game/script.js +++ b/07-Ping-Pong-Game/script.js @@ -346,7 +346,7 @@ function actionStart(e) { //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ var leftPt = { pageX: canvas.width, pageY: 0 }, rightPt = { pageX: 0, pageY: 0 }; - if (e.touches) {//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ + if (e.touches && e.touches.length >1) {//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ e.touches.forEach(element => {//่ฎฐๅฝ•ๅทฆๅŠ่พน๏ผŒๆœ€ๅทฆ่พน็š„็‚น if (element.pageX - canvas.offsetLeft < canvas.width / 2) { leftPt = element.pageX < leftPt.pageX ? element : leftPt; @@ -357,7 +357,13 @@ function actionStart(e) { if (touchYstartLeft == null) { touchYstartLeft = leftPt.pageY; } if (touchYstartRight == null) { touchYstartRight = rightPt.pageY; } return; - } else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ touchXstart็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡ + } else if(e.touches && e.touches.length == 1) {//ๅฆ‚ๆžœๆ˜ฏๅ•็‚น่งฆๆ‘ธ + if (e.touches[0].pageX - canvas.offsetLeft < canvas.width / 2) { + if (touchYstartLeft == null) { touchYstartLeft = e.touches[0].pageY; } + } else { + if (touchYstartRight == null) { touchYstartRight = e.touches[0].pageY; } + } + }else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ touchXstart็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡ if (e.pageX - canvas.offsetLeft < canvas.width / 2) { if (touchYstartLeft == null) { touchYstartLeft = e.pageY; } } else { @@ -384,7 +390,7 @@ function actionMove(e) { //e.preventDefault(); var distLeft, distRight, leftPt, rightPt; //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ - if (e.touches) { + if (e.touches && e.touches.length > 1) {//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ e.touches.forEach(element => { if (element.pageX - canvas.offsetLeft < canvas.width / 2) { leftPt = element.pageX < leftPt.pageX ? element : leftPt; @@ -405,7 +411,24 @@ function actionMove(e) { if (rightPaddleY < 0) rightPaddleY = 0; } - } else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ dist็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡x็›ธๅฏนtouchXstart็š„็งปๅŠจ่ท็ฆป + } else if(e.touches && e.touches.length == 1) {//ๅฆ‚ๆžœๆ˜ฏๅ•็‚น่งฆๆ‘ธ + if (e.touches[0].pageX - canvas.offsetLeft < canvas.width / 2) { + if (touchYstartLeft != null) { + distLeft = e.touches[0].pageY - touchYstartLeft; + leftPaddleY = previousPositionLeft + distLeft; + if (leftPaddleY + paddleHeight > canvas.height) leftPaddleY = canvas.height - paddleHeight; + if (leftPaddleY < 0) leftPaddleY = 0; + } + } else { + if (touchYstartRight != null) { + distRight = e.touches[0].pageY - touchYstartRight; + rightPaddleY = previousPositionRight + distRight; + if (rightPaddleY + paddleHeight > canvas.height) rightPaddleY = canvas.height - paddleHeight; + if (rightPaddleY < 0) rightPaddleY = 0; + } + } + +}else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ dist็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡x็›ธๅฏนtouchXstart็š„็งปๅŠจ่ท็ฆป if (e.pageX - canvas.offsetLeft < canvas.width / 2) { if (touchYstartLeft != null) { distLeft = e.pageY - touchYstartLeft; diff --git a/07-Ping-Pong-Game/style.css b/07-Ping-Pong-Game/style.css index 5cb33d2..935e7fa 100644 --- a/07-Ping-Pong-Game/style.css +++ b/07-Ping-Pong-Game/style.css @@ -3,6 +3,7 @@ flex-direction: column; align-items: center; justify-content: center; + max-height: 75vh; } .button { @@ -36,3 +37,7 @@ canvas { background: #000; } +body { + overscroll-behavior-y: contain; + max-height: 80vh; +} \ No newline at end of file From 44887ca18090a78fb273085a100ea509a1d91120 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 17 Aug 2024 00:21:38 +1000 Subject: [PATCH 52/93] fix move --- 04-Breakout-Game/style.css | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/04-Breakout-Game/style.css b/04-Breakout-Game/style.css index a862695..7c4f1f7 100644 --- a/04-Breakout-Game/style.css +++ b/04-Breakout-Game/style.css @@ -27,9 +27,10 @@ body { flex-direction: column; align-items: center; justify-content: center; - min-height: 100vh; + /*min-height: 100vh;*/ margin: 0; overscroll-behavior-y: contain; + max-height: 80vh; } h1 { From 32573f785dfd99607c1ebf1661289ec725a6b27d Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 17 Aug 2024 00:32:50 +1000 Subject: [PATCH 53/93] fix bug --- 07-Ping-Pong-Game/script.js | 83 +++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/07-Ping-Pong-Game/script.js b/07-Ping-Pong-Game/script.js index 2e43721..d1e8d97 100644 --- a/07-Ping-Pong-Game/script.js +++ b/07-Ping-Pong-Game/script.js @@ -387,76 +387,71 @@ function actionEnd(e) { } } function actionMove(e) { - //e.preventDefault(); - var distLeft, distRight, leftPt, rightPt; - //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ - if (e.touches && e.touches.length > 1) {//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ - e.touches.forEach(element => { - if (element.pageX - canvas.offsetLeft < canvas.width / 2) { - leftPt = element.pageX < leftPt.pageX ? element : leftPt; - } else {//่ฎฐๅฝ•ๅณๅŠ่พน๏ผŒๆœ€ๅณ่พน็š„็‚น - rightPt = element.pageX > rightPt.pageX ? element : rightPt; + e.preventDefault(); // ้˜ฒๆญข้กต้ขๆปšๅŠจ + + var distLeft, distRight; + + if (e.touches && e.touches.length > 1) { // ๅคš็‚น่งฆๆ‘ธ + let leftPt = e.touches[0]; + let rightPt = e.touches[0]; + + for (let i = 1; i < e.touches.length; i++) { + if (e.touches[i].pageX < leftPt.pageX) { + leftPt = e.touches[i]; } - }); - if (touchYstartLeft != null) { + if (e.touches[i].pageX > rightPt.pageX) { + rightPt = e.touches[i]; + } + } + + if (touchYstartLeft !== null && leftPt.pageX - canvas.offsetLeft < canvas.width / 2) { distLeft = leftPt.pageY - touchYstartLeft; leftPaddleY = previousPositionLeft + distLeft; - if (leftPaddleY + paddleHeight > canvas.height) leftPaddleY = canvas.height - paddleHeight; - if (leftPaddleY < 0) leftPaddleY = 0; + leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); } - if (touchYstartRight != null) { + + if (touchYstartRight !== null && rightPt.pageX - canvas.offsetLeft > canvas.width / 2) { distRight = rightPt.pageY - touchYstartRight; rightPaddleY = previousPositionRight + distRight; - if (rightPaddleY + paddleHeight > canvas.height) rightPaddleY = canvas.height - paddleHeight; - if (rightPaddleY < 0) rightPaddleY = 0; + rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); } - } else if(e.touches && e.touches.length == 1) {//ๅฆ‚ๆžœๆ˜ฏๅ•็‚น่งฆๆ‘ธ - if (e.touches[0].pageX - canvas.offsetLeft < canvas.width / 2) { - if (touchYstartLeft != null) { - distLeft = e.touches[0].pageY - touchYstartLeft; + } else if (e.touches && e.touches.length == 1) { // ๅ•็‚น่งฆๆ‘ธ + let touch = e.touches[0]; + if (touch.pageX - canvas.offsetLeft < canvas.width / 2) { + if (touchYstartLeft !== null) { + distLeft = touch.pageY - touchYstartLeft; leftPaddleY = previousPositionLeft + distLeft; - if (leftPaddleY + paddleHeight > canvas.height) leftPaddleY = canvas.height - paddleHeight; - if (leftPaddleY < 0) leftPaddleY = 0; + leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); } } else { - if (touchYstartRight != null) { - distRight = e.touches[0].pageY - touchYstartRight; + if (touchYstartRight !== null) { + distRight = touch.pageY - touchYstartRight; rightPaddleY = previousPositionRight + distRight; - if (rightPaddleY + paddleHeight > canvas.height) rightPaddleY = canvas.height - paddleHeight; - if (rightPaddleY < 0) rightPaddleY = 0; + rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); } } - -}else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ dist็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡x็›ธๅฏนtouchXstart็š„็งปๅŠจ่ท็ฆป - if (e.pageX - canvas.offsetLeft < canvas.width / 2) { - if (touchYstartLeft != null) { + } else { // ้ผ ๆ ‡็งปๅŠจ + if (e.pageX - canvas.offsetLeft < canvas.width / 2) { + if (touchYstartLeft !== null) { distLeft = e.pageY - touchYstartLeft; leftPaddleY = previousPositionLeft + distLeft; - if (leftPaddleY + paddleHeight > canvas.height) leftPaddleY = canvas.height - paddleHeight; - if (leftPaddleY < 0) leftPaddleY = 0; + leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); } } else { - if (touchYstartRight != null) { + if (touchYstartRight !== null) { distRight = e.pageY - touchYstartRight; rightPaddleY = previousPositionRight + distRight; - if (rightPaddleY + paddleHeight > canvas.height) rightPaddleY = canvas.height - paddleHeight; - if (rightPaddleY < 0) rightPaddleY = 0; + rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); } } } - - - - - } - -document.addEventListener('touchstart', actionStart); +// ไบ‹ไปถ็›‘ๅฌๅ™จ +document.addEventListener('touchstart', actionStart, { passive: false }); document.addEventListener('touchend', actionEnd); -document.addEventListener('touchmove', actionMove); -//็›ธๅบ”้ผ ๆ ‡็‚นๅ‡ปๅŽ็งปๅŠจ็š„ไบ‹ไปถ +document.addEventListener('touchmove', actionMove, { passive: false }); document.addEventListener('mousedown', actionStart); document.addEventListener('mouseup', actionEnd); document.addEventListener('mousemove', actionMove); \ No newline at end of file From c961594bb82528ab7c61935fe8f8d0936b4500e5 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 17 Aug 2024 08:53:59 +1000 Subject: [PATCH 54/93] fix bug --- 07-Ping-Pong-Game/script.js | 113 +++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 53 deletions(-) diff --git a/07-Ping-Pong-Game/script.js b/07-Ping-Pong-Game/script.js index d1e8d97..01ef092 100644 --- a/07-Ping-Pong-Game/script.js +++ b/07-Ping-Pong-Game/script.js @@ -7,6 +7,7 @@ var pauseBtn = document.getElementById("pause-btn"); var restartBtn = document.getElementById("restart-btn"); var animationId; var gameRunning = false; +var ballColor = "#FFF"; startBtn.addEventListener("click", function () { if (!gameRunning) { @@ -172,13 +173,13 @@ function draw() { // Clear canvas ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.fillStyle = "#FFF"; + ctx.fillStyle = ballColor; ctx.font = "15px Arial"; ctx.beginPath(); ctx.moveTo(canvas.width / 2, 0); ctx.lineTo(canvas.width / 2, canvas.height); - ctx.strokeStyle = "#FFF"; // Set line color to white + ctx.strokeStyle = ballColor; // Set line color to white ctx.stroke(); ctx.closePath(); @@ -344,11 +345,12 @@ var previousPositionRight = canvas.height / 2 - paddleHeight; function actionStart(e) { //e.preventDefault(); //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ + if(!gameRunning ) { return; } var leftPt = { pageX: canvas.width, pageY: 0 }, rightPt = { pageX: 0, pageY: 0 }; - if (e.touches && e.touches.length >1) {//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ + if (e.touches && e.touches.length > 1) {//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ e.touches.forEach(element => {//่ฎฐๅฝ•ๅทฆๅŠ่พน๏ผŒๆœ€ๅทฆ่พน็š„็‚น - if (element.pageX - canvas.offsetLeft < canvas.width / 2) { + if (element.pageX - canvas.offsetLeft < canvas.width / 2) { leftPt = element.pageX < leftPt.pageX ? element : leftPt; } else {//่ฎฐๅฝ•ๅณๅŠ่พน๏ผŒๆœ€ๅณ่พน็š„็‚น rightPt = element.pageX > rightPt.pageX ? element : rightPt; @@ -357,14 +359,14 @@ function actionStart(e) { if (touchYstartLeft == null) { touchYstartLeft = leftPt.pageY; } if (touchYstartRight == null) { touchYstartRight = rightPt.pageY; } return; - } else if(e.touches && e.touches.length == 1) {//ๅฆ‚ๆžœๆ˜ฏๅ•็‚น่งฆๆ‘ธ + } else if (e.touches && e.touches.length == 1) {//ๅฆ‚ๆžœๆ˜ฏๅ•็‚น่งฆๆ‘ธ if (e.touches[0].pageX - canvas.offsetLeft < canvas.width / 2) { if (touchYstartLeft == null) { touchYstartLeft = e.touches[0].pageY; } } else { if (touchYstartRight == null) { touchYstartRight = e.touches[0].pageY; } } - }else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ touchXstart็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡ - if (e.pageX - canvas.offsetLeft < canvas.width / 2) { + } else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ touchXstart็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡ + if (e.pageX - canvas.offsetLeft < canvas.width / 2) { if (touchYstartLeft == null) { touchYstartLeft = e.pageY; } } else { if (touchYstartRight == null) { touchYstartRight = e.pageY; } @@ -388,61 +390,66 @@ function actionEnd(e) { } function actionMove(e) { e.preventDefault(); // ้˜ฒๆญข้กต้ขๆปšๅŠจ - - var distLeft, distRight; - - if (e.touches && e.touches.length > 1) { // ๅคš็‚น่งฆๆ‘ธ - let leftPt = e.touches[0]; - let rightPt = e.touches[0]; - - for (let i = 1; i < e.touches.length; i++) { - if (e.touches[i].pageX < leftPt.pageX) { - leftPt = e.touches[i]; - } - if (e.touches[i].pageX > rightPt.pageX) { - rightPt = e.touches[i]; + if (touchYstartRight !== null || touchYstartLeft !== null && gameRunning) { + var distLeft, distRight; + if (e.touches && e.touches.length > 1) { // ๅคš็‚น่งฆๆ‘ธ + //ๅˆๅง‹ๅŒ–ไธบ็”ปๅธƒไธญ้—ดไฝ็ฝฎ + let leftPt = {pageX:canvas.offsetLeft + canvas.width / 2,pageY:0}; + let rightPt = {pageX:canvas.offsetLeft + canvas.width / 2,pageY:0}; + ballColor = 'red'; + for (let i = 1; i < e.touches.length; i++) { + if (e.touches[i].pageX < leftPt.pageX) { + leftPt = e.touches[i]; + + } + if (e.touches[i].pageX > rightPt.pageX) { + rightPt = e.touches[i]; + + } } - } - - if (touchYstartLeft !== null && leftPt.pageX - canvas.offsetLeft < canvas.width / 2) { - distLeft = leftPt.pageY - touchYstartLeft; - leftPaddleY = previousPositionLeft + distLeft; - leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); - } - - if (touchYstartRight !== null && rightPt.pageX - canvas.offsetLeft > canvas.width / 2) { - distRight = rightPt.pageY - touchYstartRight; - rightPaddleY = previousPositionRight + distRight; - rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); - } - } else if (e.touches && e.touches.length == 1) { // ๅ•็‚น่งฆๆ‘ธ - let touch = e.touches[0]; - if (touch.pageX - canvas.offsetLeft < canvas.width / 2) { - if (touchYstartLeft !== null) { - distLeft = touch.pageY - touchYstartLeft; + if (touchYstartLeft !== null && leftPt.pageX - canvas.offsetLeft < canvas.width / 2) { + distLeft = leftPt.pageY - touchYstartLeft; leftPaddleY = previousPositionLeft + distLeft; leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); + ballColor = 'blue'; } - } else { - if (touchYstartRight !== null) { - distRight = touch.pageY - touchYstartRight; + + if (touchYstartRight !== null && rightPt.pageX - canvas.offsetLeft > canvas.width / 2) { + distRight = rightPt.pageY - touchYstartRight; rightPaddleY = previousPositionRight + distRight; rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); + ballColor = 'green'; } - } - } else { // ้ผ ๆ ‡็งปๅŠจ - if (e.pageX - canvas.offsetLeft < canvas.width / 2) { - if (touchYstartLeft !== null) { - distLeft = e.pageY - touchYstartLeft; - leftPaddleY = previousPositionLeft + distLeft; - leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); + + } else if (e.touches && e.touches.length == 1) { // ๅ•็‚น่งฆๆ‘ธ + let touch = e.touches[0]; + if (touch.pageX - canvas.offsetLeft < canvas.width / 2) { + if (touchYstartLeft !== null) { + distLeft = touch.pageY - touchYstartLeft; + leftPaddleY = previousPositionLeft + distLeft; + leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); + } + } else { + if (touchYstartRight !== null) { + distRight = touch.pageY - touchYstartRight; + rightPaddleY = previousPositionRight + distRight; + rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); + } } - } else { - if (touchYstartRight !== null) { - distRight = e.pageY - touchYstartRight; - rightPaddleY = previousPositionRight + distRight; - rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); + } else { // ้ผ ๆ ‡็งปๅŠจ + if (e.pageX - canvas.offsetLeft < canvas.width / 2) { + if (touchYstartLeft !== null) { + distLeft = e.pageY - touchYstartLeft; + leftPaddleY = previousPositionLeft + distLeft; + leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); + } + } else { + if (touchYstartRight !== null) { + distRight = e.pageY - touchYstartRight; + rightPaddleY = previousPositionRight + distRight; + rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); + } } } } From abe8457c2735aafdf5a78a3db462d19516a2ee76 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 17 Aug 2024 10:52:11 +1000 Subject: [PATCH 55/93] now you can adjust game grid size and winning number --- 15-Connect-Four-Game/index.html | 300 ++-------------------------- 15-Connect-Four-Game/script.js | 138 ++++++++----- 15-Connect-Four-Game/style.css | 338 ++++++++++++++------------------ 3 files changed, 250 insertions(+), 526 deletions(-) diff --git a/15-Connect-Four-Game/index.html b/15-Connect-Four-Game/index.html index 6c5bf3f..132895b 100644 --- a/15-Connect-Four-Game/index.html +++ b/15-Connect-Four-Game/index.html @@ -24,299 +24,29 @@ - +
+
+ + +
+
+ + +
+
+ + +
+ +
-
-

Player - 1

-
-
- -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
- - - -
- -
-
- -
- diff --git a/15-Connect-Four-Game/script.js b/15-Connect-Four-Game/script.js index bf0a390..e502a8b 100644 --- a/15-Connect-Four-Game/script.js +++ b/15-Connect-Four-Game/script.js @@ -1,99 +1,131 @@ // DOM Variables -var buttons = document.getElementsByClassName("btn"); +var buttons var reset = document.getElementById("reset-btn"); var playerType = document.getElementById("player-type"); +var updateGridBTN = document.getElementById("update-grid"); +var widthInput = document.getElementById("grid-width"); +var heightInput = document.getElementById("grid-height"); +var winConditionInput = document.getElementById("win-condition"); // Game Flow Variables +var columns = 10; +var rows = 10; +var winCount = 4; +var filledGrid; var playerNumber = 1; // Initially player - 1 gets to start his/her turn -var filledGrid = []; // Player board + initGame(10,10,5); // (columns, rows, winCounts) -var filledCells = 0; // No. of cells that has been filled +function initGame(column, row, winCounts) { + filledGrid = create2DArray(row , column); // Player board + createGrid(row, column, 'grid'); + columns = column; + rows = row; + winCount = winCounts; + buttons = document.getElementsByClassName("btn"); + for(var i = 0; i < buttons.length; i++) { + // Handing the Event when button was clicked + buttons[i].addEventListener("click" , function() { + // Make move and disable the button to avoid furthur clicking it again + var buttonNo = this.classList[1]; + makeMove(this , buttonNo.slice(4)); + }); + } +} +function createGrid(rows, cols, targetElementId) { + const grid = document.getElementById(targetElementId); -for(var i = 0; i < 6; i++) { + let btnCount = 1; - var arr = [-1 , -1 , -1 , -1 , -1 , -1 , -1]; // Board is initialised with -1 - filledGrid.push(arr); + for (let i = 0; i < rows; i++) { + const row = document.createElement('div'); + row.className = 'row'; -} + for (let j = 0; j < cols; j++) { + const col = document.createElement('div'); + col.className = 'col'; + const btn = document.createElement('button'); + btn.className = `btn btn-${btnCount}`; -// Event Listener for Buttons + col.appendChild(btn); + row.appendChild(col); -reset.addEventListener("click" , function() { + btnCount++; + } - resetBoard(); + grid.appendChild(row); + } -}); +} +var filledCells = 0; // No. of cells that has been filled +function create2DArray(rows, cols) { + return Array.from({ length: rows }, () => + Array.from({ length: cols }, () => -1) + ); +} -for(var i = 0; i < buttons.length; i++) { +function updateGrid() { + const width = parseInt(widthInput.value); + const height = parseInt(heightInput.value); + const winCondition = parseInt(winConditionInput.value); - // Handing the Event when button was clicked + if (width < 3 || width > 20 || height < 3 || height > 20 || winCondition < 3 || winCondition > 8 ||winCondition > width || winCondition > height) { + //alert('่ฏท่พ“ๅ…ฅๆœ‰ๆ•ˆ็š„ๅ€ผ๏ผšๅฎฝๅบฆๅ’Œ้ซ˜ๅบฆๅœจ3-20ไน‹้—ด๏ผŒ่Žท่ƒœๆกไปถๅœจ3-8ไน‹้—ดใ€‚'); + alert('Please enter valid values: width and height should be between 3 and 20, and win condition should be between 3 and 8.'); + return; + } + document.getElementById("grid").innerHTML = ''; + initGame(width, height, winCondition); - buttons[i].addEventListener("click" , function() { - // Make move and disable the button to avoid furthur clicking it again + document.getElementById("grid-config").style.display = "none"; +} - var buttonNo = this.classList[1]; - makeMove(this , buttonNo.slice(4)); +// Event Listener for Buttons +updateGridBTN.addEventListener('click', updateGrid); +reset.addEventListener("click" , resetBoard); - }); -} // Function to Make Move on the passed button and disable it function makeMove(button , buttonNo) { - - var row = buttonNo % 7 === 0 ? Math.floor(buttonNo / 7) - 1 : Math.floor(buttonNo / 7); - var col = buttonNo % 7 === 0 ? 6: (buttonNo % 7) - 1; - + var row = buttonNo % columns === 0 ? Math.floor(buttonNo / columns) - 1 : Math.floor(buttonNo / columns); + var col = buttonNo % columns === 0 ? rows: (buttonNo % columns) - 1; if(playerNumber === 1) { - button.classList.add("btn-player-1"); - - filledGrid[row][col] = 1; filledCells++; - - if(playerWon(row , col , 1) === true) { setTimeout(function() { alert("Game Over: Green Wins"); resetBoard(); } , 200); } - // Update the player playerNumber = 2; playerType.textContent = "Player - 2"; - } else { - button.classList.add("btn-player-2"); - - filledGrid[row][col] = 2; filledCells++; - if(playerWon(row , col , 2) === true) { setTimeout(function() { alert("Game Over : Red Wins"); resetBoard(); } , 200); } - // Update the player playerNumber = 1; playerType.textContent = "Player - 1"; - } // If all the cells has been filled - if(filledCells === 42) { + if(filledCells === rows * columns) { setTimeout(function() { alert("Game Draw"); resetBoard(); @@ -114,10 +146,10 @@ function playerWon(row , col , player) { // Check for columns - for(var i = 0; i < 7; i++) { + for(var i = 0; i < columns; i++) { if(filledGrid[row][i] === player) { count++; - if(count === 4) return true; + if(count === winCount) return true; } else { count = 0; } @@ -128,10 +160,10 @@ function playerWon(row , col , player) { // Check for Rows - for(var i = 0; i < 6; i++) { + for(var i = 0; i < rows; i++) { if(filledGrid[i][col] === player) { count++; - if(count === 4) return true; + if(count === winCount) return true; } else { count = 0; } @@ -147,10 +179,10 @@ function playerWon(row , col , player) { var i = row - col; var j = 0; - for(; i <= 5; i++ , j++) { + for(; i <= rows-1; i++ , j++) { if(filledGrid[i][j] === player) { count++; - if(count == 4) return true; + if(count == winCount) return true; } else { count = 0; } @@ -160,10 +192,10 @@ function playerWon(row , col , player) { var i = 0; var j = col - row; - for(; j <= 6; i++ , j++) { + for(; j <= columns-1; i++ , j++) { if(filledGrid[i][j] === player) { count++; - if(count == 4) return true; + if(count == winCount) return true; } else { count = 0; } @@ -175,7 +207,7 @@ function playerWon(row , col , player) { // Check for secondary diagonal - if(row + col <= 5) { + if(row + col <= rows - 1) { var i = row + col; var j = 0; @@ -183,7 +215,7 @@ function playerWon(row , col , player) { for(; i >= 0 && j <= row + col; i-- , j++) { if(filledGrid[i][j] === player) { count++; - if(count == 4) return true; + if(count == winCount) return true; } else { count = 0; } @@ -191,13 +223,13 @@ function playerWon(row , col , player) { } else { - var i = 5; - var j = row + col - 5; + var i = rows - 1; + var j = row + col - rows + 1; - for(; j <= 6; j++ , i--) { + for(; j <= columns - 1; j++ , i--) { if(filledGrid[i][j] === player) { count++; - if(count == 4) return true; + if(count == winCount) return true; } else { count = 0; } @@ -233,8 +265,8 @@ function resetBoard() { // Filling the Board with -1 - for(var i = 0; i < 6; i++) { - for(var j = 0; j < 7; j++) { + for(var i = 0; i < rows; i++) { + for(var j = 0; j < columns; j++) { filledGrid[i][j] = -1; } } diff --git a/15-Connect-Four-Game/style.css b/15-Connect-Four-Game/style.css index 0d542bd..85d105c 100644 --- a/15-Connect-Four-Game/style.css +++ b/15-Connect-Four-Game/style.css @@ -1,239 +1,201 @@ body { - background-color: #e9e7fd; + background-color: #e9e7fd; } /* Main Container */ - #main-container { - - align-items: center; - display: flex; - flex-direction: column; - justify-content: center; - min-height: 100vh; - + align-items: center; + display: flex; + flex-direction: column; + justify-content: center; + min-height: 100vh; } /* Player Details */ - #player { - - background-color: #d5deff; - border: 8px solid #4f3ff0; - border-radius: 10px; - margin-top: 50px; - padding: 20px; - width: 550px; - + background-color: #d5deff; + border: 8px solid #4f3ff0; + border-radius: 10px; + margin-top: 50px; + padding: 20px; + width: 80%; + max-width: 550px; } #player-type { - - color: #4f3ff0; - font-family: "Poppins"; - letter-spacing: 5px; - text-align: center; - text-transform: uppercase; - + color: #4f3ff0; + font-family: "Poppins", sans-serif; + letter-spacing: 5px; + text-align: center; + text-transform: uppercase; } - +#grid-config { + background-color: #d5deff; + border: 3px solid #4f3ff0; + border-radius: 8px; + padding: 20px; + margin-top: 20px; + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + width: 80%; + max-width: 550px; + position: absolute; + } + .input-group { + display: flex; + flex-direction: column; + margin: 10px; + } + + .input-group label { + margin-bottom: 5px; + color: #4f3ff0; + font-family: "Poppins", sans-serif; + } + + .input-group input { + width: 60px; + padding: 5px; + border: 1px solid #4f3ff0; + border-radius: 4px; + } + + #update-grid { + background-color: #4f3ff0; + color: #d5deff; + border: none; + border-radius: 5px; + padding: 10px 20px; + font-family: "Poppins", sans-serif; + cursor: pointer; + transition: 0.3s; + } + + #update-grid:hover { + background-color: #3f2fd0; + } /* Grid */ - #grid { - - background-color: #4f3ff0; - border: 3.5px solid #d5deff; - border-radius: 8px; - box-shadow: 2px 3px 7px grey; - margin-top: 50px; - max-width: 600px; - padding: 3px; - + background-color: #4f3ff0; + border: 3.5px solid #d5deff; + border-radius: 8px; + box-shadow: 2px 3px 7px grey; + margin-top: 20px; + padding: 3px; + width: 80vmin; + height: 80vmin; + display: flex; + flex-direction: column; + justify-content: space-between; } /* Grid Row */ - .row { - - display: flex; - + display: flex; + justify-content: space-between; + height: calc((80vmin - 6px - 12px) / 6); /* Subtracting padding and gaps */ } /* Grid Column */ - .col { - - align-items: center; - background-color: #d5deff; - border: 1px solid #4f3ff0; - border-radius: 5px; - display: flex; - justify-content: center; - height: 75px; - margin: 5px; - width: 75px; - + align-items: center; + background-color: #d5deff; + border: 1px solid #4f3ff0; + border-radius: 5px; + display: flex; + justify-content: center; + width: calc((80vmin - 6px - 12px) / 7); /* Subtracting padding and gaps */ + margin: 1px; } /* Buttons */ - .btn { - - background-color: transparent; - border: none; - color: transparent; - height: 100%; - padding: 0; - width: 100%; - + background-color: transparent; + border: none; + color: transparent; + height: 100%; + padding: 0; + width: 100%; } #reset-btn { - - background-color: transparent; - border: 2px solid #4f3ff0; - border-radius: 5px; - color: #4f3ff0; - font-family: "Poppins"; - font-size: 1.5rem; - margin: 50px 0; - padding: 10px 40px; - text-transform: uppercase; - transition: 0.7s; - + background-color: transparent; + border: 2px solid #4f3ff0; + border-radius: 5px; + color: #4f3ff0; + font-family: "Poppins", sans-serif; + font-size: 1.5rem; + margin: 50px 0; + padding: 10px 40px; + text-transform: uppercase; + transition: 0.7s; } #reset-btn:hover { - - background-color: #4f3ff0; - color: #d5deff; - cursor: pointer; - transition: 0.7s; - + background-color: #4f3ff0; + color: #d5deff; + cursor: pointer; + transition: 0.7s; } /* Player - 1 Buttons */ - .btn-player-1 { - - background-color: #34c471; - border: 2px solid #34c471; - border-radius: 50%; - color: red; - height: 50px; - width: 50px; - + background-color: #34c471; + border: 2px solid #34c471; + border-radius: 50%; + color: red; + height: 80%; + width: 80%; } /* Player - 2 Buttons */ - .btn-player-2 { - - background-color: #df3670; - border: 2px solid #df3670; - border-radius: 50%; - color: red; - height: 50px; - width: 50px; - + background-color: #df3670; + border: 2px solid #df3670; + border-radius: 50%; + color: red; + height: 80%; + width: 80%; } /* Media Queries */ - @media (max-width: 800px) { - #grid { - width: 500px; - } - - .col { - height: 62px; - margin: 4px; - width: 62px; - } - - #player { - width: 450px; - } - - #reset-btn { - font-size: 1.2rem; - } - - .btn-player-1 { - height: 40px; - width: 40px; - } - - .btn-player-2 { - height: 40px; - width: 40px; - } + #player { + max-width: 450px; + } + + #reset-btn { + font-size: 1.2rem; + } } @media (max-width: 550px) { - #grid { - width: 400px; - } - - .col { - height: 50px; - margin: 3px; - width: 50px; - } - - #player { - width: 350px; - } - - #reset-btn { - font-size: 1rem; - } - - .btn-player-1 { - height: 30px; - width: 30px; - } - - .btn-player-2 { - height: 30px; - width: 30px; - } + #player { + max-width: 350px; + } + + #reset-btn { + font-size: 1rem; + } } -@media (max-width: 450px) { - #grid { - width: 90%; - } - - .col { - height: 40px; - margin: 2px; - } - - #player { - align-items: center; - display: flex; - border-width: 5px; - justify-content: center; - height: 30px; - width: 78%; - } - - #player-type { - font-size: 1.2rem; - } - - #reset-btn { - font-size: 0.8rem; - } - - .btn-player-1 { - height: 20px; - width: 20px; - } - - .btn-player-2 { - height: 20px; - width: 20px; - } +@media (max-width: 450px) { + #player { + align-items: center; + display: flex; + border-width: 5px; + justify-content: center; + height: 30px; + width: 78%; + } + + #player-type { + font-size: 1.2rem; + } + + #reset-btn { + font-size: 0.8rem; + } } \ No newline at end of file From 083752378c6f41f583a6e585a48f9dd5914b31c9 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 18 Aug 2024 00:09:15 +1000 Subject: [PATCH 56/93] add ai --- 15-Connect-Four-Game/script.js | 478 ++++++++++++++++++++++++++++----- 1 file changed, 407 insertions(+), 71 deletions(-) diff --git a/15-Connect-Four-Game/script.js b/15-Connect-Four-Game/script.js index e502a8b..0fb73b8 100644 --- a/15-Connect-Four-Game/script.js +++ b/15-Connect-Four-Game/script.js @@ -1,6 +1,6 @@ // DOM Variables -var buttons +var buttons var reset = document.getElementById("reset-btn"); var playerType = document.getElementById("player-type"); var updateGridBTN = document.getElementById("update-grid"); @@ -13,58 +13,60 @@ var winConditionInput = document.getElementById("win-condition"); var columns = 10; var rows = 10; var winCount = 4; -var filledGrid; +var filledGrid; var playerNumber = 1; // Initially player - 1 gets to start his/her turn - - initGame(10,10,5); // (columns, rows, winCounts) +var availableMoves = []; +initGame(10, 10, 5); // (columns, rows, winCounts) function initGame(column, row, winCounts) { - filledGrid = create2DArray(row , column); // Player board + filledGrid = create2DArray(row, column); // Player board createGrid(row, column, 'grid'); columns = column; rows = row; winCount = winCounts; + countMove = 0; + lastMove = []; buttons = document.getElementsByClassName("btn"); - for(var i = 0; i < buttons.length; i++) { + for (var i = 0; i < buttons.length; i++) { // Handing the Event when button was clicked - buttons[i].addEventListener("click" , function() { + buttons[i].addEventListener("click", function () { // Make move and disable the button to avoid furthur clicking it again var buttonNo = this.classList[1]; - makeMove(this , buttonNo.slice(4)); + makeMove(this, buttonNo.slice(4)); }); } } function createGrid(rows, cols, targetElementId) { - const grid = document.getElementById(targetElementId); + const grid = document.getElementById(targetElementId); - let btnCount = 1; + let btnCount = 1; - for (let i = 0; i < rows; i++) { - const row = document.createElement('div'); - row.className = 'row'; + for (let i = 0; i < rows; i++) { + const row = document.createElement('div'); + row.className = 'row'; - for (let j = 0; j < cols; j++) { - const col = document.createElement('div'); - col.className = 'col'; + for (let j = 0; j < cols; j++) { + const col = document.createElement('div'); + col.className = 'col'; - const btn = document.createElement('button'); - btn.className = `btn btn-${btnCount}`; + const btn = document.createElement('button'); + btn.className = `btn btn-${btnCount}`; - col.appendChild(btn); - row.appendChild(col); + col.appendChild(btn); + row.appendChild(col); - btnCount++; - } + btnCount++; + } - grid.appendChild(row); - } + grid.appendChild(row); + } } var filledCells = 0; // No. of cells that has been filled function create2DArray(rows, cols) { - return Array.from({ length: rows }, () => - Array.from({ length: cols }, () => -1) - ); + return Array.from({ length: rows }, () => + Array.from({ length: cols }, () => -1) + ); } function updateGrid() { @@ -72,7 +74,7 @@ function updateGrid() { const height = parseInt(heightInput.value); const winCondition = parseInt(winConditionInput.value); - if (width < 3 || width > 20 || height < 3 || height > 20 || winCondition < 3 || winCondition > 8 ||winCondition > width || winCondition > height) { + if (width < 3 || width > 20 || height < 3 || height > 20 || winCondition < 3 || winCondition > 8 || winCondition > width || winCondition > height) { //alert('่ฏท่พ“ๅ…ฅๆœ‰ๆ•ˆ็š„ๅ€ผ๏ผšๅฎฝๅบฆๅ’Œ้ซ˜ๅบฆๅœจ3-20ไน‹้—ด๏ผŒ่Žท่ƒœๆกไปถๅœจ3-8ไน‹้—ดใ€‚'); alert('Please enter valid values: width and height should be between 3 and 20, and win condition should be between 3 and 8.'); return; @@ -86,37 +88,51 @@ function updateGrid() { // Event Listener for Buttons updateGridBTN.addEventListener('click', updateGrid); -reset.addEventListener("click" , resetBoard); - - +reset.addEventListener("click", resetBoard); +var countMove = 0; +var lastMove = []; +function toRC(buttonNo) { + var row = Math.floor((buttonNo - 1) / columns); + var col = (buttonNo - 1) % columns; + return [row, col]; +} +function toBtNo(row, col) { + return row * columns + col + 1; +} // Function to Make Move on the passed button and disable it -function makeMove(button , buttonNo) { - var row = buttonNo % columns === 0 ? Math.floor(buttonNo / columns) - 1 : Math.floor(buttonNo / columns); - var col = buttonNo % columns === 0 ? rows: (buttonNo % columns) - 1; - if(playerNumber === 1) { +function makeMove(button, buttonNo) { + lastMove = toRC(buttonNo); + countMove++; + var row = lastMove[0]; + var col = lastMove[1]; + if (playerNumber === 1) { button.classList.add("btn-player-1"); filledGrid[row][col] = 1; filledCells++; - if(playerWon(row , col , 1) === true) { - setTimeout(function() { + if (playerWon(row, col, [1], winCount) === true) { + setTimeout(function () { alert("Game Over: Green Wins"); resetBoard(); - } , 200); + }, 200); + return; } // Update the player playerNumber = 2; playerType.textContent = "Player - 2"; + //getBestMove(filledGrid,winCount,playerNumber); + PCMove(); } else { button.classList.add("btn-player-2"); filledGrid[row][col] = 2; filledCells++; - if(playerWon(row , col , 2) === true) { - setTimeout(function() { + if (playerWon(row, col, [2], winCount) === true) { + setTimeout(function () { alert("Game Over : Red Wins"); resetBoard(); - } , 200); + }, 200); + return; } // Update the player playerNumber = 1; @@ -125,31 +141,52 @@ function makeMove(button , buttonNo) { // If all the cells has been filled - if(filledCells === rows * columns) { - setTimeout(function() { + if (filledCells === rows * columns) { + setTimeout(function () { alert("Game Draw"); resetBoard(); - } , 200); + }, 200); return; } // Disable the button is the move is made setTimeout(function () { button.disabled = true; - },10); + }, 10); } +function colorButton(points) { + var i = []; + points.forEach(function (point) { + i.push([toBtNo(point[0], point[1] - 1), point[2]]); + }) + for (var j = 0; j < buttons.length; j++) { + var mark = false; + i.forEach(element => { + if (element[0] === j) { + buttons[j].innerHTML = element[1]; + buttons[j].style.color = "red"; + mark = true; + } + }); + if (!mark) { + buttons[j].innerHTML = ""; + buttons[j].style.color = "transparent"; + } + } -function playerWon(row , col , player) { +} +var winMethod = 0; +function playerWon(row, col, player, w_count) { var count = 0; // Check for columns - for(var i = 0; i < columns; i++) { - if(filledGrid[row][i] === player) { + for (var i = 0; i < columns; i++) { + if (player.includes(filledGrid[row][i])) { count++; - if(count === winCount) return true; + if (count === w_count) { winMethod = 1; return true; } } else { count = 0; } @@ -160,10 +197,10 @@ function playerWon(row , col , player) { // Check for Rows - for(var i = 0; i < rows; i++) { - if(filledGrid[i][col] === player) { + for (var i = 0; i < rows; i++) { + if (player.includes(filledGrid[i][col])) { count++; - if(count === winCount) return true; + if (count === w_count) { winMethod = 2; return true; } } else { count = 0; } @@ -174,15 +211,15 @@ function playerWon(row , col , player) { // Check for primary diagonal - if(row >= col) { + if (row >= col) { var i = row - col; var j = 0; - for(; i <= rows-1; i++ , j++) { - if(filledGrid[i][j] === player) { + for (; i <= rows - 1; i++, j++) { + if (player.includes(filledGrid[i][j])) { count++; - if(count == winCount) return true; + if (count == w_count) { winMethod = 3; return true; } } else { count = 0; } @@ -192,10 +229,10 @@ function playerWon(row , col , player) { var i = 0; var j = col - row; - for(; j <= columns-1; i++ , j++) { - if(filledGrid[i][j] === player) { + for (; j <= columns - 1; i++, j++) { + if (player.includes(filledGrid[i][j])) { count++; - if(count == winCount) return true; + if (count == w_count) { winMethod = 3; return true; } } else { count = 0; } @@ -207,15 +244,15 @@ function playerWon(row , col , player) { // Check for secondary diagonal - if(row + col <= rows - 1) { + if (row + col <= rows - 1) { var i = row + col; var j = 0; - for(; i >= 0 && j <= row + col; i-- , j++) { - if(filledGrid[i][j] === player) { + for (; i >= 0 && j <= row + col; i--, j++) { + if (player.includes(filledGrid[i][j])) { count++; - if(count == winCount) return true; + if (count == w_count) { winMethod = 4; return true; } } else { count = 0; } @@ -226,10 +263,10 @@ function playerWon(row , col , player) { var i = rows - 1; var j = row + col - rows + 1; - for(; j <= columns - 1; j++ , i--) { - if(filledGrid[i][j] === player) { + for (; j <= columns - 1; j++, i--) { + if (player.includes(filledGrid[i][j])) { count++; - if(count == winCount) return true; + if (count == w_count) { winMethod = 4; return true; } } else { count = 0; } @@ -245,7 +282,7 @@ function resetBoard() { // Remove all the disabled buttons and the styles - for(var i = 0; i < buttons.length; i++) { + for (var i = 0; i < buttons.length; i++) { buttons[i].disabled = false; buttons[i].classList.remove("btn-player-1"); buttons[i].classList.remove("btn-player-2"); @@ -261,14 +298,313 @@ function resetBoard() { // Filled Cells is changed to 0 filledCells = 0; - + countMove = 0; + lastMove = []; // Filling the Board with -1 - for(var i = 0; i < rows; i++) { - for(var j = 0; j < columns; j++) { + for (var i = 0; i < rows; i++) { + for (var j = 0; j < columns; j++) { filledGrid[i][j] = -1; } - } + } + +} + +function PCMove() { + var r, c, i; + availableMoves = []; + var hu = playerNumber === 1 ? 2 : 1; + var pc = playerNumber; + var criticalMoves = (winCount - 2) * 2 - 2; + //ไผ˜ๅ…ˆ็บงๅˆซไฝŽ + //ไธ็”จ็ฎ—ไฝ็ฝฎ๏ผŒ็ดง่ดดๆˆ˜็•ฅ ๆŠŠ lastMove[0]๏ผŒ lastMove[1] ๅ‘จๅ›ด8ไธชๆ ผๅญ้ƒฝ่ตฐไธ€้ ไธๅฐไบŽ0 ไธๅคงไบŽrows-1 ไธๅฐไบŽ0 ไธๅคงไบŽcolumns-1็š„้ƒฝๅŠ ๅ…ฅavailableMoves + for (r = lastMove[0] - 1; r < lastMove[0] + 2; r++) { + for (c = lastMove[1] - 1; c < lastMove[1] + 2; c++) { + checkAdd(r, c, 0); + } + } + + if (countMove > criticalMoves) { + //ๅฏปๆ‰พๅฏนๆ‰‹ๅฏ่ƒฝ่Žท่ƒœ็š„ไฝ็ฝฎ + oneStepToWin(hu, 0); + //ๅฏปๆ‰พ่‡ชๅทฑๅฏ่ƒฝ่Žท่ƒœ็š„ไฝ็ฝฎ + oneStepToWin(pc, 1); + //้™ไฝŽๅทฒ่ขซๅฏนๆ‰‹ๅฐๅ ต็š„ไฝ็ฝฎๅฏน้ขไฝ็ฝฎ็š„ๅฝฑๅ“ + isBlocked(lastMove[0], lastMove[1], hu); + //้™ไฝŽๅทฒ็ปๅฐๅ ต็š„ไฝ็ฝฎๅฏน้ขไฝ็ฝฎ็š„ๅฝฑๅ“ + isBlocked(lastMove[0], lastMove[1], pc); + + //ๆ‰พๅˆฐๆ•ฐ้‡ๅคงไบŽ็ญ‰ไบŽwinCount-2็š„่ฟž็ปญๅญ็š„็ซฏ็‚น๏ผŒๅŠ ๅ…ฅavailableMovesไปฅไพฟๅฐๆ€ + // if (playerWon(lastMove[0], lastMove[1], [playerNumber === 1 ? 2 : 1], winCount - 2)) {//cont two left to win + // findEnd(lastMove[0], lastMove[1], playerNumber === 1 ? 2 : 1); + // } + // ๆฃ€ๆต‹nx x, xn x, xx n, n xx, x nx,x xn + // x nxx + } + + if (availableMoves.length > 0) { + colorButton(availableMoves); + var bestMoves = []; + var bestMovesShortlist = []; + var highestPriority = -Infinity; + + // ๆ‰พๅ‡บๆœ€้ซ˜ไผ˜ๅ…ˆ็บง + for (var i = 0; i < availableMoves.length; i++) { + if (availableMoves[i][2] > highestPriority) { + highestPriority = availableMoves[i][2]; + } + } + + // ้€‰ๆ‹ฉๆ‰€ๆœ‰ๅ…ทๆœ‰ๆœ€้ซ˜ไผ˜ๅ…ˆ็บง็š„็งปๅŠจ + for (var i = 0; i < availableMoves.length; i++) { + if (availableMoves[i][2] === highestPriority) { + bestMoves.push(availableMoves[i]); + } + } + + // ่ฏ„ไผฐๆฏไธชๆœ€ไฝณ็งปๅŠจ็š„ๅ‘จๅ›ดๆƒ…ๅ†ต + bestMoves.forEach(element => { + var moveScore = 0; + for (var i = Math.max(0, element[0] - 1); i <= Math.min(rows - 1, element[0] + 1); i++) { + for (var j = Math.max(0, element[1] - 1); j <= Math.min(columns - 1, element[1] + 1); j++) { + if (filledGrid[i][j] === hu || filledGrid[i][j] === pc) { + moveScore++; + } + } + } + element.push(moveScore); // ๅฐ†ๅˆ†ๆ•ฐๆทปๅŠ ๅˆฐ็งปๅŠจๆ•ฐ็ป„ไธญ + }); + + // ๆ นๆฎๅ‘จๅ›ดๆฃ‹ๅญๆ•ฐ้‡ๆŽ’ๅบ๏ผŒ้€‰ๆ‹ฉๅ‘จๅ›ดๆฃ‹ๅญๆœ€ๅคš็š„็งปๅŠจ + bestMovesShortlist = bestMoves.sort((a, b) => b[3] - a[3]); + + // ้€‰ๆ‹ฉ็ฌฌไธ€ไธช๏ผˆๆœ€ไฝณ๏ผ‰็งปๅŠจ + var bestMove = bestMovesShortlist[0]; + var r = bestMove[0]; + var c = bestMove[1]; + + makeMove(buttons[r * columns + c], r * columns + c + 1); + availableMoves = []; + return; + } + availableMoves = []; +} +function findEnd(r, c, player) { + //winMethod 1:col 2:row 3:diag1 4:diag2 + //ไปŽๅฝ“ๅ‰r,c็‚นๅผ€ๅง‹ๅ‘r ็š„ๆญฃ่ดŸๆ–นๅ‘ไธŠๅฏปๆ‰พไธ‹ไธ€ไธชfilledGrid[][]ไธ็ญ‰ไบŽplayer็š„็‚น ๆฃ€ๆŸฅๅŠ ๅ…ฅavailableMoves + var sd = true; + var su = true; + k = winMethod; + for (var i = 1; i < winCount - 2; i++) { + switch (k) {// 1:col 2:row 3:diag1 4:diag2 + case 1://nxx,xnx,xxn + if (sd && checkAdd(r, c + i, 1) !== player) { sd = false; } + if (su && checkAdd(r, c - i, 1) !== player) { su = false; } + break; + case 2: + if (sd && checkAdd(r + i, c, 1) !== player) { sd = false; } + if (su && checkAdd(r - i, c, 1) !== player) { su = false; } + break; + case 3: + if (sd && checkAdd(r + i, c + i, 1) !== player) { sd = false; } + if (su && checkAdd(r - i, c - i, 1) !== player) { su = false; } + break; + case 4: + if (sd && checkAdd(r + i, c - i, 1) !== player) { sd = false; } + if (su && checkAdd(r - i, c + i, 1) !== player) { su = false; } + break; + } + } + + + +} +function checkAdd(r, c, p) {//ๆฃ€ๆŸฅๅŠ ๅ…ฅavailableMoves + if (r >= 0 && r < rows && c >= 0 && c < columns) { + if (filledGrid[r][c] === -1) { + availableMoves.push([r, c, p]); + return -1; + } + return filledGrid[r][c]; + } + return 0; +} +function oneStepToWin(player, p) { + var listF = []; + for (var r = 0; r < rows; r++) { + for (var c = 0; c < columns; c++) { + if (filledGrid[r][c] === -1) { + filledGrid[r][c] = player; + if (playerWon(r, c, [player], winCount)) { + filledGrid[r][c] = -1; + addToAvailableMoves(r, c, 4 + p); + listF.push([r, c]); + } else if (playerWon(r, c, [player], winCount - 1)) { + filledGrid[r][c] = -1; + if (!listF.some(coord => coord[0] === r && coord[1] === c)) { + addToAvailableMoves(r, c, 2 + p); + } else { + addToAvailableMoves(r, c, -1); + } + } else { + filledGrid[r][c] = -1; + } + } + } + } +} +function addToAvailableMoves(r, c, p) { + for (let i = 0; i < availableMoves.length; i++) { + if (availableMoves[i][0] === r && availableMoves[i][1] === c) { + availableMoves[i][2] += p; + return; // ๆ‰พๅˆฐๅŒน้…็š„ๅๆ ‡ๅŽ็ซ‹ๅณ่ฟ”ๅ›ž + } + } + // ๅฆ‚ๆžœๅพช็Žฏ็ป“ๆŸๆฒกๆœ‰ๆ‰พๅˆฐๅŒน้…็š„ๅๆ ‡๏ผŒๆทปๅŠ ๆ–ฐ็š„ + availableMoves.push([r, c, p]); +} + +function isBlocked(r, c, player) { + var d = -2; + availableMoves.forEach(element => { + if (playerWon(r, c, [player === 1 ? 2 : 1], winCount - 2)) { + switch (winMethod) {// 1:col 2:row 3:diag1 4:diag2 + case 1: { + if (c - 1 >= 0) { + if (filledGrid[r][c - 1] === (player === 1 ? 2 : 1)) { + //up + if (filledGrid[r][c - 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } else { + //down + if (filledGrid[r][c + 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } + } else if (c + 1 < columns) { + if (filledGrid[r][c + 1] === (player === 1 ? 2 : 1)) { + //down + if (filledGrid[r][c + 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } else { + //up + if (filledGrid[r][c - 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } + + } + } + break; + case 2: { + if (r - 1 >= 0) { + if (filledGrid[r - 1][c] === (player === 1 ? 2 : 1)) { + //left + if (filledGrid[r - 4][c] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } else { + //right + if (filledGrid[r + 4][c] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } + } else if (r + 1 < rows) { + if (filledGrid[r + 1][c] === (player === 1 ? 2 : 1)) { + //right + if (filledGrid[r + 4][c] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } else { + //left + if (filledGrid[r - 4][c] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } + } + } + break; + case 3: { + if (r - 1 >= 0 && c - 1 >= 0) { + if (filledGrid[r - 1][c - 1] === (player === 1 ? 2 : 1)) { + //up + if (filledGrid[r - 4][c - 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } else { + //down + if (filledGrid[r + 4][c + 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } + } else if (r + 1 < rows && c + 1 < columns) { + if (filledGrid[r + 1][c + 1] === (player === 1 ? 2 : 1)) { + //down + if (filledGrid[r + 4][c + 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } else { + //up + if (filledGrid[r - 4][c - 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } + } + + } + break; + case 4: { + if (r - 1 >= 0 && c + 1 < columns) { + if (filledGrid[r - 1][c + 1] === (player === 1 ? 2 : 1)) { + //up + if (filledGrid[r - 4][c + 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } else { + //down + if (filledGrid[r + 4][c - 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } + } else if (r + 1 < rows && c - 1 >= 0) { + if (filledGrid[r + 1][c - 1] === (player === 1 ? 2 : 1)) { + //down + if (filledGrid[r + 4][c - 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } else { + //up + if (filledGrid[r - 4][c + 4] === (player)) { + addToAvailableMoves(r, c, d); + break; + } + } + + } + } + break; + + } + } + + }); } \ No newline at end of file From 9b187b923329dea445e4e0bab05cfe314f2a79b1 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 18 Aug 2024 00:49:17 +1000 Subject: [PATCH 57/93] improve stability --- 15-Connect-Four-Game/index.html | 54 +++++++++++++++++++++++---------- 15-Connect-Four-Game/script.js | 21 ++++++++++--- 15-Connect-Four-Game/style.css | 28 +++++++++-------- 3 files changed, 70 insertions(+), 33 deletions(-) diff --git a/15-Connect-Four-Game/index.html b/15-Connect-Four-Game/index.html index 132895b..ef16539 100644 --- a/15-Connect-Four-Game/index.html +++ b/15-Connect-Four-Game/index.html @@ -1,19 +1,20 @@ + Connect Four - + - + - + @@ -23,22 +24,42 @@ +
-
- - -
-
- - -
-
- - -
+
+ Game Settings: +
+ + +
+
+ + +
+
+ + +
+
+
+ Player Settings: +
+ + +
+
+ + +
+
+ + +
+ +
-
+

Player - 1

@@ -50,4 +71,5 @@

Player - 1

+ \ No newline at end of file diff --git a/15-Connect-Four-Game/script.js b/15-Connect-Four-Game/script.js index 0fb73b8..cb4c1de 100644 --- a/15-Connect-Four-Game/script.js +++ b/15-Connect-Four-Game/script.js @@ -7,7 +7,7 @@ var updateGridBTN = document.getElementById("update-grid"); var widthInput = document.getElementById("grid-width"); var heightInput = document.getElementById("grid-height"); var winConditionInput = document.getElementById("win-condition"); - +var player = 1; // Game Flow Variables var columns = 10; @@ -27,6 +27,7 @@ function initGame(column, row, winCounts) { countMove = 0; lastMove = []; buttons = document.getElementsByClassName("btn"); + player = document.querySelector('input[name="player"]:checked').value; for (var i = 0; i < buttons.length; i++) { // Handing the Event when button was clicked buttons[i].addEventListener("click", function () { @@ -84,6 +85,7 @@ function updateGrid() { document.getElementById("grid-config").style.display = "none"; + pcStart(); } // Event Listener for Buttons @@ -121,8 +123,7 @@ function makeMove(button, buttonNo) { // Update the player playerNumber = 2; playerType.textContent = "Player - 2"; - //getBestMove(filledGrid,winCount,playerNumber); - PCMove(); + if(player == 1){PCMove();} } else { button.classList.add("btn-player-2"); filledGrid[row][col] = 2; @@ -137,6 +138,7 @@ function makeMove(button, buttonNo) { // Update the player playerNumber = 1; playerType.textContent = "Player - 1"; + if(player == 2){PCMove();} } // If all the cells has been filled @@ -156,7 +158,7 @@ function makeMove(button, buttonNo) { } function colorButton(points) { - var i = []; +/* var i = []; points.forEach(function (point) { i.push([toBtNo(point[0], point[1] - 1), point[2]]); }) @@ -173,7 +175,7 @@ function colorButton(points) { buttons[j].innerHTML = ""; buttons[j].style.color = "transparent"; } - } + }*/ } var winMethod = 0; @@ -308,7 +310,16 @@ function resetBoard() { filledGrid[i][j] = -1; } } + pcStart(); +} +function pcStart() { + if(player == 2){ + var r = Math.floor( rows/2); + var c = Math.floor( columns/2); + var i = toBtNo(r, c); + makeMove(buttons[i], i); + } } function PCMove() { diff --git a/15-Connect-Four-Game/style.css b/15-Connect-Four-Game/style.css index 85d105c..d584a24 100644 --- a/15-Connect-Four-Game/style.css +++ b/15-Connect-Four-Game/style.css @@ -21,7 +21,11 @@ body { width: 80%; max-width: 550px; } - +fieldset { + height: 40vh; + border:#3f2fd0 2px solid; + box-shadow: 2px 3px 7px grey; +} #player-type { color: #4f3ff0; font-family: "Poppins", sans-serif; @@ -31,17 +35,17 @@ body { } #grid-config { background-color: #d5deff; - border: 3px solid #4f3ff0; - border-radius: 8px; - padding: 20px; - margin-top: 20px; - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - width: 80%; - max-width: 550px; - position: absolute; + border: 3px solid #4f3ff0; + border-radius: 8px; + padding: 20px; + margin-top: 20px; + display: flex; + justify-content: space-between; + flex-wrap: wrap; + width: 80%; + max-width: 550px; + position: absolute; + align-items: flex-end; } .input-group { display: flex; From 65ac1c29be2a943615cdacd28615122813ea8d91 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 18 Aug 2024 21:34:58 +1000 Subject: [PATCH 58/93] fix ai issue --- 15-Connect-Four-Game/script.js | 271 ++++++++++++++++++++++++--------- 1 file changed, 195 insertions(+), 76 deletions(-) diff --git a/15-Connect-Four-Game/script.js b/15-Connect-Four-Game/script.js index cb4c1de..1bacce4 100644 --- a/15-Connect-Four-Game/script.js +++ b/15-Connect-Four-Game/script.js @@ -123,7 +123,7 @@ function makeMove(button, buttonNo) { // Update the player playerNumber = 2; playerType.textContent = "Player - 2"; - if(player == 1){PCMove();} + if (player == 1) { PCMove(); } } else { button.classList.add("btn-player-2"); filledGrid[row][col] = 2; @@ -138,7 +138,7 @@ function makeMove(button, buttonNo) { // Update the player playerNumber = 1; playerType.textContent = "Player - 1"; - if(player == 2){PCMove();} + if (player == 2) { PCMove(); } } // If all the cells has been filled @@ -158,7 +158,7 @@ function makeMove(button, buttonNo) { } function colorButton(points) { -/* var i = []; + var i = []; points.forEach(function (point) { i.push([toBtNo(point[0], point[1] - 1), point[2]]); }) @@ -175,20 +175,36 @@ function colorButton(points) { buttons[j].innerHTML = ""; buttons[j].style.color = "transparent"; } - }*/ + } } var winMethod = 0; -function playerWon(row, col, player, w_count) { - +function playerWon(row, col, player, w_count, next = false) { + var returnValue = false; var count = 0; - // Check for columns - for (var i = 0; i < columns; i++) { if (player.includes(filledGrid[row][i])) { count++; - if (count === w_count) { winMethod = 1; return true; } + if (count === w_count) { + winMethod = 1; + if (!next) { returnValue = true; } + else if (w_count === winCount - 1) { + if (i + 1 < columns + && filledGrid[row][i + 1] == -1 + && i - count >= 0 + && filledGrid[row][i - count] == -1) {//ๅ‰ๅŽไธค็ซฏ้ƒฝๆ˜ฏ็ฉบ + returnValue = true; + } + } else if (w_count === winCount) { + if ((i + 1 < columns + && filledGrid[row][i + 1] == -1) + || (i - count >= 0 + && filledGrid[row][i - count] == -1)) {//ๅ‰ๅŽไธค็ซฏๆœ‰็ฉบ + returnValue = true; + } + } + } } else { count = 0; } @@ -196,19 +212,35 @@ function playerWon(row, col, player, w_count) { } count = 0; - // Check for Rows - for (var i = 0; i < rows; i++) { if (player.includes(filledGrid[i][col])) { count++; - if (count === w_count) { winMethod = 2; return true; } + if (count === w_count) { + winMethod = 2; + if (!next) { returnValue = true; } + else if (w_count === winCount - 1) { + if (i + 1 < rows + && filledGrid[i + 1][col] == -1 + && i - count >= 0 + && filledGrid[i - count][col] == -1) {//ๅ‰ๅŽไธค็ซฏ้ƒฝๆ˜ฏ็ฉบ + returnValue = true; + } + } else if (w_count === winCount) { + if ((i + 1 < rows + && filledGrid[i + 1][col] == -1) + || (i - count >= 0 + && filledGrid[i - count][col] == -1)) {//ๅ‰ๅŽไธค็ซฏๆœ‰็ฉบ + returnValue = true; + } + } + + } } else { count = 0; } } - count = 0; // Check for primary diagonal @@ -221,11 +253,34 @@ function playerWon(row, col, player, w_count) { for (; i <= rows - 1; i++, j++) { if (player.includes(filledGrid[i][j])) { count++; - if (count == w_count) { winMethod = 3; return true; } + if (count === w_count) { + winMethod = 3; + if (!next) { returnValue = true; } + else if (w_count === winCount - 1) { + if (i + 1 < rows + && j + 1 < columns + && filledGrid[i + 1][j + 1] == -1 + && i - count >= 0 + && j - count >= 0 + && filledGrid[i - count][j - count] == -1) {//ๅ‰ๅŽไธค็ซฏ้ƒฝๆ˜ฏ็ฉบ + returnValue = true; + } + } else if (w_count === winCount) { + if ((i + 1 < rows + && j + 1 < columns + && filledGrid[i + 1][j + 1] == -1) + || (i - count >= 0 + && j - count >= 0 + && filledGrid[i - count][j - count] == -1)) {//ๅ‰ๅŽไธค็ซฏๆœ‰็ฉบ + returnValue = true; + } + } + } } else { count = 0; } } + } else { var i = 0; @@ -234,12 +289,34 @@ function playerWon(row, col, player, w_count) { for (; j <= columns - 1; i++, j++) { if (player.includes(filledGrid[i][j])) { count++; - if (count == w_count) { winMethod = 3; return true; } + if (count === w_count) { + winMethod = 3; + if (!next) { returnValue = true; } + else if (w_count === winCount - 1) { + if (i + 1 < rows + && j + 1 < columns + && filledGrid[i + 1][j + 1] == -1 + && i - count >= 0 + && j - count >= 0 + && filledGrid[i - count][j - count] == -1) {//ๅ‰ๅŽไธค็ซฏ้ƒฝๆ˜ฏ็ฉบ + returnValue = true; + } + } else if (w_count === winCount) { + if ((i + 1 < rows + && j + 1 < columns + && filledGrid[i + 1][j + 1] == -1) + || (i - count >= 0 + && j - count >= 0 + && filledGrid[i - count][j - count] == -1)) {//ๅ‰ๅŽไธค็ซฏๆœ‰็ฉบ + returnValue = true; + } + } + } } else { count = 0; } - } + } } count = 0; @@ -254,12 +331,33 @@ function playerWon(row, col, player, w_count) { for (; i >= 0 && j <= row + col; i--, j++) { if (player.includes(filledGrid[i][j])) { count++; - if (count == w_count) { winMethod = 4; return true; } + if (count == w_count) { + winMethod = 4; + if (!next) { returnValue = true; } + else if (w_count === winCount - 1) { + if (i - 1 >= 0 + && j + 1 < columns + && filledGrid[i - 1][j + 1] == -1 + && i + count <= rows - 1 + && j - count >= 0 + && filledGrid[i + count][j - count] == -1) {//ๅ‰ๅŽไธค็ซฏ้ƒฝๆ˜ฏ็ฉบ + returnValue = true; + } + } else if (w_count === winCount) { + if ((i - 1 >= 0 + && j + 1 < columns + && filledGrid[i - 1][j + 1] == -1) + || (i + count <= rows + && j - count >= 0 + && filledGrid[i + count][j - count] == -1)) {//ๅ‰ๅŽไธค็ซฏๆœ‰็ฉบ + returnValue = true; + } + } + } } else { count = 0; } } - } else { var i = rows - 1; @@ -268,15 +366,36 @@ function playerWon(row, col, player, w_count) { for (; j <= columns - 1; j++, i--) { if (player.includes(filledGrid[i][j])) { count++; - if (count == w_count) { winMethod = 4; return true; } + if (count === w_count) { + winMethod = 4; + if (!next) { returnValue = true; } + else if (w_count === winCount - 1) { + if (i - 1 >= 0 + && j + 1 < columns + && filledGrid[i - 1][j + 1] == -1 + && i + count <= rows - 1 + && j - count >= 0 + && filledGrid[i + count][j - count] == -1) {//ๅ‰ๅŽไธค็ซฏ้ƒฝๆ˜ฏ็ฉบ + returnValue = true; + } + } else if (w_count === winCount) { + if ((i - 1 >= 0 + && j + 1 < columns + && filledGrid[i - 1][j + 1] == -1) + || (i + count <= rows - 1 + && j - count >= 0 + && filledGrid[i + count][j - count] == -1)) {//ๅ‰ๅŽไธค็ซฏๆœ‰็ฉบ + returnValue = true; + } + } + } } else { count = 0; } } } - return false; - + return returnValue; } // Function to reset the Board completely @@ -314,9 +433,9 @@ function resetBoard() { } function pcStart() { - if(player == 2){ - var r = Math.floor( rows/2); - var c = Math.floor( columns/2); + if (player == 2) { + var r = Math.floor(rows / 2); + var c = Math.floor(columns / 2); var i = toBtNo(r, c); makeMove(buttons[i], i); } @@ -359,21 +478,21 @@ function PCMove() { var bestMoves = []; var bestMovesShortlist = []; var highestPriority = -Infinity; - + // ๆ‰พๅ‡บๆœ€้ซ˜ไผ˜ๅ…ˆ็บง for (var i = 0; i < availableMoves.length; i++) { if (availableMoves[i][2] > highestPriority) { highestPriority = availableMoves[i][2]; } } - + // ้€‰ๆ‹ฉๆ‰€ๆœ‰ๅ…ทๆœ‰ๆœ€้ซ˜ไผ˜ๅ…ˆ็บง็š„็งปๅŠจ for (var i = 0; i < availableMoves.length; i++) { if (availableMoves[i][2] === highestPriority) { bestMoves.push(availableMoves[i]); } } - + // ่ฏ„ไผฐๆฏไธชๆœ€ไฝณ็งปๅŠจ็š„ๅ‘จๅ›ดๆƒ…ๅ†ต bestMoves.forEach(element => { var moveScore = 0; @@ -386,15 +505,15 @@ function PCMove() { } element.push(moveScore); // ๅฐ†ๅˆ†ๆ•ฐๆทปๅŠ ๅˆฐ็งปๅŠจๆ•ฐ็ป„ไธญ }); - + // ๆ นๆฎๅ‘จๅ›ดๆฃ‹ๅญๆ•ฐ้‡ๆŽ’ๅบ๏ผŒ้€‰ๆ‹ฉๅ‘จๅ›ดๆฃ‹ๅญๆœ€ๅคš็š„็งปๅŠจ bestMovesShortlist = bestMoves.sort((a, b) => b[3] - a[3]); - + // ้€‰ๆ‹ฉ็ฌฌไธ€ไธช๏ผˆๆœ€ไฝณ๏ผ‰็งปๅŠจ var bestMove = bestMovesShortlist[0]; var r = bestMove[0]; var c = bestMove[1]; - + makeMove(buttons[r * columns + c], r * columns + c + 1); availableMoves = []; return; @@ -442,38 +561,38 @@ function checkAdd(r, c, p) {//ๆฃ€ๆŸฅๅŠ ๅ…ฅavailableMoves return 0; } function oneStepToWin(player, p) { - var listF = []; - for (var r = 0; r < rows; r++) { - for (var c = 0; c < columns; c++) { - if (filledGrid[r][c] === -1) { - filledGrid[r][c] = player; - if (playerWon(r, c, [player], winCount)) { - filledGrid[r][c] = -1; - addToAvailableMoves(r, c, 4 + p); - listF.push([r, c]); - } else if (playerWon(r, c, [player], winCount - 1)) { - filledGrid[r][c] = -1; - if (!listF.some(coord => coord[0] === r && coord[1] === c)) { - addToAvailableMoves(r, c, 2 + p); - } else { - addToAvailableMoves(r, c, -1); - } - } else { - filledGrid[r][c] = -1; - } - } - } - } + var listF = []; + for (var r = 0; r < rows; r++) { + for (var c = 0; c < columns; c++) { + if (filledGrid[r][c] === -1) { + filledGrid[r][c] = player; + if (playerWon(r, c, [player], winCount)) { + filledGrid[r][c] = -1; + addToAvailableMoves(r, c, 4 + p); + listF.push([r, c]); + } else if (playerWon(r, c, [player], winCount - 1, true)) { + filledGrid[r][c] = -1; + if (!listF.some(coord => coord[0] === r && coord[1] === c)) { + addToAvailableMoves(r, c, 2 + p); + } else { + addToAvailableMoves(r, c, -1); + } + } else { + filledGrid[r][c] = -1; + } + } + } + } } function addToAvailableMoves(r, c, p) { - for (let i = 0; i < availableMoves.length; i++) { - if (availableMoves[i][0] === r && availableMoves[i][1] === c) { - availableMoves[i][2] += p; - return; // ๆ‰พๅˆฐๅŒน้…็š„ๅๆ ‡ๅŽ็ซ‹ๅณ่ฟ”ๅ›ž - } - } - // ๅฆ‚ๆžœๅพช็Žฏ็ป“ๆŸๆฒกๆœ‰ๆ‰พๅˆฐๅŒน้…็š„ๅๆ ‡๏ผŒๆทปๅŠ ๆ–ฐ็š„ - availableMoves.push([r, c, p]); + for (let i = 0; i < availableMoves.length; i++) { + if (availableMoves[i][0] === r && availableMoves[i][1] === c) { + availableMoves[i][2] += p; + return; // ๆ‰พๅˆฐๅŒน้…็š„ๅๆ ‡ๅŽ็ซ‹ๅณ่ฟ”ๅ›ž + } + } + // ๅฆ‚ๆžœๅพช็Žฏ็ป“ๆŸๆฒกๆœ‰ๆ‰พๅˆฐๅŒน้…็š„ๅๆ ‡๏ผŒๆทปๅŠ ๆ–ฐ็š„ + availableMoves.push([r, c, p]); } function isBlocked(r, c, player) { @@ -485,13 +604,13 @@ function isBlocked(r, c, player) { if (c - 1 >= 0) { if (filledGrid[r][c - 1] === (player === 1 ? 2 : 1)) { //up - if (filledGrid[r][c - 4] === (player)) { + if (c-4 >= 0 && filledGrid[r][c - 4] === (player)) { addToAvailableMoves(r, c, d); break; } } else { //down - if (filledGrid[r][c + 4] === (player)) { + if (c+4 < columns && filledGrid[r][c + 4] === (player)) { addToAvailableMoves(r, c, d); break; } @@ -499,13 +618,13 @@ function isBlocked(r, c, player) { } else if (c + 1 < columns) { if (filledGrid[r][c + 1] === (player === 1 ? 2 : 1)) { //down - if (filledGrid[r][c + 4] === (player)) { + if (c+4 < columns && filledGrid[r][c + 4] === (player)) { addToAvailableMoves(r, c, d); break; } } else { //up - if (filledGrid[r][c - 4] === (player)) { + if (c-4 >= 0 && filledGrid[r][c - 4] === (player)) { addToAvailableMoves(r, c, d); break; } @@ -518,13 +637,13 @@ function isBlocked(r, c, player) { if (r - 1 >= 0) { if (filledGrid[r - 1][c] === (player === 1 ? 2 : 1)) { //left - if (filledGrid[r - 4][c] === (player)) { + if (r-4>0 && filledGrid[r - 4][c] === (player)) { addToAvailableMoves(r, c, d); break; } } else { //right - if (filledGrid[r + 4][c] === (player)) { + if (r+4< rows && filledGrid[r + 4][c] === (player)) { addToAvailableMoves(r, c, d); break; } @@ -532,13 +651,13 @@ function isBlocked(r, c, player) { } else if (r + 1 < rows) { if (filledGrid[r + 1][c] === (player === 1 ? 2 : 1)) { //right - if (filledGrid[r + 4][c] === (player)) { + if (r+4< rows && filledGrid[r + 4][c] === (player)) { addToAvailableMoves(r, c, d); break; } } else { //left - if (filledGrid[r - 4][c] === (player)) { + if (r-4>0 && filledGrid[r - 4][c] === (player)) { addToAvailableMoves(r, c, d); break; } @@ -550,13 +669,13 @@ function isBlocked(r, c, player) { if (r - 1 >= 0 && c - 1 >= 0) { if (filledGrid[r - 1][c - 1] === (player === 1 ? 2 : 1)) { //up - if (filledGrid[r - 4][c - 4] === (player)) { + if (r-4 >= 0 && c-4 >= 0 && filledGrid[r - 4][c - 4] === (player)) { addToAvailableMoves(r, c, d); break; } } else { //down - if (filledGrid[r + 4][c + 4] === (player)) { + if (r+4 < rows && c+4 < columns && filledGrid[r + 4][c + 4] === (player)) { addToAvailableMoves(r, c, d); break; } @@ -564,13 +683,13 @@ function isBlocked(r, c, player) { } else if (r + 1 < rows && c + 1 < columns) { if (filledGrid[r + 1][c + 1] === (player === 1 ? 2 : 1)) { //down - if (filledGrid[r + 4][c + 4] === (player)) { + if (r+4 < rows && c+4 < columns && filledGrid[r + 4][c + 4] === (player)) { addToAvailableMoves(r, c, d); break; } } else { //up - if (filledGrid[r - 4][c - 4] === (player)) { + if (r-4 >= 0 && c-4 >= 0 && filledGrid[r - 4][c - 4] === (player)) { addToAvailableMoves(r, c, d); break; } @@ -583,13 +702,13 @@ function isBlocked(r, c, player) { if (r - 1 >= 0 && c + 1 < columns) { if (filledGrid[r - 1][c + 1] === (player === 1 ? 2 : 1)) { //up - if (filledGrid[r - 4][c + 4] === (player)) { + if (r-4 >= 0 && c+4 < columns && filledGrid[r - 4][c + 4] === (player)) { addToAvailableMoves(r, c, d); break; } } else { //down - if (filledGrid[r + 4][c - 4] === (player)) { + if (r+4 < rows && c-4 >= 0 && filledGrid[r + 4][c - 4] === (player)) { addToAvailableMoves(r, c, d); break; } @@ -597,13 +716,13 @@ function isBlocked(r, c, player) { } else if (r + 1 < rows && c - 1 >= 0) { if (filledGrid[r + 1][c - 1] === (player === 1 ? 2 : 1)) { //down - if (filledGrid[r + 4][c - 4] === (player)) { + if (r+4 < rows && c-4 >= 0 && filledGrid[r + 4][c - 4] === (player)) { addToAvailableMoves(r, c, d); break; } } else { //up - if (filledGrid[r - 4][c + 4] === (player)) { + if (r-4 >= 0 && c+4 < columns && filledGrid[r - 4][c + 4] === (player)) { addToAvailableMoves(r, c, d); break; } From dedec379676f61980741da162abd07bbe5273f34 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 18 Aug 2024 22:04:43 +1000 Subject: [PATCH 59/93] fix some ai bug --- 15-Connect-Four-Game/script.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/15-Connect-Four-Game/script.js b/15-Connect-Four-Game/script.js index 1bacce4..ef0551b 100644 --- a/15-Connect-Four-Game/script.js +++ b/15-Connect-Four-Game/script.js @@ -250,7 +250,7 @@ function playerWon(row, col, player, w_count, next = false) { var i = row - col; var j = 0; - for (; i <= rows - 1; i++, j++) { + for (; i <= rows - 1 && j <= columns - 1; i++, j++) { if (player.includes(filledGrid[i][j])) { count++; if (count === w_count) { @@ -286,7 +286,7 @@ function playerWon(row, col, player, w_count, next = false) { var i = 0; var j = col - row; - for (; j <= columns - 1; i++, j++) { + for (; j <= columns - 1 && i <= rows - 1; i++, j++) { if (player.includes(filledGrid[i][j])) { count++; if (count === w_count) { @@ -363,7 +363,7 @@ function playerWon(row, col, player, w_count, next = false) { var i = rows - 1; var j = row + col - rows + 1; - for (; j <= columns - 1; j++, i--) { + for (; j <= columns - 1 && i >= 0; j++, i--) { if (player.includes(filledGrid[i][j])) { count++; if (count === w_count) { @@ -435,7 +435,7 @@ function resetBoard() { function pcStart() { if (player == 2) { var r = Math.floor(rows / 2); - var c = Math.floor(columns / 2); + var c = Math.floor(columns / 2-1); var i = toBtNo(r, c); makeMove(buttons[i], i); } From f4a01165fa98aa9303362f9d40288c9c6d9f2a55 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 18 Aug 2024 22:29:40 +1000 Subject: [PATCH 60/93] improved display --- 15-Connect-Four-Game/script.js | 46 +++++++++++++++++++++------------- 15-Connect-Four-Game/style.css | 21 +++++----------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/15-Connect-Four-Game/script.js b/15-Connect-Four-Game/script.js index ef0551b..9e98ffa 100644 --- a/15-Connect-Four-Game/script.js +++ b/15-Connect-Four-Game/script.js @@ -158,24 +158,24 @@ function makeMove(button, buttonNo) { } function colorButton(points) { - var i = []; - points.forEach(function (point) { - i.push([toBtNo(point[0], point[1] - 1), point[2]]); - }) - for (var j = 0; j < buttons.length; j++) { - var mark = false; - i.forEach(element => { - if (element[0] === j) { - buttons[j].innerHTML = element[1]; - buttons[j].style.color = "red"; - mark = true; - } - }); - if (!mark) { - buttons[j].innerHTML = ""; - buttons[j].style.color = "transparent"; - } - } + // var i = []; + // points.forEach(function (point) { + // i.push([toBtNo(point[0], point[1] - 1), point[2]]); + // }) + // for (var j = 0; j < buttons.length; j++) { + // var mark = false; + // i.forEach(element => { + // if (element[0] === j) { + // buttons[j].innerHTML = element[1]; + // buttons[j].style.color = "red"; + // mark = true; + // } + // }); + // if (!mark) { + // buttons[j].innerHTML = ""; + // buttons[j].style.color = "transparent"; + // } + // } } var winMethod = 0; @@ -517,6 +517,16 @@ function PCMove() { makeMove(buttons[r * columns + c], r * columns + c + 1); availableMoves = []; return; + }else{ + for (var r = 0; r < rows; r++) { + for (var c = 0; c < columns; c++) { + if(filledGrid[r][c] === -1){ + makeMove(buttons[r * columns + c], r * columns + c + 1); + availableMoves = []; + return; + } + } + } } availableMoves = []; } diff --git a/15-Connect-Four-Game/style.css b/15-Connect-Four-Game/style.css index d584a24..4d00e77 100644 --- a/15-Connect-Four-Game/style.css +++ b/15-Connect-Four-Game/style.css @@ -92,29 +92,26 @@ fieldset { height: 80vmin; display: flex; flex-direction: column; - justify-content: space-between; + justify-content: stretch; } -/* Grid Row */ .row { display: flex; - justify-content: space-between; - height: calc((80vmin - 6px - 12px) / 6); /* Subtracting padding and gaps */ + flex-grow: 1; + margin: 0 -1px; /* ่ดŸ่พน่ทๅฏไปฅๅธฎๅŠฉๅค„็†้—ด้š™้—ฎ้ข˜ */ } -/* Grid Column */ .col { + display: flex; + flex-grow: 1; align-items: center; + justify-content: center; background-color: #d5deff; border: 1px solid #4f3ff0; border-radius: 5px; - display: flex; - justify-content: center; - width: calc((80vmin - 6px - 12px) / 7); /* Subtracting padding and gaps */ margin: 1px; } -/* Buttons */ .btn { background-color: transparent; border: none; @@ -147,21 +144,15 @@ fieldset { /* Player - 1 Buttons */ .btn-player-1 { background-color: #34c471; - border: 2px solid #34c471; border-radius: 50%; color: red; - height: 80%; - width: 80%; } /* Player - 2 Buttons */ .btn-player-2 { background-color: #df3670; - border: 2px solid #df3670; border-radius: 50%; color: red; - height: 80%; - width: 80%; } /* Media Queries */ From fa69a47980caf43826d9334eb9be237369ef49a1 Mon Sep 17 00:00:00 2001 From: Jack Date: Sun, 18 Aug 2024 22:37:48 +1000 Subject: [PATCH 61/93] update index --- index.html | 6 +++--- indexCN.html | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/index.html b/index.html index eff648e..07390a1 100644 --- a/index.html +++ b/index.html @@ -103,7 +103,7 @@

Game List


- + @@ -111,7 +111,7 @@

Game List


- + @@ -123,7 +123,7 @@

Game List


- + diff --git a/indexCN.html b/indexCN.html index 3833f40..3a2314e 100644 --- a/indexCN.html +++ b/indexCN.html @@ -103,7 +103,7 @@

ๆธธๆˆๅˆ—่กจ


- + @@ -111,7 +111,7 @@

ๆธธๆˆๅˆ—่กจ


- + @@ -123,7 +123,7 @@

ๆธธๆˆๅˆ—่กจ


- + From fd79f5ac607faa6bbb45afc432076e6e53ab8bb7 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 19 Aug 2024 00:41:42 +1000 Subject: [PATCH 62/93] modified drop --- 01-Candy-Crush-Game/index.html | 2 +- 01-Candy-Crush-Game/script.js | 281 ++++++++++++++++++++++++--------- 01-Candy-Crush-Game/style.css | 3 +- 3 files changed, 206 insertions(+), 80 deletions(-) diff --git a/01-Candy-Crush-Game/index.html b/01-Candy-Crush-Game/index.html index 8ed88d7..3382008 100644 --- a/01-Candy-Crush-Game/index.html +++ b/01-Candy-Crush-Game/index.html @@ -21,7 +21,7 @@

score

-

+

0

diff --git a/01-Candy-Crush-Game/script.js b/01-Candy-Crush-Game/script.js index 1267c5e..82204e3 100644 --- a/01-Candy-Crush-Game/script.js +++ b/01-Candy-Crush-Game/script.js @@ -1,14 +1,16 @@ document.addEventListener("DOMContentLoaded", () => { candyCrushGame(); }); - +var score_three = 5; +var score_four = 10; +var score_five = 20; function candyCrushGame() { const grid = document.querySelector(".grid"); const scoreDisplay = document.getElementById("score"); const width = 8; const squares = []; let score = 0; - + let selectedCandy = false; const candyColors = [ "url(https://raw.githubusercontent.com/arpit456jain/Amazing-Js-Projects/master/Candy%20Crush/utils/red-candy.png)", "url(https://raw.githubusercontent.com/arpit456jain/Amazing-Js-Projects/master/Candy%20Crush/utils/blue-candy.png)", @@ -50,7 +52,35 @@ function candyCrushGame() { square.addEventListener("drageleave", dragLeave) ); squares.forEach((square) => square.addEventListener("drop", dragDrop)); + squares.forEach((square) => + square.addEventListener("click", candyClicked) + ); + function candyClicked() { + if (selectedCandy) { + + colorBeingReplaced = this.style.backgroundImage; + squareIdBeingReplaced = parseInt(this.id); + this.style.backgroundImage = colorBeingDragged; + squares[ + squareIdBeingDragged + ].style.backgroundImage = colorBeingReplaced; + dragEnd(); + + squares[ + squareIdBeingDragged + ].style.transform = ""; + selectedCandy = false; + } else { + colorBeingDragged = this.style.backgroundImage; + squareIdBeingDragged = parseInt(this.id); + squares[ + squareIdBeingDragged + ].style.transform = "scale(1.3 )"; + selectedCandy = true; + } + } + // record the color and id of the candy being dragged function dragStart() { colorBeingDragged = this.style.backgroundImage; squareIdBeingDragged = parseInt(this.id); @@ -66,9 +96,10 @@ function candyCrushGame() { } function dragLeave() { - this.style.backgroundImage = ""; + //this.style.backgroundImage = ""; } - + // record the color and id of the square being replaced + // change the color and id of the square being replaced to the color and id of the candy being dragged function dragDrop() { colorBeingReplaced = this.style.backgroundImage; squareIdBeingReplaced = parseInt(this.id); @@ -89,70 +120,163 @@ function candyCrushGame() { let validMove = validMoves.includes(squareIdBeingReplaced); if (squareIdBeingReplaced && validMove) { - squareIdBeingReplaced = null; + //squareIdBeingReplaced = null; } else if (squareIdBeingReplaced && !validMove) { + //if the move is not valid, change the color back squares[ squareIdBeingReplaced ].style.backgroundImage = colorBeingReplaced; squares[ squareIdBeingDragged ].style.backgroundImage = colorBeingDragged; - } else + } else { squares[ squareIdBeingDragged ].style.backgroundImage = colorBeingDragged; + } + + if (!checkAll()) { + squares[ + squareIdBeingReplaced + ].style.backgroundImage = colorBeingReplaced; + squares[ + squareIdBeingDragged + ].style.backgroundImage = colorBeingDragged; + } } //Dropping candies once some have been cleared function moveIntoSquareBelow() { - for (i = 0; i < 55; i++) { - if (squares[i + width].style.backgroundImage === "") { - squares[i + width].style.backgroundImage = - squares[i].style.backgroundImage; - squares[i].style.backgroundImage = ""; - const firstRow = [0, 1, 2, 3, 4, 5, 6, 7]; - const isFirstRow = firstRow.includes(i); - if (isFirstRow && squares[i].style.backgroundImage === "") { - let randomColor = Math.floor( - Math.random() * candyColors.length - ); + let moved = false; + + for (let i = 62; i >= 0; i--) { + if (squares[i].style.backgroundImage === "") { + let j = i - width; + while (j >= 0 && squares[j].style.backgroundImage === "") { + j -= width; + } + + if (j >= 0) { + squares[i].style.backgroundImage = squares[j].style.backgroundImage; + squares[j].style.backgroundImage = ""; + + // ๆทปๅŠ ๅนณๆป‘็š„ไธ‹่ฝๆ•ˆๆžœ + squares[i].style.transform = `translateY(${(i - j) * 20}%)`; + setTimeout(() => { + squares[i].style.transform = "translateY(0)"; + }, 10); + + moved = true; + } + } + } + + // ไป…ๅค„็†ๆ‰€ๆœ‰็ณ–ๆžœๅฎŒๆˆไธ‹่ฝๅŽ็š„ๆƒ…ๅ†ต + if (!moved) { + for (let i = 0; i < width; i++) { + if (squares[i].style.backgroundImage === "") { + let randomColor = Math.floor(Math.random() * candyColors.length); squares[i].style.backgroundImage = candyColors[randomColor]; } } } } + function removeCandies(candies) { + candies.forEach((index) => { + const candy = squares[index]; + + // ้€ๆธ็ผฉๅฐๅนถๆทกๅ‡บ + candy.style.transition = "transform 0.3s, opacity 0.3s"; + candy.style.transform = "scale(0)"; + candy.style.opacity = "0"; + + // ๅœจๅŠจ็”ป็ป“ๆŸๅŽๆธ…็ฉบๅ›พๆกˆ + setTimeout(() => { + candy.style.backgroundImage = ""; + candy.style.transform = "scale(1)"; + candy.style.opacity = "1"; + }, 200); // ่ฟ™้‡Œ็š„300msๅบ”ไธŽๅŠจ็”ปๆ—ถ้—ด็›ธๅŒน้… + }); + } + + ///-> Checking for Matches <-/// + //For Row of Five + function checkRowForFive() { + var returnValue = false; + for (i = 0; i < 59; i++) { + let rowOfFive = [i, i + 1, i + 2, i + 3, i + 4]; + let decidedColor = squares[i].style.backgroundImage; + const isBlank = squares[i].style.backgroundImage === ""; + + const notValid = [ + 4, 5, 6, 7, // ็ฌฌ1่กŒ + 12, 13, 14, 15, // ็ฌฌ2่กŒ + 20, 21, 22, 23, // ็ฌฌ3่กŒ + 28, 29, 30, 31, // ็ฌฌ4่กŒ + 36, 37, 38, 39, // ็ฌฌ5่กŒ + 44, 45, 46, 47, // ็ฌฌ6่กŒ + 52, 53, 54, 55 // ็ฌฌ7่กŒ + ]; + + if (notValid.includes(i)) continue; + if ( + rowOfFive.every( + (index) => + squares[index].style.backgroundImage === decidedColor && + !isBlank + ) + ) { + score += score_five; + scoreDisplay.innerHTML = score; + removeCandies(rowOfFive); + returnValue = true; + } + } + return returnValue; + } + //For Column of Five + function checkColumnForFive() { + var returnValue = false; + for (i = 0; i < 31; i++) { + let columnOfFive = [i, i + width, i + width * 2, i + width * 3, i + width * 4]; + let decidedColor = squares[i].style.backgroundImage; + const isBlank = squares[i].style.backgroundImage === ""; + + if ( + columnOfFive.every( + (index) => + squares[index].style.backgroundImage === decidedColor && + !isBlank + ) + ) { + score += score_five; + scoreDisplay.innerHTML = score; + removeCandies(columnOfFive); + returnValue = true; + + } + } + return returnValue; + } //For Row of Four function checkRowForFour() { + var returnValue = false; for (i = 0; i < 60; i++) { let rowOfFour = [i, i + 1, i + 2, i + 3]; let decidedColor = squares[i].style.backgroundImage; const isBlank = squares[i].style.backgroundImage === ""; const notValid = [ - 5, - 6, - 7, - 13, - 14, - 15, - 21, - 22, - 23, - 29, - 30, - 31, - 37, - 38, - 39, - 45, - 46, - 47, - 53, - 54, - 55 + 5, 6, 7, + 13, 14, 15, + 21, 22, 23, + 29, 30, 31, + 37, 38, 39, + 45, 46, 47, + 53, 54, 55 ]; if (notValid.includes(i)) continue; @@ -163,18 +287,18 @@ function candyCrushGame() { !isBlank ) ) { - score += 4; + score += score_four; scoreDisplay.innerHTML = score; - rowOfFour.forEach((index) => { - squares[index].style.backgroundImage = ""; - }); + removeCandies(rowOfFour); + returnValue = true; } } + return returnValue } - checkRowForFour(); //For Column of Four function checkColumnForFour() { + var returnValue = false; for (i = 0; i < 39; i++) { let columnOfFour = [i, i + width, i + width * 2, i + width * 3]; let decidedColor = squares[i].style.backgroundImage; @@ -187,38 +311,31 @@ function candyCrushGame() { !isBlank ) ) { - score += 4; + score += score_four; scoreDisplay.innerHTML = score; - columnOfFour.forEach((index) => { - squares[index].style.backgroundImage = ""; - }); + removeCandies(columnOfFour); + returnValue = true; } } + return returnValue; } - checkColumnForFour(); //For Row of Three function checkRowForThree() { + var returnValue = false; for (i = 0; i < 61; i++) { let rowOfThree = [i, i + 1, i + 2]; let decidedColor = squares[i].style.backgroundImage; const isBlank = squares[i].style.backgroundImage === ""; const notValid = [ - 6, - 7, - 14, - 15, - 22, - 23, - 30, - 31, - 38, - 39, - 46, - 47, - 54, - 55 + 6, 7, + 14, 15, + 22, 23, + 30, 31, + 38, 39, + 46, 47, + 54, 55 ]; if (notValid.includes(i)) continue; @@ -229,18 +346,18 @@ function candyCrushGame() { !isBlank ) ) { - score += 3; + score += score_three; scoreDisplay.innerHTML = score; - rowOfThree.forEach((index) => { - squares[index].style.backgroundImage = ""; - }); + removeCandies(rowOfThree); + returnValue = true; } } + return returnValue; } - checkRowForThree(); //For Column of Three function checkColumnForThree() { + var returnValue = false; for (i = 0; i < 47; i++) { let columnOfThree = [i, i + width, i + width * 2]; let decidedColor = squares[i].style.backgroundImage; @@ -253,22 +370,30 @@ function candyCrushGame() { !isBlank ) ) { - score += 3; + score += score_three; scoreDisplay.innerHTML = score; - columnOfThree.forEach((index) => { - squares[index].style.backgroundImage = ""; - }); + removeCandies(columnOfThree); + returnValue = true; + } } + return returnValue; } - checkColumnForThree(); + function checkAll() { + let r5c = checkRowForFive(); + let r4c = checkRowForFour(); + let r3c = checkRowForThree(); + let c5c = checkColumnForFive(); + let c4c = checkColumnForFour(); + let c3c = checkColumnForThree(); + moveIntoSquareBelow(); + return r5c || c5c || r4c || r3c || c4c || c3c; + } + checkAll(); + scoreDisplay.addEventListener("click", checkAll); window.setInterval(function () { - checkRowForFour(); - checkColumnForFour(); - checkRowForThree(); - checkColumnForThree(); - moveIntoSquareBelow(); - }, 100); + checkAll(); + }, 410); } \ No newline at end of file diff --git a/01-Candy-Crush-Game/style.css b/01-Candy-Crush-Game/style.css index 1b371c4..47cbdf7 100644 --- a/01-Candy-Crush-Game/style.css +++ b/01-Candy-Crush-Game/style.css @@ -15,6 +15,7 @@ .grid div { height: 70px; width: 70px; + transition: transform 0.2s ease-in-out; } h3 { @@ -52,4 +53,4 @@ align-items: center; text-align: center; color: #85796b; - } \ No newline at end of file + } From 1b6691ec07fad10252e2f1924bdb0010b311415f Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 20 Aug 2024 11:26:16 +1000 Subject: [PATCH 63/93] fix pull down reflesh --- 02-Archery-Game/style.css | 1 + 1 file changed, 1 insertion(+) diff --git a/02-Archery-Game/style.css b/02-Archery-Game/style.css index d1c0b39..4613291 100644 --- a/02-Archery-Game/style.css +++ b/02-Archery-Game/style.css @@ -1,6 +1,7 @@ body{ background:#222; margin:20px; + overscroll-behavior-y: contain; } svg{ width:100%; From 1dd5e95008ad562e9f95f338685122db5d1630b4 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 20 Aug 2024 11:49:10 +1000 Subject: [PATCH 64/93] prevent pull down reflesh --- .gitignore | 1 + 02-Archery-Game/index.html | 158 ++++++++++++++------------ 02-Archery-Game/morphSVGPlugin.min.js | 13 +++ 02-Archery-Game/script.js | 6 - 4 files changed, 100 insertions(+), 78 deletions(-) create mode 100644 .gitignore create mode 100644 02-Archery-Game/morphSVGPlugin.min.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..226533b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +02-Archery-Game\morphSVGPlugin.min.js \ No newline at end of file diff --git a/02-Archery-Game/index.html b/02-Archery-Game/index.html index a1dd257..9ecaf81 100644 --- a/02-Archery-Game/index.html +++ b/02-Archery-Game/index.html @@ -1,85 +1,99 @@ - - Archery Game - - - + + Archery Game + + + - - - - - - + + + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + Draw back an arrow and launch it! + + + + - Draw back an arrow and launch it! - - - - \ No newline at end of file diff --git a/02-Archery-Game/morphSVGPlugin.min.js b/02-Archery-Game/morphSVGPlugin.min.js new file mode 100644 index 0000000..68f4eb5 --- /dev/null +++ b/02-Archery-Game/morphSVGPlugin.min.js @@ -0,0 +1,13 @@ +/*! + * VERSION: 0.9.1 + * DATE: 2019-02-21 + * UPDATES AND DOCS AT: http://greensock.com + * + * @license Copyright (c) 2008-2019, GreenSock. All rights reserved. + * MorphSVGPlugin is a Club GreenSock membership benefit; You must have a valid membership to use + * this code without violating the terms of use. Visit http://greensock.com/club/ to sign up or get more details. + * This work is subject to the software agreement that was issued with your membership. + * + * @author: Jack Doyle, jack@greensock.com + */ +var _gsScope="undefined"!=typeof module&&module.exports&&"undefined"!=typeof global?global:this||window;(_gsScope._gsQueue||(_gsScope._gsQueue=[])).push(function(){"use strict";function A(e){_gsScope.console&&console.log(e)}function R(e){function t(e,t,r,o){g=(r-e)/3,p=(o-t)/3,s.push(e+g,t+p,r-g,o-p,r,o)}var r,o,n,i,a,h,s,l,f,g,p,c,u,d=(e+"").replace(q,function(e){var t=+e;return t<1e-4&&-1e-4<(r+o)/20?t.centerX-e.centerX||t.centerY-e.centerY:o-r}function P(e,t){var r,o,n=e.slice(0),i=e.length,a=i-2;for(t|=0,r=0;ru[0].length&&x(u[0],(c[0].length-u[0].length)/6|0),C=u.length;dMath.abs(i[0]-a[a.length-2])+Math.abs(i[1]-a[a.length-1])+Math.abs(i[i.length-2]-a[0])+Math.abs(i[i.length-1]-a[1])||r%2)?(w(a),y[C]=-1,S=!0):"auto"===r?y[C]=0:"reverse"===r&&(y[C]=-1),a.closed!==i.closed&&(a.closed=i.closed=!1));return v&&A("shapeIndex:["+y.join(",")+"]"),e.shapeIndex=y}}function n(e,t){for(var r,o,n,i,a=0,h=parseFloat(e[0]),s=parseFloat(e[1]),l=h+","+s+" ",f=e.length,g=.5*t/(.5*f-1),p=0;p<3)&&((o=i?p.selector(e):e&&e[0]?e:[e])&&o[0]?(n=((o=o[0]).nodeName+"").toUpperCase(),t&&"PATH"!==n&&(o=a(o,!1),n="PATH"),e=o.getAttribute("PATH"===n?"d":"points")||"",o===r&&(e=o.getAttributeNS(null,"data-original")||e)):(A("WARNING: invalid morph to: "+e),e=!1)),e}function Y(e,t){for(var r,o,n,i,a,h,s,l,f,g,p,c,u=e.length,d=.2*(t||1);-1<--u;){for(p=(o=e[u]).isSmooth=o.isSmooth||[0,0,0,0],c=o.smoothData=o.smoothData||[0,0,0,0],p.length=4,l=o.length-2,s=6;s<=e.indexOf("left")?0:0<=e.indexOf("right")?100:isNaN(parseFloat(t[0]))?50:parseFloat(t[0]))/100,y:(0<=e.indexOf("top")?0:0<=e.indexOf("bottom")?100:isNaN(parseFloat(t[1]))?50:parseFloat(t[1]))/100}}var B,H=Math.PI,U=H/180,V=/[achlmqstvz]|(-?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/gi,X=/(?:(-|-=|\+=)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/gi,h=/(^[#\.][a-z]|[a-y][a-z])/gi,D=/[achlmqstvz]/gi,q=/[\+\-]?\d*\.?\d+e[\+\-]?\d+/gi,y=Math.atan2,Q=Math.cos,E=Math.sin,W=Math.sqrt,Z=2*H,c=.3*H,u=.7*H,p=_gsScope._gsDefine.globals.TweenLite,k="MorphSVGPlugin",J=String.fromCharCode(103,114,101,101,110,115,111,99,107,46,99,111,109),K=String.fromCharCode(47,114,101,113,117,105,114,101,115,45,109,101,109,98,101,114,115,104,105,112,47),$=function(e){for(var t=-1!==(window?window.location.href:"").indexOf(String.fromCharCode(103,114,101,101,110,115,111,99,107))&&-1!==e.indexOf(String.fromCharCode(108,111,99,97,108,104,111,115,116)),r=[J,String.fromCharCode(99,111,100,101,112,101,110,46,105,111),String.fromCharCode(99,111,100,101,112,101,110,46,112,108,117,109,98,105,110,103),String.fromCharCode(99,111,100,101,112,101,110,46,100,101,118),String.fromCharCode(99,111,100,101,112,101,110,46,97,112,112),String.fromCharCode(112,101,110,115,46,99,108,111,117,100),String.fromCharCode(112,101,110,115,46,105,111),String.fromCharCode(109,111,116,105,111,110,116,114,105,99,107,115,46,99,111,109),String.fromCharCode(99,115,115,45,116,114,105,99,107,115,46,99,111,109),String.fromCharCode(99,100,112,110,46,105,111),String.fromCharCode(103,97,110,110,111,110,46,116,118),String.fromCharCode(99,111,100,101,99,97,110,121,111,110,46,110,101,116),String.fromCharCode(116,104,101,109,101,102,111,114,101,115,116,46,110,101,116),String.fromCharCode(99,101,114,101,98,114,97,120,46,99,111,46,117,107),String.fromCharCode(116,121,109,112,97,110,117,115,46,110,101,116),String.fromCharCode(116,119,101,101,110,109,97,120,46,99,111,109),String.fromCharCode(116,119,101,101,110,108,105,116,101,46,99,111,109),String.fromCharCode(112,108,110,107,114,46,99,111),String.fromCharCode(104,111,116,106,97,114,46,99,111,109),String.fromCharCode(119,101,98,112,97,99,107,98,105,110,46,99,111,109),String.fromCharCode(97,114,99,104,105,118,101,46,111,114,103),String.fromCharCode(99,111,100,101,115,97,110,100,98,111,120,46,105,111),String.fromCharCode(115,116,97,99,107,98,108,105,116,122,46,99,111,109),String.fromCharCode(99,111,100,105,101,114,46,105,111),String.fromCharCode(106,115,102,105,100,100,108,101,46,110,101,116)],o=r.length;-1<--o;)if(-1!==e.indexOf(r[o]))return!0;return t&&window&&window.console&&console.log(String.fromCharCode(87,65,82,78,73,78,71,58,32,97,32,115,112,101,99,105,97,108,32,118,101,114,115,105,111,110,32,111,102,32)+k+String.fromCharCode(32,105,115,32,114,117,110,110,105,110,103,32,108,111,99,97,108,108,121,44,32,98,117,116,32,105,116,32,119,105,108,108,32,110,111,116,32,119,111,114,107,32,111,110,32,97,32,108,105,118,101,32,100,111,109,97,105,110,32,98,101,99,97,117,115,101,32,105,116,32,105,115,32,97,32,109,101,109,98,101,114,115,104,105,112,32,98,101,110,101,102,105,116,32,111,102,32,67,108,117,98,32,71,114,101,101,110,83,111,99,107,46,32,80,108,101,97,115,101,32,115,105,103,110,32,117,112,32,97,116,32,104,116,116,112,58,47,47,103,114,101,101,110,115,111,99,107,46,99,111,109,47,99,108,117,98,47,32,97,110,100,32,116,104,101,110,32,100,111,119,110,108,111,97,100,32,116,104,101,32,39,114,101,97,108,39,32,118,101,114,115,105,111,110,32,102,114,111,109,32,121,111,117,114,32,71,114,101,101,110,83,111,99,107,32,97,99,99,111,117,110,116,32,119,104,105,99,104,32,104,97,115,32,110,111,32,115,117,99,104,32,108,105,109,105,116,97,116,105,111,110,115,46,32,84,104,101,32,102,105,108,101,32,121,111,117,39,114,101,32,117,115,105,110,103,32,119,97,115,32,108,105,107,101,108,121,32,100,111,119,110,108,111,97,100,101,100,32,102,114,111,109,32,101,108,115,101,119,104,101,114,101,32,111,110,32,116,104,101,32,119,101,98,32,97,110,100,32,105,115,32,114,101,115,116,114,105,99,116,101,100,32,116,111,32,108,111,99,97,108,32,117,115,101,32,111,114,32,111,110,32,115,105,116,101,115,32,108,105,107,101,32,99,111,100,101,112,101,110,46,105,111,46)),t}(window?window.location.host:""),ee={rect:"rx,ry,x,y,width,height",circle:"r,cx,cy",ellipse:"rx,ry,cx,cy",line:"x1,x2,y1,y2"},te="Use MorphSVGPlugin.convertToPath(elementOrSelectorText) to convert to a path before morphing.",re=_gsScope._gsDefine.plugin({propName:"morphSVG",API:2,global:!0,version:"0.9.2",overwriteProps:["morphSVG"],init:function(e,t,r,o){var n,i,a,h,s,l,f,g,p,c,u,d,m,_,C,y,S,v,x,w,b,M,T=e.nodeType?window.getComputedStyle(e):{},N=T.fill+"",P=!("none"===N||"0"===(N.match(X)||[])[3]||"evenodd"===T.fillRule),z=(t.origin||"50 50").split(",");if("function"==typeof t&&(t=t(o,e)),!$)return window.location.href="http://"+J+K+"?plugin="+k+"&source=codepen",!1;if(s="POLYLINE"===(n=(e.nodeName+"").toUpperCase())||"POLYGON"===n,"PATH"!==n&&!s&&!t.prop)return A("WARNING: cannot morph a <"+n+"> element. "+te),!1;if(i="PATH"===n?"d":"points",("string"==typeof t||t.getBBox||t[0])&&(t={shape:t}),!t.prop&&"function"!=typeof e.setAttribute)return!1;if(h=F(t.shape||t.d||t.points||"","d"==i,e),s&&D.test(h))return A("WARNING: a <"+n+"> cannot accept path data. "+te),!1;if(l=t.shapeIndex||0===t.shapeIndex?t.shapeIndex:"auto",f=t.map||re.defaultMap,this._prop=t.prop,this._render=t.render||re.defaultRender,this._apply="updateTarget"in t?t.updateTarget:re.defaultUpdateTarget,this._rnd=Math.pow(10,isNaN(t.precision)?2:+t.precision),this._tween=r,h){if(this._target=e,S="object"==typeof t.precompile,c=this._prop?e[this._prop]:e.getAttribute(i),this._prop||e.getAttributeNS(null,"data-original")||e.setAttributeNS(null,"data-original",c),"d"==i||this._prop){if(c=R(S?t.precompile[0]:c),u=R(S?t.precompile[1]:h),!S&&!G(c,u,l,f,P))return!1;for("log"!==t.precompile&&!0!==t.precompile||A('precompile:["'+O(c)+'","'+O(u)+'"]'),(b="linear"!==(t.type||re.defaultType))&&(c=Y(c,t.smoothTolerance),u=Y(u,t.smoothTolerance),c.size||L(c),u.size||L(u),w=j(z[0]),this._origin=c.origin={x:c.left+w.x*c.width,y:c.top+w.y*c.height},z[1]&&(w=j(z[1])),this._eOrigin={x:u.left+w.x*u.width,y:u.top+w.y*u.height}),m=(this._rawPath=e._gsRawPath=c).length;-1<--m;)for(C=c[m],y=u[m],g=C.isSmooth||[],p=y.isSmooth||[],_=C.length,d=B=0;d<_;d+=2)y[d]===C[d]&&y[d+1]===C[d+1]||(b?g[d]&&p[d]?(v=C.smoothData,x=y.smoothData,M=d+(d===_-4?7-_:5),this._controlPT={_next:this._controlPT,i:d,j:m,l1s:v[d+1],l1c:x[d+1]-v[d+1],l2s:v[M],l2c:x[M]-v[M]},a=this._tweenRotation(C,y,d+2),this._tweenRotation(C,y,d,a),this._tweenRotation(C,y,M-1,a),d+=4):this._tweenRotation(C,y,d):(a=this._addTween(C,d,C[d],y[d]),a=this._addTween(C,d+1,C[d+1],y[d+1])||a))}else a=this._addTween(e,"setAttribute",e.getAttribute(i)+"",h+"","morphSVG",!1,i,I(l));b&&(this._addTween(this._origin,"x",this._origin.x,this._eOrigin.x),a=this._addTween(this._origin,"y",this._origin.y,this._eOrigin.y)),a&&(this._overwriteProps.push("morphSVG"),a.end=h,a.endProp=i)}return $},set:function(e){var t,r,o,n,i,a,h,s,l,f,g,p,c,u=this._rawPath,d=this._controlPT,m=this._anchorPT,_=this._rnd,C=this._target;if(this._super.setRatio.call(this,e),1===e&&this._apply)for(o=this._firstPT;o;)o.end&&(this._prop?C[this._prop]=o.end:C.setAttribute(o.endProp,o.end)),o=o._next;else if(u){for(;m;)a=m.sa+e*m.ca,i=m.sl+e*m.cl,m.t[m.i]=this._origin.x+Q(a)*i,m.t[m.i+1]=this._origin.y+E(a)*i,m=m._next;for(r=e<.5?2*e*e:(4-2*e)*e-1;d;)c=(h=d.i)+(h===(n=u[d.j]).length-4?7-n.length:5),a=y(n[c]-n[h+1],n[c-1]-n[h]),g=E(a),p=Q(a),l=n[h+2],f=n[h+3],i=d.l1s+r*d.l1c,n[h]=l-p*i,n[h+1]=f-g*i,i=d.l2s+r*d.l2c,n[c-1]=l+p*i,n[c]=f+g*i,d=d._next;if(C._gsRawPath=u,this._apply){for(t="",s=0;su?g:p,sl:l,cl:W(h*h+s*s)-l,i:r}},re.pathFilter=function(e,t,r,o,n){var i=R(e[0]),a=R(e[1]);G(i,a,t||0===t?t:"auto",r,n)&&(e[0]=O(i),e[1]=O(a),"log"!==o&&!0!==o||A('precompile:["'+e[0]+'","'+e[1]+'"]'))},re.pointsFilter=r,re.getTotalSize=L,re.subdivideRawBezier=re.subdivideSegment=x,re.rawPathToString=O,re.defaultType="linear",re.defaultUpdateTarget=!0,re.defaultMap="size",re.stringToRawPath=re.pathDataToRawBezier=function(e){return R(F(e,!0))},re.equalizeSegmentQuantity=G,re.convertToPath=function(e,t){"string"==typeof e&&(e=p.selector(e));for(var r=e&&0!==e.length?e.length&&e[0]&&e[0].nodeType?Array.prototype.slice.call(e,0):[e]:[],o=r.length;-1<--o;)r[o]=a(r[o],!1!==t);return r},re.pathDataToBezier=function(e,t){var r,o,n,i,a=R(F(e,!0))[0]||[],h=0,s=(t=t||{}).align||t.relative,l=t.matrix||[1,0,0,1,0,0],f=t.offsetX||0,g=t.offsetY||0;if("relative"===s||!0===s?(f-=a[0]*l[0]+a[1]*l[2],g-=a[0]*l[1]+a[1]*l[3],h="+="):(f+=l[4],g+=l[5],(s=s&&("string"==typeof s?p.selector(s):s&&s[0]?s:[s]))&&s[0]&&(f-=(i=s[0].getBBox()||{x:0,y:0}).x,g-=i.y)),r=[],n=a.length,l&&"1,0,0,1,0,0"!==l.join(","))for(o=0;o Date: Tue, 20 Aug 2024 12:04:28 +1000 Subject: [PATCH 65/93] fix touch --- 02-Archery-Game/index.html | 4 ++-- 02-Archery-Game/script.js | 30 +++++++++++++++++++----------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/02-Archery-Game/index.html b/02-Archery-Game/index.html index 9ecaf81..0322c6d 100644 --- a/02-Archery-Game/index.html +++ b/02-Archery-Game/index.html @@ -91,8 +91,8 @@ Draw back an arrow and launch it! - + + diff --git a/02-Archery-Game/script.js b/02-Archery-Game/script.js index da5afdf..af76465 100644 --- a/02-Archery-Game/script.js +++ b/02-Archery-Game/script.js @@ -25,15 +25,15 @@ var pivot = { // ๅˆคๆ–ญๅฝ“ๅ‰่ฎพๅค‡ๆ˜ฏๅฆไธบ่งฆๆ‘ธๅฑ function isTouchDevice() { - return window.matchMedia("(pointer: coarse)").matches; + return window.matchMedia("(pointer: coarse)").matches; } // ่ฎก็ฎ—ๅฑๅน•ไธญๅฟƒ function getScreenCenter() { - return { - x: window.innerWidth / 2, - y: window.innerHeight / 2 - }; + return { + x: window.innerWidth / 2, + y: window.innerHeight / 2 + }; } // // ่ฎพ็ฝฎ pivot ็‚น @@ -56,7 +56,8 @@ aim({ clientY: 300 }); - +//set up start touch +window.addEventListener("touchstart", draw) // set up start drag event window.addEventListener("mousedown", draw); @@ -75,14 +76,14 @@ function draw(e) { } function aim(e) { - try{e.preventDefault();}catch(e){} + try { e.preventDefault(); } catch (e) { } // get mouse position in relation to svg position and scale var point = getMouseSVG(e); point.x = Math.min(point.x, pivot.x - 7); point.y = Math.max(point.y, pivot.y + 7); var dx = point.x - pivot.x; var dy = point.y - pivot.y; - + // Make it more difficult by adding random angle each time var angle = Math.atan2(dy, dx) + randomAngle; var bowAngle = angle - Math.PI; @@ -118,7 +119,7 @@ function aim(e) { attr: { d: "M100,250c" + offset.x + "," + offset.y + "," + (arcWidth - offset.x) + "," + (offset.y + 50) + "," + arcWidth + ",50" }, - autoAlpha: distance/60 + autoAlpha: distance / 60 }); } @@ -226,8 +227,15 @@ function showMessage(selector) { function getMouseSVG(e) { // normalize mouse position within svg coordinates - cursor.x = e.clientX; - cursor.y = e.clientY; + if (e.touches) {//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ + cursor.x = e.touches[0].pageX; + cursor.y = e.touches[0].pageY; + } else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ + cursor.x = e.clientX; + cursor.y = e.clientY; + } + + return cursor.matrixTransform(svg.getScreenCTM().inverse()); } From 0e8678c2856443959363f2a6b1e7bb629dd4754a Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 20 Aug 2024 12:12:30 +1000 Subject: [PATCH 66/93] fix mobile display --- 28-Emoji-Catcher-Game/style.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/28-Emoji-Catcher-Game/style.css b/28-Emoji-Catcher-Game/style.css index 513afa1..4db8c0b 100644 --- a/28-Emoji-Catcher-Game/style.css +++ b/28-Emoji-Catcher-Game/style.css @@ -47,9 +47,9 @@ body { } .square { - height: 200px; - width: 200px; - margin: 10px; + height: 10vmax; + width: 10vmax; + margin: 1vmax; background: rgb(61, 61, 61); } From e2f452764ff5a522c0b1b94a98fc3625edd5c7f3 Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 20 Aug 2024 13:14:37 +1000 Subject: [PATCH 67/93] optomize size --- 08-Tetris-Game/index.html | 1 + 08-Tetris-Game/style.css | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/08-Tetris-Game/index.html b/08-Tetris-Game/index.html index 9fa1db6..5da63a6 100644 --- a/08-Tetris-Game/index.html +++ b/08-Tetris-Game/index.html @@ -2,6 +2,7 @@ Tetris Game + diff --git a/08-Tetris-Game/style.css b/08-Tetris-Game/style.css index 1922f00..cc7c719 100644 --- a/08-Tetris-Game/style.css +++ b/08-Tetris-Game/style.css @@ -1,12 +1,18 @@ body { overflow: hidden; background: #d7d7d7; + display: flex; + align-items: center; + justify-content: center; + min-height: 100vmin; } + #tetris { width: 360px; border: 1px solid black; padding: 20px; } + #canvas { width: 200px; height: 440px; @@ -14,6 +20,7 @@ body { position: relative; color: #fff; } + #canvas h1 { margin: 0; padding: 0; @@ -21,6 +28,7 @@ body { font-size: 30px; padding-top: 200px; } + .piece { border: 1px solid white; position: absolute; @@ -50,27 +58,35 @@ body { height: 19px; border: 1px solid white; } + .type0 { background-color: #a000f0; } + .type1 { background-color: #00f0f0; } + .type2 { background-color: #f0a000; } + .type3 { background-color: #0000f0; } + .type4 { background-color: #00f000; } + .type5 { background-color: #f00000; } + .type6 { background-color: #f0f000; } + #next_shape { position: relative; background-color: #000; @@ -78,6 +94,7 @@ body { width: 110px; height: 110px; } + #info { background-color: #000; color: #fff; @@ -85,4 +102,4 @@ body { width: 110px; height: 420px; padding: 10px; -} +} \ No newline at end of file From 75d8ad14afd8713f100d58b20f41561c01b0e00c Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 20 Aug 2024 20:52:51 +1000 Subject: [PATCH 68/93] fixed pingppong zoom problem --- 07-Ping-Pong-Game/style.css | 1 + 1 file changed, 1 insertion(+) diff --git a/07-Ping-Pong-Game/style.css b/07-Ping-Pong-Game/style.css index 935e7fa..e9d1a2d 100644 --- a/07-Ping-Pong-Game/style.css +++ b/07-Ping-Pong-Game/style.css @@ -36,6 +36,7 @@ canvas { background: #000; + width: 80vmin; } body { overscroll-behavior-y: contain; From a84e752d57ea9d095df121916a32c1e7f2a327be Mon Sep 17 00:00:00 2001 From: Jack Date: Tue, 20 Aug 2024 21:14:51 +1000 Subject: [PATCH 69/93] test --- 07-Ping-Pong-Game/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/07-Ping-Pong-Game/script.js b/07-Ping-Pong-Game/script.js index 01ef092..d805ab8 100644 --- a/07-Ping-Pong-Game/script.js +++ b/07-Ping-Pong-Game/script.js @@ -398,11 +398,11 @@ function actionMove(e) { let rightPt = {pageX:canvas.offsetLeft + canvas.width / 2,pageY:0}; ballColor = 'red'; for (let i = 1; i < e.touches.length; i++) { - if (e.touches[i].pageX < leftPt.pageX) { + if (e.touches[i].pageX < leftPt.pageX- canvas.offsetLeft) { leftPt = e.touches[i]; } - if (e.touches[i].pageX > rightPt.pageX) { + if (e.touches[i].pageX > rightPt.pageX- canvas.offsetLeft) { rightPt = e.touches[i]; } From aca3ead8a368af7e8cd5fa6cebe825e8921038f9 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 22 Aug 2024 09:38:19 +1000 Subject: [PATCH 70/93] add multiTouch support --- 07-Ping-Pong-Game/index.html | 3 +- 07-Ping-Pong-Game/script.js | 261 +++++++++++++++++++++++++---------- 07-Ping-Pong-Game/style.css | 3 + 3 files changed, 190 insertions(+), 77 deletions(-) diff --git a/07-Ping-Pong-Game/index.html b/07-Ping-Pong-Game/index.html index 917104c..4ebf482 100644 --- a/07-Ping-Pong-Game/index.html +++ b/07-Ping-Pong-Game/index.html @@ -3,6 +3,7 @@ Ping Pong Game + @@ -28,7 +29,7 @@ - +
diff --git a/07-Ping-Pong-Game/script.js b/07-Ping-Pong-Game/script.js index d805ab8..a389eff 100644 --- a/07-Ping-Pong-Game/script.js +++ b/07-Ping-Pong-Game/script.js @@ -34,8 +34,8 @@ addEventListener("load", (event) => { var ballRadius = 10; var ballX = canvas.width / 2; var ballY = canvas.height / 2; -var ballSpeedX = 5; -var ballSpeedY = 5; +var ballSpeedX = 4; +var ballSpeedY = 4; // Define paddle properties var paddleHeight = 80; @@ -203,6 +203,25 @@ function draw() { // Draw scores ctx.fillText("Score: " + leftPlayerScore, 10, 20); ctx.fillText("Score: " + rightPlayerScore, canvas.width - 70, 20); +return; +//debug + const lineHeight = 20; + const startY = canvas.height / 2 - (debugInfo.length * lineHeight) / 2; + + ctx.save(); + ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; + ctx.fillRect(0, startY - 10, canvas.width, debugInfo.length * lineHeight + 20); + + ctx.font = '16px Arial'; + ctx.fillStyle = 'white'; + ctx.textAlign = 'center'; + + debugInfo.forEach((info, index) => { + ctx.fillText(info, canvas.width / 2, startY + index * lineHeight); + }); + drawDebugInfo(); + + } // Game loop @@ -342,31 +361,28 @@ var touchYstartLeft = null; var previousPositionLeft = canvas.height / 2 - paddleHeight; var touchYstartRight = null; var previousPositionRight = canvas.height / 2 - paddleHeight; +const canvasBounds = canvas.getBoundingClientRect(); +const canvasMiddle = canvasBounds.width/2+canvasBounds.left; + function actionStart(e) { //e.preventDefault(); //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ if(!gameRunning ) { return; } - var leftPt = { pageX: canvas.width, pageY: 0 }, rightPt = { pageX: 0, pageY: 0 }; + var leftPt = { pageX: canvas.width, pageY: -1 }, rightPt = { pageX: 0, pageY: -1 }; - if (e.touches && e.touches.length > 1) {//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ - e.touches.forEach(element => {//่ฎฐๅฝ•ๅทฆๅŠ่พน๏ผŒๆœ€ๅทฆ่พน็š„็‚น - if (element.pageX - canvas.offsetLeft < canvas.width / 2) { - leftPt = element.pageX < leftPt.pageX ? element : leftPt; + if (e.touches && e.touches.length >= 1) {//ๅฆ‚ๆžœๆ˜ฏ่งฆๆ‘ธ + for(var i = 0; i < e.touches.length; i++){//่ฎฐๅฝ•ๅทฆๅŠ่พน๏ผŒๆœ€ๅทฆ่พน็š„็‚น + if (e.touches[i].pageX < canvasMiddle) { + leftPt = e.touches[i].pageX < leftPt.pageX ? e.touches[i] : leftPt; } else {//่ฎฐๅฝ•ๅณๅŠ่พน๏ผŒๆœ€ๅณ่พน็š„็‚น - rightPt = element.pageX > rightPt.pageX ? element : rightPt; + rightPt = e.touches[i].pageX > rightPt.pageX ? e.touches[i] : rightPt; } - }); - if (touchYstartLeft == null) { touchYstartLeft = leftPt.pageY; } - if (touchYstartRight == null) { touchYstartRight = rightPt.pageY; } - return; - } else if (e.touches && e.touches.length == 1) {//ๅฆ‚ๆžœๆ˜ฏๅ•็‚น่งฆๆ‘ธ - if (e.touches[0].pageX - canvas.offsetLeft < canvas.width / 2) { - if (touchYstartLeft == null) { touchYstartLeft = e.touches[0].pageY; } - } else { - if (touchYstartRight == null) { touchYstartRight = e.touches[0].pageY; } } - } else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ touchXstart็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡ - if (e.pageX - canvas.offsetLeft < canvas.width / 2) { + if (touchYstartLeft == null && leftPt.pageY != -1 ) { touchYstartLeft = leftPt.pageY; } + if (touchYstartRight == null && rightPt.pageY != -1) { touchYstartRight = rightPt.pageY; } + return; + } else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ touchXstart็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡ + if (e.pageX 1) { // ๅคš็‚น่งฆๆ‘ธ - //ๅˆๅง‹ๅŒ–ไธบ็”ปๅธƒไธญ้—ดไฝ็ฝฎ - let leftPt = {pageX:canvas.offsetLeft + canvas.width / 2,pageY:0}; - let rightPt = {pageX:canvas.offsetLeft + canvas.width / 2,pageY:0}; - ballColor = 'red'; - for (let i = 1; i < e.touches.length; i++) { - if (e.touches[i].pageX < leftPt.pageX- canvas.offsetLeft) { - leftPt = e.touches[i]; - - } - if (e.touches[i].pageX > rightPt.pageX- canvas.offsetLeft) { - rightPt = e.touches[i]; - - } - } + if (gameRunning) { + if (e.touches) { // ่งฆๆ‘ธไบ‹ไปถ + handleTouchMove(e); + } else { // ้ผ ๆ ‡ไบ‹ไปถ + handleMouseMove(e); + } + } +} - if (touchYstartLeft !== null && leftPt.pageX - canvas.offsetLeft < canvas.width / 2) { - distLeft = leftPt.pageY - touchYstartLeft; - leftPaddleY = previousPositionLeft + distLeft; - leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); - ballColor = 'blue'; +function handleTouchMove(e) { + let leftTouch = null; + let rightTouch = null; + + // ๆธ…้™คไน‹ๅ‰็š„่ฐƒ่ฏ•ไฟกๆฏ + clearDebugInfo(); + + // ้ๅކๆ‰€ๆœ‰่งฆๆ‘ธ็‚น,ๆ‰พๅ‡บๆœ€ๅทฆๅ’Œๆœ€ๅณ็š„่งฆๆ‘ธ็‚น๏ผŒๅนถ่ฎฐๅฝ•่ฐƒ่ฏ•ไฟกๆฏ + for (let i = 0; i < e.touches.length; i++) { + let touch = e.touches[i]; + let touchX = touch.pageX; + let touchY = touch.pageY; + + // ๆทปๅŠ ่ฐƒ่ฏ•ไฟกๆฏ + addDebugInfo(`Touch ${i}: (${Math.round(touchX)}, ${Math.round(touchY)})`); + + if (touchX < canvasMiddle) { // ๅทฆๅŠ่พน + if (!leftTouch || touchX < leftTouch.pageX ) { + leftTouch = touch; } - - if (touchYstartRight !== null && rightPt.pageX - canvas.offsetLeft > canvas.width / 2) { - distRight = rightPt.pageY - touchYstartRight; - rightPaddleY = previousPositionRight + distRight; - rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); - ballColor = 'green'; + + } else { // ๅณๅŠ่พน + if (!rightTouch || touchX > rightTouch.pageX ) { + rightTouch = touch; } + + } + } + try{addDebugInfo(`leftTouch: (${leftTouch.pageX}, ${leftTouch.pageY}, ${touchYstartLeft})`);}catch(e){} + try{addDebugInfo(`rightTouch: (${rightTouch.pageX}, ${rightTouch.pageY}, ${touchYstartRight})`);}catch(e){} + + // ๆ›ดๆ–ฐๅทฆไพงๆป‘ๆฟไฝ็ฝฎ + try{if (leftTouch && touchYstartLeft !== null) { + let distLeft = leftTouch.pageY - touchYstartLeft; + leftPaddleY = previousPositionLeft + distLeft; + leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); + addDebugInfo(`distLeft: (${distLeft})`); + }}catch(e){} + + // ๆ›ดๆ–ฐๅณไพงๆป‘ๆฟไฝ็ฝฎ + try{if (rightTouch && touchYstartRight !== null) { + let distRight = rightTouch.pageY - touchYstartRight; + rightPaddleY = previousPositionRight + distRight; + rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); + addDebugInfo(`distRight: (${distRight})`); + }}catch(e){} +} - } else if (e.touches && e.touches.length == 1) { // ๅ•็‚น่งฆๆ‘ธ - let touch = e.touches[0]; - if (touch.pageX - canvas.offsetLeft < canvas.width / 2) { - if (touchYstartLeft !== null) { - distLeft = touch.pageY - touchYstartLeft; - leftPaddleY = previousPositionLeft + distLeft; - leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); - } - } else { - if (touchYstartRight !== null) { - distRight = touch.pageY - touchYstartRight; - rightPaddleY = previousPositionRight + distRight; - rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); - } - } - } else { // ้ผ ๆ ‡็งปๅŠจ - if (e.pageX - canvas.offsetLeft < canvas.width / 2) { - if (touchYstartLeft !== null) { - distLeft = e.pageY - touchYstartLeft; - leftPaddleY = previousPositionLeft + distLeft; - leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); - } - } else { - if (touchYstartRight !== null) { - distRight = e.pageY - touchYstartRight; - rightPaddleY = previousPositionRight + distRight; - rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); - } - } +function handleMouseMove(e) { + let mouseX = e.pageX; + let mouseY = e.pageY; + + // ๆทปๅŠ ้ผ ๆ ‡ไฝ็ฝฎๅˆฐ่ฐƒ่ฏ•ไฟกๆฏ + clearDebugInfo(); + addDebugInfo(`Mouse: (${Math.round(mouseX)}, ${Math.round(mouseY)})`); + + if (mouseX < canvasMiddle) { + if (touchYstartLeft !== null) { + let distLeft = mouseY - touchYstartLeft; + leftPaddleY = previousPositionLeft + distLeft; + leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); + } + } else { + if (touchYstartRight !== null) { + let distRight = mouseY - touchYstartRight; + rightPaddleY = previousPositionRight + distRight; + rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); + } + } +} + +function clearDebugInfo() { + return; + debugInfo = []; + debugScrollY = 0; +} + +function addDebugInfo(info) { + return; + debugInfo.push(info); + if (debugInfo.length > MAX_LINES) { + debugScrollY += LINE_HEIGHT; + if (debugScrollY >= DEBUG_AREA_SIZE) { + debugScrollY = 0; } } } +function drawDebugInfo() { + const ctx = canvas.getContext('2d'); + const startX = (canvas.width - DEBUG_AREA_SIZE) / 2; + const startY = (canvas.height - DEBUG_AREA_SIZE) / 2; + + ctx.save(); + + // ็ป˜ๅˆถ่ฐƒ่ฏ•ๅŒบๅŸŸ่ƒŒๆ™ฏ + ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; + ctx.fillRect(startX, startY, DEBUG_AREA_SIZE, DEBUG_AREA_SIZE); + + // ่ฎพ็ฝฎ่ฃๅ‰ชๅŒบๅŸŸ + ctx.beginPath(); + ctx.rect(startX, startY, DEBUG_AREA_SIZE, DEBUG_AREA_SIZE); + ctx.clip(); + + ctx.font = '16px Arial'; + ctx.fillStyle = 'white'; + ctx.textAlign = 'left'; + + debugInfo.forEach((info, index) => { + let y = startY + index * LINE_HEIGHT - debugScrollY; + if (y < startY) { + y += DEBUG_AREA_SIZE; + } + ctx.fillText(info, startX + 10, y + LINE_HEIGHT); + }); + + ctx.restore(); +} + +// ๅœจๆ‚จ็š„ไธป็ป˜ๅˆถๅ‡ฝๆ•ฐไธญๆทปๅŠ ่ฟ™ไธชๅ‡ฝๆ•ฐ่ฐƒ็”จ +//function draw() { + // ... ๆ‚จ็Žฐๆœ‰็š„็ป˜ๅˆถไปฃ็  ... + + // const ctx = canvas.getContext('2d'); + // const lineHeight = 20; + // const startY = canvas.height / 2 - (debugInfo.length * lineHeight) / 2; + + // ctx.save(); + // ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; + // ctx.fillRect(0, startY - 10, canvas.width, debugInfo.length * lineHeight + 20); + + // ctx.font = '16px Arial'; + // ctx.fillStyle = 'white'; + // ctx.textAlign = 'center'; + + // debugInfo.forEach((info, index) => { + // ctx.fillText(info, canvas.width / 2, startY + index * lineHeight); + // }); + // drawDebugInfo(); +//} + // ไบ‹ไปถ็›‘ๅฌๅ™จ document.addEventListener('touchstart', actionStart, { passive: false }); document.addEventListener('touchend', actionEnd); diff --git a/07-Ping-Pong-Game/style.css b/07-Ping-Pong-Game/style.css index e9d1a2d..f6be8e1 100644 --- a/07-Ping-Pong-Game/style.css +++ b/07-Ping-Pong-Game/style.css @@ -41,4 +41,7 @@ canvas { body { overscroll-behavior-y: contain; max-height: 80vh; + user-select: none; + -moz-user-select: none; + -o-user-select: none; } \ No newline at end of file From 4de7506d6ecb156060c06b0aaedf9c6f9fecc8ed Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 22 Aug 2024 12:02:35 +1000 Subject: [PATCH 71/93] new game --- 31-Air-Hockey-Game/index.html | 509 ++++++++++++++++++++++++++++++++++ 1 file changed, 509 insertions(+) create mode 100644 31-Air-Hockey-Game/index.html diff --git a/31-Air-Hockey-Game/index.html b/31-Air-Hockey-Game/index.html new file mode 100644 index 0000000..44327a3 --- /dev/null +++ b/31-Air-Hockey-Game/index.html @@ -0,0 +1,509 @@ + + + + + Ping Pong Game + + + + + + + + + + +
+ +
+
+ + + +
+

Control: Player Left(W and S) | Player Right(โ†‘ and โ†“)

+ + + + + + + + + \ No newline at end of file From 657314d8c542e3b8b667fdf2afe195be3c4b2a17 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 22 Aug 2024 12:52:01 +1000 Subject: [PATCH 72/93] add mouse ctrl --- 31-Air-Hockey-Game/index.html | 56 ++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/31-Air-Hockey-Game/index.html b/31-Air-Hockey-Game/index.html index 44327a3..3fd8bc9 100644 --- a/31-Air-Hockey-Game/index.html +++ b/31-Air-Hockey-Game/index.html @@ -135,8 +135,8 @@
// Define paddle properties var paddleHeight = 80; var paddleWidth = paddleHeight/2; - var leftPaddleY = canvas.height / 2 - paddleHeight / 2; - var rightPaddleY = canvas.height / 2 - paddleHeight / 2; + var leftPaddleY = canvas.height / 2 ; + var rightPaddleY = canvas.height / 2 ; var leftPaddleX = 0; var rightPaddleX = canvas.width; var paddleSpeed = 10; @@ -147,9 +147,13 @@
var rightPlayerScore = 0; var maxScore = 100; var touchYstartLeft = null; - var previousPositionLeft = canvas.height / 2 - paddleHeight; + var touchXstartLeft = null; + var previousYPositionLeft = canvas.height / 2 ; + var previousXPositionLeft = 0+edgeWidth; var touchYstartRight = null; - var previousPositionRight = canvas.height / 2 - paddleHeight; + var touchXstartRight = null; + var previousYPositionRight = canvas.height / 2 ; + var previousXPositionRight = canvas.width - edgeWidth; const canvasBounds = canvas.getBoundingClientRect(); const canvasMiddle = canvasBounds.width / 2 + canvasBounds.left; var effectiveBounds = { @@ -397,14 +401,14 @@
rightPt = e.touches[i].pageX > rightPt.pageX ? e.touches[i] : rightPt; } } - if (touchYstartLeft == null && leftPt.pageY != -1) { touchYstartLeft = leftPt.pageY; } - if (touchYstartRight == null && rightPt.pageY != -1) { touchYstartRight = rightPt.pageY; } + if (touchYstartLeft == null && leftPt.pageY != -1) { touchYstartLeft = leftPt.pageY; touchXstartLeft = leftPt.pageX; } + if (touchYstartRight == null && rightPt.pageY != -1) { touchYstartRight = rightPt.pageY;touchXstartRight = rightPt.pageX; } return; } else {//ๅฆ‚ๆžœๆ˜ฏ้ผ ๆ ‡ touchXstart็ญ‰ไบŽ้ผ ๆ ‡็š„xๅๆ ‡ if (e.pageX < canvasMiddle) { - if (touchYstartLeft == null) { touchYstartLeft = e.pageY; } + if (touchYstartLeft == null) { touchYstartLeft = e.pageY;touchXstartLeft = e.pageX; } } else { - if (touchYstartRight == null) { touchYstartRight = e.pageY; } + if (touchYstartRight == null) { touchYstartRight = e.pageY; touchXstartRight = e.pageX; } } } @@ -414,11 +418,15 @@
//e.preventDefault(); if (touchYstartRight != null) { touchYstartRight = null; - previousPositionRight = rightPaddleY; + touchXstartRight = null; + previousYPositionRight = rightPaddleY; + previousXPositionRight = rightPaddleX; } if (touchYstartLeft != null) { touchYstartLeft = null; - previousPositionLeft = leftPaddleY; + touchXstartLeft = null; + previousYPositionLeft = leftPaddleY; + previousXPositionLeft = leftPaddleX; } } @@ -459,18 +467,24 @@
// ๆ›ดๆ–ฐๅทฆไพงๆป‘ๆฟไฝ็ฝฎ try { if (leftTouch && touchYstartLeft !== null) { - let distLeft = leftTouch.pageY - touchYstartLeft; - leftPaddleY = previousPositionLeft + distLeft; + let distYLeft = leftTouch.pageY - touchYstartLeft; + leftPaddleY = previousYPositionLeft + distYLeft; leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); + let distXLeft = leftTouch.pageX - touchXstartLeft; + leftPaddleX = previousXPositionLeft + distXLeft; + leftPaddleX = Math.max(0, Math.min(canvas.width/2 , leftPaddleX)); } } catch (e) { } // ๆ›ดๆ–ฐๅณไพงๆป‘ๆฟไฝ็ฝฎ try { if (rightTouch && touchYstartRight !== null) { - let distRight = rightTouch.pageY - touchYstartRight; - rightPaddleY = previousPositionRight + distRight; + let distYRight = rightTouch.pageY - touchYstartRight; + rightPaddleY = previousYPositionRight + distYRight; rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); + let distXRight = rightTouch.pageX - touchXstartRight; + rightPaddleX = previousXPositionRight + distXRight; + rightPaddleX = Math.min(canvas.width, Math.max(canvas.width/2 , rightPaddleX)); } } catch (e) { } } @@ -482,15 +496,21 @@
if (mouseX < canvasMiddle) { if (touchYstartLeft !== null) { - let distLeft = mouseY - touchYstartLeft; - leftPaddleY = previousPositionLeft + distLeft; + let distYLeft = mouseY - touchYstartLeft; + leftPaddleY = previousYPositionLeft + distYLeft; leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); + let distXLeft = mouseX - touchXstartLeft; + leftPaddleX = previousXPositionLeft + distXLeft; + leftPaddleX = Math.max(0, Math.min(canvas.width - paddleWidth, leftPaddleX)); } } else { if (touchYstartRight !== null) { - let distRight = mouseY - touchYstartRight; - rightPaddleY = previousPositionRight + distRight; + let distYRight = mouseY - touchYstartRight; + rightPaddleY = previousYPositionRight + distYRight; rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); + let distXRight = mouseX - touchXstartRight; + rightPaddleX = previousXPositionRight + distXRight; + rightPaddleX = Math.max(0, Math.min(canvas.width - paddleWidth, rightPaddleX)); } } } From 8768121a81bad3e0bd8ba7a7b668592227a7ad65 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 22 Aug 2024 14:33:27 +1000 Subject: [PATCH 73/93] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20index.html?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 31-Air-Hockey-Game/index.html | 50 +++++++++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/31-Air-Hockey-Game/index.html b/31-Air-Hockey-Game/index.html index 3fd8bc9..c6f8291 100644 --- a/31-Air-Hockey-Game/index.html +++ b/31-Air-Hockey-Game/index.html @@ -220,6 +220,36 @@
} } +function calculateCollision(sx, sy, px, py, qx, qy, r, R) { + // ่ฎก็ฎ—ๅฐ็ƒๅˆฐๅคง็ƒ็š„ๅ•ไฝๆณ•ๅ‘้‡ + const dx = px - qx; + const dy = py - qy; + const distance = Math.sqrt(dx * dx + dy * dy); + + // ๅ•ไฝๆณ•ๅ‘้‡ + const nx = dx / distance; + const ny = dy / distance; + + // ่ฎก็ฎ—ๅฐ็ƒๅœจๆณ•ๅ‘้‡ๆ–นๅ‘็š„้€Ÿๅบฆๅˆ†้‡๏ผˆๆŠ•ๅฝฑ๏ผ‰ + const vDotN = sx * nx + sy * ny; + + // ่ฎก็ฎ—ๆณ•ๅ‘้‡ๆ–นๅ‘็š„ๅๅฐ„้€Ÿๅบฆๅˆ†้‡ + const reflectedVx = sx - 2 * vDotN * nx; + const reflectedVy = sy - 2 * vDotN * ny; + + return { reflectedVx, reflectedVy }; +} + +function hasCollided(px, py, qx, qy, r, R) { + // ่ฎก็ฎ—ไธคไธช็ƒไธญๅฟƒ็š„่ท็ฆป + const dx = px - qx; + const dy = py - qy; + const distance = Math.sqrt(dx * dx + dy * dy); + + // ๆฃ€ๆŸฅๆ˜ฏๅฆ็ขฐๆ’ž + return distance <= r + R; +} + // Update game state function update() { // Move paddles @@ -260,23 +290,33 @@
} // Check if ball collides with left paddle - if ( + /*if ( ballX - ballRadius < paddleWidth && ballY > leftPaddleY && ballY < leftPaddleY + paddleHeight ) { ballSpeedX = -ballSpeedX; - } + }*/ + +if(hasCollided(ballX, ballY, leftPaddleX, leftPaddleY, ballRadius, paddleHeight/2)){ +var ballMove = calculateCollision(ballSpeedX,ballSpeedY, ballX, ballY, leftPaddleX, leftPaddleY, ballRadius, paddleHeight/2); +ballSpeedX = ballMove.reflectedVx; +ballSpeedY = ballMove.reflectedVy; +} // Check if ball collides with right paddle - if ( + /*if ( ballX + ballRadius > canvas.width - paddleWidth && ballY > rightPaddleY && ballY < rightPaddleY + paddleHeight ) { ballSpeedX = -ballSpeedX; - } - + }*/ +if(hasCollided(ballX, ballY, rightPaddleX, rightPaddleY, ballRadius, paddleHeight/2)){ +var ballMove = calculateCollision(ballSpeedX,ballSpeedY, ballX, ballY, rightPaddleX,rightPaddleY, ballRadius, paddleHeight/2); +ballSpeedX = ballMove.reflectedVx; +ballSpeedY = ballMove.reflectedVy; +} // Check if ball goes out of bounds on left or right side of canvas if (ballY > canvas.height / 2 - paddleHeight && ballY < canvas.height / 2 + paddleHeight) { if (ballX < effectiveBounds) { From 75d29925c80e343bfa1f647831e5293751202ef8 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 23 Aug 2024 01:00:03 +1000 Subject: [PATCH 74/93] air hockey online --- 07-Ping-Pong-Game/index.html | 2 +- 07-Ping-Pong-Game/style.css | 2 +- 31-Air-Hockey-Game/index.html | 150 ++++++++++++++++++---------------- index.html | 4 + indexCN.html | 4 + 5 files changed, 91 insertions(+), 71 deletions(-) diff --git a/07-Ping-Pong-Game/index.html b/07-Ping-Pong-Game/index.html index 4ebf482..9d68290 100644 --- a/07-Ping-Pong-Game/index.html +++ b/07-Ping-Pong-Game/index.html @@ -38,7 +38,7 @@ -

Control: Player Left(W and S) | Player Right(โ†‘ and โ†“)

+

Control: Player Left(W and S)/mouse/touch | Player Right(โ†‘ and โ†“)/mouse/touch

+ + + +
13Tic Tac Toe Game: Challenge a friend or AI in this simple yet strategic game of placing Xs and Os in a 3x3 grid. โญ•โŒTic Tac Toe Game: Challenge a friend in this simple yet strategic game of placing Xs and Os in a 3x3 grid. โญ•โŒ
14
15Connect Four Game: Strategically drop colored discs to connect four in a row vertically, horizontally, or diagonally in this classic board game. ๐Ÿ”ต๐Ÿ”ดConnect discs Game: Strategically drop colored discs to connect them in a row vertically, horizontally, or diagonally in this classic board game. you can challenge your friends or AI with this game. ๐Ÿ”ด๐Ÿ”ต๐Ÿ”ด
16
18Hangman Game: Guess the hidden word by suggesting letters within a certain number of guesses in this word-guessing game. ๐ŸŽฉHangman Game: Guess the hidden word by suggesting letters within a certain number of guesses in this word-guessing game. You can also check the definitions of the words with internet ๐ŸŽฉ
19
13ไบ•ๅญ—ๆฃ‹ๆธธๆˆ๏ผšๅœจ่ฟ™ไธช็ฎ€ๅ•่€Œๆˆ˜็•ฅๆ€ง็š„ๆธธๆˆไธญๆŒ‘ๆˆ˜ๆœ‹ๅ‹ๆˆ– AI๏ผŒๅœจ 3x3 ็ฝ‘ๆ ผไธญๆ”พ็ฝฎ X ๅ’Œ Oใ€‚ โญ•โŒไบ•ๅญ—ๆฃ‹ๆธธๆˆ๏ผšๅœจ่ฟ™ไธช็ฎ€ๅ•่€Œๆˆ˜็•ฅๆ€ง็š„ๆธธๆˆ๏ผŒๅœจ 3x3 ็ฝ‘ๆ ผไธญๆ”พ็ฝฎ X ๅ’Œ Oใ€‚ โญ•โŒ
14
15ๅ››/ไบ”ๅญ่ฟž็ ๆธธๆˆ๏ผšๆˆ˜็•ฅๆ€งๅœฐๆŠ•ๆ”พๅฝฉ่‰ฒๅœ†็›˜๏ผŒไปฅ็บตๅ‘ใ€ๆจชๅ‘ๆˆ–ๅฏน่ง’็บฟ่ฟžๆŽฅๅ››ไธชๅœจ่ฟ™ไธช็ปๅ…ธๆฃ‹็›˜ๆธธๆˆไธญใ€‚ ๐Ÿ”ต๐Ÿ”ดๅคšๅญ่ฟž็ ๆธธๆˆ๏ผšๆˆ˜็•ฅๆ€งๅœฐๆŠ•ๆ”พๅฝฉ่‰ฒๅœ†็›˜๏ผŒไปฅ็บตๅ‘ใ€ๆจชๅ‘ๆˆ–ๅฏน่ง’็บฟ่ฟžๆŽฅๆฃ‹ๅญไปฅ่Žทๅ–่ƒœๅˆฉ๏ผŒๅœจ่ฟ™ไธช็ปๅ…ธๆฃ‹็›˜ๆธธๆˆไธญไฝ ๅฏไปฅๆŒ‘ๆˆ˜ๆœ‹ๅ‹ๆˆ– AIใ€‚ ๐Ÿ”ต๐Ÿ”ด
16
18็ปžๅˆ‘ๆžถๆธธๆˆ๏ผšๅœจ่ฟ™ไธช็Œœๅญ—ๆธธๆˆไธญ๏ผŒ้€š่ฟ‡ๅœจๆœ‰้™็š„็Œœๆต‹ๆฌกๆ•ฐๅ†…ๅปบ่ฎฎๅญ—ๆฏๆฅ็Œœๆต‹้š่—็š„ๅ•่ฏใ€‚ ๐ŸŽฉ็ปžๅˆ‘ๆžถๆธธๆˆ๏ผšๅœจ่ฟ™ไธช็Œœๅญ—ๆธธๆˆไธญ๏ผŒ้€š่ฟ‡ๅœจๆœ‰้™็š„็Œœๆต‹ๆฌกๆ•ฐๅ†…ๅปบ่ฎฎๅญ—ๆฏๆฅ็Œœๆต‹้š่—็š„ๅ•่ฏใ€‚ๅนถ่ƒฝ้€š่ฟ‡็ฝ‘็ปœๆŸฅ่ฏข่ฏฅ่ฏ็š„่ฏป้Ÿณๅ’Œ่งฃ้‡Š ๐ŸŽฉ
1930 Guess Number Game: Guess a 4-digit number with A for right position and B for right number. Only eight chances. A good game for logical thinking.๐Ÿง ๐Ÿค–
31Air Hockey Game: A ping-pong like game with two players. control with mouse or keyboard or multi-touch screen. Play with your friends in this classic game. ๐Ÿ€๐Ÿ‘
diff --git a/indexCN.html b/indexCN.html index 3a2314e..71e99c3 100644 --- a/indexCN.html +++ b/indexCN.html @@ -173,6 +173,10 @@

ๆธธๆˆๅˆ—่กจ


30 ็Œœๆ•ฐๅญ—ๆธธๆˆ๏ผš็Œœๆต‹ไธ€ไธช 4 ไฝๆ•ฐๅญ—๏ผŒA ่กจ็คบไฝ็ฝฎๆญฃ็กฎ๏ผŒB ่กจ็คบๆ•ฐๅญ—ๆญฃ็กฎใ€‚ๅชๆœ‰ๅ…ซๆฌกๆœบไผšใ€‚ไธ€ไธช้”ป็‚ผ้€ป่พ‘ๆ€็ปด็š„ๅฅฝๆธธๆˆใ€‚๐Ÿง ๐Ÿค– + + 31 + ็ฉบๆฐ”ๆ›ฒๆฃ็ƒๆธธๆˆ๏ผšไธ€ไธช็ฑปไผผไน’ไน“็ƒ็š„ๆธธๆˆ๏ผŒ็”จ้”ฎ็›˜ๆˆ–้ผ ๆ ‡ๆˆ–ๅคš่งฆ็‚นๅฑๅน•ๆฅ่ฟ›่กŒๅฏนๆˆ˜ๅง๏ผ๐Ÿ€ ๐Ÿ‘ + From ad6bd7af79a2cfce3aa70ff2d784f30accf5409e Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 23 Aug 2024 10:48:32 +1000 Subject: [PATCH 75/93] fix bugs --- 31-Air-Hockey-Game/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/31-Air-Hockey-Game/index.html b/31-Air-Hockey-Game/index.html index ec0294f..78d9937 100644 --- a/31-Air-Hockey-Game/index.html +++ b/31-Air-Hockey-Game/index.html @@ -258,7 +258,7 @@
return distance <= r + R; } - // Update game state + // Update game state, keybroad controls function update() { // Move paddles // Move right paddle up down based on "ArrowUp" and "ArrowDown" keys @@ -550,7 +550,7 @@
if (touchYstartLeft !== null) { let distYLeft = mouseY - touchYstartLeft; leftPaddleY = previousYPositionLeft + distYLeft; - leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); + leftPaddleY = Math.max(0 + paddleHeight / 2, Math.min(canvas.height - paddleHeight/2, leftPaddleY)); let distXLeft = mouseX - touchXstartLeft; leftPaddleX = previousXPositionLeft + distXLeft; leftPaddleX = Math.max(0, Math.min(canvas.width / 2, leftPaddleX)); @@ -559,7 +559,7 @@
if (touchYstartRight !== null) { let distYRight = mouseY - touchYstartRight; rightPaddleY = previousYPositionRight + distYRight; - rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); + rightPaddleY = Math.max(0 + paddleHeight / 2, Math.min(canvas.height - paddleHeight/2, rightPaddleY)); let distXRight = mouseX - touchXstartRight; rightPaddleX = previousXPositionRight + distXRight; rightPaddleX = Math.min(canvas.width, Math.max(canvas.width / 2, rightPaddleX)); From c7f1c7942184a306f1ab84d624772283aeba6228 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 23 Aug 2024 11:38:01 +1000 Subject: [PATCH 76/93] 24 point Game --- 32-24 Point Poker Game/index.html | 204 ++++++++++++++++++++++++++++++ 32-24 Point Poker Game/str.js | 2 + 2 files changed, 206 insertions(+) create mode 100644 32-24 Point Poker Game/index.html create mode 100644 32-24 Point Poker Game/str.js diff --git a/32-24 Point Poker Game/index.html b/32-24 Point Poker Game/index.html new file mode 100644 index 0000000..5dfe0a1 --- /dev/null +++ b/32-24 Point Poker Game/index.html @@ -0,0 +1,204 @@ + + + + + + + 24็‚น + + + + +
+ + + + +
+ +
+
+ +
+
+ + + + + + \ No newline at end of file diff --git a/32-24 Point Poker Game/str.js b/32-24 Point Poker Game/str.js new file mode 100644 index 0000000..f523251 --- /dev/null +++ b/32-24 Point Poker Game/str.js @@ -0,0 +1,2 @@ +var the_string = "[1,1,1,1] [1,1,1,2] [1,1,1,3] [1,1,1,4] [1,1,1,5] [1,1,1,6] [1,1,1,7] [1,1,1,8] (1+1+1)x8 [1,1,1,9] [1,1,1,10] [1,1,1,11] (11+1)x(1+1) [1,1,1,12] (1+1)x12x1 [1,1,1,13] (13-1)x(1+1) [1,1,2,2] [1,1,2,3] [1,1,2,4] [1,1,2,5] [1,1,2,6] (1+1)x6x2 (2+1+1)x6 [1,1,2,7] (7+1)x(2+1) [1,1,2,8] (2+1)x8x1 [1,1,2,9] (9-1)x(2+1) [1,1,2,10] (10+2)x(1+1) (10+1+1)x2 [1,1,2,11] 11x2+1+1 (1+1)x11+2 (11+1)x2x1 [1,1,2,12] 12x2+1-1 12/(1-1/2) [1,1,2,13] 13x2-1-1 (1+1)x13-2 (13-1)x2x1 [1,1,3,3] [1,1,3,4] (1+1)x4x3 [1,1,3,5] (5+1)x(3+1) [1,1,3,6] (6+1+1)x3 (3+1)x6x1 [1,1,3,7] (7-1)x(3+1) (7+1)x3x1 [1,1,3,8] 8x3+1-1 [1,1,3,9] (9+3)x(1+1) (9-1)x3x1 [1,1,3,10] (10-1-1)x3 [1,1,3,11] (11+1)x(3-1) [1,1,3,12] (3-1)x12x1 [1,1,3,13] (13-1)x(3-1) [1,1,4,4] (4+1+1)x4 [1,1,4,5] (4+1)x5-1 (5+1)x4x1 [1,1,4,6] 6x4+1-1 [1,1,4,7] (7-1)x4x1 (7+1)x(4-1) [1,1,4,8] (8+4)x(1+1) (8-1-1)x4 (4-1)x8x1 [1,1,4,9] (9-1)x(4-1) [1,1,4,10] (1+1)x10+4 [1,1,4,11] [1,1,4,12] 12x4/(1+1) (4-1-1)x12 [1,1,4,13] [1,1,5,5] (5+1)x(5-1) (5x5-1)x1 [1,1,5,6] (5-1)x6x1 (6-1)x5-1 [1,1,5,7] (7+5)x(1+1) (7-1)x(5-1) [1,1,5,8] (5-1-1)x8 [1,1,5,9] [1,1,5,10] [1,1,5,11] [1,1,5,12] [1,1,5,13] [1,1,6,6] (6+6)x(1+1) (6-1-1)x6 [1,1,6,7] [1,1,6,8] 8x6/(1+1) [1,1,6,9] (1+1)x9+6 [1,1,6,10] [1,1,6,11] [1,1,6,12] (1+1)x6+12 [1,1,6,13] [1,1,7,7] [1,1,7,8] [1,1,7,9] [1,1,7,10] (1+1)x7+10 [1,1,7,11] [1,1,7,12] [1,1,7,13] [1,1,8,8] (1+1)x8+8 [1,1,8,9] [1,1,8,10] [1,1,8,11] [1,1,8,12] [1,1,8,13] [1,1,9,9] [1,1,9,10] [1,1,9,11] [1,1,9,12] [1,1,9,13] 13+9+1+1 [1,1,10,10] [1,1,10,11] [1,1,10,12] 12+10+1+1 [1,1,10,13] (13+10+1)x1 [1,1,11,11] 11+11+1+1 [1,1,11,12] (12+11+1)x1 [1,1,11,13] 13+11+1-1 [1,1,12,12] 12+12+1-1 [1,1,12,13] (13+12-1)x1 [1,1,13,13] 13+13-1-1 [1,2,2,2] [1,2,2,3] [1,2,2,4] (2+1)x4x2 [1,2,2,5] (5+1)x(2+2) (5+1)x2x2 [1,2,2,6] (6+2)x(2+1) 6x2x2x1 (2+2)x6x1 [1,2,2,7] (7-1)x(2+2) (7-1)x2x2 [1,2,2,8] (2+2-1)x8 (2x2-1)x8 [1,2,2,9] (9+2+1)x2 [1,2,2,10] (10-2)x(2+1) (10+2)x2x1 (10+1)x2+2 [1,2,2,11] (11+2-1)x2 (11x2+2)x1 [1,2,2,12] (2-1)x12x2 (12+1)x2-2 (12-1)x2+2 (2/2+1)x12 [1,2,2,13] (13+1-2)x2 (13x2-2)x1 [1,2,3,3] (3+1)x3x2 [1,2,3,4] (3+2+1)x4 4x3x2x1 (4+2)x(3+1) [1,2,3,5] (5+3)x(2+1) (5+2+1)x3 (5-1)x3x2 (3+2)x5-1 [1,2,3,6] (3+2-1)x6 (6+2)x3x1 (3-1)x6x2 [1,2,3,7] 7x3+2+1 (2+1)x7+3 (7+2-1)x3 [1,2,3,8] (2-1)x8x3 (8-2)x(3+1) (8+3+1)x2 8/(1-2/3) [1,2,3,9] 9x3-2-1 (2+1)x9-3 (9+3)x2x1 (9+1-2)x3 [1,2,3,10] 10x2+3+1 (10-2)x3x1 (10+3-1)x2 (10+2)x(3-1) [1,2,3,11] (11-3)x(2+1) (11-2-1)x3 11x2+3-1 (3-1)x11+2 [1,2,3,12] (3+1-2)x12 (3+1)x12/2 12/(3/2-1) [1,2,3,13] 13x2+1-3 (3-1)x13-2 [1,2,4,4] (4+4)x(2+1) (4+2)x4x1 (4-1)x4x2 [1,2,4,5] (5+2-1)x4 (4+2)x(5-1) [1,2,4,6] (2-1)x6x4 (6+2)x(4-1) [1,2,4,7] (7+1-2)x4 (7+4+1)x2 [1,2,4,8] (8+4)x2x1 (4+1-2)x8 (8-2)x4x1 (4/2+1)x8 [1,2,4,9] (9-2-1)x4 (9+4-1)x2 (9+1)x2+4 [1,2,4,10] (10-2)x(4-1) (10x2+4)x1 (10/2+1)x4 [1,2,4,11] (11+1)x(4-2) (11+1)x4/2 (11-1)x2+4 [1,2,4,12] (12-4)x(2+1) (2+1)x4+12 12x4x1/2 (4-2)x12x1 12/(1-2/4) [1,2,4,13] (13+1)x2-4 (13-1)x(4-2) (13-1)x4/2 [1,2,5,5] 5x5+1-2 [1,2,5,6] (5+1-2)x6 (5+1)x(6-2) (6+5+1)x2 [1,2,5,7] (7+5)x2x1 (7+1)x(5-2) (7-2)x5-1 [1,2,5,8] (5+1)x8/2 (8+5-1)x2 (8-2)x(5-1) (5-2)x8x1 [1,2,5,9] (2+1)x5+9 9x2+5+1 (9-1)x(5-2) [1,2,5,10] 10x2+5-1 10x5/2-1 [1,2,5,11] [1,2,5,12] (5-2-1)x12 (5+1)x2+12 (5-1)x12/2 [1,2,5,13] (13-5)x(2+1) 5x2+13+1 [1,2,6,6] (2+1)x6+6 (6+6)x2x1 (6-2)x6x1 (6/2+1)x6 [1,2,6,7] (7-2-1)x6 (7+6-1)x2 (7+1)x6/2 (7-1)x(6-2) [1,2,6,8] (6-2-1)x8 8x6x1/2 (8+1)x2+6 [1,2,6,9] (9-1)x6/2 (9x2+6)x1 [1,2,6,10] (2+1)x10-6 (6+1)x2+10 (10-1)x2+6 (10/2-1)x6 [1,2,6,11] 6x2+11+1 [1,2,6,12] 12x6/(2+1) (6x2+12)x1 (6/2-1)x12 [1,2,6,13] 6x2+13-1 [1,2,7,7] (7x7-1)/2 [1,2,7,8] 8x2+7+1 (7+1)x2+8 (7-1)x8/2 [1,2,7,9] 9x2+7-1 7x2+9+1 [1,2,7,10] (7x2+10)x1 [1,2,7,11] 7x2+11-1 [1,2,7,12] (7-1)x2+12 [1,2,7,13] [1,2,8,8] (8x2+8)x1 (8/2-1)x8 [1,2,8,9] 9x8/(2+1) 8x2+9-1 (9-1)x2+8 [1,2,8,10] (8-1)x2+10 [1,2,8,11] [1,2,8,12] [1,2,8,13] 13+8+2+1 [1,2,9,9] [1,2,9,10] [1,2,9,11] (2+1)x11-9 [1,2,9,12] 12+9+2+1 [1,2,9,13] (13+9+2)x1 [1,2,10,10] [1,2,10,11] 11+10+2+1 [1,2,10,12] (12+10+2)x1 [1,2,10,13] 13+10+2-1 [1,2,11,11] (11+11+2)x1 [1,2,11,12] 12+11+2-1 2/(1-11/12) [1,2,11,13] (13+11)x(2-1) [1,2,12,12] (2+1)x12-12 (12+12)x(2-1) [1,2,12,13] 13+12+1-2 2/(13/12-1) [1,2,13,13] (13+13-2)x1 [1,3,3,3] (3+3)x(3+1) (3x3-1)x3 [1,3,3,4] (4+3+1)x3 (3-1)x4x3 (3+3)x4x1 [1,3,3,5] (5+3)x3x1 (3+3)x(5-1) [1,3,3,6] (6+3-1)x3 (6+1)x3+3 [1,3,3,7] (7x3+3)x1 [1,3,3,8] (8+1)x3-3 (8-1)x3+3 [1,3,3,9] (9-3)x(3+1) (9+3)x(3-1) (3-1/3)x9 (9x3-3)x1 [1,3,3,10] (10+1-3)x3 (10-1)x3-3 [1,3,3,11] (11-3)x3x1 [1,3,3,12] (3+1)x3+12 (12-3-1)x3 (3/3+1)x12 [1,3,3,13] [1,3,4,4] (4+4)x3x1 (4+3-1)x4 [1,3,4,5] 5x4+3+1 (3+1)x5+4 (5+4-1)x3 (5+3)x(4-1) [1,3,4,6] 6/(1-3/4) [1,3,4,7] 7x4-3-1 (3+1)x7-4 7x3+4-1 (4-1)x7+3 [1,3,4,8] (3+1)x4+8 (8+1-3)x4 (8+4)x(3-1) 8/(4/3-1) [1,3,4,9] (4+1)x3+9 (9-3)x4x1 9x3+1-4 (4-1)x9-3 [1,3,4,10] (10-4)x(3+1) (10-3-1)x4 (3-1)x10+4 [1,3,4,11] (11+1-4)x3 (11-3)x(4-1) 4x3+11+1 [1,3,4,12] (12-4)x3x1 (4+1-3)x12 12x4/(3-1) (4x3+12)x1 [1,3,4,13] (13-4-1)x3 4x3+13-1 [1,3,5,5] [1,3,5,6] 6x3+5+1 (5+1)x3+6 [1,3,5,7] (7+5)x(3-1) (5+1)x(7-3) [1,3,5,8] (5+1-3)x8 5x3+8+1 (8-3)x5-1 [1,3,5,9] (9-3)x(5-1) (5x3+9)x1 (5/3+1)x9 [1,3,5,10] 10x3-5-1 5x3+10-1 [1,3,5,11] (11-5)x(3+1) (11+1)x(5-3) [1,3,5,12] (5+1)x12/3 (12+1-5)x3 (5-1)x3+12 (5-3)x12x1 [1,3,5,13] (13-5)x3x1 (13-1)x(5-3) [1,3,6,6] (6+1-3)x6 (6+6)x(3-1) (6x3+6)x1 [1,3,6,7] (7-3)x6x1 (7+1)x(6-3) 6x3+7-1 (7-1)x3+6 [1,3,6,8] (8-3-1)x6 8x6/(3-1) (6-3)x8x1 (6/3+1)x8 [1,3,6,9] (3-1)x9+6 (6-1)x3+9 (9+1)x3-6 (9-1)x(6-3) (9/3+1)x6 [1,3,6,10] (10x3-6)x1 [1,3,6,11] (11+1)x6/3 (11-1)x3-6 [1,3,6,12] (12-6)x(3+1) (6-3-1)x12 12x6x1/3 (3-1)x6+12 12/(1-3/6) [1,3,6,13] (13+1-6)x3 (13-1)x6/3 [1,3,7,7] (7-1)x(7-3) [1,3,7,8] (7-3-1)x8 3/(1-7/8) [1,3,7,9] (7+1)x9/3 [1,3,7,10] (3-1)x7+10 10x3+1-7 [1,3,7,11] [1,3,7,12] (7-1)x12/3 [1,3,7,13] 13+7+3+1 (13-7)x(3+1) [1,3,8,8] (3+1)x8-8 (3-1)x8+8 (8+1)x8/3 [1,3,8,9] 9x8x1/3 3/(9/8-1) [1,3,8,10] (10-1)x8/3 [1,3,8,11] 11x3-8-1 [1,3,8,12] 12+8+3+1 12x8/(3+1) (12/3-1)x8 [1,3,8,13] (13+8+3)x1 [1,3,9,9] (9-1)x9/3 [1,3,9,10] (10+1)x3-9 [1,3,9,11] 11+9+3+1 (11x3-9)x1 (11/3-1)x9 [1,3,9,12] (3+1)x9-12 (12-1)x3-9 (12+9+3)x1 (9/3-1)x12 [1,3,9,13] 13+9+3-1 [1,3,10,10] 10+10+3+1 [1,3,10,11] 11x3+1-10 (11+10+3)x1 [1,3,10,12] 12+10+3-1 [1,3,10,13] [1,3,11,11] 11+11+3-1 [1,3,11,12] 12x3-11-1 (11+1)x3-12 [1,3,11,13] [1,3,12,12] (12x3-12)x1 [1,3,12,13] 12x3+1-13 (13-1)x3-12 [1,3,13,13] 13+13+1-3 [1,4,4,4] (4+1)x4+4 (4+4)x(4-1) [1,4,4,5] (5x4+4)x1 [1,4,4,6] (6+1)x4-4 (6-1)x4+4 [1,4,4,7] 4x4+7+1 (7x4-4)x1 [1,4,4,8] (8-1)x4-4 (4x4+8)x1 [1,4,4,9] (9+1-4)x4 4x4+9-1 [1,4,4,10] (10-4)x4x1 [1,4,4,11] (11-4-1)x4 [1,4,4,12] (12-4)x(4-1) (4-1)x4+12 (4/4+1)x12 [1,4,4,13] [1,4,5,5] 5x4+5-1 (5-1)x5+4 [1,4,5,6] 6/(5/4-1) 4/(1-5/6) [1,4,5,7] 7x4+1-5 (5-1)x7-4 [1,4,5,8] (5+1)x(8-4) (5-1)x4+8 [1,4,5,9] (4-1)x5+9 (9-4)x5-1 [1,4,5,10] (10+1-5)x4 (10-4)x(5-1) [1,4,5,11] (11-5)x4x1 [1,4,5,12] (5+1-4)x12 (12-5-1)x4 [1,4,5,13] (13-5)x(4-1) [1,4,6,6] (4+1)x6-6 (4-1)x6+6 [1,4,6,7] (7+1-4)x6 4/(7/6-1) [1,4,6,8] (6+1-4)x8 (8-4)x6x1 8/(1-4/6) [1,4,6,9] (9-4-1)x6 [1,4,6,10] (4-1)x10-6 [1,4,6,11] (11+1-6)x4 (11+1)x(6-4) [1,4,6,12] (12-6)x4x1 12x6/(4-1) (6-4)x12x1 12/(6/4-1) (12/4+1)x6 [1,4,6,13] 13+6+4+1 (13-6-1)x4 (13-1)x(6-4) [1,4,7,7] (7+1)x(7-4) [1,4,7,8] 8x4-7-1 (7+1)x4-8 (7-1)x(8-4) (7-4)x8x1 [1,4,7,9] (9-1)x(7-4) [1,4,7,10] [1,4,7,11] (4+1)x7-11 [1,4,7,12] 12+7+4+1 (7-4-1)x12 (7+1)x12/4 (12+1-7)x4 [1,4,7,13] (13-7)x4x1 (13+7+4)x1 [1,4,8,8] (8-4-1)x8 (8x4-8)x1 (8/4+1)x8 [1,4,8,9] 9x8/(4-1) 8x4+1-9 (9-1)x4-8 [1,4,8,10] [1,4,8,11] 11+8+4+1 (11+1)x8/4 [1,4,8,12] 12x8x1/4 (8+1)x4-12 (12+8+4)x1 12/(1-4/8) [1,4,8,13] 13+8+4-1 (13+1-8)x4 (13-1)x8/4 [1,4,9,9] [1,4,9,10] 10+9+4+1 [1,4,9,11] (4-1)x11-9 9x4-11-1 (11+9+4)x1 [1,4,9,12] 12+9+4-1 (9-1)x12/4 (9x4-12)x1 [1,4,9,13] 9x4+1-13 [1,4,10,10] (10+10+4)x1 10x10/4-1 [1,4,10,11] 11+10+4-1 [1,4,10,12] 12x10/(4+1) (10-1)x4-12 4/(1-10/12) [1,4,10,13] [1,4,11,11] [1,4,11,12] [1,4,11,13] [1,4,12,12] (4-1)x12-12 (12/4-1)x12 [1,4,12,13] [1,4,13,13] [1,5,5,5] (5-1/5)x5 [1,5,5,6] 6x5-5-1 (5+1)x5-6 [1,5,5,7] [1,5,5,8] [1,5,5,9] (5+1)x(9-5) [1,5,5,10] (10-5)x5-1 [1,5,5,11] (11-5)x(5-1) [1,5,5,12] (5/5+1)x12 [1,5,5,13] 13+5+5+1 [1,5,6,6] (6x5-6)x1 [1,5,6,7] 6x5+1-7 (7-1)x5-6 [1,5,6,8] (8+1-5)x6 [1,5,6,9] (9-5)x6x1 [1,5,6,10] (5+1)x(10-6) (10-5-1)x6 [1,5,6,11] (6+1)x5-11 (11-6)x5-1 [1,5,6,12] 12+6+5+1 (5+1)x6-12 (6+1-5)x12 (12-6)x(5-1) [1,5,6,13] (13+6+5)x1 [1,5,7,7] [1,5,7,8] (7+1-5)x8 (7+1)x(8-5) [1,5,7,9] (7-1)x(9-5) [1,5,7,10] 7x5-10-1 (7/5+1)x10 [1,5,7,11] 11+7+5+1 (5+1)x(11-7) (11+1)x(7-5) (7x5-11)x1 [1,5,7,12] (7-5)x12x1 7x5+1-12 (12+7+5)x1 (12-7)x5-1 [1,5,7,13] 13+7+5-1 (13-7)x(5-1) (13-1)x(7-5) [1,5,8,8] (5-1)x8-8 (8-5)x8x1 [1,5,8,9] (9-5-1)x8 (9-1)x(8-5) 9/(1-5/8) [1,5,8,10] 10+8+5+1 (10/5+1)x8 [1,5,8,11] (8-1)x5-11 (11+8+5)x1 [1,5,8,12] (5+1)x(12-8) (8-5-1)x12 12+8+5-1 12x8/(5-1) [1,5,8,13] (13-8)x5-1 [1,5,9,9] 9+9+5+1 [1,5,9,10] (10+9+5)x1 [1,5,9,11] 11+9+5-1 [1,5,9,12] (5-1)x9-12 (9+1)x12/5 [1,5,9,13] (5+1)x(13-9) [1,5,10,10] 10+10+5-1 [1,5,10,11] (11+1)x10/5 [1,5,10,12] 12x10x1/5 12/(1-5/10) [1,5,10,13] (13-1)x10/5 [1,5,11,11] (11x11-1)/5 [1,5,11,12] (11-1)x12/5 [1,5,11,13] [1,5,12,12] 12x12/(5+1) [1,5,12,13] [1,5,13,13] [1,6,6,6] (6-1)x6-6 [1,6,6,7] [1,6,6,8] 6/(1-6/8) [1,6,6,9] (9+1-6)x6 [1,6,6,10] (10-6)x6x1 [1,6,6,11] 11+6+6+1 (11-6-1)x6 6x6-11-1 [1,6,6,12] (12+6+6)x1 (6x6-12)x1 (6/6+1)x12 [1,6,6,13] 13+6+6-1 6x6+1-13 [1,6,7,7] [1,6,7,8] [1,6,7,9] (7+1)x(9-6) [1,6,7,10] 10+7+6+1 (10+1-7)x6 (7-1)x(10-6) [1,6,7,11] (11-7)x6x1 (6-1)x7-11 (11+7+6)x1 [1,6,7,12] 12+7+6-1 (7+1-6)x12 (12-7-1)x6 (7-1)x6-12 [1,6,7,13] [1,6,8,8] (8+1-6)x8 8/(8/6-1) [1,6,8,9] 9+8+6+1 (9-6)x8x1 8/(1-6/9) [1,6,8,10] (10-6-1)x8 (10+8+6)x1 6/(10/8-1) [1,6,8,11] 11+8+6-1 (11+1-8)x6 (11+1)x(8-6) [1,6,8,12] (12-8)x6x1 (8-6)x12x1 (12/6+1)x8 [1,6,8,13] (13-8-1)x6 (13-1)x(8-6) [1,6,9,9] (9-1)x(9-6) (9+9+6)x1 [1,6,9,10] 10+9+6-1 (10/6+1)x9 [1,6,9,11] [1,6,9,12] (9-6-1)x12 (12+1-9)x6 12/(9/6-1) 6/(1-9/12) [1,6,9,13] (13-9)x6x1 [1,6,10,10] [1,6,10,11] [1,6,10,12] 12x10/(6-1) [1,6,10,13] (13+1-10)x6 [1,6,11,11] [1,6,11,12] (11+1)x12/6 [1,6,11,13] (13x11+1)/6 [1,6,12,12] 12x12x1/6 12/(1-6/12) [1,6,12,13] (13-1)x12/6 [1,6,13,13] [1,7,7,7] [1,7,7,8] [1,7,7,9] 9+7+7+1 [1,7,7,10] (7+1)x(10-7) (10+7+7)x1 [1,7,7,11] 11+7+7-1 (7-1)x(11-7) [1,7,7,12] (7/7+1)x12 [1,7,7,13] [1,7,8,8] 8+8+7+1 [1,7,8,9] (9+1-7)x8 (9+8+7)x1 [1,7,8,10] 10+8+7-1 (10-7)x8x1 [1,7,8,11] (7+1)x(11-8) (11-7-1)x8 [1,7,8,12] (8+1-7)x12 (7-1)x(12-8) [1,7,8,13] [1,7,9,9] 9+9+7-1 [1,7,9,10] (9-1)x(10-7) [1,7,9,11] (11+1)x(9-7) [1,7,9,12] (7+1)x(12-9) (9-7)x12x1 [1,7,9,13] (7-1)x(13-9) (13-1)x(9-7) [1,7,10,10] [1,7,10,11] [1,7,10,12] (10-7-1)x12 10/(1-7/12) [1,7,10,13] (7+1)x(13-10) [1,7,11,11] [1,7,11,12] [1,7,11,13] [1,7,12,12] 12x12/(7-1) [1,7,12,13] (13+1)x12/7 [1,7,13,13] (13x13-1)/7 [1,8,8,8] (8+8+8)x1 [1,8,8,9] 9+8+8-1 [1,8,8,10] (10+1-8)x8 [1,8,8,11] (11-8)x8x1 [1,8,8,12] (12-8-1)x8 (8/8+1)x12 8/(1-8/12) [1,8,8,13] [1,8,9,9] [1,8,9,10] [1,8,9,11] (11+1-9)x8 (9-1)x(11-8) 9/(11/8-1) [1,8,9,12] (12-9)x8x1 (9+1-8)x12 8/(12/9-1) [1,8,9,13] (13-9-1)x8 [1,8,10,10] [1,8,10,11] (11+1)x(10-8) [1,8,10,12] (12+1-10)x8 (10-8)x12x1 [1,8,10,13] (13-10)x8x1 (13-1)x(10-8) [1,8,11,11] [1,8,11,12] (11-8-1)x12 [1,8,11,13] (13+1-11)x8 [1,8,12,12] 12/(12/8-1) [1,8,12,13] [1,8,13,13] [1,9,9,9] [1,9,9,10] [1,9,9,11] [1,9,9,12] (9-1)x(12-9) (9/9+1)x12 [1,9,9,13] [1,9,10,10] [1,9,10,11] [1,9,10,12] (10+1-9)x12 [1,9,10,13] (9-1)x(13-10) [1,9,11,11] (11+1)x(11-9) [1,9,11,12] (11-9)x12x1 [1,9,11,13] (13-1)x(11-9) [1,9,12,12] (12-9-1)x12 [1,9,12,13] [1,9,13,13] [1,10,10,10] [1,10,10,11] [1,10,10,12] (10/10+1)x12 [1,10,10,13] [1,10,11,11] [1,10,11,12] (11+1-10)x12 (11+1)x(12-10) [1,10,11,13] [1,10,12,12] (12-10)x12x1 [1,10,12,13] (13-10-1)x12 (13-1)x(12-10) [1,10,13,13] [1,11,11,11] [1,11,11,12] (11/11+1)x12 [1,11,11,13] (11+1)x(13-11) (13/11+1)x11 [1,11,12,12] (12+1-11)x12 [1,11,12,13] (13-11)x12x1 [1,11,13,13] (13-1)x(13-11) (11/13+1)x13 [1,12,12,12] (12/12+1)x12 [1,12,12,13] (13+1-12)x12 [1,12,13,13] (13/13+1)x12 [1,13,13,13] [2,2,2,2] [2,2,2,3] (2+2)x3x2 3x2x2x2 [2,2,2,4] (4+2)x(2+2) (2+2+2)x4 (4+2)x2x2 (2x2+2)x4 [2,2,2,5] (5x2+2)x2 [2,2,2,6] [2,2,2,7] (7x2-2)x2 [2,2,2,8] (8-2)x(2+2) (8+2+2)x2 (8-2)x2x2 (2x2+8)x2 (2/2+2)x8 [2,2,2,9] (9+2)x2+2 [2,2,2,10] 10x2+2+2 10x2+2x2 [2,2,2,11] (2/2+11)x2 (11+2)x2-2 [2,2,2,12] (2+2)x12/2 (2x2-2)x12 12x2+2-2 [2,2,2,13] (13-2/2)x2 (13-2)x2+2 [2,2,3,3] (3+3)x(2+2) (3+3)x2x2 (3x2+2)x3 [2,2,3,4] (4+2+2)x3 (2x2+4)x3 [2,2,3,5] (5x2-2)x3 [2,2,3,6] (2/2+3)x6 (6-2)x3x2 (3x2-2)x6 (3x2+6)x2 [2,2,3,7] (2/2+7)x3 (7+3+2)x2 [2,2,3,8] 8x3+2-2 (8+3)x2+2 [2,2,3,9] (9-3)x(2+2) (9-3)x2x2 (9-2/2)x3 9x2+3x2 (2/3+2)x9 [2,2,3,10] (10+3)x2-2 [2,2,3,11] (11+3-2)x2 [2,2,3,12] (2+2)x3+12 (12-2-2)x3 3x2x2+12 (12-2x2)x3 (3-2/2)x12 (3-2)x12x2 12/(2-3/2) (12/2+2)x3 [2,2,3,13] (13+2-3)x2 [2,2,4,4] (4x2-2)x4 (4x2+4)x2 [2,2,4,5] 5x4+2+2 (2+2)x5+4 5x4+2x2 5x2x2+4 (2/2+5)x4 (5-2)x4x2 [2,2,4,6] 6x4+2-2 (4+2)x(6-2) (6+4+2)x2 (4-2)x6x2 (4/2+2)x6 [2,2,4,7] 7x4-2-2 (2+2)x7-4 7x4-2x2 7x2x2-4 (7-2/2)x4 (7+4)x2+2 [2,2,4,8] (2+2)x4+8 4x2x2+8 (4-2/2)x8 (4+2)x8/2 8x2+4x2 (8+2)x2+4 (8x2-4)x2 (8/2+2)x4 [2,2,4,9] 9x2+4+2 (9+4)x2-2 [2,2,4,10] (10-4)x(2+2) (10-2-2)x4 (10-4)x2x2 (10-2x2)x4 (10+4-2)x2 (10+2)x(4-2) (10+2)x4/2 (4/2+10)x2 [2,2,4,11] 11x2+4-2 (4-2)x11+2 11x4/2+2 11x2+4/2 [2,2,4,12] (4+2)x2+12 (12+2)x2-4 (12-2)x2+4 [2,2,4,13] 13x2+2-4 (4-2)x13-2 13x4/2-2 13x2-4/2 [2,2,5,5] 5x5-2/2 (5+5+2)x2 [2,2,5,6] (5-2/2)x6 (6+2)x(5-2) (6+5)x2+2 [2,2,5,7] 7x2+5x2 [2,2,5,8] (8+5)x2-2 [2,2,5,9] (9+5-2)x2 [2,2,5,10] (5+2)x2+10 (10-2)x(5-2) (2/5+2)x10 (10x5-2)/2 [2,2,5,11] (11-5)x(2+2) (11-5)x2x2 [2,2,5,12] 5x2+12+2 12/(5/2-2) [2,2,5,13] [2,2,6,6] (6+2)x6/2 6x2+6x2 [2,2,6,7] (7+2)x2+6 (7+6)x2-2 [2,2,6,8] (8-2-2)x6 (8-2x2)x6 8x2+6+2 (6+2)x2+8 (8+6-2)x2 (8-2)x(6-2) [2,2,6,9] (6/2+9)x2 (9x2-6)x2 [2,2,6,10] 6x2+10+2 10x2+6-2 (10-2)x6/2 [2,2,6,11] (11-2)x2+6 [2,2,6,12] (12-6)x(2+2) (6-2-2)x12 (12-6)x2x2 (6-2x2)x12 (6-2)x12/2 (12/2-2)x6 (12/2+6)x2 [2,2,6,13] (13+2)x2-6 [2,2,7,7] (7+7-2)x2 [2,2,7,8] (7-2-2)x8 (7-2x2)x8 7x2+8+2 [2,2,7,9] [2,2,7,10] (10/2+7)x2 [2,2,7,11] [2,2,7,12] 7x2+12-2 [2,2,7,13] 13+7+2+2 (13-7)x(2+2) 2x2+13+7 (13-7)x2x2 [2,2,8,8] (2+2)x8-8 8x2x2-8 (8-2)x8/2 (8/2+8)x2 [2,2,8,9] 9x2+8-2 [2,2,8,10] 8x2+10-2 10x2+8/2 (10x2-8)x2 (10-2)x2+8 (10/2-2)x8 [2,2,8,11] [2,2,8,12] 12+8+2+2 12x8/(2+2) 12x8/2/2 2x2+12+8 (8-2)x2+12 (8/2-2)x12 [2,2,8,13] [2,2,9,9] [2,2,9,10] (9-2)x2+10 [2,2,9,11] 11+9+2+2 2x2+11+9 [2,2,9,12] (2+2)x9-12 9x2x2-12 9x2+12/2 [2,2,9,13] [2,2,10,10] 10+10+2+2 2x2+10+10 [2,2,10,11] (11x2-10)x2 [2,2,10,12] [2,2,10,13] 2/2+13+10 [2,2,11,11] (2/11+2)x11 [2,2,11,12] 2/2+12+11 [2,2,11,13] 13+11+2-2 [2,2,12,12] 12+12+2-2 (12x2-12)x2 [2,2,12,13] 13+12-2/2 [2,2,13,13] (2-2/13)x13 [2,3,3,3] (3+3+2)x3 (3x3+3)x2 [2,3,3,4] [2,3,3,5] (5+2)x3+3 (5x3-3)x2 [2,3,3,6] 6x3+3x2 3x3x2+6 (3+3-2)x6 (3+3)x(6-2) (6+3+3)x2 [2,3,3,7] (7-3)x3x2 (7+3-2)x3 (7+2)x3-3 [2,3,3,8] (3x2-3)x8 (3-2)x8x3 (3+3)x8/2 (3/3+2)x8 [2,3,3,9] (3+2)x3+9 (9+2-3)x3 9x2+3+3 (9-2)x3+3 [2,3,3,10] 10x3-3x2 (10/2+3)x3 [2,3,3,11] (11-2)x3-3 (3/3+11)x2 [2,3,3,12] 12x2+3-3 (3+3)x2+12 [2,3,3,13] (13-3-2)x3 (13+3)x3/2 3x3+13+2 (13-3/3)x2 [2,3,4,4] (3+2)x4+4 4x4x3/2 (4-2)x4x3 [2,3,4,5] (5+3-2)x4 (5+4+3)x2 [2,3,4,6] (3-2)x6x4 6x3+4+2 (4+2)x3+6 (6-3)x4x2 (6+4-2)x3 (4/2+6)x3 6x2+4x3 (6x2-4)x3 (6/2+3)x4 [2,3,4,7] (7+2-3)x4 (4+2)x(7-3) (7+3)x2+4 [2,3,4,8] (8-4)x3x2 (4+2-3)x8 (8/2+4)x3 [2,3,4,9] 9x4x2/3 (9+3)x(4-2) (9+3)x4/2 [2,3,4,10] 10x3-4-2 (10+2-4)x3 (10-4/2)x3 4x3+10+2 (4+3)x2+10 [2,3,4,11] (11-3-2)x4 (11+4-3)x2 (11+3)x2-4 [2,3,4,12] (3x2-4)x12 (12-3x2)x4 (12+4)x3/2 (4+2)x12/3 (4-3)x12x2 (12/3+2)x4 [2,3,4,13] 4x2+13+3 (13+3-4)x2 (13-3)x2+4 [2,3,5,5] 5x5+2-3 (5+5-2)x3 (5+3)x(5-2) [2,3,5,6] 6x5-3x2 5x3x2-6 (5+2-3)x6 (5-3)x6x2 (5+3)x6/2 (6/2+5)x3 [2,3,5,7] 7x3+5-2 (5-2)x7+3 5x3+7+2 [2,3,5,8] 8x2+5+3 (5+3)x2+8 8/(2-5/3) [2,3,5,9] (9-5)x3x2 9x3+2-5 (5-2)x9-3 (9x5+3)/2 [2,3,5,10] (10+2)x(5-3) (10+5-3)x2 [2,3,5,11] (11+5)x3/2 5x2+11+3 (11+2-5)x3 (11-3)x(5-2) 11x2+5-3 5x3+11-2 (5-3)x11+2 [2,3,5,12] 12/(3-5/2) [2,3,5,13] 3x2+13+5 13x2+3-5 (5-3)x13-2 [2,3,6,6] (3+2)x6-6 6x6x2/3 (6+2)x(6-3) (6+3)x2+6 (6x3-6)x2 (6/3+2)x6 [2,3,6,7] 7x6/2+3 7x3+6/2 (7x2-6)x3 [2,3,6,8] (8+2)x3-6 6x3+8-2 (8-2)x3+6 [2,3,6,9] (9-3-2)x6 (6+2)x9/3 6x2+9+3 (9-3)x(6-2) (3-2/6)x9 9x6/2-3 9x3-6/2 (9+6-3)x2 [2,3,6,10] (10-6)x3x2 (10-3x2)x6 (10+6)x3/2 (10+2)x6/3 (10-2)x(6-3) (6/3+10)x2 [2,3,6,11] (11-3)x6/2 (11-6/2)x3 11x2+6/3 11x6/3+2 [2,3,6,12] 3x2+12+6 6x3x2-12 12x3/2+6 12x3-6x2 (12+2-6)x3 (6-2)x3+12 (12-2)x3-6 6x3+12/2 (12+3)x2-6 (12-3)x2+6 [2,3,6,13] 13+6+3+2 13x2-6/3 13x6/3-2 [2,3,7,7] 7x2+7+3 [2,3,7,8] (7+2)x8/3 (8-2)x(7-3) (8+7-3)x2 8/(7/3-2) [2,3,7,9] (9+7)x3/2 (7-2)x3+9 (7x3-9)x2 [2,3,7,10] 10x2+7-3 (10x7+2)/3 [2,3,7,11] (3+2)x7-11 3x2+11+7 (11-7)x3x2 11x3-7-2 [2,3,7,12] 12+7+3+2 (7-3-2)x12 12/(7/2-3) (7-3)x12/2 [2,3,7,13] 7x2+13-3 (13+2-7)x3 [2,3,8,8] (8-3-2)x8 (8+8)x3/2 (8x2-8)x3 [2,3,8,9] (9-3x2)x8 (9-3)x8/2 [2,3,8,10] 3x2+10+8 10x3+2-8 [2,3,8,11] 11+8+3+2 8x2+11-3 (11-2)x8/3 (11-3)x2+8 [2,3,8,12] (12-8)x3x2 (8-3x2)x12 8x3/2+12 (8-2)x12/3 (12-8/2)x3 (12/2-3)x8 (8x3-12)x2 (12/3+8)x2 [2,3,8,13] (13+3)x2-8 [2,3,9,9] 3x2+9+9 (9+2)x3-9 9x2+9-3 (9/3+9)x2 [2,3,9,10] 10+9+3+2 10x3/2+9 (9x2-10)x3 (10-2)x9/3 [2,3,9,11] [2,3,9,12] (9-3)x2+12 [2,3,9,13] (13-9)x3x2 (13-2)x3-9 (13x3+9)/2 [2,3,10,10] (10-3)x2+10 [2,3,10,11] [2,3,10,12] 12x10/(3+2) 12x3-10-2 (10+2)x3-12 10x2+12/3 (10x2-12)x3 (10/2-3)x12 10x3-12/2 [2,3,10,13] 13+10+3-2 (13-10/2)x3 [2,3,11,11] 11x3+2-11 [2,3,11,12] 12+11+3-2 [2,3,11,13] (13+11)x(3-2) [2,3,12,12] 12x12/3/2 (12+12)x(3-2) (12x3+12)/2 (12/3-2)x12 [2,3,12,13] 13+12+2-3 [2,3,13,13] 13x3-13-2 [2,4,4,4] 4x4+4x2 (4+4-2)x4 (4/2+4)x4 (4+4+4)x2 (4x4-4)x2 [2,4,4,5] (5+2)x4-4 (5x2-4)x4 (4+4)x(5-2) [2,4,4,6] (4x2-4)x6 4x4+6+2 (4+4)x6/2 (6+4)x2+4 [2,4,4,7] (7-4)x4x2 (7-2)x4+4 [2,4,4,8] (4+2)x(8-4) 8x4-4x2 4x4x2-8 (8+2-4)x4 (8+4)x(4-2) (8+4)x4/2 (8-4/2)x4 8x2+4+4 (4+4)x2+8 (4/4+2)x8 [2,4,4,9] (9-2)x4-4 [2,4,4,10] (4-2)x10+4 10x4/2+4 4x4+10-2 (10+4)x2-4 [2,4,4,11] (4/4+11)x2 (11x4+4)/2 [2,4,4,12] (12-4-2)x4 4x2+12+4 12x4/(4-2) (4-4/2)x12 12x2+4-4 [2,4,4,13] (13-4/4)x2 (13x4-4)/2 [2,4,5,5] (5+5)x2+4 [2,4,5,6] 6x5-4-2 (4+2)x5-6 5x4+6-2 (6-2)x5+4 (5+4)x2+6 [2,4,5,7] (7+5)x(4-2) (7+5)x4/2 [2,4,5,8] (8-5)x4x2 (4x2-5)x8 (5+2-4)x8 (5-4/2)x8 8x5/2+4 5x4+8/2 (5x4-8)x2 [2,4,5,9] (4+2)x(9-5) (9+2-5)x4 (9+5)x2-4 [2,4,5,10] 5x2+10+4 [2,4,5,11] 4x2+11+5 (11+5-4)x2 [2,4,5,12] (12-4)x(5-2) (5-2)x4+12 (5-4)x12x2 [2,4,5,13] 13+5+4+2 (13-5-2)x4 (13+4-5)x2 [2,4,6,6] (6+2-4)x6 (6+6)x(4-2) (6+6)x4/2 (6-4/2)x6 (6-4)x6x2 (6x2-6)x4 [2,4,6,7] (6+2)x(7-4) 7x4+2-6 (6-2)x7-4 7x2+6+4 6/(2-7/4) [2,4,6,8] 8x6/(4-2) 8x6x2/4 8x4-6-2 (6+2)x4-8 6x2+8+4 (6-2)x4+8 (8/4+2)x6 (8+6)x2-4 [2,4,6,9] (9-6)x4x2 (4-2)x9+6 9x4/2+6 9x4-6x2 (9-6/2)x4 (4/6+2)x9 6/(9/4-2) [2,4,6,10] (4+2)x(10-6) (10-4-2)x6 4x2+10+6 (10+2-6)x4 (10-4)x(6-2) (10+2)x(6-4) (10+6-4)x2 [2,4,6,11] 11x2+6-4 (6-4)x11+2 (11+4)x2-6 4/(2-11/6) [2,4,6,12] 12+6+4+2 (4+2)x6-12 (4x2-6)x12 (12-4x2)x6 (4-2)x6+12 6x4/2+12 (6+2)x12/4 (12-4)x6/2 (6x4-12)x2 12/(2-6/4) [2,4,6,13] 13x2+4-6 (6-4)x13-2 (13-4)x2+6 4/(13/6-2) [2,4,7,7] (7+7)x2-4 [2,4,7,8] (7x2-8)x4 8x7/2-4 7x4-8/2 [2,4,7,9] 4x2+9+7 (9+7-4)x2 [2,4,7,10] (10-7)x4x2 (4-2)x7+10 7x4/2+10 (10-2)x(7-4) [2,4,7,11] 11+7+4+2 (4+2)x(11-7) (11+2-7)x4 [2,4,7,12] (7+2)x4-12 12/(4-7/2) [2,4,7,13] [2,4,8,8] 4x2+8+8 (4-2)x8+8 8x4/2+8 (8-2)x(8-4) (8+8-4)x2 [2,4,8,9] (9-4-2)x8 [2,4,8,10] 10+8+4+2 10x4-8x2 (8x2-10)x4 (10-4)x8/2 (10-8/2)x4 (10+2)x8/4 10x2+8-4 8x4+2-10 (10-2)x4-8 (8/4+10)x2 (10x4+8)/2 [2,4,8,11] (11-8)x4x2 (11-4x2)x8 11x2+8/4 11x8/4+2 [2,4,8,12] (4+2)x(12-8) (8-4-2)x12 8x2+12-4 (12+2-8)x4 (8-4)x12/2 (12+4)x2-8 (12-4)x2+8 [2,4,8,13] 13x2-8/4 13x8/4-2 [2,4,9,9] 9+9+4+2 [2,4,9,10] 9x2+10-4 9x4-10-2 [2,4,9,11] [2,4,9,12] (12-9)x4x2 (9x2-12)x4 12/(9/2-4) (9x4+12)/2 (12/4+9)x2 [2,4,9,13] (4+2)x(13-9) 13+9+4-2 4/2+13+9 (13+2-9)x4 [2,4,10,10] (4/10+2)x10 [2,4,10,11] 11x4-10x2 (11-10/2)x4 (11-4)x2+10 [2,4,10,12] (10-4x2)x12 12+10+4-2 4/2+12+10 (10-2)x12/4 (10-4)x2+12 12/(10/4-2) [2,4,10,13] (13-10)x4x2 (13+4)x2-10 [2,4,11,11] 11+11+4-2 4/2+11+11 [2,4,11,12] (11-2)x4-12 [2,4,11,13] [2,4,12,12] 12x12/(4+2) 12x4-12x2 (12/2-4)x12 (12-12/2)x4 [2,4,12,13] [2,4,13,13] 13+13+2-4 13+13-4/2 [2,5,5,5] [2,5,5,6] [2,5,5,7] 7x2+5+5 [2,5,5,8] (5/5+2)x8 [2,5,5,9] 5x2+9+5 (5-2)x5+9 [2,5,5,10] (5-2/10)x5 [2,5,5,11] (5+2)x5-11 (5/5+11)x2 [2,5,5,12] 12+5+5+2 12x2+5-5 [2,5,5,13] (13-5)x(5-2) (5x5-13)x2 (13-5/5)x2 [2,5,6,6] (5x2-6)x6 (5-2)x6+6 [2,5,6,7] (7+2-5)x6 6x2+7+5 (7-5)x6x2 [2,5,6,8] 5x2+8+6 (6+2-5)x8 (6+2)x(8-5) 6x5+2-8 (8-2)x5-6 [2,5,6,9] 6x5/2+9 [2,5,6,10] (5-2)x10-6 10x6x2/5 (10+5)x2-6 (10/5+2)x6 [2,5,6,11] 11+6+5+2 (11-5-2)x6 (11-5)x(6-2) (11+6-5)x2 [2,5,6,12] 12x6/(5-2) 12x5/2-6 (5-6/2)x12 (6-5)x12x2 6x5-12/2 [2,5,6,13] (13-5)x6/2 (13+5-6)x2 [2,5,7,7] 5x2+7+7 [2,5,7,8] (5x2-7)x8 [2,5,7,9] 7x5-9-2 [2,5,7,10] 10+7+5+2 (10+2)x(7-5) (10+7-5)x2 [2,5,7,11] 11x2+7-5 (7-5)x11+2 (11x5-7)/2 [2,5,7,12] [2,5,7,13] 13x2+5-7 7x5+2-13 (7x5+13)/2 (7-5)x13-2 [2,5,8,8] 8x5-8x2 (8x5+8)/2 [2,5,8,9] 9+8+5+2 9x8/(5-2) (8-2)x(9-5) (9+8-5)x2 [2,5,8,10] (10-5-2)x8 (10-2)x(8-5) [2,5,8,11] (11-5)x8/2 (11+5)x2-8 [2,5,8,12] (5x2-8)x12 (8+2)x12/5 [2,5,8,13] (13-5x2)x8 13+8+5-2 8x2+13-5 (13+2)x8/5 (13-5)x2+8 [2,5,9,9] [2,5,9,10] 10x2+9-5 [2,5,9,11] (5-2)x11-9 9x2+11-5 (9-2)x5-11 [2,5,9,12] (9-5-2)x12 12+9+5-2 12/(5-9/2) (9-5)x12/2 [2,5,9,13] [2,5,10,10] (10+2)x10/5 (10/5+10)x2 [2,5,10,11] 11+10+5-2 11x2+10/5 11x10/5+2 [2,5,10,12] (12+5)x2-10 (12-5)x2+10 [2,5,10,13] 10x5-13x2 13x2-10/5 13x10/5-2 [2,5,11,11] [2,5,11,12] 12/(11/2-5) (11-5)x2+12 [2,5,11,13] [2,5,12,12] (12-5x2)x12 (5-2)x12-12 (12-2)x12/5 (12x5-12)/2 [2,5,12,13] 12/2+13+5 (13+5)x2-12 [2,5,13,13] [2,6,6,6] 6x2+6+6 6x6-6x2 6x6/2+6 [2,6,6,7] (7-6/2)x6 (7-2)x6-6 (7x6+6)/2 [2,6,6,8] (8-6)x6x2 (6x2-8)x6 (8+2-6)x6 (6-6/2)x8 (6/6+2)x8 [2,6,6,9] (6+2)x(9-6) (9+6)x2-6 (9x6-6)/2 [2,6,6,10] 10+6+6+2 10x6/2-6 6x6-10-2 [2,6,6,11] (6/6+11)x2 [2,6,6,12] (12-6-2)x6 (12-6)x(6-2) 12x2+6-6 (6x6+12)/2 (12/6+2)x6 [2,6,6,13] (13-6/6)x2 [2,6,7,7] [2,6,7,8] (7+2-6)x8 (8+7)x2-6 [2,6,7,9] 9+7+6+2 (9-7)x6x2 (9+2-7)x6 7x6-9x2 [2,6,7,10] (6+2)x(10-7) (7x2-10)x6 [2,6,7,11] (11+7-6)x2 [2,6,7,12] (7-6)x12x2 [2,6,7,13] 13+7+6-2 (13-7)x(6-2) (13-7-2)x6 (13+6-7)x2 [2,6,8,8] 8+8+6+2 (6-2)x8-8 (8-8/2)x6 [2,6,8,9] (6x2-9)x8 9x8x2/6 [2,6,8,10] (10-8)x6x2 (10+2-8)x6 (8-2)x(10-6) (10+2)x(8-6) (10+8-6)x2 (10+6)x2-8 8/(2-10/6) [2,6,8,11] (6+2)x(11-8) (11-6-2)x8 11x2+8-6 (8-6)x11+2 [2,6,8,12] 12+8+6-2 12x8/(6-2) (8x2-12)x6 (8-2)x6-12 (12-6)x8/2 (6-8/2)x12 8x6-12x2 [2,6,8,13] 6/2+13+8 13x2+6-8 (8-6)x13-2 [2,6,9,9] (9+9-6)x2 (6/9+2)x9 [2,6,9,10] (10-2)x(9-6) (9-10/2)x6 [2,6,9,11] (11-9)x6x2 11+9+6-2 11x6/2-9 (11+2-9)x6 [2,6,9,12] (6+2)x(12-9) (6-2)x9-12 6/2+12+9 9x2+12-6 12/(2-9/6) [2,6,9,13] [2,6,10,10] 10+10+6-2 10x2+10-6 [2,6,10,11] 6/2+11+10 (11+6)x2-10 [2,6,10,12] (10-6-2)x12 (12-10)x6x2 (6x2-10)x12 (10+2)x12/6 (12+2-10)x6 (10-6)x12/2 (10-12/2)x6 (10x6-12)/2 (12/6+10)x2 [2,6,10,13] (6+2)x(13-10) 10/2+13+6 (13-6)x2+10 [2,6,11,11] [2,6,11,12] 11x2+12/6 12/(6-11/2) 12x11/6+2 [2,6,11,13] (13-11)x6x2 (13+2-11)x6 [2,6,12,12] 12x6/2-12 12/2+12+6 (12+6)x2-12 (12-6)x2+12 [2,6,12,13] 13x2-12/6 12/(13/2-6) 13x12/6-2 [2,6,13,13] [2,7,7,7] [2,7,7,8] 8+7+7+2 (7/7+2)x8 [2,7,7,9] [2,7,7,10] (10/7+2)x7 [2,7,7,11] (7-2)x7-11 (7/7+11)x2 [2,7,7,12] 12+7+7-2 12x2+7-7 [2,7,7,13] (13-7/7)x2 [2,7,8,8] (8+2-7)x8 (7-8/2)x8 (8x7-8)/2 [2,7,8,9] (9+7)x2-8 [2,7,8,10] [2,7,8,11] (7x2-11)x8 11+8+7-2 (8-2)x(11-7) (11+8-7)x2 [2,7,8,12] (12-7-2)x8 (8-7)x12x2 [2,7,8,13] (13-7)x8/2 8/2+13+7 (13+7-8)x2 [2,7,9,9] [2,7,9,10] 10+9+7-2 (10+2)x(9-7) (10+9-7)x2 [2,7,9,11] 11x2+9-7 (9-7)x11+2 [2,7,9,12] [2,7,9,13] 9x2+13-7 13x2+7-9 (9-7)x13-2 [2,7,10,10] (10-2)x(10-7) (10+7)x2-10 [2,7,10,11] 10x7/2-11 10x2+11-7 [2,7,10,12] 12x10/(7-2) 10/2+12+7 (7-10/2)x12 [2,7,10,13] [2,7,11,11] [2,7,11,12] (11-7-2)x12 (11-7)x12/2 12/2+11+7 (11+7)x2-12 [2,7,11,13] [2,7,12,12] (7x2-12)x12 (12+2)x12/7 [2,7,12,13] 12/(7-13/2) (13-7)x2+12 [2,7,13,13] [2,8,8,8] 8x8/2-8 (8+8)x2-8 (8/8+2)x8 [2,8,8,9] (9+2-8)x8 [2,8,8,10] 10+8+8-2 (8-10/2)x8 [2,8,8,11] (8/8+11)x2 [2,8,8,12] (8-2)x(12-8) 8/2+12+8 12x2+8-8 [2,8,8,13] (13-8-2)x8 (8x2-13)x8 (13-8/8)x2 [2,8,9,9] 9+9+8-2 (9/9+2)x8 [2,8,9,10] (10+2-9)x8 (9+8)x2-10 [2,8,9,11] 8/2+11+9 (11+9-8)x2 [2,8,9,12] 9x8/2-12 (9-8)x12x2 (9-12/2)x8 (8/12+2)x9 [2,8,9,13] (8-2)x(13-9) (13+8-9)x2 9/(2-13/8) [2,8,10,10] 8/2+10+10 (10+2)x(10-8) (10+10-8)x2 (10/10+2)x8 [2,8,10,11] (11+2-10)x8 (10-2)x(11-8) 10/2+11+8 11x2+10-8 (10-8)x11+2 [2,8,10,12] 10x2+12-8 12/2+10+8 (10+8)x2-12 [2,8,10,13] 13x2+8-10 (10-8)x13-2 [2,8,11,11] (11/11+2)x8 [2,8,11,12] (12+2-11)x8 [2,8,11,13] [2,8,12,12] (12-8-2)x12 12x12/(8-2) (12-8)x12/2 (8-12/2)x12 12/(2-12/8) (12/12+2)x8 [2,8,12,13] (13+2-12)x8 [2,8,13,13] (13/13+2)x8 [2,9,9,9] [2,9,9,10] [2,9,9,11] (9/9+11)x2 [2,9,9,12] 12x2+9-9 12/2+9+9 (9+9)x2-12 [2,9,9,13] (13-9/9)x2 [2,9,10,10] 10/2+10+9 [2,9,10,11] (10+2)x(11-9) (11+10-9)x2 [2,9,10,12] (10-2)x(12-9) (10-9)x12x2 [2,9,10,13] 10x2+13-9 (13+9-10)x2 [2,9,11,11] 11x2+11-9 (11-9)x11+2 [2,9,11,12] [2,9,11,13] 13x2+9-11 (11-9)x13-2 [2,9,12,12] [2,9,12,13] (13-9-2)x12 (13-9)x12/2 [2,9,13,13] (13+9)/2+13 [2,10,10,10] [2,10,10,11] (10/10+11)x2 [2,10,10,12] (10+2)x(12-10) 12x2+10-10 [2,10,10,13] (10-2)x(13-10) (13-10/10)x2 [2,10,11,11] (11+11-10)x2 [2,10,11,12] 11x2+12-10 (11-10)x12x2 (12-10)x11+2 [2,10,11,13] (10+2)x(13-11) (13+10-11)x2 [2,10,12,12] [2,10,12,13] 13x2+10-12 (12+10)/2+13 (12-10)x13-2 [2,10,13,13] [2,11,11,11] (11/11+11)x2 [2,11,11,12] 12x2+11-11 [2,11,11,13] 11x2+13-11 (11+11)/2+13 (13-11/11)x2 (13-11)x11+2 [2,11,12,12] (12-11)x12x2 (12/12+11)x2 [2,11,12,13] (13+11-12)x2 (13+11)/2+12 [2,11,13,13] 13x2+11-13 (13-11)x13-2 (13+13)/2+11 (13/13+11)x2 [2,12,12,12] 12x2+12-12 (12+12)/2+12 [2,12,12,13] (13-12)x12x2 (13-12/12)x2 [2,12,13,13] 12x2+13-13 [2,13,13,13] (13-13/13)x2 [3,3,3,3] 3x3x3-3 [3,3,3,4] (3x3-3)x4 (4+3)x3+3 [3,3,3,5] 5x3+3x3 [3,3,3,6] 6x3+3+3 (3+3)x3+6 (3/3+3)x6 (6+3)x3-3 [3,3,3,7] (3+3)x(7-3) (3/3+7)x3 [3,3,3,8] 8x3+3-3 [3,3,3,9] (9-3/3)x3 [3,3,3,10] 10x3-3-3 (10-3)x3+3 [3,3,3,11] 11x3-3x3 [3,3,3,12] (3+3)x12/3 3x3+12+3 (3-3/3)x12 (12-3)x3-3 [3,3,3,13] [3,3,4,4] 4x3+4x3 (4x3-4)x3 [3,3,4,5] (3/3+5)x4 (5-3)x4x3 (5+4)x3-3 [3,3,4,6] 6x4+3-3 [3,3,4,7] (7-3/3)x4 (7+4-3)x3 [3,3,4,8] (3+3)x(8-4) (4-3/3)x8 (4-3)x8x3 [3,3,4,9] 4x3+9+3 (9+3-4)x3 (9/3+3)x4 [3,3,4,10] [3,3,4,11] 3x3+11+4 (11-4)x3+3 [3,3,4,12] (3+3-4)x12 (12-3-3)x4 4x3x3-12 12x3-4x3 (12/3+4)x3 [3,3,4,13] (13-4)x3-3 [3,3,5,5] 5x5-3/3 [3,3,5,6] 6x5-3-3 (3+3)x5-6 (3x3-5)x6 (5-3/3)x6 (5+3)x(6-3) 5x3+6+3 (6+5-3)x3 [3,3,5,7] (5x3-7)x3 [3,3,5,8] [3,3,5,9] (3+3)x(9-5) (5+3)x9/3 (9+3)x(5-3) (9/3+5)x3 [3,3,5,10] 3x3+10+5 (10+3-5)x3 (3-3/5)x10 [3,3,5,11] [3,3,5,12] 5x3+12-3 (12-5)x3+3 [3,3,5,13] 13+5+3+3 13x3-5x3 [3,3,6,6] (6/3+6)x3 [3,3,6,7] 7x3+6-3 (6-3)x7+3 (7+3)x3-6 [3,3,6,8] (3x3-6)x8 (6+3)x8/3 [3,3,6,9] 3x3+9+6 6x3+9-3 9x3+3-6 (6-3)x9-3 (9+3)x6/3 (9-3)x3+6 [3,3,6,10] (3+3)x(10-6) (10-3-3)x6 (6x3-10)x3 (10-6/3)x3 [3,3,6,11] 11x3-6-3 (11+3-6)x3 (11-3)x(6-3) [3,3,6,12] 12+6+3+3 (3+3)x6-12 [3,3,6,13] (13-3x3)x6 (13-3)x3-6 (13-6)x3+3 [3,3,7,7] (3/7+3)x7 [3,3,7,8] 3x3+8+7 [3,3,7,9] 7x3+9/3 (9-3)x(7-3) 9x7/3+3 [3,3,7,10] [3,3,7,11] 11+7+3+3 (3+3)x(11-7) [3,3,7,12] (3x3-7)x12 (12+3-7)x3 (7-3)x3+12 [3,3,7,13] (7x3-13)x3 [3,3,8,8] 8/(3-8/3) [3,3,8,9] (9-3-3)x8 (8+3)x3-9 (8-3)x3+9 [3,3,8,10] 10+8+3+3 8/(10/3-3) [3,3,8,11] [3,3,8,12] (3+3)x(12-8) (8-3-3)x12 (12-3x3)x8 (12-3)x8/3 [3,3,8,13] (13+3-8)x3 [3,3,9,9] 9+9+3+3 9x3-9/3 (3-3/9)x9 9x9/3-3 [3,3,9,10] 10x3+3-9 [3,3,9,11] (11-3)x9/3 (11-9/3)x3 [3,3,9,12] 12x3-9-3 (9+3)x3-12 (9-3)x12/3 [3,3,9,13] (3+3)x(13-9) [3,3,10,10] [3,3,10,11] [3,3,10,12] [3,3,10,13] 3/3+13+10 [3,3,11,11] [3,3,11,12] (11-3x3)x12 3/3+12+11 11x3+3-12 [3,3,11,13] 13+11+3-3 [3,3,12,12] 12x12/(3+3) 12+12+3-3 (12-12/3)x3 [3,3,12,13] 13+12-3/3 13x3-12-3 [3,3,13,13] [3,4,4,4] (4+3)x4-4 [3,4,4,5] (5+4-3)x4 4x4+5+3 [3,4,4,6] (6-4)x4x3 (4x3-6)x4 (4-3)x6x4 (4+4)x(6-3) (6/3+4)x4 (4/4+3)x6 [3,4,4,7] (7+3-4)x4 (4/4+7)x3 [3,4,4,8] 4x3+8+4 8x3+4-4 (8-3)x4+4 (4x4-8)x3 [3,4,4,9] 9x4-4x3 (4-4/3)x9 (4+4)x9/3 (9-4/4)x3 [3,4,4,10] (10-3)x4-4 [3,4,4,11] 4x4+11-3 [3,4,4,12] (3-4/4)x12 (12/4+3)x4 [3,4,4,13] 13+4+4+3 (13-4-3)x4 [3,4,5,5] 5x5+3-4 5x3+5+4 [3,4,5,6] (5+3-4)x6 [3,4,5,7] 4x3+7+5 (7-5)x4x3 (5+3)x(7-4) 5x4+7-3 (7-3)x5+4 (7+5-4)x3 [3,4,5,8] 8x4-5-3 (5+3)x4-8 (8+3-5)x4 (8+4)x(5-3) (5-4)x8x3 (5+4)x8/3 [3,4,5,9] (5x3-9)x4 (9+4-5)x3 [3,4,5,10] 10x4x3/5 (5-3)x10+4 [3,4,5,11] (4+3)x5-11 11x3-5-4 [3,4,5,12] 12+5+4+3 (4+3-5)x12 (5+3)x12/4 12x4/(5-3) 12x5/3+4 5x4+12/3 (5x4-12)x3 (12/4+5)x3 [3,4,5,13] (13+5)x4/3 5x3+13-4 [3,4,6,6] 4x3+6+6 6x6-4x3 (6+4)x3-6 (6+6-4)x3 [3,4,6,7] [3,4,6,8] (8-6)x4x3 (4x3-8)x6 (8+4)x6/3 (8-6/3)x4 (8/4+6)x3 [3,4,6,9] (9+3-6)x4 (9+3)x(6-4) [3,4,6,10] 6x3+10-4 10x6/3+4 (10+4-6)x3 (10-4)x3+6 [3,4,6,11] 11+6+4+3 (11-4-3)x6 6/(3-11/4) [3,4,6,12] 12x4x3/6 (12+6)x4/3 (6+3)x4-12 (6x3-12)x4 (12-4)x(6-3) (6-3)x4+12 (4-6/3)x12 [3,4,6,13] (13+3)x6/4 6/(13/4-3) [3,4,7,7] 7x3+7-4 7x4+3-7 (7-3)x7-4 (7-4)x7+3 [3,4,7,8] (7-3)x4+8 [3,4,7,9] (9-7)x4x3 9x3+4-7 (7+4)x3-9 (7-4)x9-3 [3,4,7,10] 10+7+4+3 (10+3-7)x4 (10-4)x(7-3) [3,4,7,11] (11+7)x4/3 (11-3)x(7-4) (11+4-7)x3 [3,4,7,12] 7x3+12/4 12x7/3-4 7x4-12/3 12x7/4+3 [3,4,7,13] [3,4,8,8] [3,4,8,9] 9+8+4+3 (4x3-9)x8 (9+3)x8/4 (9-3)x(8-4) [3,4,8,10] (10-4-3)x8 (10-8)x4x3 (10+8)x4/3 (10-8/4)x3 [3,4,8,11] (11+3-8)x4 8x4+3-11 (11-3)x4-8 8/(4-11/3) [3,4,8,12] 12x4/3+8 12x4-8x3 12x3-8-4 (8+4)x3-12 (12+4-8)x3 (8-4)x3+12 [3,4,8,13] (13-4)x8/3 8/(13/3-4) [3,4,9,9] (9+9)x4/3 9x4-9-3 (9-9/3)x4 (9-4)x3+9 [3,4,9,10] [3,4,9,11] (11-9)x4x3 (11x9-3)/4 [3,4,9,12] (9-4-3)x12 9x4/3+12 9x3-12/4 (12+3-9)x4 (12-4)x9/3 12x9/4-3 (3-4/12)x9 [3,4,9,13] (13+4-9)x3 [3,4,10,10] 10x3+4-10 [3,4,10,11] [3,4,10,12] (12-10)x4x3 (4x3-10)x12 (10-4)x12/3 (10-12/3)x4 12/(3-10/4) [3,4,10,13] 13+10+4-3 (13+3-10)x4 10x4-13-3 [3,4,11,11] [3,4,11,12] 12+11+4-3 (11-3)x12/4 (11-12/4)x3 [3,4,11,13] (13-11)x4x3 (13+11)x(4-3) 11x3+4-13 13x3-11-4 [3,4,12,12] (12+12)x(4-3) (12-3)x4-12 [3,4,12,13] 13+12+3-4 [3,4,13,13] [3,5,5,5] [3,5,5,6] (5+5)x3-6 (5/5+3)x6 [3,5,5,7] (7+5)x(5-3) (5/5+7)x3 [3,5,5,8] (5+3)x(8-5) 8x3+5-5 [3,5,5,9] (9-5/5)x3 (9/5+3)x5 [3,5,5,10] [3,5,5,11] 11+5+5+3 [3,5,5,12] (3-5/5)x12 [3,5,5,13] [3,5,6,6] (6+3-5)x6 (6+6)x(5-3) [3,5,6,7] (7+5)x6/3 (7+6-5)x3 [3,5,6,8] 8x6/(5-3) (5-6/3)x8 (6-5)x8x3 [3,5,6,9] (5+3)x(9-6) (5-3)x9+6 (6-3)x5+9 6x5+3-9 (9-3)x5-6 (6+5)x3-9 (9+5-6)x3 [3,5,6,10] 10+6+5+3 (10/5+6)x3 [3,5,6,11] (5x3-11)x6 6x3+11-5 (11-5)x3+6 [3,5,6,12] (5+3-6)x12 (12-5-3)x6 (5-3)x6+12 [3,5,6,13] (13-5)x(6-3) [3,5,7,7] [3,5,7,8] 7x3+8-5 7x5-8-3 (8-5)x7+3 [3,5,7,9] 9+7+5+3 9x5-7x3 (5-7/3)x9 (9+3)x(7-5) [3,5,7,10] (5+3)x(10-7) (5-3)x7+10 (10+5-7)x3 [3,5,7,11] (11-5)x(7-3) (11x7-5)/3 [3,5,7,12] (7+3)x12/5 12x3-7-5 (7+5)x3-12 [3,5,7,13] (13x5+7)/3 [3,5,8,8] 8+8+5+3 (5-3)x8+8 [3,5,8,9] 9x3+5-8 (8-5)x9-3 [3,5,8,10] [3,5,8,11] (5+3)x(11-8) (11-5-3)x8 (11-3)x(8-5) (11+5-8)x3 [3,5,8,12] (5x3-12)x8 (12+3)x8/5 [3,5,8,13] 8x5-13-3 [3,5,9,9] 9x5/3+9 (9-3)x(9-5) [3,5,9,10] (9+3)x10/5 (10-5)x3+9 [3,5,9,11] [3,5,9,12] (5+3)x(12-9) (5-9/3)x12 (12+5-9)x3 (9-5)x3+12 [3,5,9,13] 13+9+5-3 (13-5)x9/3 (13x9+3)/5 [3,5,10,10] (10-10/5)x3 [3,5,10,11] 10x3+5-11 (10-3)x5-11 [3,5,10,12] (10-5-3)x12 12+10+5-3 [3,5,10,13] (5+3)x(13-10) 13x3-10-5 (13+5-10)x3 [3,5,11,11] 11+11+5-3 [3,5,11,12] (11-5)x12/3 [3,5,11,13] [3,5,12,12] 12x5-12x3 (12x5+12)/3 [3,5,12,13] (5x3-13)x12 (13-3)x12/5 [3,5,13,13] 13+13+3-5 [3,6,6,6] (6-3)x6+6 (6+6)x6/3 (6-6/3)x6 (6/6+3)x6 [3,6,6,7] 7x6-6x3 (7+3-6)x6 (6/6+7)x3 [3,6,6,8] 8x3+6-6 (8-3)x6-6 [3,6,6,9] 9+6+6+3 9x6/3+6 6x6-9-3 (9-6/6)x3 [3,6,6,10] (6-3)x10-6 [3,6,6,11] (11x6+6)/3 [3,6,6,12] 6x3+12-6 12x6/(6-3) 6x6/3+12 12x3-6-6 (6+6)x3-12 (3-6/6)x12 (12-6)x3+6 (12/6+6)x3 [3,6,6,13] (13-6-3)x6 (13x6-6)/3 [3,6,7,7] (7+7-6)x3 (7/7+3)x6 [3,6,7,8] 8+7+6+3 (8+3-7)x6 (7-6)x8x3 [3,6,7,9] 7x3+9-6 (7-9/3)x6 (9+6-7)x3 (9-6)x7+3 [3,6,7,10] 7x6/3+10 [3,6,7,11] [3,6,7,12] (6+3-7)x12 (12-6)x(7-3) [3,6,7,13] 6x3+13-7 (13-7)x3+6 [3,6,8,8] 8x6/3+8 8x6-8x3 (8/8+3)x6 [3,6,8,9] 9x8/(6-3) (9+3-8)x6 (9+3)x(8-6) (6-9/3)x8 [3,6,8,10] (10+6-8)x3 [3,6,8,11] [3,6,8,12] (12-6-3)x8 (8-12/3)x6 [3,6,8,13] 13+8+6-3 [3,6,9,9] 9x3+6-9 (9-6)x9-3 (9/9+3)x6 [3,6,9,10] (10+3-9)x6 (9-3)x(10-6) 10x9/3-6 9x6-10x3 (6-10/3)x9 [3,6,9,11] (6-3)x11-9 (11-3)x(9-6) (11+6-9)x3 (11-6)x3+9 [3,6,9,12] 12x6x3/9 12+9+6-3 (9+3)x12/6 (9-3)x6-12 [3,6,9,13] 6/3+13+9 (13+3)x9/6 13x3-9-6 [3,6,10,10] (3-6/10)x10 (10/10+3)x6 [3,6,10,11] 11+10+6-3 (11+3-10)x6 [3,6,10,12] 6/3+12+10 10x3+6-12 10x6-12x3 (10x6+12)/3 (12+6-10)x3 (10-6)x3+12 (10-12/6)x3 [3,6,10,13] [3,6,11,11] 6/3+11+11 (11/11+3)x6 [3,6,11,12] (11-6-3)x12 (12+3-11)x6 [3,6,11,13] (13+6-11)x3 [3,6,12,12] (6-3)x12-12 (12-6)x12/3 (6-12/3)x12 (12/12+3)x6 [3,6,12,13] (13+3-12)x6 [3,6,13,13] 13+13-6/3 (13/13+3)x6 [3,7,7,7] 7+7+7+3 (7/7+7)x3 [3,7,7,8] 8x3+7-7 [3,7,7,9] (9-7/7)x3 [3,7,7,10] 7x3+10-7 (10-7)x7+3 [3,7,7,11] [3,7,7,12] (3-7/7)x12 [3,7,7,13] 13+7+7-3 (13-7)x(7-3) [3,7,8,8] (7-3)x8-8 (8-7)x8x3 (8/8+7)x3 [3,7,8,9] (9+7-8)x3 [3,7,8,10] [3,7,8,11] 7x3+11-8 (8-3)x7-11 (11-8)x7+3 [3,7,8,12] (7+3-8)x12 12+8+7-3 12x8/(7-3) (7-12/3)x8 [3,7,8,13] (13-7-3)x8 13x3-8-7 [3,7,9,9] (9+3)x(9-7) (9x7+9)/3 (9/9+7)x3 [3,7,9,10] 9x3+7-10 (10+7-9)x3 (10-7)x9-3 [3,7,9,11] 11+9+7-3 (9-3)x(11-7) [3,7,9,12] 7x3+12-9 (7-3)x9-12 (12-7)x3+9 (12-9)x7+3 [3,7,9,13] 9x7-13x3 (7-13/3)x9 [3,7,10,10] 10+10+7-3 (10/10+7)x3 [3,7,10,11] (11-3)x(10-7) (11+7-10)x3 [3,7,10,12] [3,7,10,13] 7x3+13-10 10x3+7-13 (13-10)x7+3 [3,7,11,11] (11/11+7)x3 [3,7,11,12] (11+3)x12/7 (12+7-11)x3 (11-7)x3+12 [3,7,11,13] [3,7,12,12] (12-7-3)x12 (12x7-12)/3 (12/12+7)x3 [3,7,12,13] (13-7)x12/3 12/3+13+7 (13+7-12)x3 [3,7,13,13] (13/13+7)x3 [3,8,8,8] 8x3+8-8 (8x8+8)/3 [3,8,8,9] (9-8)x8x3 (9-8/8)x3 [3,8,8,10] (10x8-8)/3 [3,8,8,11] 11+8+8-3 [3,8,8,12] 12x8/3-8 (3-8/8)x12 [3,8,8,13] [3,8,9,9] 8x3+9-9 [3,8,9,10] (10-9)x8x3 10+9+8-3 (9+3)x(10-8) [3,8,9,11] 9x3+8-11 (11-8)x9-3 [3,8,9,12] (8+3-9)x12 (9-3)x(12-8) [3,8,9,13] 9/3+13+8 (13-8)x3+9 [3,8,10,10] 8x3+10-10 [3,8,10,11] (11-10)x8x3 [3,8,10,12] 12x10/(8-3) [3,8,10,13] [3,8,11,11] 8x3+11-11 (11-3)x(11-8) [3,8,11,12] (12-11)x8x3 [3,8,11,13] [3,8,12,12] 8x3+12-12 12/3+12+8 (12-8)x3+12 [3,8,12,13] (13-8-3)x12 (13-12)x8x3 (13+3)x12/8 [3,8,13,13] 8x3+13-13 [3,9,9,9] 9+9+9-3 (9x9-9)/3 (9-9/9)x3 [3,9,9,10] (9+9-10)x3 [3,9,9,11] (9+3)x(11-9) 11x9/3-9 [3,9,9,12] 9x3+9-12 9/3+12+9 (3-9/9)x12 (12-9)x9-3 [3,9,9,13] (9-3)x(13-9) [3,9,10,10] (9-10/10)x3 [3,9,10,11] 9/3+11+10 (10+9-11)x3 [3,9,10,12] (9+3)x(12-10) (9+3-10)x12 [3,9,10,13] 9x3+10-13 (13-10)x9-3 [3,9,11,11] (3-9/11)x11 (9-11/11)x3 [3,9,11,12] (11-3)x(12-9) 12/3+11+9 (11+9-12)x3 [3,9,11,13] (9+3)x(13-11) [3,9,12,12] 12x12/(9-3) 12x9/3-12 (9-12/12)x3 [3,9,12,13] (12+9-13)x3 (13-9)x3+12 [3,9,13,13] (9-13/13)x3 [3,10,10,10] [3,10,10,11] [3,10,10,12] 12/3+10+10 (10+10-12)x3 (3-10/10)x12 [3,10,10,13] [3,10,11,11] [3,10,11,12] (10+3-11)x12 [3,10,11,13] (11-3)x(13-10) (11+10-13)x3 [3,10,12,12] [3,10,12,13] [3,10,13,13] [3,11,11,11] [3,11,11,12] (3-11/11)x12 [3,11,11,13] [3,11,12,12] (11+3-12)x12 [3,11,12,13] [3,11,13,13] [3,12,12,12] (3-12/12)x12 [3,12,12,13] (12+3-13)x12 [3,12,13,13] (3-13/13)x12 [3,13,13,13] [4,4,4,4] 4x4+4+4 [4,4,4,5] (4/4+5)x4 [4,4,4,6] 6x4+4-4 [4,4,4,7] (4+4)x(7-4) (7-4/4)x4 [4,4,4,8] 8x4-4-4 (4+4)x4-8 (4-4/4)x8 (8/4+4)x4 [4,4,4,9] (9-4)x4+4 [4,4,4,10] 10x4-4x4 (4x4-10)x4 [4,4,4,11] (11-4)x4-4 [4,4,4,12] 12+4+4+4 (4+4)x12/4 4x4+12-4 [4,4,4,13] [4,4,5,5] 5x5-4/4 (5+5-4)x4 (4/5+4)x5 [4,4,5,6] (5-4/4)x6 (5-4)x6x4 [4,4,5,7] (7+4-5)x4 [4,4,5,8] (4+4)x(8-5) (4+4-5)x8 8x5-4x4 5x4+8-4 (8-4)x5+4 [4,4,5,9] [4,4,5,10] (10-5)x4+4 (10/5+4)x4 [4,4,5,11] 11+5+4+4 11x4-5x4 [4,4,5,12] (5+4)x4-12 (12-5)x4-4 [4,4,5,13] 4x4+13-5 [4,4,6,6] [4,4,6,7] [4,4,6,8] (8+4-6)x4 (8+4)x(6-4) [4,4,6,9] (4+4)x(9-6) 9x4x4/6 [4,4,6,10] 10+6+4+4 (6-4)x10+4 [4,4,6,11] (11-6)x4+4 [4,4,6,12] (4+4-6)x12 (12-4-4)x6 (4x4-12)x6 12x4-6x4 12x4/(6-4) (12+4)x6/4 (12/6+4)x4 [4,4,6,13] (13-6)x4-4 [4,4,7,7] (4-4/7)x7 [4,4,7,8] 7x4+4-8 (8-4)x7-4 [4,4,7,9] 9+7+4+4 (9+4-7)x4 [4,4,7,10] (4+4)x(10-7) [4,4,7,11] [4,4,7,12] (12-4)x(7-4) (7-4)x4+12 (12-7)x4+4 [4,4,7,13] 13x4-7x4 [4,4,8,8] 8+8+4+4 (8+4)x8/4 (8-4)x4+8 (8-8/4)x4 [4,4,8,9] 9x4-8-4 [4,4,8,10] (10+4-8)x4 (10-4)x(8-4) 10x8/4+4 [4,4,8,11] (4+4)x(11-8) (11-4-4)x8 [4,4,8,12] 12x4x4/8 8x4+4-12 (4-8/4)x12 (12-4)x4-8 [4,4,8,13] (4x4-13)x8 (13-8)x4+4 [4,4,9,9] [4,4,9,10] [4,4,9,11] (11+4-9)x4 [4,4,9,12] (4+4)x(12-9) (9-12/4)x4 [4,4,9,13] [4,4,10,10] (10x10-4)/4 [4,4,10,11] [4,4,10,12] (10-4-4)x12 10x4-12-4 (12+4-10)x4 [4,4,10,13] (4+4)x(13-10) 4/4+13+10 [4,4,11,11] [4,4,11,12] 4/4+12+11 [4,4,11,13] 13+11+4-4 (13+4-11)x4 [4,4,12,12] 12+12+4-4 (12-4)x12/4 [4,4,12,13] 13+12-4/4 (13-4)x4-12 [4,4,13,13] [4,5,5,5] 5x5+4-5 (5/5+5)x4 [4,5,5,6] 6x4+5-5 [4,5,5,7] (7-5/5)x4 [4,5,5,8] (4-5/5)x8 [4,5,5,9] 5x4+9-5 (9-5)x5+4 [4,5,5,10] 10+5+5+4 [4,5,5,11] [4,5,5,12] [4,5,5,13] [4,5,6,6] (6-5)x6x4 (6/6+5)x4 [4,5,6,7] (7+5)x(6-4) (7+5-6)x4 [4,5,6,8] (5+4-6)x8 [4,5,6,9] 9+6+5+4 [4,5,6,10] 5x4+10-6 6x5+4-10 (10-4)x5-6 (10-6)x5+4 [4,5,6,11] (11+5)x6/4 [4,5,6,12] (6+4)x12/5 [4,5,6,13] (13-5-4)x6 [4,5,7,7] 7x5-7-4 (7/7+5)x4 [4,5,7,8] 8+7+5+4 (8+4)x(7-5) (7+5)x8/4 (8+5-7)x4 [4,5,7,9] 7x4+5-9 (7-4)x5+9 9x4-7-5 (9-5)x7-4 [4,5,7,10] (7-5)x10+4 [4,5,7,11] 5x4+11-7 (11-7)x5+4 [4,5,7,12] (5+4-7)x12 12x4/(7-5) [4,5,7,13] (13-5)x(7-4) (13x7+5)/4 [4,5,8,8] (5-8/4)x8 (8/8+5)x4 [4,5,8,9] (9+5-8)x4 (9-5)x4+8 [4,5,8,10] (8+4)x10/5 (4-8/5)x10 (8-10/5)x4 (8/10+4)x5 [4,5,8,11] (11-5)x(8-4) (11+4)x8/5 [4,5,8,12] (12-5-4)x8 5x4+12-8 8x5-12-4 (12-4)x(8-5) (8-5)x4+12 (12-8)x5+4 [4,5,8,13] 8x4+5-13 (13-5)x4-8 [4,5,9,9] (9/9+5)x4 [4,5,9,10] (10-4)x(9-5) (10+5-9)x4 [4,5,9,11] [4,5,9,12] 12x5/4+9 12x5-9x4 [4,5,9,13] 5x4+13-9 (13-9)x5+4 [4,5,10,10] 10x10/5+4 (10/10+5)x4 [4,5,10,11] 10x4-11-5 (11+5-10)x4 [4,5,10,12] 12x5x4/10 (4-10/5)x12 [4,5,10,13] 13+10+5-4 [4,5,11,11] (11-4)x5-11 (11/11+5)x4 [4,5,11,12] (11-5-4)x12 12+11+5-4 (12+5-11)x4 [4,5,11,13] (13+11)x(5-4) [4,5,12,12] (12+12)x(5-4) (5-12/4)x12 (12/12+5)x4 [4,5,12,13] 13+12+4-5 (13-5)x12/4 (13+5-12)x4 [4,5,13,13] (13/13+5)x4 [4,6,6,6] 6x4+6-6 (6+6)x(6-4) [4,6,6,7] (7-6)x6x4 (7-4)x6+6 (7-6/6)x4 [4,6,6,8] 8+6+6+4 8x6-6x4 8x6/(6-4) 6x6-8-4 (6+6)x8/4 (6-8/4)x6 (4-6/6)x8 [4,6,6,9] (6-4)x9+6 9x4-6-6 (9-4)x6-6 [4,6,6,10] (10+6)x6/4 [4,6,6,11] [4,6,6,12] (6-4)x6+12 12x6/4+6 [4,6,6,13] [4,6,7,7] 7+7+6+4 6x4+7-7 [4,6,7,8] (6+4-7)x8 (8-7)x6x4 [4,6,7,9] (9+7)x6/4 [4,6,7,10] (6-4)x7+10 7x4+6-10 (7-4)x10-6 (10-6)x7-4 [4,6,7,11] [4,6,7,12] 12x6/(7-4) (7-12/4)x6 [4,6,7,13] [4,6,8,8] 6x4+8-8 (6-4)x8+8 (8+8)x6/4 (8+4)x(8-6) [4,6,8,9] (9-8)x6x4 9x8/4+6 (4-8/6)x9 [4,6,8,10] (8-6)x10+4 (10-6)x4+8 [4,6,8,11] [4,6,8,12] (6+4-8)x12 8x6/4+12 (8+4)x12/6 (12-6)x(8-4) 12x4/(8-6) (6-12/4)x8 (8-12/6)x4 [4,6,8,13] (13-6-4)x8 [4,6,9,9] 6x4+9-9 [4,6,9,10] (10-9)x6x4 10x6/4+9 10x6-9x4 (10x9+6)/4 [4,6,9,11] [4,6,9,12] (12+4)x9/6 (12-4)x(9-6) (9-6)x4+12 [4,6,9,13] 13+9+6-4 [4,6,10,10] 6x4+10-10 10x4-10-6 (10-4)x(10-6) [4,6,10,11] (11-10)x6x4 [4,6,10,12] 12+10+6-4 (10-4)x6-12 12x10/4-6 12x10/6+4 [4,6,10,13] [4,6,11,11] 6x4+11-11 11+11+6-4 [4,6,11,12] (12-11)x6x4 [4,6,11,13] [4,6,12,12] (12-6-4)x12 6x4+12-12 12x6-12x4 (4-12/6)x12 [4,6,12,13] (13-12)x6x4 [4,6,13,13] 6x4+13-13 13+13+4-6 [4,7,7,7] (7-7/7)x4 [4,7,7,8] (7+7-8)x4 (4-7/7)x8 [4,7,7,9] [4,7,7,10] [4,7,7,11] 7x4+7-11 (11-7)x7-4 [4,7,7,12] [4,7,7,13] [4,7,8,8] (7+4-8)x8 8x7-8x4 (7-8/8)x4 [4,7,8,9] 9x8/(7-4) (8+4)x(9-7) (8+7-9)x4 [4,7,8,10] 8x7/4+10 [4,7,8,11] (11-7)x4+8 [4,7,8,12] 7x4+8-12 (12-8)x7-4 [4,7,8,13] 13+8+7-4 (13-7)x(8-4) [4,7,9,9] (7-9/9)x4 [4,7,9,10] 10x4-9-7 (9+7-10)x4 (9-7)x10+4 [4,7,9,11] (7-4)x11-9 (9-4)x7-11 [4,7,9,12] (7+4-9)x12 12+9+7-4 12x4/(9-7) [4,7,9,13] 7x4+9-13 (13-9)x7-4 [4,7,10,10] (7-10/10)x4 [4,7,10,11] 11+10+7-4 (10-4)x(11-7) (10+7-11)x4 [4,7,10,12] (10+4)x12/7 (12-4)x(10-7) (10-7)x4+12 [4,7,10,13] [4,7,11,11] (7-11/11)x4 [4,7,11,12] (11+7-12)x4 [4,7,11,13] 11x4-13-7 [4,7,12,12] (7-4)x12-12 (12x7+12)/4 (7-12/12)x4 [4,7,12,13] (13-7-4)x12 (12+7-13)x4 [4,7,13,13] (7-13/13)x4 [4,8,8,8] (8-4)x8-8 8x8/4+8 (4-8/8)x8 [4,8,8,9] (8+4-9)x8 [4,8,8,10] (8+4)x(10-8) 10x4-8-8 8x8-10x4 (8+8-10)x4 [4,8,8,11] (11x8+8)/4 [4,8,8,12] 12+8+8-4 12x8/(8-4) (12-8)x4+8 [4,8,8,13] (13x8-8)/4 [4,8,9,9] (4-9/9)x8 [4,8,9,10] (9+4-10)x8 [4,8,9,11] (8+4)x(11-9) 11+9+8-4 (9+8-11)x4 [4,8,9,12] 9x8x4/12 (8-4)x9-12 9x8-12x4 [4,8,9,13] 8/4+13+9 (13-9)x4+8 [4,8,10,10] 10+10+8-4 (10-8)x10+4 (4-10/10)x8 [4,8,10,11] (10+4-11)x8 [4,8,10,12] (8+4)x(12-10) (8+4-10)x12 8/4+12+10 (10-4)x(12-8) 12x4/(10-8) (10+8-12)x4 [4,8,10,13] [4,8,11,11] 8/4+11+11 (4-11/11)x8 [4,8,11,12] (11+4-12)x8 11x4-12-8 (12-4)x(11-8) (11-8)x4+12 [4,8,11,13] (8+4)x(13-11) (11+8-13)x4 [4,8,12,12] (12+4)x12/8 (4-12/12)x8 [4,8,12,13] (12+4-13)x8 12/4+13+8 [4,8,13,13] 13+13-8/4 (4-13/13)x8 [4,9,9,9] [4,9,9,10] 10+9+9-4 [4,9,9,11] [4,9,9,12] (9+9-12)x4 (4-12/9)x9 [4,9,9,13] [4,9,10,10] [4,9,10,11] (11-9)x10+4 [4,9,10,12] 12x10/(9-4) [4,9,10,13] (10-4)x(13-9) (10+9-13)x4 [4,9,11,11] 11x4-11-9 [4,9,11,12] (9+4-11)x12 12x11/4-9 12x4/(11-9) [4,9,11,13] [4,9,12,12] (12-4)x(12-9) 12/4+12+9 (12x9-12)/4 (12-9)x4+12 [4,9,12,13] [4,9,13,13] [4,10,10,10] [4,10,10,11] 11x4-10-10 [4,10,10,12] (12-10)x10+4 [4,10,10,13] [4,10,11,11] [4,10,11,12] 12/4+11+10 [4,10,11,13] (13-11)x10+4 [4,10,12,12] (10+4-12)x12 12x12/(10-4) 12x4/(12-10) [4,10,12,13] (12-4)x(13-10) (13-10)x4+12 [4,10,13,13] [4,11,11,11] [4,11,11,12] [4,11,11,13] [4,11,12,12] [4,11,12,13] (11+4-13)x12 12x4-13-11 12x4/(13-11) [4,11,13,13] [4,12,12,12] 12x4-12-12 12x12/4-12 [4,12,12,13] [4,12,13,13] [4,13,13,13] [5,5,5,5] 5x5-5/5 [5,5,5,6] 5x5+5-6 (5-5/5)x6 [5,5,5,7] [5,5,5,8] [5,5,5,9] 9+5+5+5 [5,5,5,10] [5,5,5,11] [5,5,5,12] (5+5)x12/5 [5,5,5,13] [5,5,6,6] (5+5-6)x6 5x5-6/6 (6-6/5)x5 [5,5,6,7] 5x5+6-7 7x5-6-5 [5,5,6,8] 8+6+5+5 [5,5,6,9] [5,5,6,10] [5,5,6,11] 6x5+5-11 (11-5)x5-6 [5,5,6,12] [5,5,6,13] [5,5,7,7] 7+7+5+5 7x7-5x5 5x5-7/7 (7+5)x(7-5) [5,5,7,8] (5+5-7)x8 5x5+7-8 [5,5,7,9] [5,5,7,10] (7+5)x10/5 [5,5,7,11] (7-11/5)x5 [5,5,7,12] [5,5,7,13] [5,5,8,8] 5x5-8/8 [5,5,8,9] 5x5+8-9 (8-5)x5+9 [5,5,8,10] (10+5)x8/5 (5-10/5)x8 [5,5,8,11] 8x5-11-5 [5,5,8,12] (5+5-8)x12 [5,5,8,13] (13-5-5)x8 (13-5)x(8-5) [5,5,9,9] 5x5-9/9 [5,5,9,10] 5x5+9-10 [5,5,9,11] (11-5)x(9-5) [5,5,9,12] [5,5,9,13] [5,5,10,10] 5x5-10/10 [5,5,10,11] 5x5+10-11 [5,5,10,12] [5,5,10,13] 5/5+13+10 (5-13/5)x10 [5,5,11,11] 5x5-11/11 [5,5,11,12] 5x5+11-12 5/5+12+11 (12-5)x5-11 [5,5,11,13] 13+11+5-5 [5,5,12,12] (12-5-5)x12 5x5-12/12 12+12+5-5 [5,5,12,13] 5x5+12-13 13+12-5/5 [5,5,13,13] 5x5-13/13 [5,6,6,6] (5-6/6)x6 [5,6,6,7] 7+6+6+5 (6+5-7)x6 6x6-7-5 (6+6)x(7-5) [5,6,6,8] (8-5)x6+6 [5,6,6,9] 9x6-6x5 [5,6,6,10] (10-5)x6-6 (6+6)x10/5 (6-10/5)x6 [5,6,6,11] [5,6,6,12] 6x5+6-12 12x5-6x6 (12-6)x5-6 [5,6,6,13] [5,6,7,7] (5-7/7)x6 [5,6,7,8] (7+5)x(8-6) (7+5-8)x6 8x6/(7-5) [5,6,7,9] (7-5)x9+6 [5,6,7,10] [5,6,7,11] [5,6,7,12] (7+5)x12/6 (7-5)x6+12 [5,6,7,13] 6x5+7-13 (13+7)x6/5 7x6-13-5 (13-7)x5-6 [5,6,8,8] (6+5-8)x8 (5-8/8)x6 [5,6,8,9] (8+5-9)x6 (9+6)x8/5 [5,6,8,10] 8x6x5/10 8x5-10-6 (8-5)x10-6 [5,6,8,11] [5,6,8,12] (12+8)x6/5 12x6/(8-5) (5-12/6)x8 [5,6,8,13] (13+5)x8/6 [5,6,9,9] (9-6)x5+9 (5-9/9)x6 [5,6,9,10] (9+5-10)x6 10x9/5+6 [5,6,9,11] (11+9)x6/5 (11+5)x9/6 [5,6,9,12] (6+5-9)x12 (12-6)x(9-5) [5,6,9,13] (13-5)x(9-6) [5,6,10,10] (10+10)x6/5 (5-10/10)x6 [5,6,10,11] (10+5-11)x6 (11-5)x(10-6) [5,6,10,12] 10x6/5+12 (6-12/10)x5 [5,6,10,13] 13+10+6-5 [5,6,11,11] (5-11/11)x6 [5,6,11,12] 12+11+6-5 (11+5-12)x6 (11-5)x6-12 [5,6,11,13] (13+11)x(6-5) (13-6)x5-11 [5,6,12,12] (12+12)x(6-5) (5-12/12)x6 [5,6,12,13] (13-6-5)x12 13+12+5-6 (12+5-13)x6 [5,6,13,13] (5-13/13)x6 [5,7,7,7] [5,7,7,8] [5,7,7,9] (7+5)x(9-7) [5,7,7,10] (7-5)x7+10 [5,7,7,11] (5-11/7)x7 [5,7,7,12] [5,7,7,13] [5,7,8,8] (7-5)x8+8 (8+7)x8/5 [5,7,8,9] (7+5-9)x8 8x5-9-7 [5,7,8,10] (7+5)x(10-8) [5,7,8,11] [5,7,8,12] [5,7,8,13] [5,7,9,9] [5,7,9,10] (10-7)x5+9 [5,7,9,11] (7+5)x(11-9) [5,7,9,12] (9+5)x12/7 [5,7,9,13] 13+9+7-5 (13-7)x(9-5) [5,7,10,10] 10x7/5+10 [5,7,10,11] (10-5)x7-11 [5,7,10,12] (7+5)x(12-10) (7+5-10)x12 12+10+7-5 [5,7,10,13] (13-5)x(10-7) [5,7,11,11] 11+11+7-5 (11-5)x(11-7) [5,7,11,12] [5,7,11,13] (7+5)x(13-11) [5,7,12,12] 12x7-12x5 [5,7,12,13] [5,7,13,13] 13+13+5-7 [5,8,8,8] 8x5-8-8 8x8-8x5 [5,8,8,9] 9x8/(8-5) (9-5)x8-8 [5,8,8,10] (8+5-10)x8 10x8/5+8 [5,8,8,11] [5,8,8,12] [5,8,8,13] 13+8+8-5 [5,8,9,9] [5,8,9,10] [5,8,9,11] (8-5)x11-9 (9+5-11)x8 (11-8)x5+9 [5,8,9,12] 12+9+8-5 12x8/(9-5) [5,8,9,13] 9x5-13-8 [5,8,10,10] [5,8,10,11] 11+10+8-5 [5,8,10,12] (10+5-12)x8 [5,8,10,13] [5,8,11,11] [5,8,11,12] (8+5-11)x12 (11+5)x12/8 (11-5)x(12-8) [5,8,11,13] (11+5-13)x8 (13-5)x(11-8) [5,8,12,12] (8-5)x12-12 [5,8,12,13] [5,8,13,13] [5,9,9,9] [5,9,9,10] [5,9,9,11] 11+9+9-5 [5,9,9,12] 9x5-12-9 (9-5)x9-12 (12-9)x5+9 [5,9,9,13] [5,9,10,10] 10+10+9-5 [5,9,10,11] 9x5-11-10 [5,9,10,12] [5,9,10,13] 10/5+13+9 (13-10)x5+9 [5,9,11,11] [5,9,11,12] [5,9,11,13] (11-5)x(13-9) [5,9,12,12] (9+5-12)x12 (12x9+12)/5 [5,9,12,13] (13+5)x12/9 (13-5)x(12-9) [5,9,13,13] [5,10,10,10] [5,10,10,11] (11x10+10)/5 [5,10,10,12] 12x10/(10-5) 10/5+12+10 [5,10,10,13] (13x10-10)/5 [5,10,11,11] 10/5+11+11 [5,10,11,12] [5,10,11,13] [5,10,12,12] [5,10,12,13] (10+5-13)x12 [5,10,13,13] 10x5-13-13 13+13-10/5 (13-5)x(13-10) [5,11,11,11] [5,11,11,12] [5,11,11,13] [5,11,12,12] 12x12/(11-5) (12x11-12)/5 [5,11,12,13] [5,11,13,13] [5,12,12,12] [5,12,12,13] [5,12,13,13] [5,13,13,13] [6,6,6,6] 6+6+6+6 6x6-6-6 [6,6,6,7] [6,6,6,8] (6+6)x(8-6) (6+6-8)x6 [6,6,6,9] 6x6x6/9 (9-6)x6+6 [6,6,6,10] 10x6-6x6 [6,6,6,11] (11-6)x6-6 [6,6,6,12] (6+6)x12/6 (6-12/6)x6 [6,6,6,13] [6,6,7,7] [6,6,7,8] [6,6,7,9] (6+6)x(9-7) (7+6-9)x6 [6,6,7,10] (10-7)x6+6 [6,6,7,11] 11x6-7x6 [6,6,7,12] 7x6-12-6 (12-7)x6-6 [6,6,7,13] [6,6,8,8] 8x6/(8-6) [6,6,8,9] (6+6-9)x8 (8-6)x9+6 [6,6,8,10] (6+6)x(10-8) (8+6-10)x6 [6,6,8,11] (11-8)x6+6 [6,6,8,12] 8x6x6/12 12x6-8x6 (8-6)x6+12 (12+6)x8/6 [6,6,8,13] (13-8)x6-6 [6,6,9,9] [6,6,9,10] (9-6)x10-6 (10+6)x9/6 [6,6,9,11] (6+6)x(11-9) (9+6-11)x6 [6,6,9,12] 12x6/(9-6) 12x9/6+6 (12-9)x6+6 [6,6,9,13] 13x6-9x6 [6,6,10,10] [6,6,10,11] [6,6,10,12] (6+6)x(12-10) (6+6-10)x12 (10+6-12)x6 (12-6)x(10-6) [6,6,10,13] 6/6+13+10 (13-10)x6+6 [6,6,11,11] [6,6,11,12] 6/6+12+11 [6,6,11,13] (6+6)x(13-11) 13+11+6-6 (11+6-13)x6 [6,6,12,12] 12+12+6-6 (12-6)x6-12 [6,6,12,13] 13+12-6/6 [6,6,13,13] [6,7,7,7] [6,7,7,8] [6,7,7,9] [6,7,7,10] (7+7-10)x6 [6,7,7,11] 7x6-11-7 [6,7,7,12] [6,7,7,13] [6,7,8,8] [6,7,8,9] 8x6/(9-7) [6,7,8,10] (7+6-10)x8 7x6-10-8 (8-6)x7+10 [6,7,8,11] (11+7)x8/6 (8+7-11)x6 [6,7,8,12] (8+6)x12/7 [6,7,8,13] [6,7,9,9] 7x6-9-9 (9+7)x9/6 (9-7)x9+6 [6,7,9,10] [6,7,9,11] [6,7,9,12] (9+7-12)x6 (9-7)x6+12 [6,7,9,13] [6,7,10,10] (10-7)x10-6 [6,7,10,11] [6,7,10,12] 12x7/6+10 12x7-10x6 12x6/(10-7) [6,7,10,13] 13+10+7-6 (13-7)x(10-6) (10+7-13)x6 [6,7,11,11] (11-6)x7-11 [6,7,11,12] (7+6-11)x12 12+11+7-6 (12-6)x(11-7) [6,7,11,13] (13+11)x(7-6) [6,7,12,12] (12+12)x(7-6) [6,7,12,13] 13+12+6-7 (13-7)x6-12 [6,7,13,13] [6,8,8,8] (8-6)x8+8 [6,8,8,9] 9x8-8x6 (8+8)x9/6 [6,8,8,10] 8x6/(10-8) (10+8)x8/6 (10-6)x8-8 [6,8,8,11] (8+6-11)x8 [6,8,8,12] 12x8/6+8 (8+8-12)x6 [6,8,8,13] [6,8,9,9] (9+9)x8/6 9x8/(9-6) [6,8,9,10] (10-8)x9+6 [6,8,9,11] 8x6/(11-9) [6,8,9,12] 9x8/6+12 (9+6-12)x8 [6,8,9,13] 13+9+8-6 (9+8-13)x6 [6,8,10,10] [6,8,10,11] (11-8)x10-6 [6,8,10,12] 8x6/(12-10) 12+10+8-6 (10+6)x12/8 12x8/(10-6) (10-8)x6+12 [6,8,10,13] (10+6-13)x8 [6,8,11,11] 11+11+8-6 [6,8,11,12] 12x6/(11-8) [6,8,11,13] 8x6-13-11 8x6/(13-11) [6,8,12,12] (8+6-12)x12 8x6-12-12 12x8-12x6 (12-6)x(12-8) 12x12/8+6 [6,8,12,13] [6,8,13,13] 13+13+6-8 [6,9,9,9] [6,9,9,10] 10x9/6+9 [6,9,9,11] (9-6)x11-9 (11-9)x9+6 [6,9,9,12] 12+9+9-6 [6,9,9,13] [6,9,10,10] [6,9,10,11] 11+10+9-6 10x9-11x6 [6,9,10,12] (10-6)x9-12 (12-9)x10-6 (12-10)x9+6 [6,9,10,13] [6,9,11,11] [6,9,11,12] (11-9)x6+12 [6,9,11,13] (13-11)x9+6 [6,9,12,12] (9-6)x12-12 (12+6)x12/9 12x6/(12-9) [6,9,12,13] (9+6-13)x12 (12-6)x(13-9) 12/6+13+9 [6,9,13,13] [6,10,10,10] 10+10+10-6 [6,10,10,11] [6,10,10,12] [6,10,10,13] (13-10)x10-6 [6,10,11,11] [6,10,11,12] 12x10/(11-6) [6,10,11,13] [6,10,12,12] 12/6+12+10 (12-10)x6+12 [6,10,12,13] 12x6/(13-10) [6,10,13,13] [6,11,11,11] [6,11,11,12] 12/6+11+11 [6,11,11,13] [6,11,12,12] (12x11+12)/6 [6,11,12,13] (13-11)x6+12 [6,11,13,13] [6,12,12,12] 12x12/(12-6) [6,12,12,13] (13x12-12)/6 [6,12,13,13] 13+13-12/6 [6,13,13,13] [7,7,7,7] [7,7,7,8] [7,7,7,9] [7,7,7,10] [7,7,7,11] [7,7,7,12] (7+7)x12/7 [7,7,7,13] [7,7,8,8] [7,7,8,9] [7,7,8,10] [7,7,8,11] (7+7-11)x8 [7,7,8,12] [7,7,8,13] [7,7,9,9] [7,7,9,10] (9-7)x7+10 [7,7,9,11] [7,7,9,12] [7,7,9,13] [7,7,10,10] [7,7,10,11] [7,7,10,12] [7,7,10,13] 7/7+13+10 [7,7,11,11] [7,7,11,12] 7/7+12+11 (12-7)x7-11 [7,7,11,13] 13+11+7-7 (13-7)x(11-7) [7,7,12,12] (7+7-12)x12 12+12+7-7 [7,7,12,13] 7x7-13-12 13+12-7/7 [7,7,13,13] [7,8,8,8] [7,8,8,9] (9-7)x8+8 [7,8,8,10] 10x8-8x7 [7,8,8,11] (11-7)x8-8 [7,8,8,12] (8+7-12)x8 [7,8,8,13] (13+8)x8/7 [7,8,9,9] [7,8,9,10] 9x8/(10-7) [7,8,9,11] [7,8,9,12] (12+9)x8/7 (9+7)x12/8 [7,8,9,13] (9+7-13)x8 [7,8,10,10] (10-8)x7+10 [7,8,10,11] (11+10)x8/7 [7,8,10,12] [7,8,10,13] 13+10+8-7 [7,8,11,11] [7,8,11,12] 12+11+8-7 12x8/(11-7) [7,8,11,13] (13+11)x(8-7) (13-8)x7-11 [7,8,12,12] (12+12)x(8-7) [7,8,12,13] (8+7-13)x12 13+12+7-8 (13-7)x(12-8) [7,8,13,13] [7,9,9,9] [7,9,9,10] [7,9,9,11] [7,9,9,12] [7,9,9,13] 13+9+9-7 [7,9,10,10] [7,9,10,11] (10-7)x11-9 (11-9)x7+10 [7,9,10,12] 12+10+9-7 [7,9,10,13] [7,9,11,11] 11+11+9-7 [7,9,11,12] (11+7)x12/9 (11-7)x9-12 [7,9,11,13] [7,9,12,12] 12x9-12x7 [7,9,12,13] [7,9,13,13] 13+13+7-9 (13-7)x(13-9) [7,10,10,10] [7,10,10,11] 11+10+10-7 [7,10,10,12] (12-10)x7+10 [7,10,10,13] [7,10,11,11] [7,10,11,12] [7,10,11,13] (13-11)x7+10 [7,10,12,12] (10-7)x12-12 12x10/(12-7) [7,10,12,13] (13+7)x12/10 [7,10,13,13] [7,11,11,11] [7,11,11,12] [7,11,11,13] [7,11,12,12] [7,11,12,13] [7,11,13,13] [7,12,12,12] [7,12,12,13] 12x12/(13-7) (13x12+12)/7 [7,12,13,13] [7,13,13,13] [8,8,8,8] [8,8,8,9] [8,8,8,10] (10-8)x8+8 [8,8,8,11] 11x8-8x8 [8,8,8,12] (8+8)x12/8 (12-8)x8-8 [8,8,8,13] (8+8-13)x8 [8,8,9,9] [8,8,9,10] [8,8,9,11] 9x8/(11-8) (11-9)x8+8 [8,8,9,12] 12x8-9x8 [8,8,9,13] (13-9)x8-8 [8,8,10,10] [8,8,10,11] [8,8,10,12] (12-10)x8+8 [8,8,10,13] 8/8+13+10 13x8-10x8 [8,8,11,11] [8,8,11,12] 8/8+12+11 [8,8,11,13] 13+11+8-8 (13-11)x8+8 [8,8,12,12] 12+12+8-8 12x8/(12-8) [8,8,12,13] 13+12-8/8 [8,8,13,13] [8,9,9,9] [8,9,9,10] [8,9,9,11] [8,9,9,12] 9x8/(12-9) [8,9,9,13] [8,9,10,10] [8,9,10,11] [8,9,10,12] (10+8)x12/9 12x10/8+9 [8,9,10,13] 9x8/(13-10) 13+10+9-8 [8,9,11,11] (11-8)x11-9 [8,9,11,12] 12+11+9-8 [8,9,11,13] (13+11)x(9-8) [8,9,12,12] (12+12)x(9-8) (12-8)x9-12 12x12/9+8 [8,9,12,13] 13+12+8-9 12x8/(13-9) [8,9,13,13] [8,10,10,10] [8,10,10,11] [8,10,10,12] 12+10+10-8 [8,10,10,13] [8,10,11,11] 11+11+10-8 [8,10,11,12] [8,10,11,13] [8,10,12,12] (12+8)x12/10 12x10-12x8 [8,10,12,13] 12x10/(13-8) [8,10,13,13] 13+13+8-10 [8,11,11,11] [8,11,11,12] [8,11,11,13] [8,11,12,12] (11-8)x12-12 [8,11,12,13] [8,11,13,13] [8,12,12,12] [8,12,12,13] [8,12,13,13] [8,13,13,13] [9,9,9,9] [9,9,9,10] [9,9,9,11] [9,9,9,12] (9+9)x12/9 [9,9,9,13] [9,9,10,10] [9,9,10,11] [9,9,10,12] [9,9,10,13] 9/9+13+10 [9,9,11,11] [9,9,11,12] 9/9+12+11 (12-9)x11-9 [9,9,11,13] 13+11+9-9 [9,9,12,12] 12+12+9-9 [9,9,12,13] 13+12-9/9 (13-9)x9-12 [9,9,13,13] [9,10,10,10] [9,10,10,11] [9,10,10,12] [9,10,10,13] 13+10+10-9 [9,10,11,11] [9,10,11,12] 12+11+10-9 (11+9)x12/10 [9,10,11,13] (13+11)x(10-9) (13-10)x11-9 [9,10,12,12] (12+12)x(10-9) [9,10,12,13] 13+12+9-10 [9,10,13,13] [9,11,11,11] 11+11+11-9 [9,11,11,12] [9,11,11,13] [9,11,12,12] 12x11-12x9 [9,11,12,13] (13+9)x12/11 [9,11,13,13] 13+13+9-11 [9,12,12,12] (12-9)x12-12 [9,12,12,13] [9,12,13,13] [9,13,13,13] [10,10,10,10] [10,10,10,11] [10,10,10,12] (10+10)x12/10 [10,10,10,13] 10/10+13+10 [10,10,11,11] [10,10,11,12] 10/10+12+11 [10,10,11,13] 13+11+10-10 [10,10,12,12] 12+12+10-10 [10,10,12,13] 13+12-10/10 [10,10,13,13] [10,11,11,11] [10,11,11,12] 12+11+11-10 [10,11,11,13] (13+11)x(11-10) 11/11+13+10 [10,11,12,12] (12+12)x(11-10) (12+10)x12/11 [10,11,12,13] 13+12+10-11 [10,11,13,13] [10,12,12,12] 12x12-12x10 [10,12,12,13] 12/12+13+10 (13-10)x12-12 [10,12,13,13] 13+13+10-12 [10,13,13,13] 13/13+13+10 [11,11,11,11] [11,11,11,12] (11+11)x12/11 11/11+12+11 [11,11,11,13] 13+11+11-11 [11,11,12,12] 12+12+11-11 [11,11,12,13] 13+12-11/11 (13+11)x(12-11) [11,11,13,13] [11,12,12,12] 12/12+12+11 (12+12)x(12-11) [11,12,12,13] 13+12+11-12 13x12-12x11 [11,12,13,13] 13/13+12+11 (13+11)x(13-12) [11,13,13,13] 13+13+11-13 [12,12,12,12] 12+12+12-12 [12,12,12,13] (12+12)x(13-12) 13+12-12/12 [12,12,13,13] 13+12+12-13 [12,13,13,13] 13+12-13/13 (13+13)x12/13 [13,13,13,13] ["; +var the_location = [78, 120, 144, 166, 229, 259, 281, 301, 324, 359, 401, 432, 483, 503, 525, 555, 587, 605, 638, 660, 684, 706, 729, 749, 779, 797, 829, 871, 894, 927, 970, 1002, 1032, 1066, 1140, 1182, 1202, 1245, 1308, 1362, 1480, 1525, 1547, 1571, 1593, 1617, 1639, 1661, 1685, 1725, 1745, 1777, 1817, 1849, 1879, 1900, 1946, 1979, 2034, 2066, 2086, 2126, 2178, 2218, 2256, 2308, 2357, 2412, 2467, 2511, 2541, 2583, 2615, 2647, 2677, 2727, 2768, 2814, 2860, 2926, 2971, 2989, 3031, 3073, 3125, 3166, 3206, 3250, 3282, 3332, 3384, 3422, 3453, 3508, 3528, 3572, 3591, 3611, 3649, 3676, 3698, 3718, 3750, 3780, 3819, 3863, 3904, 3926, 3946, 3981, 4003, 4027, 4049, 4073, 4107, 4133, 4171, 4205, 4227, 4259, 4299, 4331, 4361, 4381, 4411, 4466, 4499, 4521, 4575, 4605, 4655, 4675, 4721, 4773, 4822, 4868, 4912, 4967, 5007, 5035, 5069, 5107, 5150, 5179, 5216, 5271, 5305, 5347, 5397, 5447, 5510, 5532, 5565, 5631, 5663, 5685, 5715, 5736, 5778, 5800, 5832, 5872, 5901, 5923, 5943, 5985, 6006, 6027, 6049, 6091, 6146, 6167, 6189, 6223, 6257, 6279, 6325, 6349, 6383, 6403, 6435, 6455, 6485, 6513, 6543, 6572, 6594, 6616, 6672, 6700, 6730, 6758, 6790, 6821, 6856, 6878, 6911, 6934, 6964, 6994, 7034, 7055, 7077, 7112, 7178, 7221, 7243, 7293, 7327, 7349, 7402, 7434, 7474, 7524, 7555, 7608, 7660, 7680, 7722, 7764, 7785, 7819, 7841, 7937, 7995, 8015, 8063, 8086, 8108, 8132, 8154, 8173, 8193, 8221, 8241, 8262, 8297, 8330, 8385, 8416, 8448, 8471, 8502, 8559, 8612, 8657, 8687, 8730, 8761, 8794, 8849, 8870, 8889, 8911, 8931, 8964, 8989, 9011, 9035, 9069, 9093, 9117, 9153, 9199, 9229, 9249, 9270, 9292, 9332, 9376, 9424, 9447, 9491, 9535, 9598, 9628, 9667, 9711, 9755, 9799, 9833, 9866, 9908, 9963, 10010, 10034, 10070, 10094, 10118, 10152, 10206, 10225, 10260, 10293, 10325, 10343, 10374, 10405, 10440, 10485, 10504, 10528, 10552, 10587, 10649, 10685, 10747, 10771, 10795, 10817, 10837, 10856, 10878, 10900, 10976, 11022, 11066, 11101, 11127, 11163, 11213, 11237, 11261, 11340, 11411, 11435, 11461, 11487, 11511, 11537, 11612, 11664, 11718, 11744, 11811, 11837, 11878, 11904, 11930, 11971, 11997, 12023, 12069, 12097, 12149, 12179, 12199, 12261, 12282, 12311, 12344, 12386, 12418, 12460, 12490, 12510, 12560, 12590, 12618, 12679, 12701, 12723, 12820, 12841, 12871, 12935, 12995, 13059, 13145, 13174, 13277, 13326, 13370, 13418, 13446, 13488, 13506, 13526, 13547, 13604, 13639, 13680, 13708, 13738, 13808, 13839, 13879, 13901, 13991, 14012, 14032, 14081, 14114, 14134, 14186, 14234, 14253, 14326, 14418, 14440, 14469, 14521, 14553, 14589, 14611, 14635, 14657, 14679, 14713, 14735, 14757, 14797, 14827, 14885, 14925, 14975, 15024, 15055, 15088, 15119, 15171, 15209, 15239, 15335, 15377, 15417, 15458, 15520, 15564, 15641, 15682, 15722, 15788, 15824, 15862, 15911, 15946, 16030, 16052, 16091, 16161, 16197, 16235, 16322, 16401, 16452, 16563, 16600, 16618, 16670, 16711, 16742, 16793, 16846, 16876, 16916, 16947, 16976, 17027, 17124, 17145, 17192, 17254, 17276, 17321, 17357, 17447, 17481, 17503, 17525, 17551, 17611, 17633, 17653, 17711, 17753, 17801, 17831, 17939, 17960, 18011, 18044, 18106, 18138, 18158, 18214, 18246, 18322, 18365, 18385, 18416, 18462, 18503, 18575, 18633, 18717, 18794, 18886, 18939, 19056, 19108, 19128, 19164, 19193, 19248, 19292, 19335, 19393, 19414, 19538, 19589, 19677, 19705, 19724, 19764, 19830, 19884, 19908, 19954, 20034, 20070, 20102, 20138, 20208, 20258, 20276, 20296, 20325, 20347, 20380, 20409, 20454, 20484, 20522, 20580, 20599, 20652, 20707, 20769, 20801, 20819, 20839, 20858, 20902, 20955, 21005, 21033, 21084, 21119, 21152, 21185, 21257, 21277, 21319, 21384, 21420, 21462, 21498, 21552, 21600, 21660, 21704, 21738, 21778, 21838, 21881, 21919, 21941, 22007, 22038, 22068, 22115, 22150, 22172, 22194, 22248, 22286, 22315, 22407, 22462, 22546, 22585, 22616, 22651, 22702, 22778, 22810, 22844, 22964, 23024, 23068, 23104, 23160, 23224, 23263, 23285, 23318, 23347, 23368, 23408, 23440, 23495, 23528, 23580, 23624, 23666, 23707, 23745, 23777, 23847, 23917, 23953, 23999, 24037, 24058, 24089, 24111, 24153, 24196, 24225, 24258, 24289, 24342, 24389, 24449, 24519, 24563, 24597, 24621, 24657, 24741, 24765, 24809, 24831, 24871, 24894, 24916, 24954, 24992, 25026, 25072, 25118, 25154, 25192, 25218, 25257, 25298, 25324, 25374, 25428, 25491, 25517, 25541, 25604, 25643, 25682, 25745, 25782, 25821, 25845, 25868, 25886, 25916, 25934, 25982, 26014, 26032, 26053, 26084, 26104, 26167, 26195, 26235, 26253, 26283, 26325, 26375, 26406, 26468, 26489, 26507, 26585, 26615, 26670, 26723, 26754, 26782, 26802, 26840, 26870, 26935, 26992, 27036, 27067, 27110, 27130, 27148, 27198, 27231, 27275, 27296, 27316, 27357, 27399, 27456, 27477, 27522, 27542, 27575, 27617, 27678, 27712, 27756, 27778, 27824, 27866, 27886, 27914, 27986, 28016, 28062, 28111, 28133, 28153, 28186, 28216, 28242, 28262, 28330, 28400, 28431, 28462, 28493, 28586, 28616, 28672, 28732, 28765, 28816, 28858, 28946, 28978, 29024, 29044, 29093, 29137, 29183, 29250, 29301, 29356, 29409, 29480, 29512, 29572, 29605, 29687, 29710, 29744, 29816, 29872, 29918, 29976, 30014, 30056, 30086, 30118, 30148, 30190, 30210, 30242, 30274, 30304, 30344, 30425, 30456, 30498, 30542, 30575, 30611, 30660, 30706, 30741, 30783, 30804, 30832, 30872, 30931, 30964, 30983, 31014, 31058, 31115, 31158, 31182, 31216, 31250, 31298, 31320, 31356, 31390, 31426, 31446, 31496, 31534, 31562, 31607, 31629, 31651, 31744, 31776, 31806, 31844, 31893, 31924, 31959, 31989, 32025, 32078, 32111, 32144, 32163, 32202, 32266, 32323, 32374, 32415, 32451, 32485, 32587, 32621, 32657, 32681, 32741, 32765, 32797, 32825, 32843, 32864, 32906, 32928, 32960, 33000, 33032, 33074, 33127, 33157, 33200, 33242, 33275, 33328, 33360, 33394, 33444, 33488, 33512, 33572, 33620, 33666, 33688, 33716, 33747, 33769, 33789, 33830, 33849, 33893, 33924, 33959, 33991, 34013, 34037, 34073, 34109, 34145, 34189, 34237, 34257, 34296, 34318, 34351, 34402, 34427, 34451, 34485, 34523, 34557, 34593, 34641, 34667, 34713, 34749, 34800, 34876, 34902, 34995, 35034, 35086, 35112, 35138, 35174, 35192, 35212, 35230, 35262, 35310, 35331, 35362, 35384, 35434, 35472, 35502, 35522, 35591, 35624, 35653, 35686, 35725, 35757, 35788, 35819, 35841, 35927, 35948, 35968, 35996, 36025, 36060, 36106, 36125, 36173, 36192, 36236, 36271, 36322, 36376, 36398, 36445, 36481, 36527, 36575, 36597, 36631, 36665, 36709, 36737, 36755, 36775, 36795, 36824, 36876, 36906, 36938, 36958, 36977, 37028, 37050, 37072, 37093, 37121, 37171, 37218, 37240, 37271, 37304, 37338, 37368, 37399, 37454, 37489, 37564, 37594, 37615, 37661, 37690, 37722, 37756, 37790, 37824, 37846, 37882, 37928, 37954, 38004, 38050, 38072, 38102, 38142, 38216, 38255, 38288, 38329, 38355, 38385, 38406, 38470, 38513, 38563, 38602, 38646, 38734, 38755, 38774, 38836, 38882, 38903, 38949, 38973, 39039, 39071, 39107, 39163, 39187, 39217, 39237, 39289, 39341, 39379, 39422, 39442, 39464, 39495, 39527, 39548, 39590, 39623, 39665, 39697, 39721, 39769, 39831, 39855, 39879, 39901, 39949, 39985, 40007, 40045, 40066, 40119, 40141, 40183, 40204, 40225, 40247, 40291, 40331, 40363, 40409, 40433, 40531, 40565, 40625, 40663, 40699, 40733, 40776, 40807, 40864, 40888, 40912, 40950, 40972, 41030, 41128, 41152, 41204, 41228, 41254, 41306, 41412, 41475, 41546, 41564, 41612, 41653, 41685, 41723, 41749, 41789, 41841, 41887, 41926, 41948, 41991, 42009, 42038, 42071, 42091, 42113, 42147, 42166, 42186, 42233, 42255, 42289, 42323, 42345, 42389, 42411, 42455, 42487, 42507, 42527, 42575, 42595, 42614, 42669, 42719, 42739, 42781, 42824, 42857, 42907, 42937, 42968, 43019, 43063, 43084, 43115, 43146, 43179, 43214, 43239, 43275, 43313, 43347, 43369, 43393, 43439, 43477, 43515, 43561, 43603, 43626, 43648, 43691, 43721, 43750, 43817, 43839, 43863, 43885, 43919, 43941, 43965, 44013, 44039, 44087, 44113, 44147, 44167, 44193, 44224, 44277, 44318, 44362, 44393, 44426, 44448, 44496, 44546, 44584, 44652, 44672, 44726, 44748, 44782, 44840, 44866, 44902, 44966, 44992, 45029, 45055, 45118, 45144, 45233, 45347, 45383, 45415, 45444, 45464, 45486, 45549, 45582, 45604, 45624, 45665, 45685, 45716, 45751, 45773, 45824, 45856, 45889, 45924, 45966, 46011, 46075, 46121, 46143, 46191, 46225, 46288, 46310, 46361, 46382, 46424, 46457, 46489, 46550, 46595, 46631, 46675, 46723, 46747, 46795, 46821, 46847, 46891, 46911, 46940, 46984, 47006, 47047, 47078, 47100, 47122, 47153, 47197, 47221, 47291, 47315, 47337, 47361, 47395, 47475, 47506, 47526, 47559, 47603, 47635, 47707, 47731, 47755, 47803, 47864, 47914, 47953, 47992, 48029, 48081, 48118, 48144, 48183, 48209, 48235, 48322, 48386, 48440, 48532, 48566, 48600, 48636, 48670, 48722, 48743, 48763, 48785, 48807, 48839, 48872, 48905, 48928, 48952, 48988, 49022, 49056, 49094, 49120, 49222, 49255, 49291, 49325, 49347, 49395, 49429, 49479, 49503, 49568, 49594, 49633, 49763, 49846, 49868, 49888, 49921, 49964, 49997, 50017, 50064, 50088, 50132, 50154, 50188, 50222, 50287, 50345, 50379, 50413, 50437, 50459, 50485, 50533, 50606, 50643, 50693, 50730, 50756, 50819, 50953, 51023, 51057, 51091, 51113, 51135, 51221, 51258, 51295, 51336, 51364, 51401, 51451, 51475, 51501, 51525, 51619, 51647, 51687, 51713, 51739, 51765, 51819, 51845, 51887, 51931, 51971, 51997, 52037, 52063, 52103, 52143, 52169, 52195, 52251, 52293, 52331, 52373, 52399, 52425, 52467, 52493]; From 6d32956c9d920bc361b05520ea22b0d0993bcb0a Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 23 Aug 2024 13:26:59 +1000 Subject: [PATCH 77/93] debug --- 32-24 Point Poker Game/index.html | 75 ++++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/32-24 Point Poker Game/index.html b/32-24 Point Poker Game/index.html index 5dfe0a1..a763723 100644 --- a/32-24 Point Poker Game/index.html +++ b/32-24 Point Poker Game/index.html @@ -43,6 +43,11 @@ + + + + +
@@ -60,7 +65,19 @@ const suits = ['โ™ ', 'โ™ฅ', 'โ™ฃ', 'โ™ฆ']; const values = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']; const deck = []; - + const method = ['+', '-', '*', '/']; + + function selectedMethod(i) { + selMethord = i; + if(selectedCards.length == 2){ + var cd = calc(cardToNumber(selectedCards[0]), selMethord, cardToNumber(selectedCards[1])); + document.getElementById(`card${selectedCards[0]}`).display = "none"; + document.getElementById(`card${selectedCards[1]}`).display = "none"; + selectedCards = []; + selMethord = -1; + addCard(cd+" ", "#007f0e",cards.length); + } + } // ๅˆ›ๅปบๆ‰‘ๅ…‹็‰Œๆ•ฐ็ป„ for (let suit of suits) { for (let value of values) { @@ -88,11 +105,37 @@ // ๆ˜พ็คบๆŠฝๅ‡บ็š„็‰Œ const cardContainer = document.getElementById('cardContainer'); cardContainer.innerHTML = ''; // ๆธ…็ฉบๅฎนๅ™จ - + var index = 0; drawnCards.forEach(card => { const color = getColorForSuit(card.slice(-1)); // ๆ นๆฎ่Šฑ่‰ฒ่Žทๅ–้ขœ่‰ฒ // ไฝฟ็”จSVG็ป˜ๅˆถๅœ†่ง’็Ÿฉๅฝขๅนถๆ˜พ็คบ็‰Œ - const svg = ` + addCard(card, color,index); + index++; + + }); + cards = drawnCards; + cal(); + } + var selectedCards = []; + function clcikCard(index){ + if(selectedCards.length <2){ + selectedCards.push(index); + document.getElementById(`card${index}`).style.border = "2px solid blue"; + }else if(selectedCards.length == 2){ + if(selMethord != -1){ + var cd = calc(cardToNumber(selectedCards[0]), selMethord, cardToNumber(selectedCards[1])); + document.getElementById(`card${selectedCards[0]}`).display = "none"; + document.getElementById(`card${selectedCards[1]}`).display = "none"; + selMethord = -1; + addCard(cd+" ", "#007f0e",cards.length); + } + document.getElementById(`card${selectedCards[0]}`).style.border = ""; + document.getElementById(`card${selectedCards[1]}`).style.border = ""; + selectedCards = []; + } + } + function addCard(card, color,index) { + const svg = ` ${card} @@ -100,11 +143,10 @@ `; const div = document.createElement('div'); div.className = 'card'; + div.id = `card${index}`; + div.setAttribute('onclick', `clcikCard(${index})`); div.innerHTML = svg; cardContainer.appendChild(div); - }); - cards = drawnCards; - cal(); } function getColorForSuit(suit) { switch (suit) { @@ -198,6 +240,27 @@ document.getElementById("inputs").innerHTML = str1 + "
"; // display the inputs } + function calc(num1, op1, num2) { + var num3 = 0.0; + switch (op1) { + case 0: + num3 = num1 + num2; + break; + case 1: + num3 = num1 - num2; + break; + case 2: + num3 = num1 * num2; + break; + case 3: + num3 = num1 / num2; + break; + } + if (Math.abs(num3 - Math.round(num3)) < ep) + return (Math.round(num3)); + else + return (num3); + } From a48d64a70231418017a734b3417f814d210beb51 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 23 Aug 2024 14:31:23 +1000 Subject: [PATCH 78/93] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20index.html?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 32-24 Point Poker Game/index.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/32-24 Point Poker Game/index.html b/32-24 Point Poker Game/index.html index a763723..580c22c 100644 --- a/32-24 Point Poker Game/index.html +++ b/32-24 Point Poker Game/index.html @@ -44,7 +44,7 @@ - + @@ -68,13 +68,13 @@ const method = ['+', '-', '*', '/']; function selectedMethod(i) { - selMethord = i; + selMethod = i; if(selectedCards.length == 2){ - var cd = calc(cardToNumber(selectedCards[0]), selMethord, cardToNumber(selectedCards[1])); + var cd = calc(cardToNumber(selectedCards[0]), selMethod, cardToNumber(selectedCards[1])); document.getElementById(`card${selectedCards[0]}`).display = "none"; document.getElementById(`card${selectedCards[1]}`).display = "none"; selectedCards = []; - selMethord = -1; + selMethod = -1; addCard(cd+" ", "#007f0e",cards.length); } } @@ -126,7 +126,7 @@ var cd = calc(cardToNumber(selectedCards[0]), selMethord, cardToNumber(selectedCards[1])); document.getElementById(`card${selectedCards[0]}`).display = "none"; document.getElementById(`card${selectedCards[1]}`).display = "none"; - selMethord = -1; + selMethod = -1; addCard(cd+" ", "#007f0e",cards.length); } document.getElementById(`card${selectedCards[0]}`).style.border = ""; From c600de07cf520cabfc7b407497a2bb9620884256 Mon Sep 17 00:00:00 2001 From: Jack Date: Fri, 23 Aug 2024 23:30:54 +1000 Subject: [PATCH 79/93] Update index.html --- 32-24 Point Poker Game/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/32-24 Point Poker Game/index.html b/32-24 Point Poker Game/index.html index 580c22c..6eaaa02 100644 --- a/32-24 Point Poker Game/index.html +++ b/32-24 Point Poker Game/index.html @@ -43,7 +43,7 @@ - + @@ -122,8 +122,8 @@ selectedCards.push(index); document.getElementById(`card${index}`).style.border = "2px solid blue"; }else if(selectedCards.length == 2){ - if(selMethord != -1){ - var cd = calc(cardToNumber(selectedCards[0]), selMethord, cardToNumber(selectedCards[1])); + if(selMethod != -1){ + var cd = calc(cardToNumber(selectedCards[0]), selMethod, cardToNumber(selectedCards[1])); document.getElementById(`card${selectedCards[0]}`).display = "none"; document.getElementById(`card${selectedCards[1]}`).display = "none"; selMethod = -1; @@ -264,4 +264,4 @@ - \ No newline at end of file + From 7a80715ce73925493ca365293bb055dc82f8dbba Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 24 Aug 2024 17:04:41 +1000 Subject: [PATCH 80/93] add 24 point poker game --- 31-Air-Hockey-Game/index.html | 273 +++++++++++++----- .../index.html | 178 +++++++++--- .../str.js | 0 README.md | 2 + index.html | 4 + indexCN.html | 4 + 6 files changed, 351 insertions(+), 110 deletions(-) rename {32-24 Point Poker Game => 32-24 Point-Poker-Game}/index.html (57%) rename {32-24 Point Poker Game => 32-24 Point-Poker-Game}/str.js (100%) diff --git a/31-Air-Hockey-Game/index.html b/31-Air-Hockey-Game/index.html index 78d9937..e5acdd6 100644 --- a/31-Air-Hockey-Game/index.html +++ b/31-Air-Hockey-Game/index.html @@ -104,28 +104,20 @@
var animationId; var gameRunning = false; var ballColor = "#FFF"; - - startBtn.addEventListener("click", function () { - if (!gameRunning) { - // only start the game if gameRunning is false - gameRunning = true; // set gameRunning to true when the game starts - loop(); - } - }); - - pauseBtn.addEventListener("click", function () { - gameRunning = false; - cancelAnimationFrame(animationId); - }); - - restartBtn.addEventListener("click", function () { - document.location.reload(); - }); - - addEventListener("load", (event) => { - draw(); - }); - + //for speed calculation + var elapsed = 0; + var lastTime = 0; + var lastLeftPaddleY = null; + var lastLeftPaddleX = null; + var lastRightPaddleY = null; + var lastRightPaddleX = null; + var speedLeftPaddleX = null; + var speedLeftPaddleY = null; + var speedRightPaddleX = null; + var speedRightPaddleY = null; + //ๅฝ“็ƒๅก่พนๆ—ถ้‡็ฝฎๆธธๆˆ + var minialSpeed = 0.3; + var addSpeed = 0.1; // Define ball properties var ballRadius = 10; var ballX = canvas.width / 2; @@ -153,16 +145,11 @@
var previousXPositionLeft = 0 + edgeWidth; var touchYstartRight = null; var touchXstartRight = null; + //for position calculation var previousYPositionRight = canvas.height / 2; var previousXPositionRight = canvas.width - edgeWidth; const canvasBounds = canvas.getBoundingClientRect(); const canvasMiddle = canvasBounds.width / 2 + canvasBounds.left; - - - // Listen for keyboard events - document.addEventListener("keydown", keyDownHandler); - document.addEventListener("keyup", keyUpHandler); - // Handle key press var upPressed = false; var downPressed = false; @@ -214,40 +201,69 @@
} } - function calculateCollision(sx, sy, px, py, qx, qy, r, R) { - // ่ฎก็ฎ—ๅฐ็ƒๅˆฐๅคง็ƒ็š„ๅ•ไฝๆณ•ๅ‘้‡ + function calculateCollision(sx, sy, px, py, qx, qy, r, R, tx = 0, ty = 0) { + // ่ฎก็ฎ—ๅฐ็ƒๅˆฐๅคง็ƒ็š„ๅ‘้‡ const dx = px - qx; const dy = py - qy; const distance = Math.sqrt(dx * dx + dy * dy); - // ๅ•ไฝๆณ•ๅ‘้‡ + // ่ฎก็ฎ—ๅ•ไฝๆณ•ๅ‘้‡ const nx = dx / distance; const ny = dy / distance; + // ่ฎก็ฎ—ๅฐ็ƒ็›ธๅฏนไบŽๅคง็ƒ็š„้€Ÿๅบฆ + const relativeSx = sx - tx; + const relativeSy = sy - ty; + // ่ฎก็ฎ—ๅฐ็ƒๅœจๆณ•ๅ‘้‡ๆ–นๅ‘็š„้€Ÿๅบฆๅˆ†้‡๏ผˆๆŠ•ๅฝฑ๏ผ‰ - const vDotN = sx * nx + sy * ny; - // ๅฆ‚ๆžœๆŽฅ่ฟ‘ๅˆ‡็บฟๆ–นๅ‘๏ผŒ้ฟๅ…ๅ‡บ็Žฐๅๅฐ„ๅˆฐๅฏนไพง็š„็Žฐ่ฑก - if (Math.abs(vDotN) < 0.5) { - // ๅค„็†ๅˆ‡็บฟ็ขฐๆ’ž็š„็‰นไพ‹๏ผšๆญคๆ—ถไป…ๆ”นๅ˜ๆณ•็บฟๆ–นๅ‘็š„้€Ÿๅบฆๅˆ†้‡ - const tangentialSx = sy * nx; - const tangentialSy = -sx * ny; - return { - reflectedVx: tangentialSx, - reflectedVy: tangentialSy, - newPx: px, - newPy: py - }; + const vDotN = relativeSx * nx + relativeSy * ny; + + // ๆฃ€ๆต‹็ขฐๆ’žๅ’Œๅˆ‡็บฟๆƒ…ๅ†ต + if (distance <= r + R) { + if (Math.abs(vDotN) < 0.5) { + // ๅค„็†ๅˆ‡็บฟ็ขฐๆ’ž๏ผš้ฟๅ…ๅฐ็ƒ่ขซๅธไฝ๏ผŒๆ”นๅ˜ๅˆ‡็บฟๆ–นๅ‘้€Ÿๅบฆ + const tangentialSx = -relativeSy * nx; + const tangentialSy = relativeSx * ny; + const reflectedVx = tangentialSx + tx; + const reflectedVy = tangentialSy + ty; + + // ไฟๆŒๅฐ็ƒๅœจๅŽŸไฝ็ฝฎ๏ผŒไธไฝœไฝ็ฝฎไฟฎๆญฃ + return { + reflectedVx, + reflectedVy, + newPx: px, + newPy: py + }; + } else { + // ่ฎก็ฎ—ๅผนๆ€ง็ขฐๆ’žๅŽ็š„้€Ÿๅบฆ + const reflectedVx = relativeSx - 2 * vDotN * nx; + const reflectedVy = relativeSy - 2 * vDotN * ny; + + // ่ฎก็ฎ—ๅคง็ƒ้€Ÿๅบฆไผ ้€’็š„30%๏ผŒไฝ†ๆฒฟๆณ•็บฟๆ–นๅ‘ + const transferVx = 0.3 * tx * nx; + const transferVy = 0.3 * ty * ny; + + // ๅˆๆˆๆœ€็ปˆ้€Ÿๅบฆ๏ผŒๅๅฐ„้€ŸๅบฆๅŠ ไธŠไผ ้€’้€Ÿๅบฆ + const finalVx = reflectedVx + transferVx; + const finalVy = reflectedVy + transferVy; + + // ไฝ็ฝฎไฟฎๆญฃ๏ผšๅฐ†ๅฐ็ƒ็งปๅ‡บๅคง็ƒ็š„่กจ้ข + const overlap = r + R - distance; + const newPx = px + nx * overlap; + const newPy = py + ny * overlap; + + return { + reflectedVx: finalVx, + reflectedVy: finalVy, + newPx, + newPy + }; + } } - // ่ฎก็ฎ—ๆณ•ๅ‘้‡ๆ–นๅ‘็š„ๅๅฐ„้€Ÿๅบฆๅˆ†้‡ - const reflectedVx = sx - 2 * vDotN * nx; - const reflectedVy = sy - 2 * vDotN * ny; - // ไฝ็ฝฎไฟฎๆญฃ๏ผšๅฐ†ๅฐ็ƒ็งปๅ‡บๅคง็ƒ็š„่กจ้ข - const overlap = r + R - distance; - const newPx = px + nx * overlap; - const newPy = py + ny * overlap; - return { reflectedVx, reflectedVy, newPx, newPy }; - } + // ๆฒกๆœ‰็ขฐๆ’žๅ‘็”Ÿ๏ผŒ่ฟ”ๅ›žๅŽŸ้€Ÿๅบฆๅ’Œไฝ็ฝฎ + return { reflectedVx: sx, reflectedVy: sy, newPx: px, newPy: py }; + } function hasCollided(px, py, qx, qy, r, R) { // ่ฎก็ฎ—ไธคไธช็ƒไธญๅฟƒ็š„่ท็ฆป const dx = px - qx; @@ -288,15 +304,27 @@
leftPaddleX += paddleSpeed; } - // Move ball - ballX += ballSpeedX; - ballY += ballSpeedY; + // Check if ball collides with top or bottom of canvas if (ballY - ballRadius - edgeWidth < 0 || ballY + ballRadius + edgeWidth > canvas.height) { - ballSpeedY = -ballSpeedY; - } + if (Math.abs(ballSpeedY) > minialSpeed) { + ballSpeedY = -ballSpeedY; + if(ballSpeedY > 0) { + ballSpeedY += addSpeed; + }else{ + ballSpeedY -= addSpeed; + } + } else { + console.log("ballSpeedY: " + ballSpeedY); + reset(); + } + } + // Move ball + ballX += ballSpeedX; + ballY += ballSpeedY; + // Check if ball collides with left paddle /*if ( ballX - ballRadius < paddleWidth && @@ -307,7 +335,7 @@
}*/ if (hasCollided(ballX, ballY, leftPaddleX, leftPaddleY, ballRadius, paddleHeight / 2)) { - var ballMove = calculateCollision(ballSpeedX, ballSpeedY, ballX, ballY, leftPaddleX, leftPaddleY, ballRadius, paddleHeight / 2); + var ballMove = calculateCollision(ballSpeedX, ballSpeedY, ballX, ballY, leftPaddleX, leftPaddleY, ballRadius, paddleHeight / 2, speedLeftPaddleX, speedLeftPaddleY); ballSpeedX = ballMove.reflectedVx; ballSpeedY = ballMove.reflectedVy; ballX = ballMove.newPx; @@ -323,7 +351,7 @@
ballSpeedX = -ballSpeedX; }*/ if (hasCollided(ballX, ballY, rightPaddleX, rightPaddleY, ballRadius, paddleHeight / 2)) { - var ballMove = calculateCollision(ballSpeedX, ballSpeedY, ballX, ballY, rightPaddleX, rightPaddleY, ballRadius, paddleHeight / 2); + var ballMove = calculateCollision(ballSpeedX, ballSpeedY, ballX, ballY, rightPaddleX, rightPaddleY, ballRadius, paddleHeight / 2, speedRightPaddleX, speedRightPaddleY); ballSpeedX = ballMove.reflectedVx; ballSpeedY = ballMove.reflectedVy; ballX = ballMove.newPx; @@ -339,7 +367,18 @@
reset(); } } else if (ballX < edgeWidth || ballX > canvas.width - edgeWidth) { - ballSpeedX = -ballSpeedX; + if (Math.abs(ballSpeedX) > minialSpeed) { + ballSpeedX = -ballSpeedX; + if(ballSpeedX > 0) { + ballSpeedX += addSpeed; + }else{ + ballSpeedX -= addSpeed; + } + } else { + console.log("ballSpeedX:"+ballSpeedX); + reset(); + } + } @@ -442,6 +481,12 @@
function actionStart(e) { //e.preventDefault(); //ๅˆคๆ–ญๆ˜ฏ้ผ ๆ ‡ๅทฆ้”ฎ็‚นๅ‡ป่ฟ˜ๆ˜ฏ่งฆๆ‘ธ + lastTime = Date.now(); + lastLeftPaddleX = leftPaddleX; + lastRightPaddleX = rightPaddleX; + lastLeftPaddleY = leftPaddleY; + lastRightPaddleY = rightPaddleY; + if (!gameRunning) { return; } var leftPt = { pageX: canvas.width, pageY: -1 }, rightPt = { pageX: 0, pageY: -1 }; @@ -467,6 +512,17 @@
} function actionEnd(e) { + lastTime = 0; + lastLeftPaddleX = null; + lastRightPaddleX = null; + lastLeftPaddleY = null; + lastRightPaddleY = null; + speedLeftPaddleX = null; + speedRightPaddleX = null; + speedRightPaddleY = null; + speedLeftPaddleY = null; + + //e.preventDefault(); if (touchYstartRight != null) { touchYstartRight = null; @@ -483,6 +539,7 @@
} function actionMove(e) { + elapsed = Date.now() - lastTime; e.preventDefault(); // ้˜ฒๆญข้กต้ขๆปšๅŠจ if (gameRunning) { if (e.touches) { // ่งฆๆ‘ธไบ‹ไปถ @@ -521,10 +578,26 @@
if (leftTouch && touchYstartLeft !== null) { let distYLeft = leftTouch.pageY - touchYstartLeft; leftPaddleY = previousYPositionLeft + distYLeft; - leftPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, leftPaddleY)); + leftPaddleY = Math.max(0 + paddleHeight / 2, Math.min(canvas.height - paddleHeight / 2, leftPaddleY)); let distXLeft = leftTouch.pageX - touchXstartLeft; leftPaddleX = previousXPositionLeft + distXLeft; leftPaddleX = Math.max(0, Math.min(canvas.width / 2, leftPaddleX)); + if (speedLeftPaddleX === null && lastLeftPaddleX != leftPaddleX) { + if (lastLeftPaddleX === null) { + lastLeftPaddleX = leftPaddleX; + } else { + speedLeftPaddleX = (leftPaddleX - lastLeftPaddleX) / elapsed; + lastLeftPaddleX = leftPaddleX; + } + } + if (speedLeftPaddleY === null && lastLeftPaddleY != leftPaddleY) { + if (lastLeftPaddleY === null) { + lastLeftPaddleY = leftPaddleY; + } else { + speedLeftPaddleY = (leftPaddleY - lastLeftPaddleY) / elapsed; + lastLeftPaddleY = leftPaddleY; + } + } } } catch (e) { } @@ -533,10 +606,26 @@
if (rightTouch && touchYstartRight !== null) { let distYRight = rightTouch.pageY - touchYstartRight; rightPaddleY = previousYPositionRight + distYRight; - rightPaddleY = Math.max(0, Math.min(canvas.height - paddleHeight, rightPaddleY)); + rightPaddleY = Math.max(0 + paddleHeight / 2, Math.min(canvas.height - paddleHeight / 2, rightPaddleY)); let distXRight = rightTouch.pageX - touchXstartRight; rightPaddleX = previousXPositionRight + distXRight; rightPaddleX = Math.min(canvas.width, Math.max(canvas.width / 2, rightPaddleX)); + if (speedRightPaddleX === null && lastRightPaddleX != rightPaddleX) { + if (lastRightPaddleX === null) { + lastRightPaddleX = rightPaddleX; + } else { + speedRightPaddleX = (rightPaddleX - lastRightPaddleX) / elapsed; + lastRightPaddleX = rightPaddleX; + } + } + if (speedRightPaddleY === null && lastRightPaddleY != rightPaddleY) { + if (lastRightPaddleY === null) { + lastRightPaddleY = rightPaddleY; + } else { + speedRightPaddleY = (rightPaddleY - lastRightPaddleY) / elapsed; + lastRightPaddleY = rightPaddleY; + } + } } } catch (e) { } } @@ -550,31 +639,85 @@
if (touchYstartLeft !== null) { let distYLeft = mouseY - touchYstartLeft; leftPaddleY = previousYPositionLeft + distYLeft; - leftPaddleY = Math.max(0 + paddleHeight / 2, Math.min(canvas.height - paddleHeight/2, leftPaddleY)); + leftPaddleY = Math.max(0 + paddleHeight / 2, Math.min(canvas.height - paddleHeight / 2, leftPaddleY)); let distXLeft = mouseX - touchXstartLeft; leftPaddleX = previousXPositionLeft + distXLeft; leftPaddleX = Math.max(0, Math.min(canvas.width / 2, leftPaddleX)); + if (speedLeftPaddleX === null && lastLeftPaddleX != leftPaddleX) { + if (lastLeftPaddleX === null) { + lastLeftPaddleX = leftPaddleX; + } else { + speedLeftPaddleX = (leftPaddleX - lastLeftPaddleX) / elapsed; + } + } + if (speedLeftPaddleY === null && lastLeftPaddleY != leftPaddleY) { + if (lastLeftPaddleY === null) { + lastLeftPaddleY = leftPaddleY; + } else { + speedLeftPaddleY = (leftPaddleY - lastLeftPaddleY) / elapsed; + } + } } } else { if (touchYstartRight !== null) { let distYRight = mouseY - touchYstartRight; rightPaddleY = previousYPositionRight + distYRight; - rightPaddleY = Math.max(0 + paddleHeight / 2, Math.min(canvas.height - paddleHeight/2, rightPaddleY)); + rightPaddleY = Math.max(0 + paddleHeight / 2, Math.min(canvas.height - paddleHeight / 2, rightPaddleY)); let distXRight = mouseX - touchXstartRight; rightPaddleX = previousXPositionRight + distXRight; rightPaddleX = Math.min(canvas.width, Math.max(canvas.width / 2, rightPaddleX)); + if (speedRightPaddleX === null && lastRightPaddleX != rightPaddleX) { + if (lastRightPaddleX === null) { + lastRightPaddleX = rightPaddleX; + } else { + speedRightPaddleX = (rightPaddleX - lastRightPaddleX) / elapsed; + } + } + if (speedRightPaddleY === null && lastRightPaddleY != rightPaddleY) { + if (lastRightPaddleY === null) { + lastRightPaddleY = rightPaddleY; + } else { + speedRightPaddleY = (rightPaddleY - lastRightPaddleY) / elapsed; + } + } } } } - // ไบ‹ไปถ็›‘ๅฌๅ™จ + // Add event listeners + + startBtn.addEventListener("click", function () { + if (!gameRunning) { + // only start the game if gameRunning is false + gameRunning = true; // set gameRunning to true when the game starts + loop(); + } + }); + + pauseBtn.addEventListener("click", function () { + gameRunning = false; + cancelAnimationFrame(animationId); + }); + + restartBtn.addEventListener("click", function () { + document.location.reload(); + }); + + addEventListener("load", (event) => { + draw(); + }); + + // Listen for keyboard events + document.addEventListener("keydown", keyDownHandler); + document.addEventListener("keyup", keyUpHandler); document.addEventListener('touchstart', actionStart, { passive: false }); document.addEventListener('touchend', actionEnd); document.addEventListener('touchmove', actionMove, { passive: false }); document.addEventListener('mousedown', actionStart); document.addEventListener('mouseup', actionEnd); document.addEventListener('mousemove', actionMove); + diff --git a/32-24 Point Poker Game/index.html b/32-24 Point-Poker-Game/index.html similarity index 57% rename from 32-24 Point Poker Game/index.html rename to 32-24 Point-Poker-Game/index.html index 6eaaa02..af375aa 100644 --- a/32-24 Point Poker Game/index.html +++ b/32-24 Point-Poker-Game/index.html @@ -39,43 +39,94 @@ -
+

24็‚น

+
ๅพ—ๅˆ†: 0
+
+ + - - - - - - - + + +
- -
+ +
+
+
+ + + + + +
- + \ No newline at end of file diff --git a/32-24 Point Poker Game/str.js b/32-24 Point-Poker-Game/str.js similarity index 100% rename from 32-24 Point Poker Game/str.js rename to 32-24 Point-Poker-Game/str.js diff --git a/README.md b/README.md index f570a6c..6cb27b1 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,8 @@ fork from https://github.com/he-is-talha/html-css-javascript-games 28. **Emoji Catcher Game**: Catch falling emojis with a basket or container while avoiding bombs and other obstacles in this emoji-catching game. ๐ŸŽฏ๐Ÿ˜„ 29. **Whack a Mole Game**: Test your reaction speed by hitting randomly appearing moles with a mallet before they disappear in this classic arcade game. ๐Ÿ•น๏ธ 30. **Guess Number Game**: Guess a 4-digit number with A for right position and B for right number. Only eight chances. A good game for logical thinking.๐Ÿง ๐Ÿค– +31. **Air Hockey Game**: A ping-pong like game with two players. control with mouse or keyboard or multi-touch screen. Play with your friends in this classic game. ๐Ÿ€๐Ÿ‘ +32. **24 Point Poker Game**: A classic 24 point poker game. Get four random cards to start. Use Add or Subtract or Multiply or Divide to calculate 24. ๐ŸŽฒ๐Ÿƒ ## License diff --git a/index.html b/index.html index da98b10..221f78d 100644 --- a/index.html +++ b/index.html @@ -177,6 +177,10 @@

Game List


31 Air Hockey Game: A ping-pong like game with two players. control with mouse or keyboard or multi-touch screen. Play with your friends in this classic game. ๐Ÿ€๐Ÿ‘ + + 32 + 24 Point Poker Game: A classic 24 point poker game. Get four random cards to start. Use Add or Subtract or Multiply or Divide to calculate 24. ๐ŸŽฒ๐Ÿƒ + diff --git a/indexCN.html b/indexCN.html index 71e99c3..4b09bc9 100644 --- a/indexCN.html +++ b/indexCN.html @@ -177,6 +177,10 @@

ๆธธๆˆๅˆ—่กจ


31 ็ฉบๆฐ”ๆ›ฒๆฃ็ƒๆธธๆˆ๏ผšไธ€ไธช็ฑปไผผไน’ไน“็ƒ็š„ๆธธๆˆ๏ผŒ็”จ้”ฎ็›˜ๆˆ–้ผ ๆ ‡ๆˆ–ๅคš่งฆ็‚นๅฑๅน•ๆฅ่ฟ›่กŒๅฏนๆˆ˜ๅง๏ผ๐Ÿ€ ๐Ÿ‘ + + 32 + 24 ็‚นๆ‰‘ๅ…‹๏ผšไธ€ไธช็›Šๆ™บ่ฎก็ฎ—็ฑปๆธธๆˆ๏ผŒ้šๆœบๅ–ๅ››ๅผ ๆ‰‘ๅ…‹็‰Œ็”จๅŠ ๅ‡ไน˜้™คๅ››ๅˆ™่ฟ็ฎ—ๆฅ่ฎก็ฎ—24 ็‚น๏ผ๐Ÿƒ + From b59cb5b0175addadd4e64618463e484f68035d97 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 24 Aug 2024 17:10:10 +1000 Subject: [PATCH 81/93] update index and readme --- {32-24 Point-Poker-Game => 32-24-Point-Poker-Game}/index.html | 0 {32-24 Point-Poker-Game => 32-24-Point-Poker-Game}/str.js | 0 README.md | 2 ++ index.html | 2 +- indexCN.html | 2 +- 5 files changed, 4 insertions(+), 2 deletions(-) rename {32-24 Point-Poker-Game => 32-24-Point-Poker-Game}/index.html (100%) rename {32-24 Point-Poker-Game => 32-24-Point-Poker-Game}/str.js (100%) diff --git a/32-24 Point-Poker-Game/index.html b/32-24-Point-Poker-Game/index.html similarity index 100% rename from 32-24 Point-Poker-Game/index.html rename to 32-24-Point-Poker-Game/index.html diff --git a/32-24 Point-Poker-Game/str.js b/32-24-Point-Poker-Game/str.js similarity index 100% rename from 32-24 Point-Poker-Game/str.js rename to 32-24-Point-Poker-Game/str.js diff --git a/README.md b/README.md index 6cb27b1..b550e54 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ fork from https://github.com/he-is-talha/html-css-javascript-games | 28 | [Emoji Catcher Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/28-Emoji-Catcher-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/28-Emoji-Catcher-Game/) | | 29 | [Whack A Mole Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/29-Whack-A-Mole-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/29-Whack-A-Mole-Game/) | | 30 | [Guess Number Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/30-Guess-Number-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/30-Guess-Number-Game/) | +| 31 | [Air Hockey Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/31-Air-Hockey-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/31-Air-Hockey-Game/) | +| 32 | [24 Point Poker Game](https://github.com/leoncoolmoon/html-css-javascript-games/tree/main/32-24-Point-Poker-Game) | [Live Demo](https://leoncoolmoon.github.io/html-css-javascript-games/32-24-Point-Poker-Game/) | ## Games Description 1. **Candy Crush Game**: Enjoy the classic match-three puzzle game where you swap colored candies to create matches and clear levels. ๐Ÿฌ๐Ÿญ diff --git a/index.html b/index.html index 221f78d..1c8730c 100644 --- a/index.html +++ b/index.html @@ -179,7 +179,7 @@

Game List


32 - 24 Point Poker Game: A classic 24 point poker game. Get four random cards to start. Use Add or Subtract or Multiply or Divide to calculate 24. ๐ŸŽฒ๐Ÿƒ + 24 Point Poker Game: A classic 24 point poker game. Get four random cards to start. Use Add or Subtract or Multiply or Divide to calculate 24. ๐ŸŽฒ๐Ÿƒ diff --git a/indexCN.html b/indexCN.html index 4b09bc9..9f6262f 100644 --- a/indexCN.html +++ b/indexCN.html @@ -179,7 +179,7 @@

ๆธธๆˆๅˆ—่กจ


32 - 24 ็‚นๆ‰‘ๅ…‹๏ผšไธ€ไธช็›Šๆ™บ่ฎก็ฎ—็ฑปๆธธๆˆ๏ผŒ้šๆœบๅ–ๅ››ๅผ ๆ‰‘ๅ…‹็‰Œ็”จๅŠ ๅ‡ไน˜้™คๅ››ๅˆ™่ฟ็ฎ—ๆฅ่ฎก็ฎ—24 ็‚น๏ผ๐Ÿƒ + 24 ็‚นๆ‰‘ๅ…‹๏ผšไธ€ไธช็›Šๆ™บ่ฎก็ฎ—็ฑปๆธธๆˆ๏ผŒ้šๆœบๅ–ๅ››ๅผ ๆ‰‘ๅ…‹็‰Œ็”จๅŠ ๅ‡ไน˜้™คๅ››ๅˆ™่ฟ็ฎ—ๆฅ่ฎก็ฎ—24 ็‚น๏ผ๐Ÿƒ From dcf68c5bf8f54ae1732a209ae5503beb844bead8 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 24 Aug 2024 17:39:23 +1000 Subject: [PATCH 82/93] improve looking --- 32-24-Point-Poker-Game/index.html | 122 ++++++++++++++++++++++-------- 1 file changed, 92 insertions(+), 30 deletions(-) diff --git a/32-24-Point-Poker-Game/index.html b/32-24-Point-Poker-Game/index.html index af375aa..dcfe72c 100644 --- a/32-24-Point-Poker-Game/index.html +++ b/32-24-Point-Poker-Game/index.html @@ -6,63 +6,111 @@ 24็‚น -

24็‚น

-
ๅพ—ๅˆ†: 0
-
- - - - - - -
+

24็‚นๆธธๆˆ

+
+
ๅพ—ๅˆ†: 0
+
-
-
- -
+ + + +
+
+ +
+
- - - - - - + + + +
@@ -79,6 +127,16 @@

24็‚น

const method = ['+', '-', '*', '/']; var interval; var score = 0; + function unhide() { + document.getElementById('operation').style.display = 'block'; + document.getElementById('overlay').style.display = 'block'; + } + + function hide() { + document.getElementById('operation').style.display = 'none'; + document.getElementById('overlay').style.display = 'none'; + } + function gaveup() { clearInterval(interval); // ๅœๆญข่ฎกๆ—ถๅ™จ fail(); // ๅ€’่ฎกๆ—ถ็ป“ๆŸ๏ผŒ่งฆๅ‘failๅ‡ฝๆ•ฐ @@ -116,6 +174,7 @@

24็‚น

function selectedMethod(i) { selMethod = i; if (selectedCards.length == 2) { + hide(); var cd = calc(checkCardSourceReturnCardNumber(selectedCards[0]), selMethod, checkCardSourceReturnCardNumber(selectedCards[1])); document.getElementById(`card${selectedCards[0]}`).style.display = "none"; document.getElementById(`card${selectedCards[1]}`).style.display = "none"; @@ -199,6 +258,9 @@

24็‚น

if (selectedCards.length < 2) { selectedCards.push(index); document.getElementById(`card${index}`).style.border = "2px solid blue"; + if(selectedCards.length == 2){ + unhide(); + } } else if (selectedCards.length == 2) { if (selMethod != -1) { var cd = calc(checkCardSourceReturnCardNumber(selectedCards[0]), selMethod, checkCardSourceReturnCardNumber(selectedCards[1])); From 163f02b20010959310244cca8bc02eff26a0d470 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 24 Aug 2024 18:13:05 +1000 Subject: [PATCH 83/93] adjust touch screen --- 19-Flappy-Bird-Game/index.html | 2 +- 19-Flappy-Bird-Game/style.css | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/19-Flappy-Bird-Game/index.html b/19-Flappy-Bird-Game/index.html index b3b54fc..913135d 100644 --- a/19-Flappy-Bird-Game/index.html +++ b/19-Flappy-Bird-Game/index.html @@ -3,7 +3,7 @@ Flappy Bird - + Date: Mon, 26 Aug 2024 16:13:32 +1000 Subject: [PATCH 84/93] improved UI --- 30-Guess-Number-Game/index.html | 280 +++++++++++++++++++++++++------- 1 file changed, 217 insertions(+), 63 deletions(-) diff --git a/30-Guess-Number-Game/index.html b/30-Guess-Number-Game/index.html index bacdda4..a8de9e0 100644 --- a/30-Guess-Number-Game/index.html +++ b/30-Guess-Number-Game/index.html @@ -1,117 +1,271 @@ - + - Number Guessing Game + ็Œœๆ•ฐๅญ—ๆธธๆˆ - - - -

Number Guessing Game

-

Enter a 4-digit number in the form below, with no repeated digits, and click the "Guess" button.

-

If both the position and the number are correct, you get an "A". If only the number is correct but in the wrong position, you get a "B".

-

You can click the "New Game" button to start a new game.

- -
- - - -
+ showResultPopup(message); + updateGameInfo(); + } + + const giveUp = () => { + if (isGameActive) { + endGame(false, "ไฝ ๆ”พๅผƒไบ†ๆธธๆˆใ€‚"); + } else { + alert("ๆฒกๆœ‰่ฟ›่กŒไธญ็š„ๆธธๆˆใ€‚"); + } + } + + const showResultPopup = (message) => { + document.getElementById("give-up-btn").style.display = "none"; + document.getElementById("result-message").textContent = message; + document.getElementById("result-details").textContent = `ๆญฃ็กฎ็ญ”ๆกˆๆ˜ฏ ${answer}`; + document.getElementById("overlay").style.display = "block"; + document.getElementById("result-popup").style.display = "block"; + document.getElementById("result-popup").focus(); + document.addEventListener("keypress", hideResultPopup); + document.addEventListener("mousedown", hideResultPopup); + document.addEventListener("touchstart", hideResultPopup); + } + + const hideResultPopup = () => { + document.getElementById("overlay").style.display = "none"; + document.getElementById("result-popup").style.display = "none"; + document.removeEventListener("keypress", hideResultPopup); + document.removeEventListener("mousedown", hideResultPopup); + document.removeEventListener("touchstart", hideResultPopup); + records = []; + } + + document.getElementById("guess").addEventListener("keyup", (event) => { + if (event.keyCode === 13) { + submitGuess(document.getElementById("guess").value); + } + }); + document.getElementById("guess").focus(); + \ No newline at end of file From 76a2c480076b437c4401a6e48b20cf5748601667 Mon Sep 17 00:00:00 2001 From: Jack Date: Mon, 26 Aug 2024 21:27:48 +1000 Subject: [PATCH 85/93] add langusge support --- 30-Guess-Number-Game/index.html | 129 +++++++++++++++++++++++++++----- 1 file changed, 110 insertions(+), 19 deletions(-) diff --git a/30-Guess-Number-Game/index.html b/30-Guess-Number-Game/index.html index a8de9e0..1ebbb63 100644 --- a/30-Guess-Number-Game/index.html +++ b/30-Guess-Number-Game/index.html @@ -1,5 +1,5 @@ - + ็Œœๆ•ฐๅญ—ๆธธๆˆ @@ -110,20 +110,20 @@
-

็Œœๆ•ฐๅญ—ๆธธๆˆ

+

็Œœๆ•ฐๅญ—ๆธธๆˆ

- ็งฏๅˆ†: 0 - ๅ‰ฉไฝ™ๆ—ถ้—ด: 300็ง’ - ๅ‰ฉไฝ™็Œœๆต‹: 8 + ็งฏๅˆ†: 0 + ๅ‰ฉไฝ™ๆ—ถ้—ด: 300็ง’ + ๅ‰ฉไฝ™็Œœๆต‹: 8
-

ๅœจไธ‹้ข็š„่กจๅ•ไธญ่พ“ๅ…ฅไธ€ไธช4ไฝๆ•ฐๅญ—๏ผˆๆ•ฐๅญ—ไธ้‡ๅค๏ผ‰๏ผŒ็„ถๅŽ็‚นๅ‡ป"็Œœๆต‹"ๆŒ‰้’ฎใ€‚ไฝ ๆœ‰8ๆฌกๆœบไผšๅ’Œ300็ง’ๆ—ถ้—ดใ€‚

-

ๅฆ‚ๆžœๆ•ฐๅญ—ๅ’Œไฝ็ฝฎ้ƒฝๆญฃ็กฎ๏ผŒไฝ ไผšๅพ—ๅˆฐไธ€ไธช"A"ใ€‚ๅฆ‚ๆžœๆ•ฐๅญ—ๆญฃ็กฎไฝ†ไฝ็ฝฎ้”™่ฏฏ๏ผŒไฝ ไผšๅพ—ๅˆฐไธ€ไธช"B"ใ€‚

+

ๅœจไธ‹้ข็š„่กจๅ•ไธญ่พ“ๅ…ฅไธ€ไธช4ไฝๆ•ฐๅญ—๏ผˆๆ•ฐๅญ—ไธ้‡ๅค๏ผ‰๏ผŒ็„ถๅŽ็‚นๅ‡ป"็Œœๆต‹"ๆŒ‰้’ฎใ€‚ไฝ ๆœ‰8ๆฌกๆœบไผšๅ’Œ300็ง’ๆ—ถ้—ดใ€‚

+

ๅฆ‚ๆžœๆ•ฐๅญ—ๅ’Œไฝ็ฝฎ้ƒฝๆญฃ็กฎ๏ผŒไฝ ไผšๅพ—ๅˆฐไธ€ไธช"A"ใ€‚ๅฆ‚ๆžœๆ•ฐๅญ—ๆญฃ็กฎไฝ†ไฝ็ฝฎ้”™่ฏฏ๏ผŒไฝ ไผšๅพ—ๅˆฐไธ€ไธช"B"ใ€‚

-

็Œœๆต‹่ฎฐๅฝ•:

- +

็Œœๆต‹่ฎฐๅฝ•:

+ - +
@@ -134,6 +134,97 @@

- \ No newline at end of file + From edb5167ae4539132f8730d1debd7b9c51020b00b Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 29 Aug 2024 21:24:24 +1000 Subject: [PATCH 86/93] add new game --- 33-helicopter-game/index.html | 1150 +++++++++++++++++++++++++++++++++ 1 file changed, 1150 insertions(+) create mode 100644 33-helicopter-game/index.html diff --git a/33-helicopter-game/index.html b/33-helicopter-game/index.html new file mode 100644 index 0000000..ff7b57a --- /dev/null +++ b/33-helicopter-game/index.html @@ -0,0 +1,1150 @@ + + + + + ๅฏไปฅๅฐ„ๅ‡ป็š„3D็›ดๅ‡ๆœบ + + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + From 4e0e959e968ba4afb8af77381fd7055191c645a6 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 29 Aug 2024 21:42:00 +1000 Subject: [PATCH 87/93] shooting game --- 33-helicopter-game/index.html | 160 +++++++++++++++++++++++++++++++++- 1 file changed, 159 insertions(+), 1 deletion(-) diff --git a/33-helicopter-game/index.html b/33-helicopter-game/index.html index ff7b57a..9dc5347 100644 --- a/33-helicopter-game/index.html +++ b/33-helicopter-game/index.html @@ -2,7 +2,7 @@ - ๅฏไปฅๅฐ„ๅ‡ป็š„3D็›ดๅ‡ๆœบ + ็›ดๅ‡ๆœบๅฐ„ๅ‡ปๅฐๆธธๆˆ +
ๅพ—ๅˆ†: 0
+
ๆ—ถ้—ด: 60s
+
+

ๆธธๆˆ็ป“ๆŸ

+

ไฝ ็š„ๅพ—ๅˆ†:

+

็‚นๅ‡ปไปปๆ„ๅค„้‡ๆ–ฐๅผ€ๅง‹

+
+
@@ -999,7 +1045,18 @@ From da1fa518822c091c5f44a49462047ff81b6b607e Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 10 Oct 2024 11:42:48 +1000 Subject: [PATCH 89/93] add 34 game --- 34-RubikCube-Game/README.en.md | 36 + 34-RubikCube-Game/README.md | 39 + 34-RubikCube-Game/css/style.css | 344 ++++ 34-RubikCube-Game/index.html | 78 + 34-RubikCube-Game/js/common.js | 3001 +++++++++++++++++++++++++++++++ 5 files changed, 3498 insertions(+) create mode 100644 34-RubikCube-Game/README.en.md create mode 100644 34-RubikCube-Game/README.md create mode 100644 34-RubikCube-Game/css/style.css create mode 100644 34-RubikCube-Game/index.html create mode 100644 34-RubikCube-Game/js/common.js diff --git a/34-RubikCube-Game/README.en.md b/34-RubikCube-Game/README.en.md new file mode 100644 index 0000000..99295cb --- /dev/null +++ b/34-RubikCube-Game/README.en.md @@ -0,0 +1,36 @@ +# mofang + +#### Description +{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/34-RubikCube-Game/README.md b/34-RubikCube-Game/README.md new file mode 100644 index 0000000..16ccea7 --- /dev/null +++ b/34-RubikCube-Game/README.md @@ -0,0 +1,39 @@ +# mofang + +#### ไป‹็ป +{**ไปฅไธ‹ๆ˜ฏ Gitee ๅนณๅฐ่ฏดๆ˜Ž๏ผŒๆ‚จๅฏไปฅๆ›ฟๆขๆญค็ฎ€ไป‹** +Gitee ๆ˜ฏ OSCHINA ๆŽจๅ‡บ็š„ๅŸบไบŽ Git ็š„ไปฃ็ ๆ‰˜็ฎกๅนณๅฐ๏ผˆๅŒๆ—ถๆ”ฏๆŒ SVN๏ผ‰ใ€‚ไธ“ไธบๅผ€ๅ‘่€…ๆไพ›็จณๅฎšใ€้ซ˜ๆ•ˆใ€ๅฎ‰ๅ…จ็š„ไบ‘็ซฏ่ฝฏไปถๅผ€ๅ‘ๅไฝœๅนณๅฐ +ๆ— ่ฎบๆ˜ฏไธชไบบใ€ๅ›ข้˜Ÿใ€ๆˆ–ๆ˜ฏไผไธš๏ผŒ้ƒฝ่ƒฝๅคŸ็”จ Gitee ๅฎž็Žฐไปฃ็ ๆ‰˜็ฎกใ€้กน็›ฎ็ฎก็†ใ€ๅไฝœๅผ€ๅ‘ใ€‚ไผไธš้กน็›ฎ่ฏท็œ‹ [https://gitee.com/enterprises](https://gitee.com/enterprises)} + +#### ่ฝฏไปถๆžถๆž„ +่ฝฏไปถๆžถๆž„่ฏดๆ˜Ž + + +#### ๅฎ‰่ฃ…ๆ•™็จ‹ + +1. xxxx +2. xxxx +3. xxxx + +#### ไฝฟ็”จ่ฏดๆ˜Ž + +1. xxxx +2. xxxx +3. xxxx + +#### ๅ‚ไธŽ่ดก็Œฎ + +1. Fork ๆœฌไป“ๅบ“ +2. ๆ–ฐๅปบ Feat_xxx ๅˆ†ๆ”ฏ +3. ๆไบคไปฃ็  +4. ๆ–ฐๅปบ Pull Request + + +#### ็‰นๆŠ€ + +1. ไฝฟ็”จ Readme\_XXX.md ๆฅๆ”ฏๆŒไธๅŒ็š„่ฏญ่จ€๏ผŒไพ‹ๅฆ‚ Readme\_en.md, Readme\_zh.md +2. Gitee ๅฎ˜ๆ–นๅšๅฎข [blog.gitee.com](https://blog.gitee.com) +3. ไฝ ๅฏไปฅ [https://gitee.com/explore](https://gitee.com/explore) ่ฟ™ไธชๅœฐๅ€ๆฅไบ†่งฃ Gitee ไธŠ็š„ไผ˜็ง€ๅผ€ๆบ้กน็›ฎ +4. [GVP](https://gitee.com/gvp) ๅ…จ็งฐๆ˜ฏ Gitee ๆœ€ๆœ‰ไปทๅ€ผๅผ€ๆบ้กน็›ฎ๏ผŒๆ˜ฏ็ปผๅˆ่ฏ„ๅฎšๅ‡บ็š„ไผ˜็ง€ๅผ€ๆบ้กน็›ฎ +5. Gitee ๅฎ˜ๆ–นๆไพ›็š„ไฝฟ็”จๆ‰‹ๅ†Œ [https://gitee.com/help](https://gitee.com/help) +6. Gitee ๅฐ้ขไบบ็‰ฉๆ˜ฏไธ€ๆกฃ็”จๆฅๅฑ•็คบ Gitee ไผšๅ‘˜้ฃŽ้‡‡็š„ๆ ็›ฎ [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/34-RubikCube-Game/css/style.css b/34-RubikCube-Game/css/style.css new file mode 100644 index 0000000..eabdd0e --- /dev/null +++ b/34-RubikCube-Game/css/style.css @@ -0,0 +1,344 @@ + +*, *:before, *:after { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + box-sizing: border-box; + cursor: inherit; + margin: 0; + padding: 0; + outline: none; + font-size: inherit; + font-family: inherit; + font-weight: inherit; + font-style: inherit; + text-transform: uppercase; +} +*:focus { + outline: none; +} + +html { + -webkit-tap-highlight-color: transparent; + -webkit-text-size-adjust: 100%; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; + overflow: hidden; + height: 100%; +} + +body { + font-family: "BungeeFont", sans-serif; + font-weight: normal; + font-style: normal; + line-height: 1; + cursor: default; + overflow: hidden; + height: 100%; + font-size: 5rem; +} + +.icon { + display: inline-block; + font-size: inherit; + overflow: visible; + vertical-align: -0.125em; + preserveAspectRatio: none; +} + +.range { + position: relative; + width: 14em; + z-index: 1; + opacity: 0; +} +.range:not(:last-child) { + margin-bottom: 2em; +} +.range__label { + position: relative; + font-size: 0.9em; + line-height: 0.75em; + padding-bottom: 0.5em; + z-index: 2; +} +.range__track { + position: relative; + height: 1em; + margin-left: 0.5em; + margin-right: 0.5em; + z-index: 3; +} +.range__track-line { + position: absolute; + background: rgba(0, 0, 0, 0.2); + height: 2px; + top: 50%; + margin-top: -1px; + left: -0.5em; + right: -0.5em; + transform-origin: left center; +} +.range__handle { + position: absolute; + width: 0; + height: 0; + top: 50%; + left: 0; + cursor: pointer; + z-index: 1; +} +.range__handle div { + transition: background 500ms ease; + position: absolute; + left: 0; + top: 0; + width: 0.9em; + height: 0.9em; + border-radius: 0.2em; + margin-left: -0.45em; + margin-top: -0.45em; + background: #41aac8; + border-bottom: 2px solid rgba(0, 0, 0, 0.2); +} +.range.is-active .range__handle div { + transform: scale(1.25); +} +.range__handle:after { + content: ""; + position: absolute; + left: 0; + top: 0; + width: 3em; + height: 3em; + margin-left: -1.5em; + margin-top: -1.5em; +} +.range__list { + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + position: relative; + padding-top: 0.5em; + font-size: 0.55em; + color: rgba(0, 0, 0, 0.5); + z-index: 1; +} + +.stats { + position: relative; + width: 14em; + z-index: 1; + display: flex; + justify-content: space-between; + opacity: 0; +} +.stats:not(:last-child) { + margin-bottom: 1.5em; +} +.stats i { + display: inline-block; + color: rgba(0, 0, 0, 0.5); + font-size: 0.9em; +} +.stats b { + display: inline-block; + font-size: 0.9em; +} + +.text { + position: absolute; + left: 0; + right: 0; + text-align: center; + line-height: 0.75; + perspective: 100rem; + opacity: 0; +} +.text i { + display: inline-block; + opacity: 0; + white-space: pre-wrap; +} +.text--title { + bottom: 75%; + font-size: 4.4em; + height: 1.2em; +} +.text--title span { + display: block; +} +.text--title span:first-child { + font-size: 0.5em; + margin-bottom: 0.2em; +} +.text--note { + top: 87%; + font-size: 1em; +} +.text--timer { + bottom: 78%; + font-size: 3.5em; + line-height: 1; +} +.text--complete, .text--best-time { + font-size: 1.5em; + top: 83%; + line-height: 1em; +} + +.btn { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + background-color: transparent; + border-radius: 0; + border-width: 0; + position: absolute; + pointer-events: none; + font-size: 1.2em; + color: rgba(0, 0, 0, 0.25); + opacity: 0; +} +.btn:after { + position: absolute; + content: ""; + width: 3em; + height: 3em; + left: 50%; + top: 50%; + margin-left: -1.5em; + margin-top: -1.5em; + border-radius: 100%; +} +.btn--bl { + bottom: 0.8em; + left: 0.8em; +} +.btn--br { + bottom: 0.8em; + right: 0.8em; +} +.btn--bc { + bottom: 0.8em; + left: calc(50% - 0.5em); +} +.btn--pwa { + transition: color 500ms ease; + color: inherit; + height: 1em; +} +.btn--pwa svg { + font-size: 0.6em; + margin: 0.35em 0; +} +.btn svg { + display: block; +} + +.mofang { + pointer-events: none; + color: #070d15; +} +.mofang, .mofang__background, .mofang__game, .mofang__texts, .mofang__prefs, .mofang__stats, .mofang__buttons { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + overflow: hidden; +} +.mofang__background { + z-index: 1; + transition: background 500ms ease; + background: #d1d5db; +} +.mofang__background:after { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + content: ""; + background-image: linear-gradient(to bottom, white 50%, rgba(255, 255, 255, 0) 100%); +} +.mofang__game { + pointer-events: all; + z-index: 2; +} +.mofang__game canvas { + display: block; + width: 100%; + height: 100%; +} +.mofang__texts { + z-index: 3; +} +.mofang__prefs, .mofang__stats { + display: flex; + flex-flow: column nowrap; + justify-content: center; + align-items: center; + overflow: hidden; + z-index: 4; +} +.mofang__buttons { + z-index: 5; +} +.mofang__notification { + transition: transform 500ms ease, opacity 500ms ease; + font-family: sans-serif; + position: absolute; + left: 50%; + bottom: 0.6em; + padding: 0.6em; + margin-left: -9.4em; + width: 18.8em; + z-index: 6; + background: rgba(17, 17, 17, 0.9); + border-radius: 0.8em; + display: flex; + align-items: center; + flex-flow: row nowrap; + color: #fff; + user-select: none; + opacity: 0; + pointer-events: none; + transform: translateY(100%); +} +.mofang__notification.is-active { + opacity: 1; + pointer-events: all; + transform: none; +} +.mofang__notification * { + text-transform: none; +} +.mofang__notification-icon { + background-size: 100% 100%; + left: 0.6em; + top: 0.6em; + width: 2.8em; + height: 2.8em; + border-radius: 0.5em; + background: #fff; + margin-right: 0.6em; + display: block; +} +.mofang__notification-text { + font-size: 0.75em; + line-height: 1.4em; +} +.mofang__notification-text .icon { + color: #4f82fd; + font-size: 1.1em; +} +.mofang__notification-text b { + font-weight: 700; +} + +.btn--stats { + visibility: hidden; +} \ No newline at end of file diff --git a/34-RubikCube-Game/index.html b/34-RubikCube-Game/index.html new file mode 100644 index 0000000..69cb5f2 --- /dev/null +++ b/34-RubikCube-Game/index.html @@ -0,0 +1,78 @@ + + + + + ้ญ”ๆ–น + + + + +
+
+
+
+

+ ้ญ”ๆ–น +

+
+ ๅŒๅ‡ปๅณๅฏๅผ€ๅง‹ +
+
+ 0:00 +
+
+ ๅฎŒๆˆ! +
+
+ + ๆœ€ไฝณๆ—ถ้—ด! +
+
+ +
+ + + + +
+ +
+
+ ๅ…จ้ƒจ่งฃๅ†ณ:- +
+
+ ๆœ€ไฝณๆ—ถ้—ด:- +
+
+ ๆœ€ๅทฎๆ—ถ้—ด:- +
+
+ ๅนณๅ‡ๅ€ผ 5:- +
+
+ ๅนณๅ‡ๅ€ผ 12:- +
+
+ ๅนณๅ‡ๅ€ผ 25:- +
+
+ +
+ + + + + +
+
+ + + + + \ No newline at end of file diff --git a/34-RubikCube-Game/js/common.js b/34-RubikCube-Game/js/common.js new file mode 100644 index 0000000..33bcad6 --- /dev/null +++ b/34-RubikCube-Game/js/common.js @@ -0,0 +1,3001 @@ +const animationEngine = (() => { + let uniqueID = 0; + class AnimationEngine { + constructor() { + this.ids = []; + this.animations = {}; + this.update = this.update.bind( this ); + this.raf = 0; + this.time = 0; + } + update() { + const now = performance.now(); + const delta = now - this.time; + this.time = now; + let i = this.ids.length; + this.raf = i ? requestAnimationFrame( this.update ) : 0; + while ( i-- ) + this.animations[ this.ids[ i ] ] && this.animations[ this.ids[ i ] ].update( delta ); + } + + add( animation ) { + animation.id = uniqueID ++; + this.ids.push( animation.id ); + this.animations[ animation.id ] = animation; + if ( this.raf !== 0 ) return; + this.time = performance.now(); + this.raf = requestAnimationFrame( this.update ); + + } + + remove( animation ) { + const index = this.ids.indexOf( animation.id ); + if ( index < 0 ) return; + this.ids.splice( index, 1 ); + delete this.animations[ animation.id ]; + animation = null; + } + } + + return new AnimationEngine(); +} )(); + +class Animation { + constructor( start ) { + if ( start === true ) this.start(); + } + start() { + animationEngine.add( this ); + } + stop() { + animationEngine.remove( this ); + } + update( delta ) {} +} + +class World extends Animation { + constructor( game ) { + super( true ); + this.game = game; + this.container = this.game.dom.game; + this.scene = new THREE.Scene(); + + this.renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } ); + this.renderer.setPixelRatio( window.devicePixelRatio ); + this.container.appendChild( this.renderer.domElement ); + + this.camera = new THREE.PerspectiveCamera( 2, 1, 0.1, 10000 ); + this.stage = { width: 2, height: 3 }; + this.fov = 10; + + this.createLights(); + this.onResize = []; + this.resize(); + window.addEventListener( 'resize', () => this.resize(), false ); + } + + update() { + this.renderer.render( this.scene, this.camera ); + + } + // ๆŽงๅˆถ็ช—ๅฃๅคงๅฐ + resize() { + this.width = this.container.offsetWidth; + this.height = this.container.offsetHeight; + this.renderer.setSize( this.width, this.height ); + this.camera.fov = this.fov; + this.camera.aspect = this.width / this.height; + + const aspect = this.stage.width / this.stage.height; + const fovRad = this.fov * THREE.Math.DEG2RAD; + + let distance = ( aspect < this.camera.aspect ) + ? ( this.stage.height / 2 ) / Math.tan( fovRad / 2 ) + : ( this.stage.width / this.camera.aspect ) / ( 2 * Math.tan( fovRad / 2 ) ); + + distance *= 0.5; + + this.camera.position.set( distance, distance, distance); + this.camera.lookAt( this.scene.position ); + this.camera.updateProjectionMatrix(); + + const docFontSize = ( aspect < this.camera.aspect ) + ? ( this.height / 100 ) * aspect + : this.width / 100; + + document.documentElement.style.fontSize = docFontSize + 'px'; + + if ( this.onResize ) this.onResize.forEach( cb => cb() ); + + } + // ๅˆ›ๅปบๅ…‰็บฟ + createLights() { + this.lights = { + holder: new THREE.Object3D, + ambient: new THREE.AmbientLight( 0xffffff, 0.69 ), + front: new THREE.DirectionalLight( 0xffffff, 0.36 ), + back: new THREE.DirectionalLight( 0xffffff, 0.19 ), + }; + + this.lights.front.position.set( 1.5, 5, 3 ); + this.lights.back.position.set( -1.5, -5, -3 ); + + this.lights.holder.add( this.lights.ambient ); + this.lights.holder.add( this.lights.front ); + this.lights.holder.add( this.lights.back ); + + this.scene.add( this.lights.holder ); + + } + + enableShadows() { + this.renderer.shadowMap.enabled = true; + this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; + + this.lights.front.castShadow = true; + + this.lights.front.shadow.mapSize.width = 512; + this.lights.front.shadow.mapSize.height = 512; + + var d = 1.5; + this.lights.front.shadow.camera.left = -d; + this.lights.front.shadow.camera.right = d; + this.lights.front.shadow.camera.top = d; + this.lights.front.shadow.camera.bottom = -d; + this.lights.front.shadow.camera.near = 1; + this.lights.front.shadow.camera.far = 9; + this.game.cube.holder.traverse( node => { + if ( node instanceof THREE.Mesh ) { + node.castShadow = true; + node.receiveShadow = true; + + } + } ); + + } + +} + +function RoundedBoxGeometry( size, radius, radiusSegments ) { + THREE.BufferGeometry.call( this ); + this.type = 'RoundedBoxGeometry'; + radiusSegments = ! isNaN( radiusSegments ) ? Math.max( 1, Math.floor( radiusSegments ) ) : 1; + + var width, height, depth; + width = height = depth = size; + radius = size * radius; + + radius = Math.min( radius, Math.min( width, Math.min( height, Math.min( depth ) ) ) / 2 ); + + var edgeHalfWidth = width / 2 - radius; + var edgeHalfHeight = height / 2 - radius; + var edgeHalfDepth = depth / 2 - radius; + + this.parameters = { + width: width, + height: height, + depth: depth, + radius: radius, + radiusSegments: radiusSegments + }; + + var rs1 = radiusSegments + 1; + var totalVertexCount = ( rs1 * radiusSegments + 1 ) << 3; + + var positions = new THREE.BufferAttribute( new Float32Array( totalVertexCount * 3 ), 3 ); + var normals = new THREE.BufferAttribute( new Float32Array( totalVertexCount * 3 ), 3 ); + + var + cornerVerts = [], + cornerNormals = [], + normal = new THREE.Vector3(), + vertex = new THREE.Vector3(), + vertexPool = [], + normalPool = [], + indices = [] + ; + + var + lastVertex = rs1 * radiusSegments, + cornerVertNumber = rs1 * radiusSegments + 1 + ; + + doVertices(); + doFaces(); + doCorners(); + doHeightEdges(); + doWidthEdges(); + doDepthEdges(); + + function doVertices() { + + var cornerLayout = [ + new THREE.Vector3( 1, 1, 1 ), + new THREE.Vector3( 1, 1, - 1 ), + new THREE.Vector3( - 1, 1, - 1 ), + new THREE.Vector3( - 1, 1, 1 ), + new THREE.Vector3( 1, - 1, 1 ), + new THREE.Vector3( 1, - 1, - 1 ), + new THREE.Vector3( - 1, - 1, - 1 ), + new THREE.Vector3( - 1, - 1, 1 ) + ]; + + for ( var j = 0; j < 8; j ++ ) { + + cornerVerts.push( [] ); + cornerNormals.push( [] ); + + } + + var PIhalf = Math.PI / 2; + var cornerOffset = new THREE.Vector3( edgeHalfWidth, edgeHalfHeight, edgeHalfDepth ); + + for ( var y = 0; y <= radiusSegments; y ++ ) { + + var v = y / radiusSegments; + var va = v * PIhalf; + var cosVa = Math.cos( va ); + var sinVa = Math.sin( va ); + + if ( y == radiusSegments ) { + + vertex.set( 0, 1, 0 ); + var vert = vertex.clone().multiplyScalar( radius ).add( cornerOffset ); + cornerVerts[ 0 ].push( vert ); + vertexPool.push( vert ); + var norm = vertex.clone(); + cornerNormals[ 0 ].push( norm ); + normalPool.push( norm ); + continue; + + } + + for ( var x = 0; x <= radiusSegments; x ++ ) { + + var u = x / radiusSegments; + var ha = u * PIhalf; + vertex.x = cosVa * Math.cos( ha ); + vertex.y = sinVa; + vertex.z = cosVa * Math.sin( ha ); + + var vert = vertex.clone().multiplyScalar( radius ).add( cornerOffset ); + cornerVerts[ 0 ].push( vert ); + vertexPool.push( vert ); + + var norm = vertex.clone().normalize(); + cornerNormals[ 0 ].push( norm ); + normalPool.push( norm ); + + } + + } + + for ( var i = 1; i < 8; i ++ ) { + + for ( var j = 0; j < cornerVerts[ 0 ].length; j ++ ) { + + var vert = cornerVerts[ 0 ][ j ].clone().multiply( cornerLayout[ i ] ); + cornerVerts[ i ].push( vert ); + vertexPool.push( vert ); + + var norm = cornerNormals[ 0 ][ j ].clone().multiply( cornerLayout[ i ] ); + cornerNormals[ i ].push( norm ); + normalPool.push( norm ); + + } + + } + + } + + function doCorners() { + + var flips = [ + true, + false, + true, + false, + false, + true, + false, + true + ]; + + var lastRowOffset = rs1 * ( radiusSegments - 1 ); + + for ( var i = 0; i < 8; i ++ ) { + var cornerOffset = cornerVertNumber * i; + for ( var v = 0; v < radiusSegments - 1; v ++ ) { + var r1 = v * rs1; + var r2 = ( v + 1 ) * rs1; + for ( var u = 0; u < radiusSegments; u ++ ) { + var u1 = u + 1; + var a = cornerOffset + r1 + u; + var b = cornerOffset + r1 + u1; + var c = cornerOffset + r2 + u; + var d = cornerOffset + r2 + u1; + if ( ! flips[ i ] ) { + indices.push( a ); + indices.push( b ); + indices.push( c ); + indices.push( b ); + indices.push( d ); + indices.push( c ); + } else { + indices.push( a ); + indices.push( c ); + indices.push( b ); + indices.push( b ); + indices.push( c ); + indices.push( d ); + } + } + } + for ( var u = 0; u < radiusSegments; u ++ ) { + var a = cornerOffset + lastRowOffset + u; + var b = cornerOffset + lastRowOffset + u + 1; + var c = cornerOffset + lastVertex; + if ( ! flips[ i ] ) { + indices.push( a ); + indices.push( b ); + indices.push( c ); + } else { + indices.push( a ); + indices.push( c ); + indices.push( b ); + } + } + } + } + + function doFaces() { + var a = lastVertex; + var b = lastVertex + cornerVertNumber; + var c = lastVertex + cornerVertNumber * 2; + var d = lastVertex + cornerVertNumber * 3; + indices.push( a ); + indices.push( b ); + indices.push( c ); + indices.push( a ); + indices.push( c ); + indices.push( d ); + a = lastVertex + cornerVertNumber * 4; + b = lastVertex + cornerVertNumber * 5; + c = lastVertex + cornerVertNumber * 6; + d = lastVertex + cornerVertNumber * 7; + + indices.push( a ); + indices.push( c ); + indices.push( b ); + indices.push( a ); + indices.push( d ); + indices.push( c ); + + a = 0; + b = cornerVertNumber; + c = cornerVertNumber * 4; + d = cornerVertNumber * 5; + + indices.push( a ); + indices.push( c ); + indices.push( b ); + indices.push( b ); + indices.push( c ); + indices.push( d ); + + a = cornerVertNumber * 2; + b = cornerVertNumber * 3; + c = cornerVertNumber * 6; + d = cornerVertNumber * 7; + + indices.push( a ); + indices.push( c ); + indices.push( b ); + indices.push( b ); + indices.push( c ); + indices.push( d ); + + a = radiusSegments; + b = radiusSegments + cornerVertNumber * 3; + c = radiusSegments + cornerVertNumber * 4; + d = radiusSegments + cornerVertNumber * 7; + + indices.push( a ); + indices.push( b ); + indices.push( c ); + indices.push( b ); + indices.push( d ); + indices.push( c ); + + a = radiusSegments + cornerVertNumber; + b = radiusSegments + cornerVertNumber * 2; + c = radiusSegments + cornerVertNumber * 5; + d = radiusSegments + cornerVertNumber * 6; + + indices.push( a ); + indices.push( c ); + indices.push( b ); + indices.push( b ); + indices.push( c ); + indices.push( d ); + + } + + function doHeightEdges() { + for ( var i = 0; i < 4; i ++ ) { + var cOffset = i * cornerVertNumber; + var cRowOffset = 4 * cornerVertNumber + cOffset; + var needsFlip = i & 1 === 1; + for ( var u = 0; u < radiusSegments; u ++ ) { + var u1 = u + 1; + var a = cOffset + u; + var b = cOffset + u1; + var c = cRowOffset + u; + var d = cRowOffset + u1; + if ( ! needsFlip ) { + indices.push( a ); + indices.push( b ); + indices.push( c ); + indices.push( b ); + indices.push( d ); + indices.push( c ); + } else { + indices.push( a ); + indices.push( c ); + indices.push( b ); + indices.push( b ); + indices.push( c ); + indices.push( d ); + } + } + } + } + + function doDepthEdges() { + var cStarts = [ 0, 2, 4, 6 ]; + var cEnds = [ 1, 3, 5, 7 ]; + for ( var i = 0; i < 4; i ++ ) { + var cStart = cornerVertNumber * cStarts[ i ]; + var cEnd = cornerVertNumber * cEnds[ i ]; + var needsFlip = 1 >= i; + for ( var u = 0; u < radiusSegments; u ++ ) { + var urs1 = u * rs1; + var u1rs1 = ( u + 1 ) * rs1; + var a = cStart + urs1; + var b = cStart + u1rs1; + var c = cEnd + urs1; + var d = cEnd + u1rs1; + if ( needsFlip ) { + indices.push( a ); + indices.push( c ); + indices.push( b ); + indices.push( b ); + indices.push( c ); + indices.push( d ); + } else { + indices.push( a ); + indices.push( b ); + indices.push( c ); + indices.push( b ); + indices.push( d ); + indices.push( c ); + } + } + } + } + + function doWidthEdges() { + var end = radiusSegments - 1; + var cStarts = [ 0, 1, 4, 5 ]; + var cEnds = [ 3, 2, 7, 6 ]; + var needsFlip = [ 0, 1, 1, 0 ]; + for ( var i = 0; i < 4; i ++ ) { + var cStart = cStarts[ i ] * cornerVertNumber; + var cEnd = cEnds[ i ] * cornerVertNumber; + for ( var u = 0; u <= end; u ++ ) { + var a = cStart + radiusSegments + u * rs1; + var b = cStart + ( u != end ? radiusSegments + ( u + 1 ) * rs1 : cornerVertNumber - 1 ); + var c = cEnd + radiusSegments + u * rs1; + var d = cEnd + ( u != end ? radiusSegments + ( u + 1 ) * rs1 : cornerVertNumber - 1 ); + if ( ! needsFlip[ i ] ) { + indices.push( a ); + indices.push( b ); + indices.push( c ); + indices.push( b ); + indices.push( d ); + indices.push( c ); + } else { + indices.push( a ); + indices.push( c ); + indices.push( b ); + indices.push( b ); + indices.push( c ); + indices.push( d ); + } + } + } + } + + var index = 0; + for ( var i = 0; i < vertexPool.length; i ++ ) { + positions.setXYZ( + index, + vertexPool[ i ].x, + vertexPool[ i ].y, + vertexPool[ i ].z + ); + normals.setXYZ( + index, + normalPool[ i ].x, + normalPool[ i ].y, + normalPool[ i ].z + ); + index ++; + } + this.setIndex( new THREE.BufferAttribute( new Uint16Array( indices ), 1 ) ); + this.addAttribute( 'position', positions ); + this.addAttribute( 'normal', normals ); +} + +RoundedBoxGeometry.prototype = Object.create( THREE.BufferGeometry.prototype ); +RoundedBoxGeometry.constructor = RoundedBoxGeometry; +function RoundedPlaneGeometry( size, radius, depth ) { + var x, y, width, height; + x = y = - size / 2; + width = height = size; + radius = size * radius; + const shape = new THREE.Shape(); + shape.moveTo( x, y + radius ); + shape.lineTo( x, y + height - radius ); + shape.quadraticCurveTo( x, y + height, x + radius, y + height ); + shape.lineTo( x + width - radius, y + height ); + shape.quadraticCurveTo( x + width, y + height, x + width, y + height - radius ); + shape.lineTo( x + width, y + radius ); + shape.quadraticCurveTo( x + width, y, x + width - radius, y ); + shape.lineTo( x + radius, y ); + shape.quadraticCurveTo( x, y, x, y + radius ); + const geometry = new THREE.ExtrudeBufferGeometry( + shape, + { depth: depth, bevelEnabled: false, curveSegments: 3 } + ); + + return geometry; +} + +class Cube { + constructor( game ) { + this.game = game; + this.geometry = { + pieceSize: 1 / 3, + pieceCornerRadius: 0.12, + edgeCornerRoundness: 0.15, + edgeScale: 0.82, + edgeDepth: 0.01, + }; + + this.holder = new THREE.Object3D(); + this.object = new THREE.Object3D(); + this.animator = new THREE.Object3D(); + this.holder.add( this.animator ); + this.animator.add( this.object ); + + this.cubes = []; + this.generatePositions(); + this.generateModel(); + this.pieces.forEach( piece => { + this.cubes.push( piece.userData.cube ); + this.object.add( piece ); + }); + + this.holder.traverse( node => { + if ( node.frustumCulled ) node.frustumCulled = false; + }); + this.game.world.scene.add( this.holder ); + } + + reset() { + this.game.controls.edges.rotation.set( 0, 0, 0 ); + this.holder.rotation.set( 0, 0, 0 ); + this.object.rotation.set( 0, 0, 0 ); + this.animator.rotation.set( 0, 0, 0 ); + this.pieces.forEach( piece => { + piece.position.copy( piece.userData.start.position ); + piece.rotation.copy( piece.userData.start.rotation ); + }); + } + + generatePositions() { + let x, y, z; + this.positions = []; + for ( x = 0; x < 3; x ++ ) { + for ( y = 0; y < 3; y ++ ) { + for ( z = 0; z < 3; z ++ ) { + let position = new THREE.Vector3( x - 1, y - 1, z - 1 ); + let edges = []; + if ( x == 0 ) edges.push(0); + if ( x == 2 ) edges.push(1); + if ( y == 0 ) edges.push(2); + if ( y == 2 ) edges.push(3); + if ( z == 0 ) edges.push(4); + if ( z == 2 ) edges.push(5); + position.edges = edges; + this.positions.push( position ); + } + } + } + } + generateModel() { + this.pieces = []; + this.edges = []; + const pieceSize = 1 / 3; + const mainMaterial = new THREE.MeshLambertMaterial(); + const pieceMesh = new THREE.Mesh( + new RoundedBoxGeometry( pieceSize, this.geometry.pieceCornerRadius, 3 ), + mainMaterial.clone() + ); + const edgeGeometry = RoundedPlaneGeometry( + pieceSize, + this.geometry.edgeCornerRoundness, + this.geometry.edgeDepth ); + this.positions.forEach( ( position, index ) => { + const piece = new THREE.Object3D(); + const pieceCube = pieceMesh.clone(); + const pieceEdges = []; + piece.position.copy( position.clone().divideScalar( 3 ) ); + piece.add( pieceCube ); + piece.name = index; + piece.edgesName = ''; + position.edges.forEach( position => { + const edge = new THREE.Mesh( edgeGeometry, mainMaterial.clone() ); + const name = [ 'L', 'R', 'D', 'U', 'B', 'F' ][ position ]; + const distance = pieceSize / 2; + edge.position.set( + distance * [ - 1, 1, 0, 0, 0, 0 ][ position ], + distance * [ 0, 0, - 1, 1, 0, 0 ][ position ], + distance * [ 0, 0, 0, 0, - 1, 1 ][ position ] + ); + edge.rotation.set( + Math.PI / 2 * [ 0, 0, 1, - 1, 0, 0 ][ position ], + Math.PI / 2 * [ - 1, 1, 0, 0, 2, 0 ][ position ], + 0 + ); + edge.scale.set( + this.geometry.edgeScale, + this.geometry.edgeScale, + this.geometry.edgeScale + ); + edge.name = name; + piece.add( edge ); + pieceEdges.push( name ); + this.edges.push( edge ); + }); + + piece.userData.edges = pieceEdges; + piece.userData.cube = pieceCube; + piece.userData.start = { + position: piece.position.clone(), + rotation: piece.rotation.clone(), + }; + this.pieces.push( piece ); + + }); + } +} + +const Easing = { + Power: { + In: power => { + power = Math.round( power || 1 ); + return t => Math.pow( t, power ); + }, + + Out: power => { + power = Math.round( power || 1 ); + return t => 1 - Math.abs( Math.pow( t - 1, power ) ); + }, + + InOut: power => { + power = Math.round( power || 1 ); + return t => ( t < 0.5 ) + ? Math.pow( t * 2, power ) / 2 + : ( 1 - Math.abs( Math.pow( ( t * 2 - 1 ) - 1, power ) ) ) / 2 + 0.5; + }, + }, + + Sine: { + In: () => t => 1 + Math.sin( Math.PI / 2 * t - Math.PI / 2 ), + Out: () => t => Math.sin( Math.PI / 2 * t ), + InOut: () => t => ( 1 + Math.sin( Math.PI * t - Math.PI / 2 ) ) / 2, + }, + Back: { + Out: s => { + s = s || 1.70158; + return t => { return ( t -= 1 ) * t * ( ( s + 1 ) * t + s ) + 1; }; + }, + In: s => { + s = s || 1.70158; + return t => { return t * t * ( ( s + 1 ) * t - s ); }; + } + }, + + Elastic: { + Out: ( amplitude, period ) => { + let PI2 = Math.PI * 2; + let p1 = ( amplitude >= 1 ) ? amplitude : 1; + let p2 = ( period || 0.3 ) / ( amplitude < 1 ? amplitude : 1 ); + let p3 = p2 / PI2 * ( Math.asin( 1 / p1 ) || 0 ); + p2 = PI2 / p2; + return t => { return p1 * Math.pow( 2, -10 * t ) * Math.sin( ( t - p3 ) * p2 ) + 1 } + }, + }, +}; + +class Tween extends Animation { + constructor( options ) { + super( false ); + this.duration = options.duration || 500; + this.easing = options.easing || ( t => t ); + this.onUpdate = options.onUpdate || ( () => {} ); + this.onComplete = options.onComplete || ( () => {} ); + this.delay = options.delay || false; + this.yoyo = options.yoyo ? false : null; + this.progress = 0; + this.value = 0; + this.delta = 0; + this.getFromTo( options ); + if ( this.delay ) setTimeout( () => super.start(), this.delay ); + else super.start(); + this.onUpdate( this ); + } + + update( delta ) { + const old = this.value * 1; + const direction = ( this.yoyo === true ) ? - 1 : 1; + this.progress += ( delta / this.duration ) * direction; + this.value = this.easing( this.progress ); + this.delta = this.value - old; + if ( this.values !== null ) this.updateFromTo(); + if ( this.yoyo !== null ) this.updateYoyo(); + else if ( this.progress <= 1 ) this.onUpdate( this ); + else { + this.progress = 1; + this.value = 1; + this.onUpdate( this ); + this.onComplete( this ); + super.stop(); + } + } + + updateYoyo() { + if ( this.progress > 1 || this.progress < 0 ) { + this.value = this.progress = ( this.progress > 1 ) ? 1 : 0; + this.yoyo = ! this.yoyo; + } + this.onUpdate( this ); + } + + updateFromTo() { + this.values.forEach( key => { + this.target[ key ] = this.from[ key ] + ( this.to[ key ] - this.from[ key ] ) * this.value; + } ); + } + + getFromTo( options ) { + if ( ! options.target || ! options.to ) { + this.values = null; + return; + } + this.target = options.target || null; + this.from = options.from || {}; + this.to = options.to || null; + this.values = []; + if ( Object.keys( this.from ).length < 1 ) + Object.keys( this.to ).forEach( key => { this.from[ key ] = this.target[ key ]; } ); + Object.keys( this.to ).forEach( key => { this.values.push( key ); } ); + } +} + +window.addEventListener( 'touchmove', () => {} ); +document.addEventListener( 'touchmove', event => { event.preventDefault(); }, { passive: false } ); + +class Draggable { + constructor( element, options ) { + this.position = { + current: new THREE.Vector2(), + start: new THREE.Vector2(), + delta: new THREE.Vector2(), + old: new THREE.Vector2(), + drag: new THREE.Vector2(), + }; + + this.options = Object.assign( { + calcDelta: false, + }, options || {} ); + + this.element = element; + this.touch = null; + this.drag = { + start: ( event ) => { + if ( event.type == 'mousedown' && event.which != 1 ) return; + if ( event.type == 'touchstart' && event.touches.length > 1 ) return; + this.getPositionCurrent( event ); + if ( this.options.calcDelta ) { + this.position.start = this.position.current.clone(); + this.position.delta.set( 0, 0 ); + this.position.drag.set( 0, 0 ); + } + + this.touch = ( event.type == 'touchstart' ); + this.onDragStart( this.position ); + window.addEventListener( ( this.touch ) ? 'touchmove' : 'mousemove', this.drag.move, false ); + window.addEventListener( ( this.touch ) ? 'touchend' : 'mouseup', this.drag.end, false ); + + }, + + move: ( event ) => { + if ( this.options.calcDelta ) { + this.position.old = this.position.current.clone(); + } + + this.getPositionCurrent( event ); + if ( this.options.calcDelta ) { + this.position.delta = this.position.current.clone().sub( this.position.old ); + this.position.drag = this.position.current.clone().sub( this.position.start ); + } + + this.onDragMove( this.position ); + }, + + end: ( event ) => { + this.getPositionCurrent( event ); + this.onDragEnd( this.position ); + window.removeEventListener( ( this.touch ) ? 'touchmove' : 'mousemove', this.drag.move, false ); + window.removeEventListener( ( this.touch ) ? 'touchend' : 'mouseup', this.drag.end, false ); + }, + + }; + + this.onDragStart = () => {}; + this.onDragMove = () => {}; + this.onDragEnd = () => {}; + this.enable(); + return this; + } + + enable() { + this.element.addEventListener( 'touchstart', this.drag.start, false ); + this.element.addEventListener( 'mousedown', this.drag.start, false ); + return this; + } + + disable() { + this.element.removeEventListener( 'touchstart', this.drag.start, false ); + this.element.removeEventListener( 'mousedown', this.drag.start, false ); + return this; + } + + getPositionCurrent( event ) { + const dragEvent = event.touches + ? ( event.touches[ 0 ] || event.changedTouches[ 0 ] ) + : event; + this.position.current.set( dragEvent.pageX, dragEvent.pageY ); + } + + convertPosition( position ) { + position.x = ( position.x / this.element.offsetWidth ) * 2 - 1; + position.y = - ( ( position.y / this.element.offsetHeight ) * 2 - 1 ); + return position; + } + +} + +const STILL = 0; +const PREPARING = 1; +const ROTATING = 2; +const ANIMATING = 3; +class Controls { + constructor( game ) { + this.game = game; + this.flipConfig = 0; + this.flipEasings = [ Easing.Power.Out( 3 ), Easing.Sine.Out(), Easing.Back.Out( 2 ) ]; + this.flipSpeeds = [ 125, 200, 350 ]; + this.raycaster = new THREE.Raycaster(); + const helperMaterial = new THREE.MeshBasicMaterial( { depthWrite: false, transparent: true, opacity: 0, color: 0x0033ff } ); + this.group = new THREE.Object3D(); + this.game.cube.object.add( this.group ); + + this.helper = new THREE.Mesh( + new THREE.PlaneBufferGeometry( 20, 20 ), + helperMaterial.clone(), + ); + + this.helper.rotation.set( 0, Math.PI / 4, 0 ); + this.game.world.scene.add( this.helper ); + + this.edges = new THREE.Mesh( + new THREE.BoxBufferGeometry( 0.95, 0.95, 0.95 ), + helperMaterial.clone(), + ); + + this.game.world.scene.add( this.edges ); + + this.onSolved = () => {}; + this.onMove = () => {}; + + this.momentum = []; + + this.scramble = null; + this.state = STILL; + + this.initDraggable(); + + } + + enable() { + this.draggable.enable(); + } + + disable() { + this.draggable.disable(); + } + + initDraggable() { + this.draggable = new Draggable( this.game.dom.game ); + this.draggable.onDragStart = position => { + if ( this.scramble !== null ) return; + if ( this.state === PREPARING || this.state === ROTATING ) return; + this.gettingDrag = this.state === ANIMATING; + const edgeIntersect = this.getIntersect( position.current, this.edges, false ); + if ( edgeIntersect !== false ) { + this.dragNormal = edgeIntersect.face.normal.round(); + this.flipType = 'layer'; + this.attach( this.helper, this.edges ); + + this.helper.rotation.set( 0, 0, 0 ); + this.helper.position.set( 0, 0, 0 ); + this.helper.lookAt( this.dragNormal ); + this.helper.translateZ( 0.5 ); + this.helper.updateMatrixWorld(); + + this.detach( this.helper, this.edges ); + + } else { + + this.dragNormal = new THREE.Vector3( 0, 0, 1 ); + this.flipType = 'cube'; + + this.helper.position.set( 0, 0, 0 ); + this.helper.rotation.set( 0, Math.PI / 4, 0 ); + this.helper.updateMatrixWorld(); + + } + + const planeIntersect = this.getIntersect( position.current, this.helper, false ).point; + if ( planeIntersect === false ) return; + + this.dragCurrent = this.helper.worldToLocal( planeIntersect ); + this.dragTotal = new THREE.Vector3(); + this.state = ( this.state === STILL ) ? PREPARING : this.state; + + }; + + this.draggable.onDragMove = position => { + + if ( this.scramble !== null ) return; + if ( this.state === STILL || ( this.state === ANIMATING && this.gettingDrag === false ) ) return; + + const planeIntersect = this.getIntersect( position.current, this.helper, false ); + if ( planeIntersect === false ) return; + + const point = this.helper.worldToLocal( planeIntersect.point.clone() ); + + this.dragDelta = point.clone().sub( this.dragCurrent ).setZ( 0 ); + this.dragTotal.add( this.dragDelta ); + this.dragCurrent = point; + this.addMomentumPoint( this.dragDelta ); + + if ( this.state === PREPARING && this.dragTotal.length() > 0.05 ) { + + this.dragDirection = this.getMainAxis( this.dragTotal ); + + if ( this.flipType === 'layer' ) { + + const direction = new THREE.Vector3(); + direction[ this.dragDirection ] = 1; + + const worldDirection = this.helper.localToWorld( direction ).sub( this.helper.position ); + const objectDirection = this.edges.worldToLocal( worldDirection ).round(); + + this.flipAxis = objectDirection.cross( this.dragNormal ).negate(); + + this.dragIntersect = this.getIntersect( position.current, this.game.cube.cubes, true ); + + this.selectLayer( this.getLayer( false ) ); + + } else { + + const axis = ( this.dragDirection != 'x' ) + ? ( ( this.dragDirection == 'y' && position.current.x > this.game.world.width / 2 ) ? 'z' : 'x' ) + : 'y'; + + this.flipAxis = new THREE.Vector3(); + this.flipAxis[ axis ] = 1 * ( ( axis == 'x' ) ? - 1 : 1 ); + + } + + this.flipAngle = 0; + this.state = ROTATING; + + } else if ( this.state === ROTATING ) { + + const rotation = this.dragDelta[ this.dragDirection ]; + + if ( this.flipType === 'layer' ) { + + this.group.rotateOnAxis( this.flipAxis, rotation ); + this.flipAngle += rotation; + + } else { + + this.edges.rotateOnWorldAxis( this.flipAxis, rotation ); + this.game.cube.object.rotation.copy( this.edges.rotation ); + this.flipAngle += rotation; + + } + + } + + }; + + this.draggable.onDragEnd = position => { + + if ( this.scramble !== null ) return; + if ( this.state !== ROTATING ) { + + this.gettingDrag = false; + this.state = STILL; + return; + + } + + this.state = ANIMATING; + + const momentum = this.getMomentum()[ this.dragDirection ]; + const flip = ( Math.abs( momentum ) > 0.05 && Math.abs( this.flipAngle ) < Math.PI / 2 ); + + const angle = flip + ? this.roundAngle( this.flipAngle + Math.sign( this.flipAngle ) * ( Math.PI / 4 ) ) + : this.roundAngle( this.flipAngle ); + + const delta = angle - this.flipAngle; + + if ( this.flipType === 'layer' ) { + + this.rotateLayer( delta, false, layer => { + + this.state = this.gettingDrag ? PREPARING : STILL; + this.gettingDrag = false; + + this.checkIsSolved(); + + } ); + + } else { + + this.rotateCube( delta, () => { + + this.state = this.gettingDrag ? PREPARING : STILL; + this.gettingDrag = false; + + } ); + + } + + }; + + } + + rotateLayer( rotation, scramble, callback ) { + + const config = scramble ? 0 : this.flipConfig; + + const easing = this.flipEasings[ config ]; + const duration = this.flipSpeeds[ config ]; + const bounce = ( config == 2 ) ? this.bounceCube() : ( () => {} ); + + this.rotationTween = new Tween( { + easing: easing, + duration: duration, + onUpdate: tween => { + + let deltaAngle = tween.delta * rotation; + this.group.rotateOnAxis( this.flipAxis, deltaAngle ); + bounce( tween.value, deltaAngle, rotation ); + + }, + onComplete: () => { + + if ( ! scramble ) this.onMove(); + + const layer = this.flipLayer.slice( 0 ); + + this.game.cube.object.rotation.setFromVector3( this.snapRotation( this.game.cube.object.rotation.toVector3() ) ); + this.group.rotation.setFromVector3( this.snapRotation( this.group.rotation.toVector3() ) ); + this.deselectLayer( this.flipLayer ); + + callback( layer ); + + }, + } ); + + } + + bounceCube() { + + let fixDelta = true; + + return ( progress, delta, rotation ) => { + + if ( progress >= 1 ) { + + if ( fixDelta ) { + + delta = ( progress - 1 ) * rotation; + fixDelta = false; + + } + + this.game.cube.object.rotateOnAxis( this.flipAxis, delta ); + + } + + } + + } + + rotateCube( rotation, callback ) { + + const config = this.flipConfig; + const easing = [ Easing.Power.Out( 4 ), Easing.Sine.Out(), Easing.Back.Out( 2 ) ][ config ]; + const duration = [ 100, 150, 350 ][ config ]; + + this.rotationTween = new Tween( { + easing: easing, + duration: duration, + onUpdate: tween => { + + this.edges.rotateOnWorldAxis( this.flipAxis, tween.delta * rotation ); + this.game.cube.object.rotation.copy( this.edges.rotation ); + + }, + onComplete: () => { + + this.edges.rotation.setFromVector3( this.snapRotation( this.edges.rotation.toVector3() ) ); + this.game.cube.object.rotation.copy( this.edges.rotation ); + callback(); + + }, + } ); + + } + + selectLayer( layer ) { + + this.group.rotation.set( 0, 0, 0 ); + this.movePieces( layer, this.game.cube.object, this.group ); + this.flipLayer = layer; + + } + + deselectLayer( layer ) { + + this.movePieces( layer, this.group, this.game.cube.object ); + this.flipLayer = null; + + } + + movePieces( layer, from, to ) { + + from.updateMatrixWorld(); + to.updateMatrixWorld(); + + layer.forEach( index => { + + const piece = this.game.cube.pieces[ index ]; + + piece.applyMatrix( from.matrixWorld ); + from.remove( piece ); + piece.applyMatrix( new THREE.Matrix4().getInverse( to.matrixWorld ) ); + to.add( piece ); + + } ); + + } + + getLayer( position ) { + + const layer = []; + let axis; + + if ( position === false ) { + + axis = this.getMainAxis( this.flipAxis ); + position = this.getPiecePosition( this.dragIntersect.object ); + + } else { + + axis = this.getMainAxis( position ); + + } + + this.game.cube.pieces.forEach( piece => { + + const piecePosition = this.getPiecePosition( piece ); + + if ( piecePosition[ axis ] == position[ axis ] ) layer.push( piece.name ); + + } ); + + return layer; + + } + + getPiecePosition( piece ) { + + let position = new THREE.Vector3() + .setFromMatrixPosition( piece.matrixWorld ) + .multiplyScalar( 3 ); + + return this.game.cube.object.worldToLocal( position.sub( this.game.cube.animator.position ) ).round(); + + } + + scrambleCube() { + + if ( this.scramble == null ) { + + this.scramble = this.game.scrambler; + this.scramble.callback = ( typeof callback !== 'function' ) ? () => {} : callback; + + } + + const converted = this.scramble.converted; + const move = converted[ 0 ]; + const layer = this.getLayer( move.position ); + + this.flipAxis = new THREE.Vector3(); + this.flipAxis[ move.axis ] = 1; + + this.selectLayer( layer ); + this.rotateLayer( move.angle, true, () => { + + converted.shift(); + + if ( converted.length > 0 ) { + + this.scrambleCube(); + + } else { + + this.scramble = null; + + } + + } ); + + } + + getIntersect( position, object, multiple ) { + + this.raycaster.setFromCamera( + this.draggable.convertPosition( position.clone() ), + this.game.world.camera + ); + + const intersect = ( multiple ) + ? this.raycaster.intersectObjects( object ) + : this.raycaster.intersectObject( object ); + + return ( intersect.length > 0 ) ? intersect[ 0 ] : false; + + } + + getMainAxis( vector ) { + + return Object.keys( vector ).reduce( + ( a, b ) => Math.abs( vector[ a ] ) > Math.abs( vector[ b ] ) ? a : b + ); + + } + + detach( child, parent ) { + + child.applyMatrix( parent.matrixWorld ); + parent.remove( child ); + this.game.world.scene.add( child ); + + } + + attach( child, parent ) { + + child.applyMatrix( new THREE.Matrix4().getInverse( parent.matrixWorld ) ); + this.game.world.scene.remove( child ); + parent.add( child ); + + } + + addMomentumPoint( delta ) { + + const time = Date.now(); + + this.momentum = this.momentum.filter( moment => time - moment.time < 500 ); + + if ( delta !== false ) this.momentum.push( { delta, time } ); + + } + + getMomentum() { + + const points = this.momentum.length; + const momentum = new THREE.Vector2(); + + this.addMomentumPoint( false ); + + this.momentum.forEach( ( point, index ) => { + + momentum.add( point.delta.multiplyScalar( index / points ) ); + + } ); + + return momentum; + + } + + roundAngle( angle ) { + + const round = Math.PI / 2; + return Math.sign( angle ) * Math.round( Math.abs( angle) / round ) * round; + + } + + snapRotation( angle ) { + + return angle.set( + this.roundAngle( angle.x ), + this.roundAngle( angle.y ), + this.roundAngle( angle.z ) + ); + + } + + checkIsSolved() { + + const start = performance.now(); + + let solved = true; + const sides = { 'x-': [], 'x+': [], 'y-': [], 'y+': [], 'z-': [], 'z+': [] }; + + this.game.cube.edges.forEach( edge => { + + const position = edge.parent + .localToWorld( edge.position.clone() ) + .sub( this.game.cube.object.position ); + + const mainAxis = this.getMainAxis( position ); + const mainSign = position.multiplyScalar( 2 ).round()[ mainAxis ] < 1 ? '-' : '+'; + + sides[ mainAxis + mainSign ].push( edge.name ); + + } ); + + Object.keys( sides ).forEach( side => { + + if ( ! sides[ side ].every( value => value === sides[ side ][ 0 ] ) ) solved = false; + + } ); + + if ( solved ) this.onSolved(); + + } + +} + +class Scrambler { + + constructor( game ) { + + this.game = game; + + this.scrambleLength = 20; + + this.moves = []; + this.conveted = []; + this.pring = ''; + + } + + scramble( scramble ) { + + let count = 0; + this.moves = ( typeof scramble !== 'undefined' ) ? scramble.split( ' ' ) : []; + + if ( this.moves.length < 1 ) { + + const faces = 'UDLRFB'; + const modifiers = [ "", "'", "2" ]; + const total = ( typeof scramble === 'undefined' ) ? this.scrambleLength : scramble; + + + while ( count < total ) { + + const move = faces[ Math.floor( Math.random() * 6 ) ] + modifiers[ Math.floor( Math.random() * 3 ) ]; + if ( count > 0 && move.charAt( 0 ) == this.moves[ count - 1 ].charAt( 0 ) ) continue; + if ( count > 1 && move.charAt( 0 ) == this.moves[ count - 2 ].charAt( 0 ) ) continue; + this.moves.push( move ); + count ++; + + } + + } + + this.callback = () => {}; + this.convert(); + this.print = this.moves.join( ' ' ); + + return this; + + } + + convert( moves ) { + + this.converted = []; + + this.moves.forEach( move => { + + const face = move.charAt( 0 ); + const modifier = move.charAt( 1 ); + + const axis = { D: 'y', U: 'y', L: 'x', R: 'x', F: 'z', B: 'z' }[ face ]; + const row = { D: -1, U: 1, L: -1, R: 1, F: 1, B: -1 }[ face ]; + + const position = new THREE.Vector3(); + position[ { D: 'y', U: 'y', L: 'x', R: 'x', F: 'z', B: 'z' }[ face ] ] = row; + + const angle = ( Math.PI / 2 ) * - row * ( ( modifier == "'" ) ? - 1 : 1 ); + + const convertedMove = { position, axis, angle, name: move }; + + this.converted.push( convertedMove ); + if ( modifier == "2" ) this.converted.push( convertedMove ); + + } ); + + } + +} + +class Transition { + + constructor( game ) { + + this.game = game; + + this.tweens = {}; + this.durations = {}; + this.data = { + cubeY: -0.2, + cameraZoom: 0.85, + }; + + this.activeTransitions = 0; + + } + + init() { + + this.game.controls.disable(); + + this.game.cube.object.position.y = this.data.cubeY; + this.game.controls.edges.position.y = this.data.cubeY; + this.game.cube.animator.position.y = 4; + this.game.cube.animator.rotation.x = - Math.PI / 3; + this.game.world.camera.zoom = this.data.cameraZoom; + this.game.world.camera.updateProjectionMatrix(); + + this.tweens.buttons = {}; + this.tweens.timer = []; + this.tweens.title = []; + this.tweens.best = []; + this.tweens.complete = []; + this.tweens.range = []; + this.tweens.stats = []; + + } + + buttons( show, hide ) { + + const buttonTween = ( button, show ) => { + + return new Tween( { + target: button.style, + duration: 300, + easing: show ? Easing.Power.Out( 2 ) : Easing.Power.In( 3 ), + from: { opacity: show ? 0 : 1 }, + to: { opacity: show ? 1 : 0 }, + onUpdate: tween => { + + const translate = show ? 1 - tween.value : tween.value; + button.style.transform = `translate3d(0, ${translate * 1.5}em, 0)`; + + }, + onComplete: () => button.style.pointerEvents = show ? 'all' : 'none' + } ); + + }; + + hide.forEach( button => + this.tweens.buttons[ button ] = buttonTween( this.game.dom.buttons[ button ], false ) + ); + + setTimeout( () => show.forEach( button => { + + this.tweens.buttons[ button ] = buttonTween( this.game.dom.buttons[ button ], true ); + + } ), hide ? 500 : 0 ); + + } + + cube( show ) { + + this.activeTransitions++; + + try { this.tweens.cube.stop(); } catch(e) {} + const currentY = this.game.cube.animator.position.y; + const currentRotation = this.game.cube.animator.rotation.x; + + this.tweens.cube = new Tween( { + duration: show ? 3000 : 1250, + easing: show ? Easing.Elastic.Out( 0.8, 0.6 ) : Easing.Back.In( 1 ), + onUpdate: tween => { + + this.game.cube.animator.position.y = show + ? ( 1 - tween.value ) * 4 + : currentY + tween.value * 4; + + this.game.cube.animator.rotation.x = show + ? ( 1 - tween.value ) * Math.PI / 3 + : currentRotation + tween.value * - Math.PI / 3; + + } + } ); + + this.durations.cube = show ? 1500 : 1500; + + setTimeout( () => this.activeTransitions--, this.durations.cube ); + + } + + float() { + + try { this.tweens.float.stop(); } catch(e) {} + this.tweens.float = new Tween( { + duration: 1500, + easing: Easing.Sine.InOut(), + yoyo: true, + onUpdate: tween => { + + this.game.cube.holder.position.y = (- 0.02 + tween.value * 0.04); + this.game.cube.holder.rotation.x = 0.005 - tween.value * 0.01; + this.game.cube.holder.rotation.z = - this.game.cube.holder.rotation.x; + this.game.cube.holder.rotation.y = this.game.cube.holder.rotation.x; + + }, + } ); + + } + + zoom( play, time ) { + + this.activeTransitions++; + + const zoom = ( play ) ? 1 : this.data.cameraZoom; + const duration = ( time > 0 ) ? Math.max( time, 1500 ) : 1500; + const rotations = ( time > 0 ) ? Math.round( duration / 1500 ) : 1; + const easing = Easing.Power.InOut( ( time > 0 ) ? 2 : 3 ); + + this.tweens.zoom = new Tween( { + target: this.game.world.camera, + duration: duration, + easing: easing, + to: { zoom: zoom }, + onUpdate: () => { this.game.world.camera.updateProjectionMatrix(); }, + } ); + + this.tweens.rotate = new Tween( { + target: this.game.cube.animator.rotation, + duration: duration, + easing: easing, + to: { y: - Math.PI * 2 * rotations }, + onComplete: () => { this.game.cube.animator.rotation.y = 0; }, + } ); + + this.durations.zoom = duration; + + setTimeout( () => this.activeTransitions--, this.durations.zoom ); + + } + + elevate( complete ) { + + this.activeTransitions++; + + const cubeY = + + this.tweens.elevate = new Tween( { + target: this.game.cube.object.position, + duration: complete ? 1500 : 0, + easing: Easing.Power.InOut( 3 ), + to: { y: complete ? -0.05 : this.data.cubeY } + } ); + + this.durations.elevate = 1500; + + setTimeout( () => this.activeTransitions--, this.durations.elevate ); + + } + + complete( show, best ) { + + this.activeTransitions++; + + const text = best ? this.game.dom.texts.best : this.game.dom.texts.complete; + + if ( text.querySelector( 'span i' ) === null ) + text.querySelectorAll( 'span' ).forEach( span => this.splitLetters( span ) ); + + const letters = text.querySelectorAll( '.icon, i' ); + + this.flipLetters( best ? 'best' : 'complete', letters, show ); + + text.style.opacity = 1; + + const duration = this.durations[ best ? 'best' : 'complete' ]; + + if ( ! show ) setTimeout( () => this.game.dom.texts.timer.style.transform = '', duration ); + + setTimeout( () => this.activeTransitions--, duration ); + + } + + stats( show ) { + + if ( show ) this.game.scores.calcStats(); + + this.activeTransitions++; + + this.tweens.stats.forEach( tween => { tween.stop(); tween = null; } ); + + let tweenId = -1; + + const stats = this.game.dom.stats.querySelectorAll( '.stats' ); + const easing = show ? Easing.Power.Out( 2 ) : Easing.Power.In( 3 ); + + stats.forEach( ( stat, index ) => { + + const delay = index * ( show ? 80 : 60 ); + + this.tweens.stats[ tweenId++ ] = new Tween( { + delay: delay, + duration: 400, + easing: easing, + onUpdate: tween => { + + const translate = show ? ( 1 - tween.value ) * 2 : tween.value; + const opacity = show ? tween.value : ( 1 - tween.value ); + + stat.style.transform = `translate3d(0, ${translate}em, 0)`; + stat.style.opacity = opacity; + + } + } ); + + } ); + + this.durations.stats = 0; + + setTimeout( () => this.activeTransitions--, this.durations.stats ); + + } + + preferences( show ) { + + this.activeTransitions++; + + this.tweens.range.forEach( tween => { tween.stop(); tween = null; } ); + + let tweenId = -1; + let listMax = 0; + + const ranges = this.game.dom.prefs.querySelectorAll( '.range' ); + const easing = show ? Easing.Power.Out(2) : Easing.Power.In(3); + + ranges.forEach( ( range, rangeIndex ) => { + + const label = range.querySelector( '.range__label' ); + const track = range.querySelector( '.range__track-line' ); + const handle = range.querySelector( '.range__handle' ); + const list = range.querySelectorAll( '.range__list div' ); + + const delay = rangeIndex * ( show ? 120 : 100 ); + + label.style.opacity = show ? 0 : 1; + track.style.opacity = show ? 0 : 1; + handle.style.opacity = show ? 0 : 1; + handle.style.pointerEvents = show ? 'all' : 'none'; + + this.tweens.range[ tweenId++ ] = new Tween( { + delay: show ? delay : delay, + duration: 400, + easing: easing, + onUpdate: tween => { + + const translate = show ? ( 1 - tween.value ) : tween.value; + const opacity = show ? tween.value : ( 1 - tween.value ); + + label.style.transform = `translate3d(0, ${translate}em, 0)`; + label.style.opacity = opacity; + + } + } ); + + this.tweens.range[ tweenId++ ] = new Tween( { + delay: show ? delay + 100 : delay, + duration: 400, + easing: easing, + onUpdate: tween => { + + const translate = show ? ( 1 - tween.value ) : tween.value; + const scale = show ? tween.value : ( 1 - tween.value ); + const opacity = scale; + + track.style.transform = `translate3d(0, ${translate}em, 0) scale3d(${scale}, 1, 1)`; + track.style.opacity = opacity; + + } + } ); + + this.tweens.range[ tweenId++ ] = new Tween( { + delay: show ? delay + 100 : delay, + duration: 400, + easing: easing, + onUpdate: tween => { + + const translate = show ? ( 1 - tween.value ) : tween.value; + const opacity = 1 - translate; + const scale = 0.5 + opacity * 0.5; + + handle.style.transform = `translate3d(0, ${translate}em, 0) scale3d(${scale}, ${scale}, ${scale})`; + handle.style.opacity = opacity; + + } + } ); + + list.forEach( ( listItem, labelIndex ) => { + + listItem.style.opacity = show ? 0 : 1; + + this.tweens.range[ tweenId++ ] = new Tween( { + delay: show ? delay + 200 + labelIndex * 50 : delay, + duration: 400, + easing: easing, + onUpdate: tween => { + + const translate = show ? ( 1 - tween.value ) : tween.value; + const opacity = show ? tween.value : ( 1 - tween.value ); + + listItem.style.transform = `translate3d(0, ${translate}em, 0)`; + listItem.style.opacity = opacity; + + } + } ); + + } ); + + listMax = list.length > listMax ? list.length - 1 : listMax; + + range.style.opacity = 1; + + } ); + + this.durations.preferences = show + ? ( ( ranges.length - 1 ) * 100 ) + 200 + listMax * 50 + 400 + : ( ( ranges.length - 1 ) * 100 ) + 400; + + setTimeout( () => this.activeTransitions--, this.durations.preferences ); + + } + + title( show ) { + + this.activeTransitions++; + + const title = this.game.dom.texts.title; + + if ( title.querySelector( 'span i' ) === null ) + title.querySelectorAll( 'span' ).forEach( span => this.splitLetters( span ) ); + + const letters = title.querySelectorAll( 'i' ); + + this.flipLetters( 'title', letters, show ); + + title.style.opacity = 1; + + const note = this.game.dom.texts.note; + + this.tweens.title[ letters.length ] = new Tween( { + target: note.style, + easing: Easing.Sine.InOut(), + duration: show ? 800 : 400, + yoyo: show ? true : null, + from: { opacity: show ? 0 : ( parseFloat( getComputedStyle( note ).opacity ) ) }, + to: { opacity: show ? 1 : 0 }, + } ); + + setTimeout( () => this.activeTransitions--, this.durations.title ); + + } + + timer( show ) { + + this.activeTransitions++; + + const timer = this.game.dom.texts.timer; + + timer.style.opacity = 0; + this.game.timer.convert(); + this.game.timer.setText(); + + this.splitLetters( timer ); + const letters = timer.querySelectorAll( 'i' ); + this.flipLetters( 'timer', letters, show ); + + timer.style.opacity = 1; + + setTimeout( () => this.activeTransitions--, this.durations.timer ); + + } + + splitLetters( element ) { + + const text = element.innerHTML; + + element.innerHTML = ''; + + text.split( '' ).forEach( letter => { + + const i = document.createElement( 'i' ); + + i.innerHTML = letter; + + element.appendChild( i ); + + } ); + + } + + flipLetters( type, letters, show ) { + + try { this.tweens[ type ].forEach( tween => tween.stop() ); } catch(e) {} + letters.forEach( ( letter, index ) => { + + letter.style.opacity = show ? 0 : 1; + + this.tweens[ type ][ index ] = new Tween( { + easing: Easing.Sine.Out(), + duration: show ? 800 : 400, + delay: index * 50, + onUpdate: tween => { + + const rotation = show ? ( 1 - tween.value ) * -80 : tween.value * 80; + + letter.style.transform = `rotate3d(0, 1, 0, ${rotation}deg)`; + letter.style.opacity = show ? tween.value : ( 1 - tween.value ); + + }, + } ); + + } ); + + this.durations[ type ] = ( letters.length - 1 ) * 50 + ( show ? 800 : 400 ); + + } + +} + +class Timer extends Animation { + + constructor( game ) { + + super( false ); + + this.game = game; + this.reset(); + + } + + start( continueGame ) { + + this.startTime = continueGame ? ( Date.now() - this.deltaTime ) : Date.now(); + this.deltaTime = 0; + this.converted = this.convert(); + + super.start(); + + } + + reset() { + + this.startTime = 0; + this.currentTime = 0; + this.deltaTime = 0; + this.converted = '0:00'; + + } + + stop() { + + this.currentTime = Date.now(); + this.deltaTime = this.currentTime - this.startTime; + this.convert(); + + super.stop(); + + return { time: this.converted, millis: this.deltaTime }; + + } + + update() { + + const old = this.converted; + + this.currentTime = Date.now(); + this.deltaTime = this.currentTime - this.startTime; + this.convert(); + + if ( this.converted != old ) { + + localStorage.setItem( 'theCube_time', this.deltaTime ); + this.setText(); + + } + + } + + convert() { + + const seconds = parseInt( ( this.deltaTime / 1000 ) % 60 ); + const minutes = parseInt( ( this.deltaTime / ( 1000 * 60 ) ) ); + + this.converted = minutes + ':' + ( seconds < 10 ? '0' : '' ) + seconds; + + } + + setText() { + + this.game.dom.texts.timer.innerHTML = this.converted; + + } + +} + +const RangeHTML = [ + + '
', + '
', + '
', + '
', + '
', + '
', + '
', + '
', + +].join( '\n' ); + +document.querySelectorAll( 'range' ).forEach( el => { + + const temp = document.createElement( 'div' ); + temp.innerHTML = RangeHTML; + + const range = temp.querySelector( '.range' ); + const rangeLabel = range.querySelector( '.range__label' ); + const rangeList = range.querySelector( '.range__list' ); + + range.setAttribute( 'name', el.getAttribute( 'name' ) ); + rangeLabel.innerHTML = el.getAttribute( 'title' ); + + el.getAttribute( 'list' ).split( ',' ).forEach( listItemText => { + + const listItem = document.createElement( 'div' ); + listItem.innerHTML = listItemText; + rangeList.appendChild( listItem ); + + } ); + + el.parentNode.replaceChild( range, el ); + +} ); + +class Range { + + constructor( name, options ) { + + options = Object.assign( { + range: [ 0, 1 ], + value: 0, + step: 0, + onUpdate: () => {}, + onComplete: () => {}, + }, options || {} ); + + this.element = document.querySelector( '.range[name="' + name + '"]' ); + this.track = this.element.querySelector( '.range__track' ); + this.handle = this.element.querySelector( '.range__handle' ); + + this.value = options.value; + this.min = options.range[0]; + this.max = options.range[1]; + this.step = options.step; + + this.onUpdate = options.onUpdate; + this.onComplete = options.onComplete; + + this.value = this.round( this.limitValue( this.value ) ); + this.setHandlePosition(); + + this.initDraggable(); + + } + + initDraggable() { + + let current; + + this.draggable = new Draggable( this.handle, { calcDelta: true } ); + + this.draggable.onDragStart = position => { + + current = this.positionFromValue( this.value ); + this.handle.style.left = current + 'px'; + + }; + + this.draggable.onDragMove = position => { + + current = this.limitPosition( current + position.delta.x ); + this.value = this.round( this.valueFromPosition( current ) ); + this.setHandlePosition(); + + this.onUpdate( this.value ); + + }; + + this.draggable.onDragEnd = position => { + + this.onComplete( this.value ); + + }; + + } + + round( value ) { + + if ( this.step < 1 ) return value; + + return Math.round( ( value - this.min ) / this.step ) * this.step + this.min; + + } + + limitValue( value ) { + + const max = Math.max( this.max, this.min ); + const min = Math.min( this.max, this.min ); + + return Math.min( Math.max( value, min ), max ); + + } + + limitPosition( position ) { + + return Math.min( Math.max( position, 0 ), this.track.offsetWidth ); + + } + + percentsFromValue( value ) { + + return ( value - this.min ) / ( this.max - this.min ); + + } + + valueFromPosition( position ) { + + return this.min + ( this.max - this.min ) * ( position / this.track.offsetWidth ); + + } + + positionFromValue( value ) { + + return this.percentsFromValue( value ) * this.track.offsetWidth; + + } + + setHandlePosition() { + + this.handle.style.left = this.percentsFromValue( this.value ) * 100 + '%'; + + } + +} + +class Preferences { + + constructor( game ) { + + this.game = game; + + } + + init() { + + this.ranges = { + + flip: new Range( 'flip', { + value: this.game.controls.flipConfig, + range: [ 0, 2 ], + step: 1, + onUpdate: value => { + + this.game.controls.flipConfig = value; + + }, + } ), + + scramble: new Range( 'scramble', { + value: this.game.scrambler.scrambleLength, + range: [ 20, 30 ], + step: 5, + onUpdate: value => { + + this.game.scrambler.scrambleLength = value; + + }, + } ), + + fov: new Range( 'fov', { + value: this.game.world.fov, + range: [ 2, 45 ], + onUpdate: value => { + + this.game.world.fov = value; + this.game.world.resize(); + + }, + } ), + + theme: new Range( 'theme', { + value: { cube: 0, erno: 1, dust: 2, camo: 3, rain: 4 }[ this.game.themes.theme ], + range: [ 0, 4 ], + step: 1, + onUpdate: value => { + + const theme = [ 'cube', 'erno', 'dust', 'camo', 'rain' ][ value ]; + this.game.themes.setTheme( theme ); + + }, + } ), + + }; + + } + +} + +class Confetti { + + constructor( game ) { + + this.game = game; + this.started = 0; + + this.options = { + speed: { min: 0.0011, max: 0.0022 }, + revolution: { min: 0.01, max: 0.05 }, + size: { min: 0.1, max: 0.15 }, + colors: [ 0x41aac8, 0x82ca38, 0xffef48, 0xef3923, 0xff8c0a ], + }; + + this.geometry = new THREE.PlaneGeometry( 1, 1 ); + this.material = new THREE.MeshLambertMaterial( { side: THREE.DoubleSide } ); + + this.holders = [ + new ConfettiStage( this.game, this, 1, 20 ), + new ConfettiStage( this.game, this, -1, 30 ), + ]; + + } + + start() { + + if ( this.started > 0 ) return; + + this.holders.forEach( holder => { + + this.game.world.scene.add( holder.holder ); + holder.start(); + this.started ++; + + } ); + + } + + stop() { + + if ( this.started == 0 ) return; + + this.holders.forEach( holder => { + + holder.stop( () => { + + this.game.world.scene.remove( holder.holder ); + this.started --; + + } ); + + } ); + + } + + updateColors( colors ) { + + this.holders.forEach( holder => { + + holder.options.colors.forEach( ( color, index ) => { + + holder.options.colors[ index ] = colors[ [ 'D', 'F', 'R', 'B', 'L' ][ index ] ]; + + } ); + + } ); + + } + +} + +class ConfettiStage extends Animation { + + constructor( game, parent, distance, count ) { + + super( false ); + + this.game = game; + this.parent = parent; + + this.distanceFromCube = distance; + + this.count = count; + this.particles = []; + + this.holder = new THREE.Object3D(); + this.holder.rotation.copy( this.game.world.camera.rotation ); + + this.object = new THREE.Object3D(); + this.holder.add( this.object ); + + this.resizeViewport = this.resizeViewport.bind( this ); + this.game.world.onResize.push( this.resizeViewport ); + this.resizeViewport(); + + this.geometry = this.parent.geometry; + this.material = this.parent.material; + + this.options = this.parent.options; + + let i = this.count; + while ( i-- ) this.particles.push( new Particle( this ) ); + + } + + start() { + + this.time = performance.now(); + this.playing = true; + + let i = this.count; + while ( i-- ) this.particles[ i ].reset(); + + super.start(); + + } + + stop( callback ) { + + this.playing = false; + this.completed = 0; + this.callback = callback; + + } + + reset() { + + super.stop(); + + this.callback(); + + } + + update() { + + const now = performance.now(); + const delta = now - this.time; + this.time = now; + + let i = this.count; + + while ( i-- ) + if ( ! this.particles[ i ].completed ) this.particles[ i ].update( delta ); + + if ( ! this.playing && this.completed == this.count ) this.reset(); + + } + + resizeViewport() { + + const fovRad = this.game.world.camera.fov * THREE.Math.DEG2RAD; + + this.height = 2 * Math.tan( fovRad / 2 ) * ( this.game.world.camera.position.length() - this.distanceFromCube ); + this.width = this.height * this.game.world.camera.aspect; + + const scale = 1 / this.game.transition.data.cameraZoom; + + this.width *= scale; + this.height *= scale; + + this.object.position.z = this.distanceFromCube; + this.object.position.y = this.height / 2; + + } + +} + +class Particle { + + constructor( confetti ) { + + this.confetti = confetti; + this.options = this.confetti.options; + + this.velocity = new THREE.Vector3(); + this.force = new THREE.Vector3(); + + this.mesh = new THREE.Mesh( this.confetti.geometry, this.confetti.material.clone() ); + this.confetti.object.add( this.mesh ); + + this.size = THREE.Math.randFloat( this.options.size.min, this.options.size.max ); + this.mesh.scale.set( this.size, this.size, this.size ); + + return this; + + } + + reset( randomHeight = true ) { + + this.completed = false; + + this.color = new THREE.Color( this.options.colors[ Math.floor( Math.random() * this.options.colors.length ) ] ); + this.mesh.material.color.set( this.color ); + + this.speed = THREE.Math.randFloat( this.options.speed.min, this.options.speed.max ) * - 1; + this.mesh.position.x = THREE.Math.randFloat( - this.confetti.width / 2, this.confetti.width / 2 ); + this.mesh.position.y = ( randomHeight ) + ? THREE.Math.randFloat( this.size, this.confetti.height + this.size ) + : this.size; + + this.revolutionSpeed = THREE.Math.randFloat( this.options.revolution.min, this.options.revolution.max ); + this.revolutionAxis = [ 'x', 'y', 'z' ][ Math.floor( Math.random() * 3 ) ]; + this.mesh.rotation.set( Math.random() * Math.PI / 3, Math.random() * Math.PI / 3, Math.random() * Math.PI / 3 ); + + } + + stop() { + + this.completed = true; + this.confetti.completed ++; + + } + + update( delta ) { + + this.mesh.position.y += this.speed * delta; + this.mesh.rotation[ this.revolutionAxis ] += this.revolutionSpeed; + + if ( this.mesh.position.y < - this.confetti.height - this.size ) + ( this.confetti.playing ) ? this.reset( false ) : this.stop(); + + } + +} + +class Scores { + + constructor( game ) { + + this.game = game; + + this.scores = []; + this.solves = 0; + this.best = 0; + this.worst = 0; + + } + + addScore( time ) { + + this.scores.push( time ); + this.solves++; + + if ( this.scores.lenght > 100 ) this.scores.shift(); + + let bestTime = false; + + if ( time < this.best || this.best === 0 ) { + + this.best = time; + bestTime = true; + + } + + if ( time > this.worst ) this.worst = time; + + return bestTime; + + } + + calcStats() { + + this.setStat( 'total-solves', this.solves ); + this.setStat( 'best-time', this.convertTime( this.best ) ); + this.setStat( 'worst-time', this.convertTime( this.worst ) ); + this.setStat( 'average-5', this.getAverage( 5 ) ); + this.setStat( 'average-12', this.getAverage( 12 ) ); + this.setStat( 'average-25', this.getAverage( 25 ) ); + + } + + setStat( name, value ) { + + if ( value === 0 ) return; + + this.game.dom.stats.querySelector( `.stats[name="${name}"] b` ).innerHTML = value; + + } + + getAverage( count ) { + + if ( this.scores.length < count ) return 0; + + return this.convertTime( this.scores.slice(-count).reduce( ( a, b ) => a + b, 0 ) / count ); + + } + + convertTime( time ) { + + if ( time <= 0 ) return 0; + + const seconds = parseInt( ( time / 1000 ) % 60 ); + const minutes = parseInt( ( time / ( 1000 * 60 ) ) ); + + return minutes + ':' + ( seconds < 10 ? '0' : '' ) + seconds; + + } + +} + +class Storage { + + constructor( game ) { + + this.game = game; + + } + + init() { + + this.loadGame(); + this.loadPreferences(); + + } + + loadGame() { + + this.game.saved = false; + + } + + + loadPreferences() { + + this.game.controls.flipConfig = 0; + this.game.scrambler.scrambleLength = 20; + + this.game.world.fov = 10; + this.game.world.resize(); + + this.game.themes.setTheme( 'cube' ); + + return false; + + } + +} + +class Themes { + + constructor( game ) { + + this.game = game; + this.theme = null; + + this.colors = { + cube: { + U: 0xfff7ff, + D: 0xffef48, + F: 0xef3923, + R: 0x41aac8, + B: 0xff8c0a, + L: 0x82ca38, + P: 0x08101a, + G: 0xd1d5db, + }, + erno: { + U: 0xffffff, + D: 0xffd500, + F: 0xc41e3a, + R: 0x0051ba, + B: 0xff5800, + L: 0x009e60, + P: 0x111111, + G: 0x8abdff, + }, + dust: { + U: 0xfff6eb, + D: 0xe7c48d, + F: 0x8f253e, + R: 0x607e69, + B: 0xbe6f62, + L: 0x849f5d, + P: 0x111111, + G: 0xE7C48D, + }, + camo: { + U: 0xfff6eb, + D: 0xbfb672, + F: 0x805831, + R: 0x718456, + B: 0x37241c, + L: 0x37431d, + P: 0x111111, + G: 0xBFB672, + }, + rain: { + U: 0xfafaff, + D: 0xedb92d, + F: 0xce2135, + R: 0x449a89, + B: 0xec582f, + L: 0xa3a947, + P: 0x111111, + G: 0x87b9ac, + }, + }; + + } + + setTheme( theme ) { + + if ( theme === this.theme ) return; + + this.theme = theme; + + const colors = this.colors[ this.theme ]; + + this.game.cube.pieces.forEach( piece => { + + piece.userData.cube.material.color.setHex( colors.P ); + + } ); + + this.game.cube.edges.forEach( edge => { + + edge.material.color.setHex( colors[ edge.name ] ); + + } ); + + this.game.dom.rangeHandles.forEach( handle => { + + handle.style.background = '#' + colors.R.toString(16).padStart(6, '0'); + + } ); + + this.game.confetti.updateColors( colors ); + + this.game.dom.back.style.background = '#' + colors.G.toString(16).padStart(6, '0'); + this.game.dom.buttons.pwa.style.color = '#' + colors.R.toString(16).padStart(6, '0'); + + } + +} + +class IconsConverter { + + constructor( options ) { + + options = Object.assign( { + tagName: 'icon', + className: 'icon', + styles: false, + icons: {}, + observe: false, + convert: false, + }, options || {} ); + + this.tagName = options.tagName; + this.className = options.className; + this.icons = options.icons; + + this.svgTag = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ); + this.svgTag.setAttribute( 'class', this.className ); + + if ( options.styles ) this.addStyles(); + if ( options.convert ) this.convertAllIcons(); + + if ( options.observe ) { + + const MutationObserver = window.MutationObserver || window.WebKitMutationObserver; + this.observer = new MutationObserver( mutations => { this.convertAllIcons(); } ); + this.observer.observe( document.documentElement, { childList: true, subtree: true } ); + + } + + return this; + + } + + convertAllIcons() { + + document.querySelectorAll( this.tagName ).forEach( icon => { this.convertIcon( icon ); } ); + + } + + convertIcon( icon ) { + + const svgData = this.icons[ icon.attributes[0].localName ]; + + if ( typeof svgData === 'undefined' ) return; + + const svg = this.svgTag.cloneNode( true ); + const viewBox = svgData.viewbox.split( ' ' ); + + svg.setAttributeNS( null, 'viewBox', svgData.viewbox ); + svg.style.width = viewBox[2] / viewBox[3] + 'em'; + svg.style.height = '1em'; + svg.innerHTML = svgData.content; + + icon.parentNode.replaceChild( svg, icon ); + + } + + addStyles() { + + const style = document.createElement( 'style' ); + style.innerHTML = `.${this.className} { display: inline-block; font-size: inherit; overflow: visible; vertical-align: -0.125em; preserveAspectRatio: none; }`; + document.head.appendChild( style ); + + } + +} + +const Icons = new IconsConverter( { + + icons: { + settings: { + viewbox: '0 0 512 512', + content: '', + }, + back: { + viewbox: '0 0 512 512', + content: '', + }, + trophy: { + viewbox: '0 0 576 512', + content: '', + }, + share: { + viewbox: '0 0 36 50', + content: '', + }, + pwa: { + viewbox: '0 0 740 280', + content: '', + } + }, + + convert: true, + +} ); + +const MENU = 0; +const PLAYING = 1; +const COMPLETE = 2; +const STATS = 3; +const PREFS = 4; + +const SHOW = true; +const HIDE = false; + +class Game { + constructor() { + const qs = document.querySelector.bind( document ); + const qsa = document.querySelectorAll.bind( document ); + this.dom = { + ui: qs( '.mofang' ), + game: qs( '.mofang__game' ), + back: qs( '.mofang__background' ), + texts: qs( '.mofang__texts' ), + prefs: qs( '.mofang__prefs' ), + stats: qs( '.mofang__stats' ), + texts: { + title: qs( '.text--title' ), + note: qs( '.text--note' ), + timer: qs( '.text--timer' ), + stats: qs( '.text--timer' ), + complete: qs( '.text--complete' ), + best: qs( '.text--best-time' ), + }, + buttons: { + prefs: qs( '.btn--prefs' ), + back: qs( '.btn--back' ), + stats: qs( '.btn--stats' ), + pwa: qs( '.btn--pwa' ), + }, + rangeHandles: qsa( '.range__handle div' ), + }; + + this.world = new World( this ); + this.cube = new Cube( this ); + this.controls = new Controls( this ); + this.scrambler = new Scrambler( this ); + this.transition = new Transition( this ); + this.timer = new Timer( this ); + this.preferences = new Preferences( this ); + this.scores = new Scores( this ); + this.storage = new Storage( this ); + this.confetti = new Confetti( this ); + this.themes = new Themes( this ); + + this.initActions(); + + this.state = MENU; + this.saved = false; + this.newGame = false; + + this.storage.init(); + this.preferences.init(); + this.transition.init(); + + this.scores.calcStats(); + + setTimeout( () => { + + this.transition.float(); + this.transition.cube( SHOW ); + + setTimeout( () => this.transition.title( SHOW ), 700 ); + setTimeout( () => this.transition.buttons( [ 'prefs', 'pwa' ], [] ), 1000 ); + + }, 500 ); + + } + + initActions() { + + let tappedTwice = false; + + this.dom.game.onclick = event => { + + if ( this.transition.activeTransitions > 0 ) return; + if ( this.state === PLAYING ) return; + + if ( this.state === MENU ) { + + if ( ! tappedTwice ) { + + tappedTwice = true; + setTimeout( () => tappedTwice = false, 300 ); + return false; + + } + + if ( ! this.saved ) { + + this.scrambler.scramble(); + this.controls.scrambleCube(); + this.newGame = true; + + } + + const duration = this.saved ? 0 : this.scrambler.converted.length * this.controls.flipSpeeds[0]; + + this.state = PLAYING; + this.saved = true; + + this.transition.buttons( [], [ 'pwa', 'prefs' ] ); + + this.transition.zoom( PLAYING, duration ); + this.transition.title( HIDE ); + + setTimeout( () => { + + this.transition.timer( SHOW ); + this.transition.buttons( [ 'back' ], [] ); + + }, this.transition.durations.zoom - 1000 ); + + setTimeout( () => { + + this.controls.enable(); + if ( ! this.newGame ) this.timer.start( true ); + + }, this.transition.durations.zoom ); + + } else if ( this.state === COMPLETE ) { + + this.state = STATS; + this.saved = false; + + this.transition.timer( HIDE ); + this.transition.complete( HIDE, this.bestTime ); + this.transition.cube( HIDE ); + this.timer.reset(); + + setTimeout( () => { + + this.cube.reset(); + this.confetti.stop(); + + this.transition.stats( SHOW ); + this.transition.elevate( 0 ); + + }, 1000 ); + + return false; + + } else if ( this.state === STATS ) { + + this.state = MENU; + + this.transition.buttons( [ 'pwa', 'prefs' ], [] ); + + this.transition.stats( HIDE ); + + setTimeout( () => this.transition.cube( SHOW ), 500 ); + setTimeout( () => this.transition.title( SHOW ), 1200 ); + + } + + }; + + this.controls.onMove = () => { + + if ( this.newGame ) { + + this.timer.start( true ); + this.newGame = false; + + } + + }; + + this.dom.buttons.back.onclick = event => { + + if ( this.transition.activeTransitions > 0 ) return; + + if ( this.state === PREFS ) { + + this.state = MENU; + + this.transition.buttons( [ 'pwa', 'prefs' ], [ 'back' ] ); + + this.transition.preferences( HIDE ); + + setTimeout( () => this.transition.cube( SHOW ), 500 ); + setTimeout( () => this.transition.title( SHOW ), 1200 ); + + } else if ( this.state === PLAYING ) { + + this.state = MENU; + + this.transition.buttons( [ 'pwa', 'prefs' ], [ 'back' ] ); + + this.transition.zoom( MENU, 0 ); + + this.controls.disable(); + if ( ! this.newGame ) this.timer.stop(); + this.transition.timer( HIDE ); + + setTimeout( () => this.transition.title( SHOW ), this.transition.durations.zoom - 1000 ); + + this.playing = false; + this.controls.disable(); + + } + + }; + + this.dom.buttons.prefs.onclick = event => { + + if ( this.transition.activeTransitions > 0 ) return; + + this.state = PREFS; + + this.transition.buttons( [ 'back' ], [ 'pwa', 'prefs' ] ); + + this.transition.title( HIDE ); + this.transition.cube( HIDE ); + + setTimeout( () => this.transition.preferences( SHOW ), 1000 ); + + }; + + this.dom.buttons.stats.onclick = event => { + + if ( this.transition.activeTransitions > 0 ) return; + + this.state = STATS; + + this.transition.buttons( [], [ 'pwa', 'prefs' ] ); + + this.transition.title( HIDE ); + this.transition.cube( HIDE ); + + setTimeout( () => this.transition.stats( SHOW ), 1000 ); + + }; + + this.controls.onSolved = () => { + + this.transition.buttons( [], [ 'back' ] ); + + this.state = COMPLETE; + this.saved = false; + + this.controls.disable(); + this.timer.stop(); + + this.bestTime = this.scores.addScore( this.timer.deltaTime ); + + this.transition.zoom( MENU, 0 ); + this.transition.elevate( SHOW ); + + setTimeout( () => { + + this.transition.complete( SHOW, this.bestTime ); + this.confetti.start(); + + }, 1000 ); + + }; + + } + +} + +window.game = new Game(); \ No newline at end of file From c57a54bc5547ca6509972d494913c36771a32559 Mon Sep 17 00:00:00 2001 From: Jack Date: Thu, 10 Oct 2024 19:13:39 +1000 Subject: [PATCH 90/93] update index --- index.html | 8 ++++++++ indexCN.html | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/index.html b/index.html index 1c8730c..10b6e49 100644 --- a/index.html +++ b/index.html @@ -181,6 +181,14 @@

Game List


32
24 Point Poker Game: A classic 24 point poker game. Get four random cards to start. Use Add or Subtract or Multiply or Divide to calculate 24. ๐ŸŽฒ๐Ÿƒ + + 33 + helicopter Game: A simple helicopter shooting games (still under developing) + + + 34 + rubik's Cube Game: A virtual rubik's cube game. (still under developing)๐ŸŽฒ๐Ÿƒ + diff --git a/indexCN.html b/indexCN.html index 9f6262f..47b6786 100644 --- a/indexCN.html +++ b/indexCN.html @@ -181,6 +181,14 @@

ๆธธๆˆๅˆ—่กจ


32 24 ็‚นๆ‰‘ๅ…‹๏ผšไธ€ไธช็›Šๆ™บ่ฎก็ฎ—็ฑปๆธธๆˆ๏ผŒ้šๆœบๅ–ๅ››ๅผ ๆ‰‘ๅ…‹็‰Œ็”จๅŠ ๅ‡ไน˜้™คๅ››ๅˆ™่ฟ็ฎ—ๆฅ่ฎก็ฎ—24 ็‚น๏ผ๐Ÿƒ + + 33 + ็›ดๅ‡้ฃžๆœบๅฐ„ๅ‡ปๆธธๆˆ๏ผšไธ€ไธช็ฎ€ๅ•็š„็›ดๅ‡้ฃžๆœบๅฐ„ๅ‡ปๆธธๆˆ๏ผŒๅผ€ๅ‘ไธญ + + + 34 + ้ญ”ๆ–นๆธธๆˆไธ€ไธช่™šๆ‹Ÿ้ญ”ๆ–น๏ผŒๅผ€ๅ‘ไธญ๐ŸŽฒ๐Ÿƒ + From f4cfb4650701d8270a3893ccb15aeb2ec43ac94e Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 5 Apr 2025 14:57:19 +1000 Subject: [PATCH 91/93] Update index.html MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ๅขžๅŠ ไบ†้‡็ฝฎๆœฌๅฑ€ๆŒ‰้’ฎ๏ผŒไฟฎๅคไบ†้‡็‚น็‰Œ้ขๅ’Œ้‡็‚นๅผ€ๅง‹็š„้”™่ฏฏ --- 32-24-Point-Poker-Game/index.html | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/32-24-Point-Poker-Game/index.html b/32-24-Point-Poker-Game/index.html index dcfe72c..d5fd7c9 100644 --- a/32-24-Point-Poker-Game/index.html +++ b/32-24-Point-Poker-Game/index.html @@ -97,9 +97,10 @@

24็‚นๆธธๆˆ

- + - + +
@@ -201,7 +202,8 @@

24็‚นๆธธๆˆ

function drawCards() { startCountdown(); // ๆธ…็ฉบไธŠๆฌก่พ“ๅ‡บ - document.getElementById("outputs").innerHTML = " "; + document.getElementById("outputs").innerHTML = " "; + document.getElementById("startButton").style.display = "none"; showResult(false); // ้šๆœบๆŠฝๅ–4ๅผ ไธ้‡ๅค็š„็‰Œ let drawnCards = []; @@ -255,7 +257,15 @@

24็‚นๆธธๆˆ

}; var selectedCards = []; function clcikCard(index) { - if (selectedCards.length < 2) { + // ๆฃ€ๆŸฅๆ˜ฏๅฆๅทฒ็ป้€‰ไธญไบ†่ฟ™ๅผ ๅก็‰‡ + const cardIndex = selectedCards.indexOf(index); + if (cardIndex !== -1) { + // ๅฆ‚ๆžœๅทฒ็ป้€‰ไธญ๏ผŒๅ–ๆถˆ้€‰ๆ‹ฉ + document.getElementById(`card${index}`).style.border = "none"; + selectedCards.splice(cardIndex, 1); + // ๅฆ‚ๆžœไน‹ๅ‰ๅทฒ็ปๆ˜พ็คบๆ“ไฝœ็ช—ๅฃ๏ผŒ็Žฐๅœจๅบ”่ฏฅ้š่— + hide(); + } else if (selectedCards.length < 2) { selectedCards.push(index); document.getElementById(`card${index}`).style.border = "2px solid blue"; if(selectedCards.length == 2){ @@ -414,4 +424,4 @@

24็‚นๆธธๆˆ

- \ No newline at end of file + From 565d2c441883cddf4c1fb50d9c434290808994a5 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 5 Apr 2025 15:42:14 +1000 Subject: [PATCH 92/93] fix readme --- {33-helicopter-game => 33-helicopter-temp}/index.html | 0 README.md | 2 ++ index.html | 2 +- indexCN.html | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) rename {33-helicopter-game => 33-helicopter-temp}/index.html (100%) diff --git a/33-helicopter-game/index.html b/33-helicopter-temp/index.html similarity index 100% rename from 33-helicopter-game/index.html rename to 33-helicopter-temp/index.html diff --git a/README.md b/README.md index b550e54..25e375e 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,8 @@ fork from https://github.com/he-is-talha/html-css-javascript-games 30. **Guess Number Game**: Guess a 4-digit number with A for right position and B for right number. Only eight chances. A good game for logical thinking.๐Ÿง ๐Ÿค– 31. **Air Hockey Game**: A ping-pong like game with two players. control with mouse or keyboard or multi-touch screen. Play with your friends in this classic game. ๐Ÿ€๐Ÿ‘ 32. **24 Point Poker Game**: A classic 24 point poker game. Get four random cards to start. Use Add or Subtract or Multiply or Divide to calculate 24. ๐ŸŽฒ๐Ÿƒ +33. **Helicopter Game**: A simple helicopter shooting game. Control your helicopter to avoid obstacles and shoot enemies. (still under developing) ๐Ÿš๐Ÿ’ฅ +34. **Rubik's Cube Game**: A virtual Rubik's cube game that lets you solve the classic puzzle in 3D. Rotate and twist to align all colors on each face. (still under developing) ๐ŸŽฒ๐Ÿงฉ ## License diff --git a/index.html b/index.html index 10b6e49..5758848 100644 --- a/index.html +++ b/index.html @@ -187,7 +187,7 @@

Game List


34 - rubik's Cube Game: A virtual rubik's cube game. (still under developing)๐ŸŽฒ๐Ÿƒ + rubik's Cube Game: A virtual rubik's cube game. (still under developing)๐ŸŽฒ๐Ÿƒ diff --git a/indexCN.html b/indexCN.html index 47b6786..f1f4617 100644 --- a/indexCN.html +++ b/indexCN.html @@ -187,7 +187,7 @@

ๆธธๆˆๅˆ—่กจ


34 - ้ญ”ๆ–นๆธธๆˆไธ€ไธช่™šๆ‹Ÿ้ญ”ๆ–น๏ผŒๅผ€ๅ‘ไธญ๐ŸŽฒ๐Ÿƒ + ้ญ”ๆ–นๆธธๆˆไธ€ไธช่™šๆ‹Ÿ้ญ”ๆ–น๏ผŒๅผ€ๅ‘ไธญ๐ŸŽฒ๐Ÿƒ From 68e786803d4ae444fb81a82bd7cc5310078b1a34 Mon Sep 17 00:00:00 2001 From: Jack Date: Sat, 5 Apr 2025 15:43:56 +1000 Subject: [PATCH 93/93] change name --- {33-helicopter-temp => 33-helicopter-Game}/index.html | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {33-helicopter-temp => 33-helicopter-Game}/index.html (100%) diff --git a/33-helicopter-temp/index.html b/33-helicopter-Game/index.html similarity index 100% rename from 33-helicopter-temp/index.html rename to 33-helicopter-Game/index.html