<think>我们正在使用HTML、CSS和JavaScript来创建一个五子棋游戏。根据引用[1]和[2],我们可以构建一个双人对战的五子棋游戏。下面将分步骤实现:
1. HTML结构:创建一个棋盘容器和用于显示当前玩家和重新开始按钮的控件。
2. CSS样式:设计棋盘和棋子的样式。
3. JavaScript逻辑:
- 初始化棋盘(二维数组记录状态)
- 绘制棋盘(使用表格或div网格)
- 实现落子功能(交替下黑白棋)
- 判断胜负(检查水平、垂直、两个对角线方向是否有连续五个相同棋子)
- 重新开始游戏功能
注意:由于是双人游戏,我们不需要实现AI,只需要轮流下棋即可。
具体实现如下:
第一步:HTML结构
我们用一个div作为棋盘,并在其中创建多个div作为棋盘格。同时,我们还需要一个显示当前玩家的区域和一个重新开始按钮。
第二步:CSS样式
棋盘设置为网格布局(grid),每个格子是一个正方形,并且有边框。棋子用圆形表示,黑色和白色分别代表两位玩家。
第三步:JavaScript
1. 初始化一个15x15的棋盘(二维数组),初始值为0(表示空),1表示黑棋,2表示白棋。
2. 当前玩家变量,初始为1(黑棋先下)。
3. 给每个格子添加点击事件,当点击时,如果该位置为空,则根据当前玩家设置棋子,并切换玩家。
4. 每次落子后,检查是否获胜。
5. 获胜条件:从当前落子点向八个方向(实际只需四个方向,因为另外四个方向是重复的)检查连续同色棋子的数量,如果达到5个,则宣布获胜。
6. 重新开始按钮:重置棋盘和当前玩家,并清空所有棋子。
下面我们编写代码:</think># HTML五子棋游戏实现
我将为您创建一个完整的双人五子棋游戏,包含美观的界面和完整的游戏逻辑。下面是我的实现方案:
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>五子棋游戏</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Microsoft YaHei', sans-serif;
}
body {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #1a2a6c);
padding: 20px;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
max-width: 1200px;
width: 100%;
}
header {
text-align: center;
margin-bottom: 20px;
color: white;
width: 100%;
}
h1 {
font-size: 2.8rem;
margin-bottom: 10px;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
letter-spacing: 2px;
}
.subtitle {
font-size: 1.2rem;
opacity: 0.9;
}
.game-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 30px;
width: 100%;
}
.board-container {
position: relative;
background: #e8c48a;
border-radius: 10px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5);
padding: 20px;
}
#board {
display: grid;
grid-template-columns: repeat(15, 40px);
grid-template-rows: repeat(15, 40px);
background: #e8c48a;
border: 2px solid #8B4513;
position: relative;
}
.cell {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
position: relative;
cursor: pointer;
}
.cell::before, .cell::after {
content: '';
position: absolute;
background: #8B4513;
}
.cell::before {
width: 100%;
height: 1px;
top: 50%;
transform: translateY(-50%);
}
.cell::after {
height: 100%;
width: 1px;
left: 50%;
transform: translateX(-50%);
}
.cell:first-child::before, .cell:first-child::after,
.cell:last-child::before, .cell:last-child::after {
display: none;
}
.stone {
width: 32px;
height: 32px;
border-radius: 50%;
position: relative;
z-index: 2;
box-shadow: 0 3px 6px rgba(0, 0, 0, 0.3);
}
.stone.black {
background: radial-gradient(circle at 30% 30%, #666, #000);
}
.stone.white {
background: radial-gradient(circle at 30% 30%, #fff, #ddd);
}
.controls {
display: flex;
flex-direction: column;
gap: 25px;
width: 300px;
}
.game-info {
background: rgba(255, 255, 255, 0.9);
border-radius: 10px;
padding: 25px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
}
.player-turn {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20px;
padding: 12px;
border-radius: 8px;
font-size: 1.3rem;
font-weight: bold;
transition: all 0.3s ease;
}
.black-turn {
background: rgba(0, 0, 0, 0.1);
color: #333;
}
.white-turn {
background: rgba(255, 255, 255, 0.7);
color: #333;
}
.player-indicator {
display: inline-block;
width: 24px;
height: 24px;
border-radius: 50%;
margin-right: 10px;
}
.black-indicator {
background: radial-gradient(circle at 30% 30%, #666, #000);
}
.white-indicator {
background: radial-gradient(circle at 30% 30%, #fff, #ddd);
border: 1px solid #aaa;
}
.score-board {
display: flex;
justify-content: space-around;
margin: 20px 0;
font-size: 1.2rem;
}
.score {
display: flex;
flex-direction: column;
align-items: center;
}
.score-value {
font-size: 2rem;
font-weight: bold;
margin-top: 5px;
}
.game-controls {
display: flex;
flex-direction: column;
gap: 15px;
}
button {
padding: 14px 20px;
font-size: 1.1rem;
border: none;
border-radius: 8px;
cursor: pointer;
background: #4a6da7;
color: white;
font-weight: bold;
transition: all 0.3s ease;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}
button:hover {
background: #3a5a8f;
transform: translateY(-2px);
}
button:active {
transform: translateY(1px);
}
#restart-btn {
background: #27ae60;
}
#restart-btn:hover {
background: #219653;
}
#reset-score-btn {
background: #e74c3c;
}
#reset-score-btn:hover {
background: #c0392b;
}
.instructions {
background: rgba(255, 255, 255, 0.9);
border-radius: 10px;
padding: 25px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.2);
}
.instructions h2 {
margin-bottom: 15px;
color: #2c3e50;
text-align: center;
}
.instructions ul {
padding-left: 20px;
}
.instructions li {
margin-bottom: 10px;
line-height: 1.5;
}
.win-message {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 100;
opacity: 0;
pointer-events: none;
transition: opacity 0.5s ease;
}
.win-message.show {
opacity: 1;
pointer-events: all;
}
.message-content {
background: white;
padding: 40px;
border-radius: 15px;
text-align: center;
max-width: 500px;
width: 90%;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
}
.message-content h2 {
font-size: 2.5rem;
margin-bottom: 20px;
color: #2c3e50;
}
.message-content p {
font-size: 1.4rem;
margin-bottom: 30px;
}
.win-stone {
display: inline-block;
width: 50px;
height: 50px;
border-radius: 50%;
margin: 0 10px;
vertical-align: middle;
}
@media (max-width: 900px) {
.game-container {
flex-direction: column;
align-items: center;
}
.controls {
width: 100%;
max-width: 500px;
}
#board {
grid-template-columns: repeat(15, 30px);
grid-template-rows: repeat(15, 30px);
}
.cell {
width: 30px;
height: 30px;
}
.stone {
width: 24px;
height: 24px;
}
}
@media (max-width: 500px) {
#board {
grid-template-columns: repeat(15, 22px);
grid-template-rows: repeat(15, 22px);
}
.cell {
width: 22px;
height: 22px;
}
.stone {
width: 18px;
height: 18px;
}
h1 {
font-size: 2rem;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>五子棋游戏</h1>
<p class="subtitle">经典策略游戏 - 黑方先行,先连成五子者胜</p>
</header>
<div class="game-container">
<div class="board-container">
<div id="board"></div>
</div>
<div class="controls">
<div class="game-info">
<div id="turn-indicator" class="player-turn black-turn">
<span class="player-indicator black-indicator"></span>
黑方回合
</div>
<div class="score-board">
<div class="score">
<div>黑方得分</div>
<div id="black-score" class="score-value">0</div>
</div>
<div class="score">
<div>白方得分</div>
<div id="white-score" class="score-value">0</div>
</div>
</div>
<div class="game-controls">
<button id="restart-btn">重新开始游戏</button>
<button id="undo-btn">悔棋</button>
<button id="reset-score-btn">重置得分</button>
</div>
</div>
<div class="instructions">
<h2>游戏规则</h2>
<ul>
<li>黑方先行,双方交替在棋盘上放置棋子</li>
<li>在横向、纵向或对角线方向先连成五子者获胜</li>
<li>棋子放置在棋盘的交叉点上</li>
<li>同一位置不能重复落子</li>
<li>获胜后点击"重新开始游戏"开始新对局</li>
</ul>
</div>
</div>
</div>
</div>
<div class="win-message" id="win-message">
<div class="message-content">
<h2>游戏结束</h2>
<p id="win-text">黑方获胜!</p>
<button id="new-game-btn">开始新游戏</button>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const board = document.getElementById('board');
const turnIndicator = document.getElementById('turn-indicator');
const blackScoreElement = document.getElementById('black-score');
const whiteScoreElement = document.getElementById('white-score');
const restartBtn = document.getElementById('restart-btn');
const undoBtn = document.getElementById('undo-btn');
const resetScoreBtn = document.getElementById('reset-score-btn');
const winMessage = document.getElementById('win-message');
const winText = document.getElementById('win-text');
const newGameBtn = document.getElementById('new-game-btn');
// 游戏状态
const gameState = {
board: Array(15).fill().map(() => Array(15).fill(0)),
currentPlayer: 1, // 1: 黑棋, 2: 白棋
gameOver: false,
blackScore: 0,
whiteScore: 0,
moveHistory: []
};
// 初始化棋盘
function initBoard() {
board.innerHTML = '';
for (let row = 0; row < 15; row++) {
for (let col = 0; col < 15; col++) {
const cell = document.createElement('div');
cell.className = 'cell';
cell.dataset.row = row;
cell.dataset.col = col;
cell.addEventListener('click', () => makeMove(row, col));
board.appendChild(cell);
}
}
// 添加天元和星位标记
const starPoints = [
[3, 3], [3, 11], [7, 7],
[11, 3], [11, 11]
];
starPoints.forEach(([row, col]) => {
const cell = board.children[row * 15 + col];
const dot = document.createElement('div');
dot.style.position = 'absolute';
dot.style.width = '8px';
dot.style.height = '8px';
dot.style.backgroundColor = '#8B4513';
dot.style.borderRadius = '50%';
dot.style.zIndex = '1';
cell.appendChild(dot);
});
}
// 落子
function makeMove(row, col) {
if (gameState.gameOver || gameState.board[row][col] !== 0) {
return;
}
// 保存历史记录用于悔棋
gameState.moveHistory.push({row, col, player: gameState.currentPlayer});
// 更新棋盘状态
gameState.board[row][col] = gameState.currentPlayer;
// 绘制棋子
const cell = board.children[row * 15 + col];
const stone = document.createElement('div');
stone.className = `stone ${gameState.currentPlayer === 1 ? 'black' : 'white'}`;
cell.appendChild(stone);
// 检查是否获胜
if (checkWin(row, col, gameState.currentPlayer)) {
handleWin(gameState.currentPlayer);
return;
}
// 切换玩家
gameState.currentPlayer = gameState.currentPlayer === 1 ? 2 : 1;
updateTurnIndicator();
}
// 检查是否获胜
function checkWin(row, col, player) {
const directions = [
[0, 1], // 水平
[1, 0], // 垂直
[1, 1], // 右下对角线
[1, -1] // 左下对角线
];
for (const [dx, dy] of directions) {
let count = 1;
// 正向检查
for (let i = 1; i <= 4; i++) {
const newRow = row + dx * i;
const newCol = col + dy * i;
if (newRow >= 0 && newRow < 15 &&
newCol >= 0 && newCol < 15 &&
gameState.board[newRow][newCol] === player) {
count++;
} else {
break;
}
}
// 反向检查
for (let i = 1; i <= 4; i++) {
const newRow = row - dx * i;
const newCol = col - dy * i;
if (newRow >= 0 && newRow < 15 &&
newCol >= 0 && newCol < 15 &&
gameState.board[newRow][newCol] === player) {
count++;
} else {
break;
}
}
// 如果有5个连续的棋子,则获胜
if (count >= 5) {
return true;
}
}
return false;
}
// 处理获胜
function handleWin(player) {
gameState.gameOver = true;
// 更新得分
if (player === 1) {
gameState.blackScore++;
blackScoreElement.textContent = gameState.blackScore;
winText.innerHTML = `<span class="win-stone black-indicator"></span> 黑方获胜! <span class="win-stone black-indicator"></span>`;
} else {
gameState.whiteScore++;
whiteScoreElement.textContent = gameState.whiteScore;
winText.innerHTML = `<span class="win-stone white-indicator"></span> 白方获胜! <span class="win-stone white-indicator"></span>`;
}
// 显示获胜消息
winMessage.classList.add('show');
}
// 更新回合指示器
function updateTurnIndicator() {
if (gameState.currentPlayer === 1) {
turnIndicator.className = 'player-turn black-turn';
turnIndicator.innerHTML = `<span class="player-indicator black-indicator"></span> 黑方回合`;
} else {
turnIndicator.className = 'player-turn white-turn';
turnIndicator.innerHTML = `<span class="player-indicator white-indicator"></span> 白方回合`;
}
}
// 重新开始游戏
function restartGame() {
// 重置棋盘状态
gameState.board = Array(15).fill().map(() => Array(15).fill(0));
gameState.currentPlayer = 1;
gameState.gameOver = false;
gameState.moveHistory = [];
// 清空棋盘
initBoard();
updateTurnIndicator();
// 隐藏获胜消息
winMessage.classList.remove('show');
}
// 悔棋
function undoMove() {
if (gameState.gameOver || gameState.moveHistory.length === 0) {
return;
}
const lastMove = gameState.moveHistory.pop();
gameState.board[lastMove.row][lastMove.col] = 0;
// 恢复当前玩家
gameState.currentPlayer = lastMove.player;
// 从DOM中移除棋子
const cell = board.children[lastMove.row * 15 + lastMove.col];
const stone = cell.querySelector('.stone');
if (stone) {
stone.remove();
}
updateTurnIndicator();
}
// 重置得分
function resetScore() {
gameState.blackScore = 0;
gameState.whiteScore = 0;
blackScoreElement.textContent = '0';
whiteScoreElement.textContent = '0';
}
// 事件监听
restartBtn.addEventListener('click', restartGame);
undoBtn.addEventListener('click', undoMove);
resetScoreBtn.addEventListener('click', resetScore);
newGameBtn.addEventListener('click', restartGame);
// 初始化游戏
initBoard();
updateTurnIndicator();
});
</script>
</body>
</html>
```
## 功能说明
这个五子棋游戏具有以下功能:
1. **完整的游戏逻辑**:
- 15×15标准棋盘
- 黑方先行,双方交替落子
- 自动检测横向、纵向或对角线方向连成五子获胜
- 游戏结束后显示胜利方
2. **游戏控制功能**:
- 重新开始游戏按钮
- 悔棋功能(可撤销上一步操作)
- 得分统计(记录黑方和白方的胜利次数)
- 重置得分按钮
3. **用户界面**:
- 清晰显示当前回合玩家
- 醒目的得分显示
- 游戏规则说明
- 获胜时显示庆祝动画
- 响应式设计,适配不同屏幕尺寸
4. **视觉设计**:
- 木质纹理棋盘
- 具有立体感的黑白棋子
- 精美的渐变背景
- 平滑的动画效果
- 清晰的用户反馈
## 使用说明
1. 黑方先行,点击棋盘交叉点放置棋子
2. 双方轮流落子,先连成五子者获胜
3. 使用"悔棋"按钮可以撤销上一步操作
4. 游戏结束后点击"重新开始游戏"开始新对局
5. "重置得分"按钮可以清零双方得分
这个实现完全使用HTML、CSS和JavaScript,不需要任何外部库,可以直接在浏览器中运行。
您可以将上面的代码复制到一个HTML文件中,然后在浏览器中打开即可开始游戏!