Python猜拳游戏的工程化重构:从脚本到人机交互系统
2026/10/13 8:53:22
独木桥问题是经典的并发同步问题,展示了资源互斥访问的场景。本文将详细介绍如何使用Flutter for OpenHarmony框架开发一款独木桥问题模拟系统。文章涵盖了人物数据模型、桥状态管理、异步队列处理、Future延迟模拟等核心技术点。通过本文学习,读者将掌握Flutter在鸿蒙平台上的异步编程技巧,了解并发模拟与资源管理的实现方法。
独木桥问题是操作系统中的经典同步问题:
| 功能模块 | 具体功能 |
|---|---|
| 人物管理 | 南侧9人、北侧8人,不同过桥速度 |
| 桥状态显示 | 显示桥空闲/被占用状态 |
| 队列处理 | 按顺序依次过桥 |
| 过程模拟 | 异步模拟每个人过桥过程 |
| 进度统计 | 显示已过桥人数 |
| 控制功能 | 开始/重置模拟 |
| 参数 | 说明 | 示例 |
|---|---|---|
| id | 唯一标识 | S1, S2…N1, N2… |
| name | 显示名称 | 南1, 南2…北1, 北2… |
| side | 所属方向 | south, north |
| crossingSpeed | 过桥速度(毫秒) | 1000-2800 |
桥是一个共享资源,具有以下约束:
| 方向 | 人数 | 标识 |
|---|---|---|
| 南侧 | 9人 | S1-S9 |
| 北侧 | 8人 | N1-N8 |
| 总计 | 17人 | - |
UI组件
状态管理
异步处理
BridgeCrossingApp (应用根组件) └── BridgeCrossingPage (模拟页面) ├── AppBar (导航栏 + 进度显示) ├── 控制面板 │ ├── 开始按钮 │ └── 重置按钮 ├── 桥状态显示 │ ├── 空闲状态 │ └── 占用状态 └── 人员列表 └── PersonCard (17个)classPerson{finalStringid;// 唯一标识finalStringname;// 显示名称finalStringside;// 'south' 或 'north'bool isOnBridge;// 是否在桥上bool hasCrossed;// 是否已过桥int crossingSpeed;// 过桥速度(毫秒)Person({requiredthis.id,requiredthis.name,requiredthis.side,this.isOnBridge=false,this.hasCrossed=false,this.crossingSpeed=1000,});Colorgetcolor=>side=='south'?Colors.blue:Colors.orange;}enumBridgeStatus{idle,// 空闲occupied,// 被占用}void_initializePeople(){_people.clear();// 南侧9人for(int i=1;i<=9;i++){_people.add(Person(id:'S$i',name:'南$i',side:'south',crossingSpeed:1000+(i*200),// 不同速度));}// 北侧8人for(int i=1;i<=8;i++){_people.add(Person(id:'N$i',name:'北$i',side:'north',crossingSpeed:1000+(i*150),// 不同速度));}setState((){_crossedCount=0;_hasStarted=false;});}Container(padding:constEdgeInsets.all(16),color:Colors.teal.shade50,child:Row(children:[ElevatedButton.icon(onPressed:_hasStarted?null:_startSimulation,icon:constIcon(Icons.play_arrow),label:constText('开始模拟'),style:ElevatedButton.styleFrom(backgroundColor:Colors.green,foregroundColor:Colors.white,),),constSizedBox(width:12),ElevatedButton.icon(onPressed:_resetSimulation,icon:constIcon(Icons.refresh),label:constText('重置'),style:ElevatedButton.styleFrom(backgroundColor:Colors.grey,),),],),)Container(padding:constEdgeInsets.all(16),color:Colors.grey.shade100,child:Row(mainAxisAlignment:MainAxisAlignment.center,children:[Icon(_bridgeStatus==BridgeStatus.occupied?Icons.block:Icons.check_circle,color:_bridgeStatus==BridgeStatus.occupied?Colors.red:Colors.green,),constSizedBox(width:8),Text(_bridgeStatus==BridgeStatus.occupied?'桥被占用:${_currentCrosser?.name}正在过桥':'桥空闲',style:constTextStyle(fontSize:16,fontWeight:FontWeight.bold),),],),)Widget_buildPersonCard(Personperson){StringstatusText;ColorstatusColor;if(person.isOnBridge){statusText='正在过桥...';statusColor=Colors.orange;}elseif(person.hasCrossed){statusText='已过桥 ✓';statusColor=Colors.green;}else{statusText='等待中';statusColor=Colors.grey;}returnCard(margin:constEdgeInsets.only(bottom:8),child:ListTile(leading:CircleAvatar(backgroundColor:person.color,child:Text(person.name.substring(1),style:constTextStyle(color:Colors.white,fontWeight:FontWeight.bold,),),),title:Text(person.name,style:constTextStyle(fontWeight:FontWeight.bold),),subtitle:Text('速度:${person.crossingSpeed}ms'),trailing:Container(padding:constEdgeInsets.symmetric(horizontal:12,vertical:6),decoration:BoxDecoration(color:statusColor,borderRadius:BorderRadius.circular(12),),child:Text(statusText,style:constTextStyle(color:Colors.white,fontWeight:FontWeight.bold,),),),),);}void_startSimulation(){if(_hasStarted)return;setState((){_hasStarted=true;});_processQueue();}void_processQueue()async{// 按顺序过桥for(varpersonin_people){if(!person.hasCrossed){await_crossBridge(person);setState((){_crossedCount++;});// 滚动到底部if(_scrollController.hasClients){_scrollController.animateTo(_scrollController.position.maxScrollExtent,duration:constDuration(milliseconds:300),curve:Curves.easeInOut,);}}}// 全部完成if(mounted){setState((){_bridgeStatus=BridgeStatus.idle;});ScaffoldMessenger.of(context).showSnackBar(constSnackBar(content:Text('所有人都已安全过桥!'),backgroundColor:Colors.green,),);}}算法要点
Future<void>_crossBridge(Personperson)async{setState((){_bridgeStatus=BridgeStatus.occupied;_currentCrosser=person;person.isOnBridge=true;});// 模拟过桥时间awaitFuture.delayed(Duration(milliseconds:person.crossingSpeed));if(mounted){setState((){person.isOnBridge=false;person.hasCrossed=true;_bridgeStatus=BridgeStatus.idle;_currentCrosser=null;});}}异步处理要点
void_resetSimulation(){setState((){_hasStarted=false;_bridgeStatus=BridgeStatus.idle;_currentCrosser=null;_crossedCount=0;for(varpersonin_people){person.isOnBridge=false;person.hasCrossed=false;}});_initializePeople();}voidmain(){runApp(constBridgeCrossingApp());}classBridgeCrossingAppextendsStatelessWidget{constBridgeCrossingApp({super.key});@overrideWidgetbuild(BuildContextcontext){returnMaterialApp(title:'独木桥问题',theme:ThemeData(colorScheme:ColorScheme.fromSeed(seedColor:Colors.teal),useMaterial3:true,),home:constBridgeCrossingPage(),);}}class_BridgeCrossingPageStateextendsState<BridgeCrossingPage>{finalList<Person>_people=[];BridgeStatus_bridgeStatus=BridgeStatus.idle;Person?_currentCrosser;int _crossedCount=0;finalScrollController_scrollController=ScrollController();bool _hasStarted=false;@overridevoidinitState(){super.initState();_initializePeople();}@overridevoiddispose(){_scrollController.dispose();super.dispose();}}AppBar(title:constText('独木桥问题'),backgroundColor:Theme.of(context).colorScheme.inversePrimary,actions:[Center(child:Padding(padding:constEdgeInsets.only(right:16),child:Text('已过桥:$_crossedCount/17',style:constTextStyle(fontSize:16,fontWeight:FontWeight.bold),),),),],)cdE:\HarmonyOS\oh.code\bridge_crossing flutter run -d ohos初始化测试
模拟流程测试
状态显示测试
重置功能测试
完成提示测试
本文详细介绍了使用Flutter for OpenHarmony开发独木桥问题模拟系统的完整过程,涵盖了以下核心技术点:
这个项目展示了Flutter在并发模拟和异步编程方面的完整流程。读者可以基于此项目添加更多功能,如:
通过本文的学习,读者应该能够理解异步编程的基本概念,掌握Flutter在鸿蒙平台上的异步处理技巧,为开发更复杂的并发应用打下基础。
欢迎加入开源鸿蒙跨平台社区: 开源鸿蒙跨平台开发者社区