JustCode 源码随笔-12

Attempting to train a self-evolving artificial intelligence model – 00001
尝试训练自主进化型人工智能模型 – 00001

上篇文章结尾处提到,我们无法预知未来,所以保持平常心其实挺好的。确实,过于期待或过于恐惧反而容易让我们忽略技术本身,因此,这篇文章开始是一个新的系列,尽力保持一种务实的风格,深入理解人工智能的底层原理。
The conclusion of the previous article mentioned that we cannot predict the future, so maintaining a calm attitude is actually a good idea. Indeed, excessive expectations or fears can easily lead us to overlook the technology itself. Therefore, this article marks the beginning of a new series, aiming to maintain a practical style and delve into the underlying principles of artificial intelligence.

所以,话不多说,本篇文章先尝试编写一个生命游戏模拟器,以下是具体的代码尝试:
So, without further ado, in this article, we will first attempt to write a Game of Life simulator. Below is the specific code attempt:

<!DOCTYPE html>
<html>
<head>
  <title>生命游戏</title>
  <style>
    /* General styles */
    body {
      font-family: Arial, sans-serif;
      text-align: center;
      background-color: #f0f0f0;
      margin: 0;
      padding: 0;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      height: 100vh;
    }

    /* Header styles */
    h1 {
      color: #333;
    }

    /* Controls container styles */
    .controls {
      margin-top: 20px;
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      align-items: center;
    }

    .control-group {
      margin: 10px;
    }

    .control-label {
      font-weight: bold;
      margin-right: 5px; /* Reduced margin for labels */
    }

    .control-input {
      padding: 5px;
      font-size: 14px;
      border: 1px solid #ccc;
      border-radius: 4px;
      width: 40px; /* Reduced input field width */
    }

    .control-button {
      padding: 5px 10px;
      font-size: 14px;
      background-color: #333;
      color: #fff;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    }

    /* Grid styles */
    .grid {
      display: grid;
      grid-gap: 1px;
      margin-top: 20px;
    }

    .cell {
      width: 10px;
      height: 10px;
      border: 1px solid #ccc;
      background-color: #fff;
    }

    .alive {
      background-color: #333;
    }
  </style>
</head>
<body>
  <h1>生命游戏</h1>
  <div class="controls">
    <div class="control-group">
      <label class="control-label" for="rows">行:</label>
      <input class="control-input" type="number" id="rows" min="1" value="50">
    </div>
    <div class="control-group">
      <label class="control-label" for="cols">列:</label>
      <input class="control-input" type="number" id="cols" min="1" value="50">
    </div>
    <div class="control-group">
      <button class="control-button" onclick="resizeGrid()">调整大小</button>
    </div>
    <div class="control-group">
      <label class="control-label" for="speed">速度:</label>
      <input class="control-input" type="range" id="speed" min="50" max="1000" step="50" value="250" onchange="changeSpeed(this.value)">
      <span id="speedValue">250ms</span>
    </div>
    <div class="control-group">
      <button class="control-button" onclick="startGame()">开始游戏</button>
      <button class="control-button" onclick="stopGame()">停止游戏</button>
      <button class="control-button" onclick="clearGrid()">清空网格</button>
      <button class="control-button" onclick="randomizeGrid()">随机生成</button>
    </div>
  </div>
  <div class="grid" id="grid"></div>

  <script>
    let numRows = 50;
    let numCols = 50;
    const cellSize = 10;
    let grid = Array.from({ length: numRows }, () => Array.from({ length: numCols }, () => false));
    let intervalId;
    let speed = 250;

    const gridElement = document.getElementById('grid');

    function createGrid() {
      gridElement.innerHTML = '';
      gridElement.style.gridTemplateColumns = `repeat(${numCols}, ${cellSize}px)`;
      gridElement.style.gridTemplateRows = `repeat(${numRows}, ${cellSize}px)`;

      for (let i = 0; i < numRows; i++) {
        for (let j = 0; j < numCols; j++) {
          const cell = document.createElement('div');
          cell.classList.add('cell');
          cell.style.width = `${cellSize}px`;
          cell.style.height = `${cellSize}px`;
          cell.addEventListener('click', () => toggleCell(i, j));
          gridElement.appendChild(cell);
        }
      }
    }

    createGrid();

    function updateGrid() {
      const newGrid = Array.from({ length: numRows }, () => Array.from({ length: numCols }, () => false));
      for (let i = 0; i < numRows; i++) {
        for (let j = 0; j < numCols; j++) {
          const neighbors = countNeighbors(i, j);
          if (grid[i][j]) {
            if (neighbors === 2 || neighbors === 3) {
              newGrid[i][j] = true;
            }
          } else {
            if (neighbors === 3) {
              newGrid[i][j] = true;
            }
          }
        }
      }
      grid = newGrid;
    }

    function countNeighbors(x, y) {
      let count = 0;
      const deltas = [-1, 0, 1];
      for (let dx of deltas) {
        for (let dy of deltas) {
          if (dx === 0 && dy === 0) continue;
          const newX = x + dx;
          const newY = y + dy;
          if (newX >= 0 && newX < numRows && newY >= 0 && newY < numCols && grid[newX][newY]) {
            count++;
          }
        }
      }
      return count;
    }

    function startGame() {
      intervalId = setInterval(() => {
        updateGrid();
        renderGrid();
      }, speed);
      document.querySelector('button[onclick="startGame"]').disabled = true;
    }

    function stopGame() {
      clearInterval(intervalId);
      document.querySelector('button[onclick="startGame"]').disabled = false;
    }

    function clearGrid() {
      grid = Array.from({ length: numRows }, () => Array.from({ length: numCols }, () => false));
      renderGrid();
      stopGame();
    }

    function toggleCell(x, y) {
      grid[x][y] = !grid[x][y];
      renderGrid();
    }

    function renderGrid() {
      const cells = document.querySelectorAll('.cell');
      for (let i = 0; i < numRows; i++) {
        for (let j = 0; j < numCols; j++) {
          const cell = cells[i * numCols + j];
          if (grid[i][j]) {
            cell.classList.add('alive');
          } else {
            cell.classList.remove('alive');
          }
        }
      }
    }

    function changeSpeed(newSpeed) {
      speed = parseInt(newSpeed);
      document.getElementById('speedValue').textContent = `${newSpeed}ms`;
      if (intervalId) {
        stopGame();
        startGame();
      }
    }

    function randomizeGrid() {
      grid = Array.from({ length: numRows }, () =>
        Array.from({ length: numCols }, () => Math.random() < 0.3)
      );
      renderGrid();
    }

    function resizeGrid() {
      const newRows = parseInt(document.getElementById('rows').value);
      const newCols = parseInt(document.getElementById('cols').value);
      if (newRows >= 1 && newCols >= 1) {
        numRows = newRows;
        numCols = newCols;
        createGrid();
        randomizeGrid();
      }
    }
  </script>
</body>
</html>

这段代码实现了一个生命游戏(Conway’s Game of Life)的模拟器,用户可以在网格上设置初始状态,然后观察细胞的演化过程。控制面板允许用户调整模拟速度、开始/停止模拟、清空网格以及随机生成初始状态。
This code implements a simulator for Conway’s Game of Life, allowing users to set the initial state on a grid and observe the evolution of cells. The control panel allows users to adjust the simulation speed, start/stop the simulation, clear the grid, and randomly generate the initial state.

读者可以新建一个HTML文档,再将源码复制粘贴到文档中,保存并退出,再用浏览器打开这个文档,就会得到一个生命游戏模拟器界面。
Readers can create a new HTML document, then copy and paste the source code into the document, save and exit, and then open this document using a web browser to access a Game of Life simulator interface.

经过测试代码可正常运行。
Tested and works fine.

下次再会。
See you next time.