写了个五子棋

作者分享了使用MFC开发联网对战五子棋的经历,重点讨论了类设计、多线程及PostMessage的使用等问题,并提出了解决方案。

还没放假的时候想着写一个可以联网对战的五子棋,主要是刚刚学了些MFC,想动动手,结果一下子就把本地的给写了出来,但是根本没有考虑有关结构,还有哪些该做一个类,类与类之间的继承等关系,外加要考虑到多线程,以及不知道类里面的PostMessage怎么写……结果当轮到写网络部分的时候就卡住了,客户端这边有棋子添加但是服务器端这边就没有……

总之问题一大堆,只好一一解决……

终于,在今天把这个问题解决了!关键是过程中遇到的几个值得思索的问题!

1.怎么在类里面用PostMessage来转到类里面的成员函数;

2.类里面通过View文件的MESSAGE路由表转到类里面的函数的时候貌似会新建一个对象,这个问题完全不懂;

3.对于类多一点,会有思维混乱的时候……

 

所以,接下来的工作应该是:

1.多看书,多学习,应该了解MFC的内部机制,这样才不至于糊里糊涂;

2.应该多学习一些对于编程的流程控制或者管理方面的知识;

3.多动手锻炼!

http://download.youkuaiyun.com/source/2049516

<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文件中,然后在浏览器中打开即可开始游戏!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值