鱼C论坛

 找回密码
 立即注册
查看: 2681|回复: 2

[作品展示] 【HTML】数学华容道!

[复制链接]
发表于 2022-1-25 17:55:36 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
我做了一个数学华容道,给大家玩一玩。
(小插曲:我有三个文件,为了大家,我把它整合成了一个文件
我的JS用的是ES6,根本不兼容IE

  1. <!DOCTYPE html>
  2. <html lang="en">
  3.   <head>
  4.     <meta charset="UTF-8" />
  5.     <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  6.     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  7.     <title>数学华容道</title>
  8.     <style>
  9.       * {
  10.         margin: 0;
  11.         padding: 0;
  12.       }

  13.       #app {
  14.         position: relative;
  15.         min-height: 100vh;
  16.       }

  17.       #container {
  18.         position: absolute;
  19.         top: 10%;
  20.         left: 50%;
  21.         transform: translate(-50%, -50%);
  22.       }

  23.       #start {
  24.         top: 50%;
  25.         left: 50%;
  26.         transform: translate(-50%, -50%);
  27.         min-width: 200px;
  28.         min-height: 100px;
  29.         font-size: 50px;
  30.         position: absolute;
  31.       }

  32.       #win {
  33.         display: none;
  34.         position: absolute;
  35.         top: 50%;
  36.         left: 50%;
  37.         font-size: 50px;
  38.         transform: translate(-50%, -50%);
  39.       }

  40.       table {
  41.         position: absolute;
  42.         top: 50%;
  43.         left: 50%;
  44.         transform: translate(-50%, -50%);
  45.       }
  46.       tbody {
  47.         opacity: 0.25;
  48.       }

  49.       tr {
  50.         display: flex;
  51.       }

  52.       td {
  53.         width: 50px;
  54.         height: 50px;
  55.         border: 1px solid #000;
  56.         display: flex;
  57.         justify-content: center;
  58.         align-items: center;
  59.         user-select: none;
  60.       }
  61.     </style>
  62.   </head>
  63.   <body>
  64.     <div id="app">
  65.       <div id="container">
  66.         <h1>数学华容道</h1>

  67.         <select>
  68.           <option value="3">3x3</option>
  69.           <option value="4">4x4</option>
  70.           <option value="5">5x5</option>
  71.           <option value="6">6x6</option>
  72.         </select>
  73.       </div>

  74.       <table id="game">
  75.         <tbody></tbody>
  76.       </table>

  77.       <button id="start">开始</button>

  78.       <h1 id="win">你赢了!</h1>
  79.     </div>

  80.     <script>
  81.       document.getElementById('start').addEventListener('click', () => {
  82.         const gameElem = document
  83.           .getElementById('game')
  84.           .getElementsByTagName('tbody')[0]
  85.         const game = []
  86.         const gameWin = []
  87.         const sideLength = parseInt(
  88.           document.getElementsByTagName('select')[0].value
  89.         )
  90.         let win = false

  91.         // 创建游戏
  92.         function createGame() {
  93.           let rows = []
  94.           for (let i = 0; i < sideLength; i++) {
  95.             rows.push(document.createElement('tr'))
  96.           }
  97.           for (let i = 0; i < sideLength; i++) {
  98.             for (let j = 0; j < sideLength; j++) {
  99.               rows[i].append(document.createElement('td'))
  100.             }
  101.           }
  102.           gameElem.append(...rows)

  103.           for (let i = 1; i < sideLength * sideLength; i++) {
  104.             gameWin.push(i)
  105.           }
  106.           gameWin.push(0)
  107.           game.push(...gameWin)
  108.         }

  109.         // 华容道里的东西被点击时
  110.         function onclick(e) {
  111.           if (e !== undefined) {
  112.             const num = parseInt(e.innerHTML)
  113.             const i1 = game.indexOf(num)
  114.             const i2 = game.indexOf(0)

  115.             const varCon = (() => {
  116.               for (let i = 2; i < sideLength; i++) {
  117.                 if (i1 % sideLength === i) {
  118.                   return true
  119.                 }
  120.               }
  121.               return false
  122.             })()
  123.             const con =
  124.               e.innerHTML != '' &&
  125.               (game[i1 + sideLength] === 0 ||
  126.                 game[i1 - sideLength] === 0 ||
  127.                 (game[i1 + 1] === 0 && (i1 + 1) % sideLength != 0) ||
  128.                 (game[i1 - 1] === 0 && ((i1 - 1) % sideLength == 0 || varCon)))

  129.             if (con) {
  130.               game[i1] = game.splice(i2, 1, game[i1])[0]

  131.               render()
  132.             }
  133.           }
  134.         }

  135.         // 渲染游戏
  136.         function render() {
  137.           Array.from(gameElem.getElementsByTagName('td')).forEach((e, i) => {
  138.             e.innerHTML = game[i] || ''
  139.           })
  140.         }

  141.         // 打乱华容道
  142.         function randomGame() {
  143.           for (let i = 0; i < 1000; i++) {
  144.             const i2 = game.indexOf(0)
  145.             let i1
  146.             // 打乱华容道的四种选择
  147.             switch (Math.floor(Math.random() * 4) + 1) {
  148.               // 往右移
  149.               case 1:
  150.                 i1 = i2 + 1
  151.                 break

  152.               // 往左移
  153.               case 2:
  154.                 i1 = i2 - 1
  155.                 break

  156.               // 往下移
  157.               case 3:
  158.                 i1 = i2 + sideLength
  159.                 break

  160.               // 往上移
  161.               case 4:
  162.                 i1 = i2 - sideLength
  163.                 break
  164.             }

  165.             render()
  166.             const elem = gameElem.getElementsByTagName('td')[i1]
  167.             onclick(elem)
  168.           }
  169.         }

  170.         gameElem.style.opacity = '1'
  171.         document.getElementById('start').style.display = 'none'

  172.         createGame()
  173.         render()
  174.         randomGame()

  175.         document.getElementsByTagName('select')[0].disabled = true

  176.         Array.from(gameElem.getElementsByTagName('td')).forEach((e) => {
  177.           e.addEventListener('click', () => {
  178.             // 如果游戏还没结束,则点击有效
  179.             if (!win) {
  180.               onclick(e)

  181.               if (game.toString() === gameWin.toString()) {
  182.                 win = true

  183.                 gameElem.style.opacity = '0.25'
  184.                 document.getElementById('win').style.display = 'block'
  185.               }
  186.             }
  187.           })
  188.         })
  189.       })
  190.     </script>
  191.   </body>
  192. </html>
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-1-26 08:44:06 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2022-1-27 22:13:04 From FishC Mobile | 显示全部楼层
感谢分享,学到了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-19 16:42

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表