简介
五子棋是游戏厅中的第一款游戏,采用标准的 15x15 棋盘,支持双人轮流对弈。核心功能包括落子判定、五连检测、悔棋操作和落子历史记录。
棋盘渲染
CSS Grid 棋盘
使用 CSS Grid 布局渲染 15x15 棋盘,每个单元格为正方形:
1.gomoku-board {
2 display: grid;
3 grid-template-columns: repeat(15, var(--cell-size, 36px));
4 grid-template-rows: repeat(15, var(--cell-size, 36px));
5 background: #deb887;
6 border: 2px solid #8b4513;
7}
棋盘线条通过伪元素绘制——每个单元格的 ::before 和 ::after 分别绘制横向和纵向线:
1.gomoku-cell::before {
2 content: '';
3 position: absolute;
4 top: 50%;
5 left: 0; right: 0;
6 height: 1px;
7 background: #8b7355;
8}
9.gomoku-cell::after {
10 content: '';
11 position: absolute;
12 left: 50%;
13 top: 0; bottom: 0;
14 width: 1px;
15 background: #8b7355;
16}
天元和星位
棋盘中间的"天元"和四个角的"星位"使用额外的圆点标记:
1var starPoints = [
2 [3, 3], [3, 7], [3, 11],
3 [7, 3], [7, 7], [7, 11],
4 [11, 3], [11, 7], [11, 11]
5];
游戏逻辑
落子与状态管理
使用二维数组 board[row][col] 存储棋盘状态,'black' 或 'white' 表示落子:
1var board = [];
2for (var i = 0; i < 15; i++) {
3 board[i] = [];
4 for (var j = 0; j < 15; j++) board[i][j] = null;
5}
落子时检查位置是否为空,然后切换玩家:
1function placePiece(row, col) {
2 if (board[row][col] || gameOver) return;
3 board[row][col] = currentPlayer;
4 renderPiece(row, col);
5 if (checkWin(row, col)) {
6 gameOver = true;
7 showResult(currentPlayer + ' 获胜!');
8 return;
9 }
10 currentPlayer = currentPlayer === 'black' ? 'white' : 'black';
11 addHistory(row, col);
12}
五连检测
从落子位置向四个方向(水平、垂直、两条对角线)扫描,统计连续同色棋子数:
1function checkWin(row, col) {
2 var directions = [[1, 0], [0, 1], [1, 1], [1, -1]];
3 var player = board[row][col];
4 for (var d = 0; d < directions.length; d++) {
5 var count = 1;
6 // 正方向扫描
7 for (var i = 1; i < 5; i++) {
8 var r = row + directions[d][0] * i;
9 var c = col + directions[d][1] * i;
10 if (r >= 0 && r < 15 && c >= 0 && c < 15 && board[r][c] === player) count++;
11 else break;
12 }
13 // 反方向扫描
14 for (var i = 1; i < 5; i++) {
15 var r = row - directions[d][0] * i;
16 var c = col - directions[d][1] * i;
17 if (r >= 0 && r < 15 && c >= 0 && c < 15 && board[r][c] === player) count++;
18 else break;
19 }
20 if (count >= 5) return true;
21 }
22 return false;
23}
悔棋功能
使用 history 栈记录每一步的位置和玩家,悔棋时弹出栈顶并清除对应棋子:
1var history = [];
2
3function addHistory(row, col) {
4 history.push({row: row, col: col, player: board[row][col]});
5}
6
7function undo() {
8 if (history.length === 0) return;
9 var last = history.pop();
10 board[last.row][last.col] = null;
11 currentPlayer = last.player;
12 removePiece(last.row, last.col);
13}
落子记录
在右侧面板显示落子序列,每步包含序号、坐标和玩家颜色:
1function renderHistory() {
2 var list = document.getElementById('gomoku-history');
3 list.innerHTML = '';
4 history.forEach(function(move, i) {
5 var item = document.createElement('div');
6 item.className = 'gomoku-history-item';
7 item.innerHTML = '<span class="move-num">' + (i + 1) + '</span>' +
8 '<span class="move-piece ' + move.player + '"></span>' +
9 '<span class="move-pos">(' + move.row + ', ' + move.col + ')</span>';
10 list.appendChild(item);
11 });
12}
交互设计
- 点击落子:棋盘单元格点击事件,计算行列坐标后调用
placePiece - 悔棋按钮:清空最后一手,恢复玩家回合
- 重新开始:重置棋盘、历史和玩家状态
- 状态提示:顶部显示当前玩家和回合信息
样式细节
- 黑子:纯黑径向渐变,模拟立体效果
- 白子:纯白径向渐变,带浅灰边框
- 最后落子位置:添加红色圆点标记,方便定位
1.gomoku-piece.black {
2 background: radial-gradient(circle at 35% 35%, #555, #000);
3 box-shadow: 2px 2px 4px rgba(0,0,0,.3);
4}
5.gomoku-piece.white {
6 background: radial-gradient(circle at 35% 35%, #fff, #ddd);
7 box-shadow: 2px 2px 4px rgba(0,0,0,.2);
8 border: 1px solid #ccc;
9}
总结
五子棋实现的核心在于 CSS Grid 棋盘渲染、方向扫描五连检测算法和栈式悔棋机制。纯 DOM 实现避免了 Canvas 的事件坐标计算,直接利用 DOM 事件系统完成交互。
留言评论
期待你的想法评论加载中