五子棋游戏

embedded/2025/4/1 3:09:38/

五子棋 - deveco

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>五子棋 - deveco</title><style>body {font-family: Arial, sans-serif;display: flex;flex-direction: column;align-items: center;background-color: #f5f5f5;}h1 {color: #333;}#board {display: flex;flex-direction: column;background-color: #dcb35c;padding: 10px;border-radius: 5px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);margin: 20px 0;}.row {display: flex;}.cell {width: 30px;height: 30px;border: 1px solid #000;display: flex;justify-content: center;align-items: center;position: relative;cursor: pointer;}.piece {width: 24px;height: 24px;border-radius: 50%;}.black {background-color: #000;box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);}.white {background-color: #fff;box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);}#status {font-size: 18px;font-weight: bold;margin: 10px 0;}button {padding: 10px 20px;background-color: #4CAF50;color: white;border: none;border-radius: 5px;cursor: pointer;font-size: 16px;margin: 0 5px;}#controls {display: flex;margin-bottom: 15px;}.difficulty {margin-top: 15px;}select {padding: 5px;margin-left: 10px;}</style>
</head>
<body><h1>五子棋</h1><div id="status">当前玩家:黑棋</div><div id="controls"><button id="restart">重新开始</button><button id="toggle-ai">切换AI模式</button></div><div class="difficulty">难度: <select id="ai-level"><option value="easy">简单</option><option value="medium" selected>中等</option><option value="hard">困难</option></select></div><div id="board"></div><script>// 游戏状态const gameState = {board: [],currentPlayer: 1, // 1=黑棋, 2=白棋gameOver: false,size: 15,aiEnabled: true,aiPlayer: 2, // AI默认使用白棋aiLevel: 'medium'};// 初始化棋盘function initGame() {gameState.board = Array(gameState.size).fill().map(() => Array(gameState.size).fill(0));gameState.currentPlayer = 1;gameState.gameOver = false;renderBoard();// 更新AI状态按钮document.getElementById('toggle-ai').textContent = gameState.aiEnabled ? "关闭AI模式" : "开启AI模式";}// 渲染棋盘function renderBoard() {const board = document.getElementById('board');board.innerHTML = '';for (let i = 0; i < gameState.size; i++) {const row = document.createElement('div');row.className = 'row';for (let j = 0; j < gameState.size; j++) {const cell = document.createElement('div');cell.className = 'cell';if (gameState.board[i][j] === 1) {const piece = document.createElement('div');piece.className = 'piece black';cell.appendChild(piece);} else if (gameState.board[i][j] === 2) {const piece = document.createElement('div');piece.className = 'piece white';cell.appendChild(piece);}cell.addEventListener('click', () => makeMove(i, j));row.appendChild(cell);}board.appendChild(row);}// 更新状态const status = document.getElementById('status');if (gameState.gameOver) {const winner = gameState.currentPlayer === 1 ? '黑棋' : '白棋';const isAI = gameState.aiEnabled && gameState.currentPlayer === gameState.aiPlayer;status.textContent = `游戏结束,${winner}${isAI ? '(AI)' : ''}胜利!`;} else {const currentPlayerText = gameState.currentPlayer === 1 ? '黑棋' : '白棋';const isAI = gameState.aiEnabled && gameState.currentPlayer === gameState.aiPlayer;status.textContent = `当前玩家:${currentPlayerText}${isAI ? '(AI思考中...)' : ''}`;}}// 落子function makeMove(row, col) {// 如果游戏结束或该位置已有棋子,则不允许落子if (gameState.gameOver || gameState.board[row][col] !== 0) {return;}// 如果当前是AI回合且AI启用,则忽略玩家点击if (gameState.aiEnabled && gameState.currentPlayer === gameState.aiPlayer) {return;}// 玩家落子gameState.board[row][col] = gameState.currentPlayer;// 检查是否获胜if (checkWin(row, col)) {gameState.gameOver = true;renderBoard();return;}// 切换玩家gameState.currentPlayer = gameState.currentPlayer === 1 ? 2 : 1;renderBoard();// 如果AI启用且现在是AI回合,则AI落子if (gameState.aiEnabled && gameState.currentPlayer === gameState.aiPlayer && !gameState.gameOver) {setTimeout(makeAIMove, 500); // 延迟500ms,让玩家能看到自己的落子}}// AI落子function makeAIMove() {if (gameState.gameOver) return;const move = findBestMove();if (move) {gameState.board[move.row][move.col] = gameState.aiPlayer;if (checkWin(move.row, move.col)) {gameState.gameOver = true;renderBoard();return;}gameState.currentPlayer = gameState.currentPlayer === 1 ? 2 : 1;renderBoard();}}// AI寻找最佳落子位置function findBestMove() {const aiLevel = gameState.aiLevel;const emptyPositions = [];// 找出所有空位置for (let i = 0; i < gameState.size; i++) {for (let j = 0; j < gameState.size; j++) {if (gameState.board[i][j] === 0) {emptyPositions.push({row: i, col: j});}}}// 如果是第一步,随机选择靠近中心的位置if (emptyPositions.length === gameState.size * gameState.size) {const center = Math.floor(gameState.size / 2);const offset = Math.floor(Math.random() * 3) - 1; // -1, 0, 或 1return {row: center + offset,col: center + Math.floor(Math.random() * 3) - 1};}// 评估每个位置的分数const movesWithScores = emptyPositions.map(pos => {return {...pos,score: evaluatePosition(pos.row, pos.col, aiLevel)};});// 根据难度增加随机性if (aiLevel === 'easy') {// 简单模式有50%概率随机落子if (Math.random() < 0.5) {return emptyPositions[Math.floor(Math.random() * emptyPositions.length)];}} else if (aiLevel === 'medium') {// 中等模式有20%概率不选最佳位置if (Math.random() < 0.2) {movesWithScores.sort((a, b) => b.score - a.score);const topMoves = movesWithScores.slice(0, Math.min(5, movesWithScores.length));return topMoves[Math.floor(Math.random() * topMoves.length)];}}// 选择分数最高的位置movesWithScores.sort((a, b) => b.score - a.score);return movesWithScores[0];}// 评估位置分数function evaluatePosition(row, col, aiLevel) {const humanPlayer = gameState.aiPlayer === 1 ? 2 : 1;let score = 0;// 优先考虑靠近中心的位置const center = Math.floor(gameState.size / 2);const distanceFromCenter = Math.abs(row - center) + Math.abs(col - center);score -= distanceFromCenter;// 检查周围是否有棋子let hasNeighbor = false;for (let i = Math.max(0, row - 2); i <= Math.min(gameState.size - 1, row + 2); i++) {for (let j = Math.max(0, col - 2); j <= Math.min(gameState.size - 1, col + 2); j++) {if (gameState.board[i][j] !== 0) {hasNeighbor = true;break;}}if (hasNeighbor) break;}if (!hasNeighbor) {return score - 50; // 远离所有棋子的位置不太好}// 检查各个方向的得分const directions = [[0, 1],   // 水平[1, 0],   // 垂直[1, 1],   // 右下对角线[1, -1]   // 右上对角线];for (const [dr, dc] of directions) {// 检查AI自己的得分score += evaluateDirection(row, col, dr, dc, gameState.aiPlayer) * 2;// 检查阻止对手的得分const humanScore = evaluateDirection(row, col, dr, dc, humanPlayer);// 如果对手即将获胜,优先阻止if (humanScore >= 100) {score += humanScore * 1.5;} else {score += humanScore;}}// 根据难度调整if (aiLevel === 'hard') {// 困难模式增加攻击性,更注重自己的连子score *= 1.2;} else if (aiLevel === 'easy') {// 简单模式减弱AI能力score *= 0.7;}return score;}// 评估某个方向上的得分function evaluateDirection(row, col, dr, dc, player) {const opponent = player === 1 ? 2 : 1;let score = 0;// 模拟在该位置放置棋子const tempBoard = JSON.parse(JSON.stringify(gameState.board));tempBoard[row][col] = player;// 检查连续棋子let count = 1; // 包括当前位置let open = [true, true]; // 两端是否开放// 正向检查for (let i = 1; i < 5; i++) {const r = row + i * dr;const c = col + i * dc;if (r >= 0 && r < gameState.size && c >= 0 && c < gameState.size) {if (tempBoard[r][c] === player) {count++;} else if (tempBoard[r][c] === opponent) {open[0] = false;break;} else {break;}} else {open[0] = false;break;}}// 反向检查for (let i = 1; i < 5; i++) {const r = row - i * dr;const c = col - i * dc;if (r >= 0 && r < gameState.size && c >= 0 && c < gameState.size) {if (tempBoard[r][c] === player) {count++;} else if (tempBoard[r][c] === opponent) {open[1] = false;break;} else {break;}} else {open[1] = false;break;}}// 根据连续棋子数和开放端计算得分const openEnds = (open[0] ? 1 : 0) + (open[1] ? 1 : 0);if (count >= 5) return 10000; // 五连珠,必胜if (count === 4) {if (openEnds === 2) return 5000; // 活四if (openEnds === 1) return 1000; // 冲四}if (count === 3) {if (openEnds === 2) return 500; // 活三if (openEnds === 1) return 100; // 冲三}if (count === 2) {if (openEnds === 2) return 50; // 活二if (openEnds === 1) return 10; // 冲二}if (count === 1) {if (openEnds === 2) return 5; // 活一if (openEnds === 1) return 1; // 冲一}return 0;}// 检查是否获胜function checkWin(row, col) {const directions = [[0, 1],   // 水平[1, 0],   // 垂直[1, 1],   // 右下对角线[1, -1]   // 右上对角线];const player = gameState.board[row][col];for (const [dr, dc] of directions) {let count = 1;// 正向检查for (let i = 1; i < 5; i++) {const r = row + i * dr;const c = col + i * dc;if (r >= 0 && r < gameState.size && c >= 0 && c < gameState.size && gameState.board[r][c] === player) {count++;} else {break;}}// 反向检查for (let i = 1; i < 5; i++) {const r = row - i * dr;const c = col - i * dc;if (r >= 0 && r < gameState.size && c >= 0 && c < gameState.size && gameState.board[r][c] === player) {count++;} else {break;}}if (count >= 5) {return true;}}return false;}// 启动游戏document.addEventListener('DOMContentLoaded', () => {initGame();// 重新开始按钮document.getElementById('restart').addEventListener('click', initGame);// 切换AI模式按钮document.getElementById('toggle-ai').addEventListener('click', () => {gameState.aiEnabled = !gameState.aiEnabled;document.getElementById('toggle-ai').textContent = gameState.aiEnabled ? "关闭AI模式" : "开启AI模式";// 如果切换到AI模式且当前是AI回合,则AI立即落子if (gameState.aiEnabled && gameState.currentPlayer === gameState.aiPlayer && !gameState.gameOver) {setTimeout(makeAIMove, 500);}});// 难度选择document.getElementById('ai-level').addEventListener('change', (e) => {gameState.aiLevel = e.target.value;});});</script>
</body>
</html>


http://www.ppmy.cn/embedded/177634.html

相关文章

html5现代图片滑动展示组件实现详解

现代图片滑动展示组件实现详解 这里写目录标题 现代图片滑动展示组件实现详解项目介绍技术栈核心实现HTML结构CSS样式设计JavaScript功能实现 技术要点解析1. 无缝滑动的实现2. 响应式设计3. 触摸事件优化4. 性能优化 扩展优化建议总结 项目介绍 本文将详细介绍一个基于原生Ja…

5-管理员-维护权限

在“后台”-“人员管理”-“权限”下&#xff0c;通过不同的操作按钮&#xff0c;按照权限分组对权限进行设置。操作部分的按钮依次为 视野维护&#xff1a;设置该分组可以查看、访问的视图。权限维护&#xff1a;设置分组成员可以操作的具体动作等所有在禅道中涉及的权限。成…

Quarkus云原生服务开发详解

以下是基于最新信息的Quarkus搭建步骤: 1. 搭建开发环境 安装Java开发工具包(JDK):Quarkus基于Java,因此需要安装JDK。推荐安装JDK 11或更高版本。安装Maven:Quarkus项目通常使用Maven作为构建工具。安装GraalVM(可选):如果需要将应用编译为原生可执行文件,需要安装…

图像对比分析并生成报告

pip install pyautogui """ 图像对比分析工具 功能&#xff1a;实现像素级差异、结构相似性(SSIM)、直方图相似度和特征匹配率四种对比方法 作者&#xff1a;智能助手 版本&#xff1a;1.2 日期&#xff1a;2025-02-27""" import os import cv2 …

在Vue 3 + TypeScript + Vite 项目中安装和使用 SCSS

在Vue 3 TypeScript Vite 项目中安装和使用 SCSS 1、安装 SCSS 的相关依赖 npm install sass --save-dev2、配置 Vite 对于 Vue 3&#xff0c;Vite 已经内置了对 SCSS 的支持&#xff0c;通常不需要额外的配置。但是&#xff0c;如果需要自定义配置&#xff0c;可以在路径…

大语言模型参数指标详解

&#xff08;这张图是AI生成的&#xff0c;看着还行&#xff5e;&#xff09; 1. TTFT &#xff08;首Tokens时延&#xff0c;Time to First Token&#xff09; TTFT 指的是用户发起请求到模型返回第一个 Token 所需的时间&#xff0c;直接影响用户对响应速度的感知&#xf…

CSS3学习教程,从入门到精通,CSS3 媒体查询实现响应式布局语法指南(21)

CSS3 媒体查询实现响应式布局语法指南 一、媒体查询核心语法 1. 基础语法结构 media 媒体类型 and (媒体特性) {/* 匹配条件时应用的CSS规则 */ }2. 媒体类型&#xff08;可省略&#xff09; 类型值说明all所有设备&#xff08;默认值&#xff09;screen屏幕设备print打印机…

etcd性能测试

etcd性能测试 本文参考官方文档完成etcd性能测试&#xff0c;提供etcd官方推荐的性能测试方案。 1. 理解性能&#xff1a;延迟与吞吐量 etcd 提供稳定、持续的高性能。有两个因素决定性能&#xff1a;延迟和吞吐量。延迟是完成一项操作所花费的时间。吞吐量是在某个时间段内…