代码:
<!DOCTYPE html>
<html lang="zh">
<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;
}
body {
font-family: 'Microsoft YaHei', sans-serif;
background-color: #f0f0f0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 20px;
}
.game-container {
width: 100%;
max-width: 600px;
text-align: center;
}
h1 {
color: #333;
font-size: 24px;
margin-bottom: 20px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
}
.game-board {
display: grid;
grid-template-columns: repeat(7, 1fr);
grid-template-rows: repeat(9, 1fr);
gap: 1px;
background-color: #333;
border: 4px solid #222;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
margin: 0 auto;
width: 100%;
max-width: 500px;
aspect-ratio: 7/9;
}
.cell {
background-color: #e9e0c9;
display: flex;
align-items: center;
justify-content: center;
position: relative;
cursor: pointer;
transition: background-color 0.2s;
}
.cell:hover {
background-color: #d9cfb9;
}
.cell.selected {
background-color: #f8e0a0;
}
.cell.highlighted {
background-color: #a0d8f8;
}
.cell.den {
position: relative;
}
.cell.den::after {
content: '';
position: absolute;
width: 80%;
height: 80%;
background-color: rgba(150, 150, 150, 0.3);
border-radius: 10%;
z-index: 1;
}
.cell.trap {
position: relative;
}
.cell.trap::after {
content: '';
position: absolute;
width: 70%;
height: 70%;
border: 2px dashed #555;
border-radius: 50%;
z-index: 1;
}
.cell.river {
background-color: #a0d8f8;
}
.animal {
width: 80%;
height: 80%;
border-radius: 10%;
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
color: white;
font-size: 18px;
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
user-select: none;
z-index: 2;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
image-rendering: pixelated;
}
.animal.red {
background-color: #e74c3c;
}
.animal.blue {
background-color: #3498db;
}
.rat::before {
content: '鼠';
}
.cat::before {
content: '猫';
}
.dog::before {
content: '狗';
}
.wolf::before {
content: '狼';
}
.leopard::before {
content: '豹';
}
.tiger::before {
content: '虎';
}
.lion::before {
content: '狮';
}
.elephant::before {
content: '象';
}
.status {
margin-top: 20px;
padding: 10px;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.turn-indicator {
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
margin: 10px 0;
}
.team-indicator {
width: 20px;
height: 20px;
border-radius: 50%;
}
.team-red {
background-color: #e74c3c;
}
.team-blue {
background-color: #3498db;
}
.restart-btn {
margin-top: 15px;
padding: 8px 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.3s;
}
.restart-btn:hover {
background-color: #45a049;
}
.game-rules {
margin-top: 20px;
text-align: left;
background-color: #fff;
padding: 15px;
border-radius: 4px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
font-size: 14px;
}
.game-rules h3 {
margin-bottom: 10px;
color: #333;
}
.game-rules p {
margin-bottom: 8px;
line-height: 1.5;
}
.capture-log {
margin-top: 10px;
padding: 5px;
max-height: 80px;
overflow-y: auto;
background-color: #f9f9f9;
border-radius: 4px;
border: 1px solid #ddd;
font-size: 14px;
}
.message {
margin: 3px 0;
}
@media (max-width: 500px) {
.game-board {
width: 95%;
}
.animal {
font-size: 14px;
}
}
</style>
</head>
<body>
<div class="game-container">
<h1>像素斗兽棋</h1>
<div class="turn-indicator">
当前回合: <div class="team-indicator team-red" id="current-team"></div>
<span id="current-team-text">红方</span>
</div>
<div class="game-board" id="game-board"></div>
<div class="status" id="status">选择一个棋子开始游戏</div>
<div class="capture-log" id="capture-log"></div>
<button class="restart-btn" id="restart-btn">重新开始</button>
<div class="game-rules">
<h3>游戏规则</h3>
<p>1. 红蓝双方轮流移动,点击己方棋子后点击目标位置进行移动</p>
<p>2. 棋子等级: 象(8) > 狮(7) > 虎(6) > 豹(5) > 狼(4) > 狗(3) > 猫(2) > 鼠(1)</p>
<p>3. 高等级棋子可以吃低等级棋子,同等级可以互相吃</p>
<p>4. 鼠可以进入河流,且只有鼠能吃象</p>
<p>5. 狮和虎可以跳过河流(横跳和竖跳)</p>
<p>6. 走入对方兽穴或吃掉所有对方棋子获胜</p>
<p>7. 己方陷阱中的敌方棋子没有战斗力,可以被任何棋子吃掉</p>
</div>
</div>
<script>
// 游戏主逻辑
document.addEventListener('DOMContentLoaded', function() {
// 游戏元素
const gameBoard = document.getElementById('game-board');
const status = document.getElementById('status');
const captureLog = document.getElementById('capture-log');
const restartBtn = document.getElementById('restart-btn');
const currentTeamIndicator = document.getElementById('current-team');
const currentTeamText = document.getElementById('current-team-text');
// 游戏状态
let currentTeam = 'red'; // 红方先行
let selectedCell = null;
let validMoves = [];
let gameOver = false;
// 棋盘布局 (9行×7列)
// 0: 空, 1-8: 红方动物(鼠到象), -1到-8: 蓝方动物, 9: 河流, 10: 陷阱, 11: 兽穴
const initialBoard = [
[0, 0, 11, 0, 11, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 9, 9, 0, 9, 9, 0],
[0, 9, 9, 0, 9, 9, 0],
[0, 9, 9, 0, 9, 9, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 0, -11, 0, -11, 0, 0]
];
// 添加陷阱
initialBoard[0][2] = initialBoard[0][4] = 0; // 清除兽穴位置
initialBoard[0][3] = 11; // 蓝方兽穴
initialBoard[8][3] = -11; // 红方兽穴
initialBoard[1][3] = 10; // 蓝方陷阱
initialBoard[0][2] = initialBoard[0][4] = 10; // 蓝方陷阱
initialBoard[7][3] = -10; // 红方陷阱
initialBoard[8][2] = initialBoard[8][4] = -10; // 红方陷阱
// 初始化棋子位置
const initialPieces = [
{ row: 0, col: 0, type: -7 }, // 蓝狮
{ row: 0, col: 6, type: -6 }, // 蓝虎
{ row: 1, col: 1, type: -8 }, // 蓝象
{ row: 1, col: 5, type: -5 }, // 蓝豹
{ row: 2, col: 0, type: -4 }, // 蓝狼
{ row: 2, col: 2, type: -2 }, // 蓝猫
{ row: 2, col: 4, type: -3 }, // 蓝狗
{ row: 2, col: 6, type: -1 }, // 蓝鼠
{ row: 6, col: 0, type: 1 }, // 红鼠
{ row: 6, col: 2, type: 3 }, // 红狗
{ row: 6, col: 4, type: 2 }, // 红猫
{ row: 6, col: 6, type: 4 }, // 红狼
{ row: 7, col: 1, type: 5 }, // 红豹
{ row: 7, col: 5, type: 8 }, // 红象
{ row: 8, col: 0, type: 6 }, // 红虎
{ row: 8, col: 6, type: 7 } // 红狮
];
// 棋盘和棋子数据
let board = [];
// 初始化棋盘
function initializeBoard() {
gameBoard.innerHTML = '';
board = JSON.parse(JSON.stringify(initialBoard));
// 创建棋盘格子
for (let row = 0; row < 9; row++) {
for (let col = 0; col < 7; col++) {
const cell = document.createElement('div');
cell.className = 'cell';
cell.dataset.row = row;
cell.dataset.col = col;
// 设置特殊格子样式
if (board[row][col] === 9) {
cell.classList.add('river');
} else if (board[row][col] === 10 || board[row][col] === -10) {
cell.classList.add('trap');
} else if (board[row][col] === 11 || board[row][col] === -11) {
cell.classList.add('den');
}
cell.addEventListener('click', handleCellClick);
gameBoard.appendChild(cell);
}
}
// 放置棋子
initialPieces.forEach(piece => {
board[piece.row][piece.col] = piece.type;
placePiece(piece.row, piece.col, piece.type);
});
// 重置游戏状态
currentTeam = 'red';
updateCurrentTeamIndicator();
selectedCell = null;
validMoves = [];
gameOver = false;
status.textContent = '选择一个棋子开始游戏';
captureLog.innerHTML = '';
}
// 更新当前回合指示器
function updateCurrentTeamIndicator() {
currentTeamIndicator.className = `team-indicator team-${currentTeam}`;
currentTeamText.textContent = currentTeam === 'red' ? '红方' : '蓝方';
}
// 放置棋子
function placePiece(row, col, type) {
const cell = document.querySelector(`.cell[data-row="${row}"][data-col="${col}"]`);
// 移除已有棋子
const existingPiece = cell.querySelector('.animal');
if (existingPiece) {
cell.removeChild(existingPiece);
}
// 如果type不为0,则添加新棋子
if (type !== 0 && type !== 9 && type !== 10 && type !== -10 && type !== 11 && type !== -11) {
const animal = document.createElement('div');
const team = type > 0 ? 'red' : 'blue';
const animalType = getAnimalType(Math.abs(type));
animal.className = `animal ${animalType} ${team}`;
cell.appendChild(animal);
}
}
// 根据数字获取动物类型
function getAnimalType(typeNum) {
const types = {
1: 'rat',
2: 'cat',
3: 'dog',
4: 'wolf',
5: 'leopard',
6: 'tiger',
7: 'lion',
8: 'elephant'
};
return types[typeNum] || '';
}
// 根据数字获取动物名称
function getAnimalName(typeNum) {
const names = {
1: '鼠',
2: '猫',
3: '狗',
4: '狼',
5: '豹',
6: '虎',
7: '狮',
8: '象'
};
return names[Math.abs(typeNum)] || '';
}
// 处理格子点击事件
function handleCellClick(e) {
if (gameOver) return;
const cell = e.currentTarget;
const row = parseInt(cell.dataset.row);
const col = parseInt(cell.dataset.col);
// 已经选中一个格子,尝试移动
if (selectedCell) {
const selectedRow = parseInt(selectedCell.dataset.row);
const selectedCol = parseInt(selectedCell.dataset.col);
// 检查是否是有效移动
const validMove = validMoves.some(move => move.row === row && move.col === col);
if (validMove) {
// 执行移动
movePiece(selectedRow, selectedCol, row, col);
// 清除选中和高亮
clearSelection();
} else if (board[row][col] !== 0 &&
((currentTeam === 'red' && board[row][col] > 0) ||
(currentTeam === 'blue' && board[row][col] < 0))) {
// 选择了同队的另一个棋子
clearSelection();
selectCell(cell, row, col);
} else {
// 点击了无效的位置,取消选择
clearSelection();
}
} else {
// 没有选中格子,检查是否选择了己方棋子
const pieceType = board[row][col];
if ((currentTeam === 'red' && pieceType > 0) ||
(currentTeam === 'blue' && pieceType < 0)) {
selectCell(cell, row, col);
}
}
}
// 选择棋子
function selectCell(cell, row, col) {
selectedCell = cell;
cell.classList.add('selected');
// 计算有效移动
validMoves = getValidMoves(row, col);
// 高亮显示有效移动
validMoves.forEach(move => {
const targetCell = document.querySelector(`.cell[data-row="${move.row}"][data-col="${move.col}"]`);
targetCell.classList.add('highlighted');
});
const animalName = getAnimalName(board[row][col]);
status.textContent = `选择了${currentTeam === 'red' ? '红' : '蓝'}方${animalName},请选择移动位置`;
}
// 清除选中和高亮
function clearSelection() {
if (selectedCell) {
selectedCell.classList.remove('selected');
selectedCell = null;
}
// 移除所有高亮
document.querySelectorAll('.cell.highlighted').forEach(cell => {
cell.classList.remove('highlighted');
});
validMoves = [];
status.textContent = `${currentTeam === 'red' ? '红' : '蓝'}方回合,请选择棋子`;
}
// 移动棋子
function movePiece(fromRow, fromCol, toRow, toCol) {
const pieceType = board[fromRow][fromCol];
const targetType = board[toRow][toCol];
// 记录捕获
if (targetType !== 0 && targetType !== 9 && targetType !== 10 &&
targetType !== -10 && targetType !== 11 && targetType !== -11) {
logCapture(pieceType, targetType);
}
// 更新棋盘数据
board[toRow][toCol] = pieceType;
board[fromRow][fromCol] = 0;
// 更新视觉表示
placePiece(fromRow, fromCol, 0);
placePiece(toRow, toCol, pieceType);
// 检查游戏结束
if (checkGameEnd(toRow, toCol)) {
return;
}
// 切换回合
currentTeam = currentTeam === 'red' ? 'blue' : 'red';
updateCurrentTeamIndicator();
status.textContent = `${currentTeam === 'red' ? '红' : '蓝'}方回合,请选择棋子`;
}
// 记录捕获
function logCapture(attackerType, defenderType) {
const attackerTeam = attackerType > 0 ? '红' : '蓝';
const defenderTeam = defenderType > 0 ? '红' : '蓝';
const attackerName = getAnimalName(attackerType);
const defenderName = getAnimalName(defenderType);
const message = document.createElement('div');
message.className = 'message';
message.textContent = `${attackerTeam}方${attackerName}吃掉了${defenderTeam}方${defenderName}`;
captureLog.appendChild(message);
captureLog.scrollTop = captureLog.scrollHeight;
}
// 检查游戏是否结束
function checkGameEnd(row, col) {
// 检查是否进入对方兽穴
if ((currentTeam === 'red' && board[row][col] > 0 && row === 0 && col === 3) ||
(currentTeam === 'blue' && board[row][col] < 0 && row === 8 && col === 3)) {
endGame(`${currentTeam === 'red' ? '红' : '蓝'}方进入兽穴获胜!`);
return true;
}
// 检查对方是否没有棋子了
let redPieces = 0;
let bluePieces = 0;
for (let r = 0; r < 9; r++) {
for (let c = 0; c < 7; c++) {
if (board[r][c] > 0 && board[r][c] < 9) redPieces++;
if (board[r][c] < 0 && board[r][c] > -9) bluePieces++;
}
}
if (redPieces === 0) {
endGame('蓝方吃掉所有红方棋子获胜!');
return true;
} else if (bluePieces === 0) {
endGame('红方吃掉所有蓝方棋子获胜!');
return true;
}
return false;
}
// 游戏结束
function endGame(message) {
gameOver = true;
status.textContent = message;
}
// 获取有效移动
function getValidMoves(row, col) {
const moves = [];
const pieceType = board[row][col];
const pieceRank = Math.abs(pieceType);
// 四个方向: 上、右、下、左
const directions = [
{dr: -1, dc: 0},
{dr: 0, dc: 1},
{dr: 1, dc: 0},
{dr: 0, dc: -1}
];
// 检查每个方向
directions.forEach(dir => {
const newRow = row + dir.dr;
const newCol = col + dir.dc;
// 如果在棋盘范围内
if (newRow >= 0 && newRow < 9 && newCol >= 0 && newCol < 7) {
const targetType = board[newRow][newCol];
// 狮子和老虎可以跳过河流
if ((pieceRank === 6 || pieceRank === 7) &&
board[newRow][newCol] === 9) {
// 寻找跳过河流后的格子
let jumpRow = newRow;
let jumpCol = newCol;
let hasAnimalInRiver = false;
// 继续同一方向直到离开河流
while (board[jumpRow][jumpCol] === 9) {
jumpRow += dir.dr;
jumpCol += dir.dc;
// 检查是否出界
if (jumpRow < 0 || jumpRow >= 9 || jumpCol < 0 || jumpCol >= 7) {
break;
}
// 检查河里是否有老鼠
if (board[jumpRow][jumpCol] === 1 || board[jumpRow][jumpCol] === -1) {
hasAnimalInRiver = true;
break;
}
}
// 如果没有老鼠阻挡并且跳出了河流区域
if (!hasAnimalInRiver &&
jumpRow >= 0 && jumpRow < 9 && jumpCol >= 0 && jumpCol < 7 &&
board[jumpRow][jumpCol] !== 9) {
// 检查落点
if (canMoveTo(pieceType, board[jumpRow][jumpCol], jumpRow, jumpCol)) {
moves.push({row: jumpRow, col: jumpCol});
}
}
}
// 常规移动检查
else if (canMoveTo(pieceType, targetType, newRow, newCol)) {
// 老鼠可以进入河流,其他动物不行
if (board[newRow][newCol] === 9 && pieceRank !== 1) {
// 不能移动
} else {
moves.push({row: newRow, col: newCol});
}
}
}
});
return moves;
}
// 检查是否可以移动到目标位置
function canMoveTo(pieceType, targetType, targetRow, targetCol) {
// 不能移动到己方兽穴
if ((pieceType > 0 && targetType === -11) || (pieceType < 0 && targetType === 11)) {
return false;
}
// 检查是否是空格子或河流
if (targetType === 0 || targetType === 9 || targetType === 10 ||
targetType === -10 || targetType === 11 || targetType === -11) {
return true;
}
// 检查是否是敌方棋子
const isPieceRed = pieceType > 0;
const isTargetRed = targetType > 0;
if (isPieceRed === isTargetRed) {
return false; // 不能吃自己的棋子
}
// 检查是否在敌方陷阱中
if ((isPieceRed && board[targetRow][targetCol-1] === -10) ||
(isPieceRed && board[targetRow][targetCol+1] === -10) ||
(isPieceRed && board[targetRow-1]?.[targetCol] === -10) ||
(isPieceRed && board[targetRow+1]?.[targetCol] === -10) ||
(!isPieceRed && board[targetRow][targetCol-1] === 10) ||
(!isPieceRed && board[targetRow][targetCol+1] === 10) ||
(!isPieceRed && board[targetRow-1]?.[targetCol] === 10) ||
(!isPieceRed && board[targetRow+1]?.[targetCol] === 10)) {
return true; // 在陷阱里的动物可以被任何敌方动物吃掉
}
// 检查正常战斗力
const pieceRank = Math.abs(pieceType);
const targetRank = Math.abs(targetType);
// 鼠可以吃象的特殊规则
if (pieceRank === 1 && targetRank === 8) {
return true;
}
// 象不能吃鼠的特殊规则
if (pieceRank === 8 && targetRank === 1) {
return false;
}
// 正常战斗力比较
return pieceRank >= targetRank;
}
// 重新开始游戏
restartBtn.addEventListener('click', initializeBoard);
// 初始化游戏
initializeBoard();
});
</script>
</body>
</html>