“2048”游戏网页版html+css+js

“2048”游戏网页版html+css+js

 别忘了请点个赞+收藏+关注支持一下博主喵!!!

   2048 游戏是一个非常流行的数字拼图游戏,玩家通过移动方块使相同数字的方块合并,最终达到 2048 或更高分数。本教程将详细介绍如何使用 HTML、CSS 和 JavaScript 创建一个简单的 2048 游戏网页。。

  项目结构如下:(懒得搭vue了)

2048-game/
├── index.html
├── styles.css
└── script.js

1. index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"> <!-- 设置文档的字符编码为 UTF-8 --><meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 使页面在移动设备上适配屏幕宽度 --><title>2048 Game</title> <!-- 页面标题 --><link rel="stylesheet" href="styles.css"> <!-- 引入外部 CSS 文件 -->
</head>
<body><div class="game-container"> <!-- 游戏容器,用于包裹整个游戏界面 --><div class="score-container">0</div> <!-- 分数显示区域 --><div class="grid-container"> <!-- 网格容器,用于包裹 4x4 的游戏网格 --><div class="grid-row"> <!-- 每一行的网格 --><div class="grid-cell"></div> <!-- 每一个网格单元 --><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div><div class="grid-row"><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div><div class="grid-row"><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div><div class="grid-row"><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div><div class="grid-cell"></div></div></div><button id="restart-button">Restart</button> <!-- 重新开始按钮 --></div><script src="script.js"></script> <!-- 引入外部 JavaScript 文件 -->
</body>
</html>

2. styles.css

body {display: flex; /* 使用 Flexbox 布局 */justify-content: center; /* 水平居中 */align-items: center; /* 垂直居中 */height: 100vh; /* 占满整个视窗高度 */margin: 0; /* 移除默认外边距 */background-color: #faf8ef; /* 背景颜色 */font-family: Arial, sans-serif; /* 字体设置 */
}.game-container {width: 500px; /* 容器宽度 */height: 500px; /* 容器高度 */position: relative; /* 相对定位 */background-color: #bbada0; /* 背景颜色 */border-radius: 10px; /* 圆角 */box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3); /* 阴影效果 */
}.score-container {position: absolute; /* 绝对定位 */top: 10px; /* 距离顶部 10px */left: 10px; /* 距离左边 10px */background-color: #eee4da; /* 背景颜色 */padding: 10px; /* 内边距 */border-radius: 5px; /* 圆角 */font-size: 24px; /* 字体大小 */font-weight: bold; /* 加粗字体 */
}.grid-container {width: 400px; /* 网格容器宽度 */height: 400px; /* 网格容器高度 */position: absolute; /* 绝对定位 */top: 50%; /* 距离顶部 50% */left: 50%; /* 距离左边 50% */transform: translate(-50%, -50%); /* 居中对齐 */display: grid; /* 使用 Grid 布局 */grid-template-columns: repeat(4, 100px); /* 4 列,每列 100px */grid-template-rows: repeat(4, 100px); /* 4 行,每行 100px */gap: 10px; /* 网格间距 */
}.grid-cell {background-color: #cdc1b4; /* 背景颜色 */border-radius: 3px; /* 圆角 */display: flex; /* 使用 Flexbox 布局 */justify-content: center; /* 水平居中 */align-items: center; /* 垂直居中 */font-size: 32px; /* 字体大小 */font-weight: bold; /* 加粗字体 */color: #776e65; /* 文字颜色 */
}/* 不同数字的方块样式 */
.grid-cell.number-2 { background-color: #eee4da; color: #776e65; }
.grid-cell.number-4 { background-color: #ede0c8; color: #776e65; }
.grid-cell.number-8 { background-color: #f2b179; color: #f9f6f2; }
.grid-cell.number-16 { background-color: #f59563; color: #f9f6f2; }
.grid-cell.number-32 { background-color: #f67c5f; color: #f9f6f2; }
.grid-cell.number-64 { background-color: #f65e3b; color: #f9f6f2; }
.grid-cell.number-128 { background-color: #edcf72; color: #f9f6f2; }
.grid-cell.number-256 { background-color: #edcc61; color: #f9f6f2; }
.grid-cell.number-512 { background-color: #edc850; color: #f9f6f2; }
.grid-cell.number-1024 { background-color: #edc53f; color: #f9f6f2; }
.grid-cell.number-2048 { background-color: #edc22e; color: #f9f6f2; }#restart-button {position: absolute; /* 绝对定位 */bottom: 10px; /* 距离底部 10px */left: 50%; /* 距离左边 50% */transform: translateX(-50%); /* 水平居中 */padding: 10px 20px; /* 内边距 */background-color: #8f7a66; /* 背景颜色 */color: #f9f6f2; /* 文字颜色 */border: none; /* 无边框 */border-radius: 5px; /* 圆角 */cursor: pointer; /* 鼠标指针样式 */font-size: 18px; /* 字体大小 */font-weight: bold; /* 加粗字体 */
}#restart-button:hover {background-color: #746655; /* 鼠标悬停时的背景颜色 */
}

3. 最难的script.js

代码分布详解:

1. 获取 DOM 元素

const grid = document.querySelector('.grid-container'); // 获取网格容器
const cells = document.querySelectorAll('.grid-cell'); // 获取所有网格单元
const scoreContainer = document.querySelector('.score-container'); // 获取分数显示区域
const restartButton = document.getElementById('restart-button'); // 获取重新开始按钮

这些代码通过 querySelectorgetElementById 方法获取页面上的各个元素,以便后续操作。

2. 初始化变量

let score = 0; // 初始化分数
let hasWon = false; // 标记是否已经赢得游戏const matrix = [[0, 0, 0, 0], // 初始化 4x4 的矩阵[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]
];const winNumber = 2048; // 赢得游戏的目标数字
  • score:当前得分。
  • hasWon:标记是否已经赢得游戏。
  • matrix:4x4 的二维数组,用于存储游戏中的数字。
  • winNumber:赢得游戏的目标数字,即 2048。

 3. 获取随机空格子

function getRandomEmptyCell() {const emptyCells = []; // 存储所有空格子的坐标for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (matrix[i][j] === 0) { // 如果格子为空emptyCells.push({ row: i, col: j }); // 将坐标加入空格子列表}}}if (emptyCells.length > 0) { // 如果有空格子const randomIndex = Math.floor(Math.random() * emptyCells.length); // 随机选择一个空格子return emptyCells[randomIndex];}return null; // 没有空格子返回 null
}

这个函数遍历 matrix,找到所有为空的格子,并将它们的坐标存储在 emptyCells 数组中。如果存在空格子,则随机选择一个返回;否则返回 null。 

算法步骤:

  1. 初始化一个空数组 emptyCells,用于存储所有空格子的坐标。
  2. 使用两层嵌套循环遍历 matrix,检查每个格子是否为空(即 matrix[i][j] === 0)。
  3. 如果格子为空,将该格子的坐标 { row: i, col: j } 推入 emptyCells 数组。
  4. 循环结束后,检查 emptyCells 是否有元素。
  5. 如果有空格子,随机选择一个空格子的索引 randomIndex,并返回该空格子的坐标。
  6. 如果没有空格子,返回 null

4. 添加随机方块

function addRandomTile() {const cell = getRandomEmptyCell();if (cell) {const value = Math.random() < 0.9 ? 2 : 4; // 90% 的概率生成 2,10% 的概率生成 4matrix[cell.row][cell.col] = value; // 更新矩阵updateGrid(); // 更新网格显示}
}

这个函数调用 getRandomEmptyCell 获取一个随机的空格子,然后以 90% 的概率生成 2,10% 的概率生成 4,并更新 matrix 和网格显示。 

算法步骤:

  1. 调用 getRandomEmptyCell 获取一个随机的空格子。
  2. 如果找到了空格子:
    • 生成一个随机值 value,90% 的概率生成 2,10% 的概率生成 4。
    • 更新 matrix 中对应位置的值为 value
    • 调用 updateGrid 更新网格显示。

5. 更新网格显示

function updateGrid() {cells.forEach((cell, index) => {const row = Math.floor(index / 4); // 计算当前单元格所在的行const col = index % 4; // 计算当前单元格所在的列const value = matrix[row][col]; // 获取矩阵中的值cell.textContent = value || ''; // 显示值,如果没有值则显示空字符串cell.classList.remove('number-2', 'number-4', 'number-8', 'number-16', 'number-32', 'number-64', 'number-128', 'number-256', 'number-512', 'number-1024', 'number-2048'); // 移除所有样式类if (value !== 0) { // 如果有值,添加对应的样式类cell.classList.add(`number-${value}`);}});
}

这个函数遍历所有 cells,根据 matrix 中的值更新每个单元格的文本内容和样式类。 

算法步骤:

  1. 遍历所有 cells,使用 forEach 方法。
  2. 对于每个 cell,计算其在 matrix 中的行 row 和列 col
  3. 获取 matrix 中对应位置的值 value
  4. 设置 cell 的文本内容为 value,如果没有值则显示为空字符串。
  5. 移除 cell 上的所有样式类。
  6. 如果 value 不为 0,添加对应的样式类 number-${value}

6. 向上移动

function moveUp() {for (let col = 0; col < 4; col++) { // 遍历每一列let tempCol = []; // 临时存储非零值for (let row = 0; row < 4; row++) {if (matrix[row][col] !== 0) {tempCol.push(matrix[row][col]); // 将非零值加入临时列表}}tempCol = mergeTiles(tempCol); // 合并相同的值for (let row = 0; row < 4; row++) {matrix[row][col] = tempCol[row] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}

这个函数处理向上移动的操作:

  1. 遍历每一列。
  2. 将每列中的非零值存储到 tempCol 中。
  3. 调用 mergeTiles 合并相同的值。
  4. 更新 matrix
  5. 添加新的方块。
  6. 检查游戏是否结束。

算法步骤:

  1. 遍历每一列 col
  2. 初始化一个空数组 tempCol,用于存储当前列中的非零值。
  3. 使用内层循环遍历当前列的每一行 row,将非零值推入 tempCol
  4. 调用 mergeTiles 合并 tempCol 中的相同值。
  5. 使用内层循环更新 matrix 中当前列的值,从 tempCol 中取值,如果 tempCol 中没有值则设为 0。
  6. 调用 addRandomTile 添加一个新的方块。
  7. 调用 checkGameOver 检查游戏是否结束。

 7. 向下移动

function moveDown() {for (let col = 0; col < 4; col++) { // 遍历每一列let tempCol = []; // 临时存储非零值for (let row = 3; row >= 0; row--) {if (matrix[row][col] !== 0) {tempCol.push(matrix[row][col]); // 将非零值加入临时列表}}tempCol = mergeTiles(tempCol); // 合并相同的值for (let row = 3; row >= 0; row--) {matrix[row][col] = tempCol[3 - row] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}

这个函数处理向下移动的操作,与 moveUp 类似,只是方向相反。 

8. 向左移动

function moveLeft() {for (let row = 0; row < 4; row++) { // 遍历每一行let tempRow = []; // 临时存储非零值for (let col = 0; col < 4; col++) {if (matrix[row][col] !== 0) {tempRow.push(matrix[row][col]); // 将非零值加入临时列表}}tempRow = mergeTiles(tempRow); // 合并相同的值for (let col = 0; col < 4; col++) {matrix[row][col] = tempRow[col] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}

 这个函数处理向左移动的操作,与 moveUp 类似,只是方向不同。

  1. 遍历每一行 row
  2. 初始化一个空数组 tempRow,用于存储当前行中的非零值。
  3. 使用内层循环遍历当前行的每一列 col,将非零值推入 tempRow
  4. 调用 mergeTiles 合并 tempRow 中的相同值。
  5. 使用内层循环更新 matrix 中当前行的值,从 tempRow 中取值,如果 tempRow 中没有值则设为 0。
  6. 调用 addRandomTile 添加一个新的方块。
  7. 调用 checkGameOver 检查游戏是否结束。

9. 向右移动

function moveRight() {for (let row = 0; row < 4; row++) { // 遍历每一行let tempRow = []; // 临时存储非零值for (let col = 3; col >= 0; col--) {if (matrix[row][col] !== 0) {tempRow.push(matrix[row][col]); // 将非零值加入临时列表}}tempRow = mergeTiles(tempRow); // 合并相同的值for (let col = 3; col >= 0; col--) {matrix[row][col] = tempRow[3 - col] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}

这个函数处理向右移动的操作,与 moveLeft 类似,只是方向相反。 

10. 合并相同的值

function mergeTiles(tiles) {for (let i = 0; i < tiles.length - 1; i++) {if (tiles[i] === tiles[i + 1]) { // 如果相邻的两个值相同tiles[i] *= 2; // 合并值tiles.splice(i + 1, 1); // 删除合并后的值score += tiles[i]; // 更新分数scoreContainer.textContent = score; // 更新分数显示if (tiles[i] === winNumber && !hasWon) { // 如果达到目标值且未赢过alert('You Win!'); // 提示胜利hasWon = true; // 标记已赢}}}while (tiles.length < 4) { // 确保列表长度为 4tiles.push(0);}return tiles;
}

这个函数合并 tiles 列表中的相同值:

  1. 遍历 tiles,如果相邻的两个值相同,则合并它们。
  2. 更新分数和分数显示。
  3. 如果达到目标值 2048 且未赢过,则提示胜利。
  4. 确保 tiles 列表长度为 4。

算法步骤:

  1. 遍历 tiles 数组,检查相邻的两个值是否相同。
  2. 如果相邻的两个值相同:
    • 将第一个值乘以 2。
    • 从数组中删除第二个值。
    • 更新分数 score 并更新分数显示。
    • 如果合并后的值等于 winNumber 且未赢过,提示胜利并标记已赢。
  3. 使用 while 循环确保 tiles 数组的长度为 4,不足的部分用 0 填充。
  4. 返回合并后的 tiles 数组。

 11. 检查游戏是否结束

function checkGameOver() {let gameOver = true; // 默认游戏结束for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (matrix[i][j] === 0 || // 如果有空格子(i < 3 && matrix[i][j] === matrix[i + 1][j]) || // 或者有相邻的相同值(j < 3 && matrix[i][j] === matrix[i][j + 1])) {gameOver = false; // 游戏未结束break;}}if (!gameOver) break;}if (gameOver) {alert('Game Over!'); // 提示游戏结束}
}

这个函数检查游戏是否结束:

  1. 遍历 matrix,检查是否有空格子或相邻的相同值。
  2. 如果有空格子或相邻的相同值,则游戏未结束。
  3. 否则,提示游戏结束。

算法步骤:

  1. 初始化一个布尔变量 gameOver 为 true,默认游戏结束。
  2. 使用两层嵌套循环遍历 matrix,检查每个格子是否为空或有相邻的相同值。
  3. 如果有空格子或有相邻的相同值,将 gameOver 设为 false 并跳出循环。
  4. 如果 gameOver 仍为 true,提示游戏结束。

 12. 重新开始游戏

function restartGame() {matrix.forEach(row => row.fill(0)); // 重置矩阵score = 0; // 重置分数hasWon = false; // 重置胜利标记scoreContainer.textContent = score; // 更新分数显示addRandomTile(); // 添加初始方块addRandomTile(); // 添加初始方块updateGrid(); // 更新网格显示
}

这个函数重置游戏:

  1. 重置 matrix
  2. 重置分数和胜利标记。
  3. 更新分数显示。
  4. 添加两个初始方块。
  5. 更新网格显示。

算法步骤:

  1. 使用 forEach 方法遍历 matrix 的每一行,将每一行的值全部设为 0。
  2. 将分数 score 设为 0。
  3. 将胜利标记 hasWon 设为 false
  4. 更新分数显示。
  5. 调用 addRandomTile 两次,添加两个初始方块。
  6. 调用 updateGrid 更新网格显示。

 13. 监听键盘事件

document.addEventListener('keydown', (event) => {switch (event.key) {case 'ArrowUp': // 上箭头moveUp();break;case 'ArrowDown': // 下箭头moveDown();break;case 'ArrowLeft': // 左箭头moveLeft();break;case 'ArrowRight': // 右箭头moveRight();break;}
});

 这个事件监听器监听键盘事件,根据按键方向调用相应的移动函数

14. 监听重新开始按钮点击事件

restartButton.addEventListener('click', restartGame);

这个事件监听器监听重新开始按钮的点击事件,调用 restartGame 重置游戏。 

15. 初始化游戏

restartGame();

最终代码:

const grid = document.querySelector('.grid-container'); // 获取网格容器
const cells = document.querySelectorAll('.grid-cell'); // 获取所有网格单元
const scoreContainer = document.querySelector('.score-container'); // 获取分数显示区域
const restartButton = document.getElementById('restart-button'); // 获取重新开始按钮let score = 0; // 初始化分数
let hasWon = false; // 标记是否已经赢得游戏const matrix = [[0, 0, 0, 0], // 初始化 4x4 的矩阵[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]
];const winNumber = 2048; // 赢得游戏的目标数字// 获取一个随机的空格子
function getRandomEmptyCell() {const emptyCells = []; // 存储所有空格子的坐标for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (matrix[i][j] === 0) { // 如果格子为空emptyCells.push({ row: i, col: j }); // 将坐标加入空格子列表}}}if (emptyCells.length > 0) { // 如果有空格子const randomIndex = Math.floor(Math.random() * emptyCells.length); // 随机选择一个空格子return emptyCells[randomIndex];}return null; // 没有空格子返回 null
}// 在随机选择的空格子中添加一个新方块(2 或 4)
function addRandomTile() {const cell = getRandomEmptyCell();if (cell) {const value = Math.random() < 0.9 ? 2 : 4; // 90% 的概率生成 2,10% 的概率生成 4matrix[cell.row][cell.col] = value; // 更新矩阵updateGrid(); // 更新网格显示}
}// 更新 HTML 网格中的方块显示
function updateGrid() {cells.forEach((cell, index) => {const row = Math.floor(index / 4); // 计算当前单元格所在的行const col = index % 4; // 计算当前单元格所在的列const value = matrix[row][col]; // 获取矩阵中的值cell.textContent = value || ''; // 显示值,如果没有值则显示空字符串cell.classList.remove('number-2', 'number-4', 'number-8', 'number-16', 'number-32', 'number-64', 'number-128', 'number-256', 'number-512', 'number-1024', 'number-2048'); // 移除所有样式类if (value !== 0) { // 如果有值,添加对应的样式类cell.classList.add(`number-${value}`);}});
}// 向上移动
function moveUp() {for (let col = 0; col < 4; col++) { // 遍历每一列let tempCol = []; // 临时存储非零值for (let row = 0; row < 4; row++) {if (matrix[row][col] !== 0) {tempCol.push(matrix[row][col]); // 将非零值加入临时列表}}tempCol = mergeTiles(tempCol); // 合并相同的值for (let row = 0; row < 4; row++) {matrix[row][col] = tempCol[row] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 向下移动
function moveDown() {for (let col = 0; col < 4; col++) { // 遍历每一列let tempCol = []; // 临时存储非零值for (let row = 3; row >= 0; row--) {if (matrix[row][col] !== 0) {tempCol.push(matrix[row][col]); // 将非零值加入临时列表}}tempCol = mergeTiles(tempCol); // 合并相同的值for (let row = 3; row >= 0; row--) {matrix[row][col] = tempCol[3 - row] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 向左移动
function moveLeft() {for (let row = 0; row < 4; row++) { // 遍历每一行let tempRow = []; // 临时存储非零值for (let col = 0; col < 4; col++) {if (matrix[row][col] !== 0) {tempRow.push(matrix[row][col]); // 将非零值加入临时列表}}tempRow = mergeTiles(tempRow); // 合并相同的值for (let col = 0; col < 4; col++) {matrix[row][col] = tempRow[col] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 向右移动
function moveRight() {for (let row = 0; row < 4; row++) { // 遍历每一行let tempRow = []; // 临时存储非零值for (let col = 3; col >= 0; col--) {if (matrix[row][col] !== 0) {tempRow.push(matrix[row][col]); // 将非零值加入临时列表}}tempRow = mergeTiles(tempRow); // 合并相同的值for (let col = 3; col >= 0; col--) {matrix[row][col] = tempRow[3 - col] || 0; // 更新矩阵}}addRandomTile(); // 添加新的方块checkGameOver(); // 检查游戏是否结束
}// 合并相同的值
function mergeTiles(tiles) {for (let i = 0; i < tiles.length - 1; i++) {if (tiles[i] === tiles[i + 1]) { // 如果相邻的两个值相同tiles[i] *= 2; // 合并值tiles.splice(i + 1, 1); // 删除合并后的值score += tiles[i]; // 更新分数scoreContainer.textContent = score; // 更新分数显示if (tiles[i] === winNumber && !hasWon) { // 如果达到目标值且未赢过alert('You Win!'); // 提示胜利hasWon = true; // 标记已赢}}}while (tiles.length < 4) { // 确保列表长度为 4tiles.push(0);}return tiles;
}// 检查游戏是否结束
function checkGameOver() {let gameOver = true; // 默认游戏结束for (let i = 0; i < 4; i++) {for (let j = 0; j < 4; j++) {if (matrix[i][j] === 0 || // 如果有空格子(i < 3 && matrix[i][j] === matrix[i + 1][j]) || // 或者有相邻的相同值(j < 3 && matrix[i][j] === matrix[i][j + 1])) {gameOver = false; // 游戏未结束break;}}if (!gameOver) break;}if (gameOver) {alert('Game Over!'); // 提示游戏结束}
}// 重新开始游戏
function restartGame() {matrix.forEach(row => row.fill(0)); // 重置矩阵score = 0; // 重置分数hasWon = false; // 重置胜利标记scoreContainer.textContent = score; // 更新分数显示addRandomTile(); // 添加初始方块addRandomTile(); // 添加初始方块updateGrid(); // 更新网格显示
}// 监听键盘事件
document.addEventListener('keydown', (event) => {switch (event.key) {case 'ArrowUp': // 上箭头moveUp();break;case 'ArrowDown': // 下箭头moveDown();break;case 'ArrowLeft': // 左箭头moveLeft();break;case 'ArrowRight': // 右箭头moveRight();break;}
});// 监听重新开始按钮点击事件
restartButton.addEventListener('click', restartGame);// 初始化游戏
restartGame();

 别忘了请点个赞+收藏+关注支持一下博主喵!!!

累了,水一下吧。。。。。。∗︎˚(* ˃̤൬˂̤ *)˚∗︎

gitee:2048-game: html+css+js设计的一个2048游戏(网页)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/467851.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Scala 的包及其导入

Scala使用包来创建用于模块化程序的命名空间。通过在Scala文件的顶部声明一个或多个包名称可以创建包&#xff0c;另一种声明包的方式是使用0&#xff0c;这种方式可以嵌套包&#xff0c;并且提供更好的范围与封装控制。对于包的导入&#xff0c;Scala与Java的区别之一便是&…

使用 HuggingFace 提供的 Elasticsearch 托管交叉编码器进行重新排名

作者&#xff1a;来自 Elastic Jeff Vestal 了解如何使用 Hugging Face 的模型在 Elasticsearch 中托管和执行语义重新排序。 在这篇简短的博文中&#xff0c;我将向你展示如何使用 Hugging Face 中的模型在搜索时在你自己的 Elasticsearch 集群中执行语义重新排序。我们将使用…

深究JS底层原理

一、JS中八种数据类型判断方法 在JavaScript中&#xff0c;数据类型分为两大类&#xff1a;基本&#xff08;原始&#xff09;数据类型和引用&#xff08;对象&#xff09;数据类型。 基本数据类型&#xff08;Primitive Data Types&#xff09; 基本数据类型是表示简单的数…

C++虚继承演示

在继承中如果出现&#xff1a; 这种情况&#xff0c;B和C都继承了A&#xff0c;D继承了B、C 在D中访问A的成员会出现&#xff1a; 这样的警告 是因为在继承时A出现两条分支&#xff1a;ABD、ACD 编译器不知道访问的A中的元素是经过B继承还是C继承 所以B、C在继承A时要用到…

【1】虚拟机安装

1.安装VMware WorkStation Pro VMware下载地址&#xff1a; 密钥&#xff1a;YF390-0HF8P-M81RQ-2DXQE-M2UT6 2.新建虚拟机 centos7下载地址&#xff1a;centos-7.9.2009-isos-x86_64安装包下载_开源镜像站-阿里云

【机器学习】均方误差根(RMSE:Root Mean Squared Error)

均方误差根&#xff08;Root Mean Squared Error&#xff0c;RMSE&#xff09;是机器学习和统计学中常用的误差度量指标&#xff0c;用于评估预测值与真实值之间的差异。它通常用于回归模型的评价&#xff0c;以衡量模型的预测精度。 RMSE的定义与公式 给定预测值 和实际值 …

python可视化进阶

引用&#xff1a; 首先需要安装 plotnine from plotnine import* import joypy数据可视化进阶操作 3.1 类别数据可视化 【例3-1】——绘制简单条形图 【代码框3-1】——绘制简单条形图 # 图3-1的绘制代码 import pandas as pd import matplotlib.pyplot as plt from cvxpy …

玩的花,云产品也能拼团了!!!

说起拼单大家都不陌生&#xff0c;电商一贯的营销手段&#xff0c;不过确实可以给消费者省下一笔钱。双11到了&#xff0c;腾讯云产品也玩起了拼团&#xff0c;这明显是对开发人员和各企业的福利。 对于有云产品需求的个人或企业&#xff0c;这次绝对是难得的一次薅羊毛机会。…

设计模式-七个基本原则之一-开闭原则 + SpringBoot案例

开闭原则:(SRP) 面向对象七个基本原则之一 对扩展开放&#xff1a;软件实体&#xff08;类、模块、函数等&#xff09;应该能够通过增加新功能来进行扩展。对修改关闭&#xff1a;一旦软件实体被开发完成&#xff0c;就不应该修改它的源代码。 要看实际场景&#xff0c;比如组内…

Flutter 插件 sliding_up_panel 实现从底部滑出的面板

前言 sliding_up_panel 是一个 Flutter 插件&#xff0c;用于实现从底部滑出的面板。它在设计上非常灵活&#xff0c;能够适应多种 UI 场景&#xff0c;比如从底部滑出的菜单、可拖动的弹出面板等。以下是 sliding_up_panel 的详细用法&#xff0c;包括常用的参数说明和示例代…

出海企业如何借助云计算平台实现多区域部署?

云计算de小白 如需进一步了解&#xff0c;请单击链接了解有关 Akamai 云计算的更多信息 在本文中我们将告诉大家如何在Linode云计算平台上借助VLAN快速实现多地域部署。 首先我们需要明确一些基本概念和思想&#xff1a; 部署多区域 VLAN 为了在多区域部署中在不同的 VLAN …

Linux(CentOS)安装 JDK

CentOS版本&#xff1a;CentOS 7 JDK版本&#xff1a;JDK17 1、下载 JDK 官网&#xff1a;https://www.oracle.com/ 2、上传 JDK 文件到 CentOS 使用FinalShell远程登录工具&#xff0c;并且使用 root 用户连接登录&#xff08;注意这里说的root用户连接登录是指这样的&…

多边形电子围栏算法

在日常生活工作中&#xff0c;我们经常接触到电子围栏&#xff0c;大部分的电子围栏基本上都是圆形的&#xff0c;想要知道某一个点是否在圆形区域内&#xff0c;算法很简单&#xff0c;只需要知道这个圆形区域的圆心坐标和被测点的坐标的距离是否小于半径即可。两点的距离小于…

柯桥学日语J.TEST考试是什么?J.TEST考试报名

J.TEST考试是什么&#xff1f; J.TEST全称为实用日本语鉴定考试&#xff0c;在2007年获得了国家劳动和社会保障部的认可&#xff0c;作为面对母语为非日本语的人员进行的日本语能力测试&#xff0c;J.TEST被越来越多的日本企业所认可&#xff0c;由于其对日语的实际运用能力具有…

谈谈ssh-keygen进行多host配置及使用

背景 传统的Telnet、FTP协议都是使用明文传输数据&#xff0c;存在一定的安全风险&#xff0c;如果传输数据被截取&#xff0c;可能造成数据泄露风险&#xff0c;尤其对于敏感数据&#xff0c;泄露造成的损失无法估计。最近公司、github等平台都不再支持http方式进行代码下载工…

谷粒商城-高级篇-认证服务

1、环境搭建 1、创建gulimall-auth-server模块 2、导入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schem…

独显装完ubuntu后启动黑屏显示/dev/sda:clean files blocks的解决方案

解决方案如下&#xff1a; 选中Ubuntu按E键 在编辑界面倒数第2行的linux那行&#xff08;后面有quiet splash选项&#xff09;的最后添加nomodeset 然后按F10保存重启 然后管理员权限打开/etc/modprobe.d/blacklist.conf&#xff0c;在文件末尾添加&#xff1a; blacklist…

ArcGIS 地理信息系统 任意文件读取漏洞复现

0x01 产品简介 ArcGIS是由美国Esri公司研发的地理信息系统(GIS)软件,它整合了数据库、软件工程、人工智能、网络技术、云计算等主流的IT技术,旨在为用户提供一套完整的、开放的企业级GIS解决方案,它包含了一套带有用户界面组件的Windows桌面应用。可以实现从简单到复杂的…

Linux 系统结构

Linux系统一般有4个主要部分&#xff1a;内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构&#xff0c;它们使得用户可以运行程序、管理文件并使用系统。 1. linux内核 内核是操作系统的核心&#xff0c;具有很多最基本功能&#xff0c;它…

SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder”

SLF4J常见问题 1、SLF4J简介2、SLF4J实现原理3、SLF4J常见问题 1、SLF4J简介 SLF4J&#xff08;Simple Logging Facade for Java&#xff09;是一个为Java程序提供日志输出的统一接口&#xff0c;并不具备具体的日志实现方案&#xff0c;类似JDBC&#xff0c;SLF4J只做两件事&a…