iOS多线程机器人棋盘游戏:回合与线程逻辑实现难题
7x7机器人棋盘游戏:回合逻辑与多线程同步解决方案
核心思路是用同步原语控制多线程的回合节奏,让每个机器人在独立线程中执行,但严格按照回合顺序完成移动,避免乱序或竞争问题。以下是具体实现方案:
1. 核心同步组件定义
先初始化全局的同步控制对象,用于协调回合的开始、结束,以及保护共享资源:
// 调度组:等待所有机器人完成当前回合移动 dispatch_group_t roundGroup = dispatch_group_create(); // 信号量:触发机器人开始当前回合的移动 dispatch_semaphore_t roundStartSemaphore = dispatch_semaphore_create(0); // 原子变量:标记当前回合是否已结束(如机器人拿到奖品) atomic_bool roundEnded = false; // 锁:保护棋盘状态、得分等共享资源 NSLock *boardLock = [[NSLock alloc] init]; NSLock *scoreLock = [[NSLock alloc] init];
2. 机器人独立线程逻辑
为每个机器人创建独立串行队列,线程内循环执行「等待回合信号→移动→通知完成」的逻辑:
// 机器人A的独立线程 dispatch_queue_t robotAQueue = dispatch_queue_create("com.game.robotA", DISPATCH_QUEUE_SERIAL); dispatch_async(robotAQueue, ^{ while (true) { // 等待回合开始信号 dispatch_semaphore_wait(roundStartSemaphore, DISPATCH_TIME_FOREVER); if (roundEnded) continue; // 回合已结束,跳过本轮 [boardLock lock]; // 执行移动逻辑: // 1. 获取当前位置 // 2. 筛选上下左右可移动区域(排除对方轨迹、已访问区域) // 3. 移动或停留,更新自身轨迹到棋盘 bool reachedPrize = // 判断是否到达奖品位置 [boardLock unlock]; if (reachedPrize) { atomic_store(&roundEnded, true); // 更新总分 [scoreLock lock]; robotAScore++; [scoreLock unlock]; } // 通知调度组:本机器人完成当前回合移动 dispatch_group_leave(roundGroup); } }); // 机器人B的线程逻辑与A完全一致,仅队列名称、得分变量不同 dispatch_queue_t robotBQueue = dispatch_queue_create("com.game.robotB", DISPATCH_QUEUE_SERIAL); dispatch_async(robotBQueue, ^{ // 重复上述逻辑,对应robotBScore });
3. 回合驱动主逻辑
创建专门的回合管理线程,负责每轮的初始化、回合循环驱动:
dispatch_queue_t roundManagerQueue = dispatch_queue_create("com.game.roundManager", DISPATCH_QUEUE_SERIAL); dispatch_async(roundManagerQueue, ^{ while (true) { // 重置本轮游戏状态 [boardLock lock]; // 1. 随机在7x7棋盘空位置放置奖品 // 2. 重置机器人A到(0,0)、机器人B到(6,6) // 3. 清空双方轨迹记录 [boardLock unlock]; atomic_store(&roundEnded, false); while (!roundEnded) { // 标记两个机器人即将进入本轮移动 dispatch_group_enter(roundGroup); dispatch_group_enter(roundGroup); // 触发两个机器人开始移动 dispatch_semaphore_signal(roundStartSemaphore); dispatch_semaphore_signal(roundStartSemaphore); // 等待所有机器人完成本次移动 dispatch_group_wait(roundGroup, DISPATCH_TIME_FOREVER); // 检查是否双方都无法移动(平局) [boardLock lock]; bool bothCantMove = // 判断A、B均无有效移动区域 [boardLock unlock]; if (bothCantMove) { atomic_store(&roundEnded, true); // 平局处理(如双方均不得分) } } // 本轮结束,输出当前总分 [scoreLock lock]; NSLog(@"本轮结束 | A得分:%d | B得分:%d", robotAScore, robotBScore); [scoreLock unlock]; // 可选:添加延迟,让结果展示更直观 [NSThread sleepForTimeInterval:1.0]; } });
关键注意事项
- 共享资源保护:棋盘状态、得分、回合标记等必须通过锁或原子操作保护,避免多线程竞争导致的异常
- 同步匹配:确保
dispatch_group_enter和dispatch_group_leave的调用次数严格对应,信号量的signal与wait次数匹配,防止死锁 - 退出控制:可添加
atomic_bool gameRunning变量,通过修改它来终止所有线程的循环
内容的提问来源于stack exchange,提问作者Vinícius Albino
相关产品推荐
相关产品推荐

