递归7_旗子的移动问题

static int count = 1;
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    chessAction(4);

}

/**
 问题描述:有2n个棋子排成一行,白子用0代表,黑子用1代表。n=5的状态为:
 0000011111_ _ (右边至少两个空位)
 移动规则:
 (1)每次必须移动相邻的两个棋子,这两个棋子不能互换位置
 (2)移动的颜色不限,移动的方向不限
 要求:
 最后成为  _ _ 0101010101     的状态(中间无空格)。

 */

void chessAction(int n) {

    if (n < 4) {
        return;
    }else if(n == 4) { //递归结束的

        //当递归到规模为4 的时候
        //  00001111__
        //  0123456789
        //1:000__11101
        printf("第%d步:%d&%d和空格(%d&%d)交换\n",count++,3,4,8,9);
        //2:0001011__1
        printf("第%d步:%d&%d和空格(%d&%d)交换\n",count++,7,8,3,4);
        //3:0__1011001
        printf("第%d步:%d&%d和空格(%d&%d)交换\n",count++,1,2,7,8);
        //4:010101__01
        printf("第%d步:%d&%d和空格(%d&%d)交换\n",count++,6,7,1,2);
        //5:__01010101
        printf("第%d步:%d&%d和空格(%d&%d)交换\n",count++,0,1,6,7);

    }else {
        //开始递归
        //把规模为n 的问题 转化成 规模为 n-1 的问题

        //1.把 第n-1 和 n 和空格(2n,2n+1)交换
        printf("第%d步:%d&%d和空格(%d&%d)交换\n",count++,n-1,n,2*n,2*n+1);

        //2.把 第2n-22n-2和空格(n-1,n)交换
        printf("第%d步:%d&%d和空格(%d&%d)交换\n",count++,2*n-2,2*n-2,n-1,n);

        //经过上步操作变成了问题为n-1 的规模
        chessAction(n-1);


    }


}


@end
import { ref, reactive, onMounted, onUnmounted, computed } from "vue" import { useHandleEvent } from "./useHandleEvent" export function useMinesweeper(gameGridRef: Ref<HTMLElement>) { const theme = ref({ title: "扫雷 - 经典版", background: "#000000", foreground: "#000000", border: "#000000", font: "16px/24px 'Microsoft YaHei', sans-serif" }) // 游戏状态 const gameState = ref<"ready" | "playing" | "won" | "lost">("ready") const gameTime = ref(0) const timer = ref<NodeJS.Timeout | null>(null) // const musicPlaying = ref(false) const isResetting = ref(false) const lastTapTime = ref(0) const tapTimeout = ref<NodeJS.Timeout | null>(null) // 游戏配置 const difficulty = ref<"beginner" | "intermediate" | "expert">("beginner") const gridSize = reactive({ rows: 9, cols: 9 }) const mineCount = ref(10) const remainingMines = ref(10) const isMobile = ref(false) const difficulties = [ { name: "初级", key: "beginner" }, { name: "中级", key: "intermediate" }, { name: "高级", key: "expert" } ] // 游戏数据 const grid = ref<any[][]>([]) const score = ref(0) const highlightedCells = ref<{ row: number; col: number }[]>([]) const pressedCells = ref<{ row: number; col: number }[]>([]) // 弹窗控制 const showScoreboard = ref(false) const showShareModal = ref(false) const scoreboardType = ref<"beginner" | "intermediate" | "expert">("beginner") const playerName = ref("玩家") // 排行榜数据 const leaderboards = reactive({ beginner: [] as any[], intermediate: [] as any[], expert: [] as any[] }) // 计算属性 const gameFace = computed(() => { if (gameState.value === "won") { return "😎" } if (gameState.value === "lost") { return "😵" } return "😊" }) const getScoreboardTitle = computed(() => { return { beginner: "初级排行榜", intermediate: "中级排行榜", expert: "高级排行榜" }[scoreboardType.value] }) const getScoreboard = computed(() => { return leaderboards[scoreboardType.value] }) const getDifficultyName = computed(() => { return { beginner: "初级", intermediate: "中级", expert: "高级" }[difficulty.value] }) // 检测移动设备 const detectMobile = () => { return ( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1) ) } // 初始化游戏 const init = () => { // 检测设备类型 isMobile.value = detectMobile() console.log("isMobile.value", isMobile.value, gameGridRef.value) resetGame() loadLeaderboard() // 尝试自动播放音乐 // setTimeout(() => { // toggleMusic() // }, 1000) } // 重置游戏 const resetGame = () => { gameState.value = "ready" gameTime.value = 0 remainingMines.value = mineCount.value score.value = 0 removeHighlight() removePressed() if (timer.value) { clearInterval(timer.value) timer.value = null } createGrid() showScoreboard.value = false showShareModal.value = false isResetting.value = false } // 延迟重置游戏(带动画效果) const delayedResetGame = () => { isResetting.value = true // 添加重置动画效果 for (let i = 0; i < gridSize.rows; i++) { for (let j = 0; j < gridSize.cols; j++) { grid.value[i][j].resetAnimating = true } } // 1秒后重置游戏 setTimeout(() => { resetGame() }, 1000) } // 创建网格 const createGrid = () => { grid.value = [] for (let i = 0; i < gridSize.rows; i++) { const row = [] for (let j = 0; j < gridSize.cols; j++) { row.push({ isMine: false, // 是否是雷 isRevealed: false, // 是否已经翻开 isFlagged: false, // 是否被标记为雷 isQuestion: false, // 是否被标记为问号 isHighlighted: false, // 是否被高亮显示 isPressed: false, // 是否被按下 resetAnimating: false, // 是否正在重置动画 number: 0 // 周围雷数量 }) } grid.value.push(row) } console.log("grid.value", grid.value, gameGridRef.value) } // 设置难度 const setDifficulty = (level: "beginner" | "intermediate" | "expert") => { difficulty.value = level switch (level) { case "beginner": gridSize.rows = 9 gridSize.cols = 9 mineCount.value = 10 break case "intermediate": gridSize.rows = 16 gridSize.cols = 16 mineCount.value = 40 break case "expert": gridSize.rows = 16 gridSize.cols = 30 mineCount.value = 99 break } remainingMines.value = mineCount.value resetGame() } // 开始游戏(第一次点击时) const startGame = (firstClickRow: number, firstClickCol: number) => { // 放置雷 placeMines(firstClickRow, firstClickCol) // 计算每个格子的数字 calculateCellValues() // 开始计时 gameState.value = "playing" timer.value = setInterval(() => { if (gameState.value === "playing") { gameTime.value++ } }, 1000) } // 放置雷(避开第一次点击的位置) const placeMines = (firstClickRow: number, firstClickCol: number) => { let minesPlaced = 0 while (minesPlaced < mineCount.value) { const row = Math.floor(Math.random() * gridSize.rows) const col = Math.floor(Math.random() * gridSize.cols) // 确保第一次点击的位置不是雷 if (row === firstClickRow && col === firstClickCol) continue if (!grid.value[row][col].isMine) { grid.value[row][col].isMine = true minesPlaced++ } } } // 计算每个格子的数字(周围雷数量) const calculateCellValues = () => { for (let i = 0; i < gridSize.rows; i++) { for (let j = 0; j < gridSize.cols; j++) { if (!grid.value[i][j].isMine) { grid.value[i][j].number = countAdjacentMines(i, j) } } } } // 计算周围雷数量 const countAdjacentMines = (row: number, col: number) => { let count = 0 for (let i = Math.max(0, row - 1); i <= Math.min(gridSize.rows - 1, row + 1); i++) { for (let j = Math.max(0, col - 1); j <= Math.min(gridSize.cols - 1, col + 1); j++) { if (i === row && j === col) continue if (grid.value[i][j].isMine) { count++ } } } return count } // 统一处理单元格event事件 useHandleEvent(gameGridRef, (event) => { const { type, cell, originalEvent } = event const { row, col } = cell const gridCell = grid.value[row][col] console.log("type", type) switch (type) { case "down": // 按下效果 gridCell.isPressed = true break case "up": // 取消按下效果 gridCell.isPressed = false removeHighlight() removePressed() break case "longclick": // 处理右键/长按事件 originalEvent.preventDefault() if (!gridCell.isRevealed) { // 循环切换标记状态:无标记 -> 旗帜 -> 问号 -> 无标记 if (!gridCell.isFlagged && !gridCell.isQuestion) { gridCell.isFlagged = true } else if (gridCell.isFlagged) { gridCell.isFlagged = false gridCell.isQuestion = true } else { gridCell.isQuestion = false } } break case "dblclick": // 处理双击事件 if (gridCell.isRevealed && gridCell.number > 0) { // 如果单元格已经翻开且有数字,尝试翻开周围的单元格 revealAdjacentCells(row, col) } break case "click": // 处理单击事件 if (!gridCell.isFlagged && !gridCell.isQuestion && !gridCell.isRevealed) { // 翻开单元格 revealCell(row, col) } break } }) // 处理单元格点击 const handleCellClick = (row: number, col: number, event: MouseEvent) => { if (gameState.value === "won" || gameState.value === "lost") return const cell = grid.value[row][col] // 在移动设备上,双击事件由handleDoubleClick处理 if (isMobile.value && cell.isRevealed && cell.number > 0) { return } // 在PC上,左键点击翻开格子 if (!isMobile.value && event.button === 0 && !cell.isFlagged && !cell.isQuestion) { revealCell(row, col) } } // 处理单元格右键点击 const handleCellRightClick = (row: number, col: number) => { if (gameState.value === "won" || gameState.value === "lost") return // 在PC上,右键标记旗帜 if (!isMobile.value) { toggleCellMark(row, col) } } // 处理单元格双击 const handleCellDoubleClick = (row: number, col: number) => { if (gameState.value === "won" || gameState.value === "lost") return const cell = grid.value[row][col] // 在移动设备上,双击标记旗帜 if (isMobile.value && !cell.isRevealed) { toggleCellMark(row, col) return } // 在PC上,双击已翻开的数字 if (cell.isRevealed && cell.number > 0) { handleDoubleClickOnNumber(row, col) } } // 处理单元格鼠标按下 const handleCellMouseDown = (row: number, col: number, event: MouseEvent) => { if (gameState.value === "won" || gameState.value === "lost") return const cell = grid.value[row][col] // 如果是已翻开的数字,高亮周围未翻开的格子 if (cell.isRevealed && cell.number > 0 && event.button === 0) { highlightAdjacentCells(row, col) } } // 处理单元格鼠标释放 const handleCellMouseUp = () => { removeHighlight() removePressed() } // 处理单元格触摸开始 const handleCellTouchStart = (row: number, col: number, event: TouchEvent) => { if (gameState.value === "won" || gameState.value === "lost") return const cell = grid.value[row][col] const currentTime = new Date().getTime() const tapLength = currentTime - lastTapTime.value // 清除之前的点击超时 if (tapTimeout.value) clearTimeout(tapTimeout.value) // 如果是已翻开的数字,高亮周围未翻开的格子 if (cell.isRevealed && cell.number > 0) { highlightAdjacentCells(row, col) } // 处理双击逻辑 if (tapLength < 300 && tapLength > 0) { // 双击事件 toggleCellMark(row, col) event.preventDefault() } else { // 设置单击超时 tapTimeout.value = setTimeout(() => { // 单击事件 if (!cell.isFlagged && !cell.isQuestion) { revealCell(row, col) } }, 300) } lastTapTime.value = currentTime } // 处理单元格触摸结束 const handleCellTouchEnd = () => { removeHighlight() removePressed() } // 处理双击数字 const handleDoubleClickOnNumber = (row: number, col: number) => { // const cell = grid.value[row][col]; // 移除之前的高亮 removeHighlight() // 检查周围是否有未标记的雷 let hasUnmarkedMine = false for (let i = Math.max(0, row - 1); i <= Math.min(gridSize.rows - 1, row + 1); i++) { for (let j = Math.max(0, col - 1); j <= Math.min(gridSize.cols - 1, col + 1); j++) { if (i === row && j === col) continue const adjCell = grid.value[i][j] if (adjCell.isMine && !adjCell.isFlagged) { hasUnmarkedMine = true break } } } // 高亮周围未翻开的格子 for (let i = Math.max(0, row - 1); i <= Math.min(gridSize.rows - 1, row + 1); i++) { for (let j = Math.max(0, col - 1); j <= Math.min(gridSize.cols - 1, col + 1); j++) { if (i === row && j === col) continue const adjCell = grid.value[i][j] if (!adjCell.isRevealed && !adjCell.isFlagged && !adjCell.isQuestion) { adjCell.isHighlighted = true highlightedCells.value.push({ row: i, col: j }) // 如果有未标记的雷,模拟按下动作 if (hasUnmarkedMine) { adjCell.isPressed = true pressedCells.value.push({ row: i, col: j }) } } } } // 如果没有未标记的雷,翻开周围格子 if (!hasUnmarkedMine) { return revealAdjacentCells(row, col) } // 设置定时器移除效果 setTimeout(() => { removeHighlight() removePressed() }, 100) } // 高亮周围未翻开的格子 const highlightAdjacentCells = (row: number, col: number) => { const cell = grid.value[row][col] if (!cell.isRevealed || cell.number === 0) return // 清除之前的高亮 removeHighlight() // 高亮周围未翻开的格子 for (let i = Math.max(0, row - 1); i <= Math.min(gridSize.rows - 1, row + 1); i++) { for (let j = Math.max(0, col - 1); j <= Math.min(gridSize.cols - 1, col + 1); j++) { if (i === row && j === col) continue const adjCell = grid.value[i][j] console.log("adjCell: ", isMobile.value, adjCell.number, adjCell) if (!adjCell.isRevealed && !adjCell.isFlagged && !adjCell.isQuestion) { adjCell.isHighlighted = true highlightedCells.value.push({ row: i, col: j }) // 在移动设备上,显示按下动画 if (isMobile.value) { adjCell.isPressed = true pressedCells.value.push({ row: i, col: j }) } } } } } // 移除高亮 const removeHighlight = () => { highlightedCells.value.forEach((pos) => { if (grid.value[pos.row] && grid.value[pos.row][pos.col]) { grid.value[pos.row][pos.col].isHighlighted = false } }) highlightedCells.value = [] } // 移除按下状态 const removePressed = () => { pressedCells.value.forEach((pos) => { if (grid.value[pos.row] && grid.value[pos.row][pos.col]) { grid.value[pos.row][pos.col].isPressed = false } }) pressedCells.value = [] } // 切换单元格标记(旗子/问号) const toggleCellMark = (row: number, col: number) => { const cell = grid.value[row][col] if (cell.isRevealed) return if (!cell.isFlagged && !cell.isQuestion) { cell.isFlagged = true remainingMines.value-- if (cell.isMine) score.value += 10 // 正确标记雷得10分 } else if (cell.isFlagged) { cell.isFlagged = false cell.isQuestion = true remainingMines.value++ } else if (cell.isQuestion) { cell.isQuestion = false } } // 揭示单元格 const revealCell = (row: number, col: number) => { const cell = grid.value[row][col] // 如果游戏还未开始(第一次点击) if (gameState.value === "ready") { return startGame(row, col) } if (cell.isRevealed || cell.isFlagged || cell.isQuestion) return // 如果是雷,游戏结束 if (cell.isMine) { cell.isRevealed = true revealAllMines() gameState.value = "lost" if (timer.value) { clearInterval(timer.value) } return } // 揭示当前单元格 cell.isRevealed = true // 如果是空白单元格,递归揭示周围 if (cell.number === 0) { revealAdjacentCells(row, col) } // 检查是否获胜 checkWinCondition() } // 揭示相邻单元格 const revealAdjacentCells = (row: number, col: number) => { for (let i = Math.max(0, row - 1); i <= Math.min(gridSize.rows - 1, row + 1); i++) { for (let j = Math.max(0, col - 1); j <= Math.min(gridSize.cols - 1, col + 1); j++) { if (i === row && j === col) continue const adjCell = grid.value[i][j] if (!adjCell.isRevealed && !adjCell.isFlagged && !adjCell.isQuestion) { revealCell(i, j) } } } } // 揭示所有雷 const revealAllMines = () => { for (let i = 0; i < gridSize.rows; i++) { for (let j = 0; j < gridSize.cols; j++) { const cell = grid.value[i][j] if (cell.isMine) { cell.isRevealed = true } } } } // 检查获胜条件 const checkWinCondition = () => { let unrevealedSafeCells = 0 for (let i = 0; i < gridSize.rows; i++) { for (let j = 0; j < gridSize.cols; j++) { const cell = grid.value[i][j] if (!cell.isRevealed && !cell.isMine) { unrevealedSafeCells++ } } } if (unrevealedSafeCells === 0) { gameState.value = "won" if (timer.value) { clearInterval(timer.value) } // 标记所有剩余雷 markAllRemainingMines() } } // 标记所有剩余雷 const markAllRemainingMines = () => { for (let i = 0; i < gridSize.rows; i++) { for (let j = 0; j < gridSize.cols; j++) { const cell = grid.value[i][j] if (cell.isMine && !cell.isFlagged) { cell.isFlagged = true remainingMines.value-- score.value += 10 // 正确标记雷得10分 } } } } // 计算得分 const calculateScore = () => { const baseScore = score.value const timeBonus = Math.max(0, 1000 - gameTime.value * 10) const difficultyBonus = { beginner: 500, intermediate: 1000, expert: 2000 }[difficulty.value] return baseScore + timeBonus + difficultyBonus } // 获取单元格显示内容 const getCellDisplay = (cell: any) => { if (cell.isRevealed) { // if (cell.isMine) return "💣"; if (cell.isMine) return "" if (cell.number === 0) return "" return cell.number } if (cell.isFlagged) return "🚩" if (cell.isQuestion) return "?" return "" } // // 切换音乐 // const toggleMusic = () => { // const music = document.getElementById("backgroundMusic") as HTMLAudioElement // if (musicPlaying.value) { // music.pause() // } else { // music.play().catch(() => console.log("自动播放被阻止,请手动点击播放")) // } // musicPlaying.value = !musicPlaying.value // } // 加载排行榜 const loadLeaderboard = () => { const savedLeaderboard = localStorage.getItem("minesweeperLeaderboard") if (savedLeaderboard) { Object.assign(leaderboards, JSON.parse(savedLeaderboard)) } else { // 初始示例数据 leaderboards.beginner = [ { player: "玩家1", time: 45, score: 850, date: "2023-06-15" }, { player: "玩家2", time: 52, score: 820, date: "2023-06-14" } ] leaderboards.intermediate = [ { player: "高手1", time: 120, score: 1500, date: "2023-06-15" }, { player: "高手2", time: 135, score: 1450, date: "2023-06-14" } ] leaderboards.expert = [ { player: "专家1", time: 240, score: 2500, date: "2023-06-15" }, { player: "专家2", time: 260, score: 2400, date: "2023-06-14" } ] saveLeaderboard() } } // 保存排行榜 const saveLeaderboard = () => { localStorage.setItem("minesweeperLeaderboard", JSON.stringify(leaderboards)) } // 分享结果 const shareResult = () => { const shareText = `我在${theme.value.title}游戏中取得了${calculateScore()}分!难度:${ getDifficultyName.value },用时:${gameTime.value}秒` if (navigator.share) { navigator .share({ title: "扫雷战绩分享", text: shareText, url: window.location.href }) .catch(console.error) } else { alert(`分享内容: ${shareText}\n复制链接分享给朋友: ${window.location.href}`) } showShareModal.value = false } // 保存到排行榜 const saveToLeaderboard = () => { const newEntry = { player: playerName.value || "匿名玩家", time: gameTime.value, score: calculateScore(), date: new Date().toISOString().split("T")[0] } // 添加到排行榜 leaderboards[difficulty.value].push(newEntry) // 排序并保留前10名 leaderboards[difficulty.value].sort((a, b) => b.score - a.score) leaderboards[difficulty.value] = leaderboards[difficulty.value].slice(0, 10) // 保存到本地存储 saveLeaderboard() alert("已保存到排行榜!") showShareModal.value = false showScoreboard.value = true scoreboardType.value = difficulty.value } // 生命周期钩子 onMounted(() => { init() }) onUnmounted(() => { if (timer.value) { clearInterval(timer.value) } if (tapTimeout.value) { clearTimeout(tapTimeout.value) } }) // 返回所有需要暴露的状态和方法 return { // 状态 gameState, gameTime, // musicPlaying, isResetting, difficulty, gridSize, mineCount, remainingMines, isMobile, grid, score, difficulties, showScoreboard, showShareModal, scoreboardType, playerName, leaderboards, // 计算属性 gameFace, getScoreboardTitle, getScoreboard, getDifficultyName, // 方法 removeHighlight, setDifficulty, handleCellClick, handleCellRightClick, handleCellDoubleClick, handleCellMouseDown, handleCellMouseUp, handleCellTouchStart, handleCellTouchEnd, resetGame, delayedResetGame, toggleCellMark, revealCell, getCellDisplay, // toggleMusic, saveToLeaderboard, calculateScore, shareResult } } 请分析这段代码,帮我梳理并修改:单击或右键点击未翻开格子上依次为插旗/问号/取消,在数字上单击或双击如果范围内有超出的未翻开的格子则提醒,否则就递归翻开;在未翻开格子上双击则直接翻开;
最新发布
08-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值