鱼C论坛

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

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

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

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

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

x
我做了一个数学华容道,给大家玩一玩。
(小插曲:我有三个文件,为了大家,我把它整合成了一个文件
我的JS用的是ES6,根本不兼容IE
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>数学华容道</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }

      #app {
        position: relative;
        min-height: 100vh;
      }

      #container {
        position: absolute;
        top: 10%;
        left: 50%;
        transform: translate(-50%, -50%);
      }

      #start {
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        min-width: 200px;
        min-height: 100px;
        font-size: 50px;
        position: absolute;
      }

      #win {
        display: none;
        position: absolute;
        top: 50%;
        left: 50%;
        font-size: 50px;
        transform: translate(-50%, -50%);
      }

      table {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
      }
      tbody {
        opacity: 0.25;
      }

      tr {
        display: flex;
      }

      td {
        width: 50px;
        height: 50px;
        border: 1px solid #000;
        display: flex;
        justify-content: center;
        align-items: center;
        user-select: none;
      }
    </style>
  </head>
  <body>
    <div id="app">
      <div id="container">
        <h1>数学华容道</h1>

        <select>
          <option value="3">3x3</option>
          <option value="4">4x4</option>
          <option value="5">5x5</option>
          <option value="6">6x6</option>
        </select>
      </div>

      <table id="game">
        <tbody></tbody>
      </table>

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

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

    <script>
      document.getElementById('start').addEventListener('click', () => {
        const gameElem = document
          .getElementById('game')
          .getElementsByTagName('tbody')[0]
        const game = []
        const gameWin = []
        const sideLength = parseInt(
          document.getElementsByTagName('select')[0].value
        )
        let win = false

        // 创建游戏
        function createGame() {
          let rows = []
          for (let i = 0; i < sideLength; i++) {
            rows.push(document.createElement('tr'))
          }
          for (let i = 0; i < sideLength; i++) {
            for (let j = 0; j < sideLength; j++) {
              rows[i].append(document.createElement('td'))
            }
          }
          gameElem.append(...rows)

          for (let i = 1; i < sideLength * sideLength; i++) {
            gameWin.push(i)
          }
          gameWin.push(0)
          game.push(...gameWin)
        }

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

            const varCon = (() => {
              for (let i = 2; i < sideLength; i++) {
                if (i1 % sideLength === i) {
                  return true
                }
              }
              return false
            })()
            const con =
              e.innerHTML != '' &&
              (game[i1 + sideLength] === 0 ||
                game[i1 - sideLength] === 0 ||
                (game[i1 + 1] === 0 && (i1 + 1) % sideLength != 0) ||
                (game[i1 - 1] === 0 && ((i1 - 1) % sideLength == 0 || varCon)))

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

              render()
            }
          }
        }

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

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

              // 往左移
              case 2:
                i1 = i2 - 1
                break

              // 往下移
              case 3:
                i1 = i2 + sideLength
                break

              // 往上移
              case 4:
                i1 = i2 - sideLength
                break
            }

            render()
            const elem = gameElem.getElementsByTagName('td')[i1]
            onclick(elem)
          }
        }

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

        createGame()
        render()
        randomGame()

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

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

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

                gameElem.style.opacity = '0.25'
                document.getElementById('win').style.display = 'block'
              }
            }
          })
        })
      })
    </script>
  </body>
</html>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-26 08:44:06 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-27 22:13:04 From FishC Mobile | 显示全部楼层
感谢分享,学到了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-22 21:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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