当前位置: 首页 > news >正文

UVa 220 Othello

题目分析

本题一个模拟黑白棋(奥赛罗棋)游戏的问题。题目要求读取多个游戏对局,根据命令执行相应的操作,包括:

  • L命令:列出当前玩家所有合法的落子位置,按行主序输出
  • Mxy命令:在指定位置落子,并翻转被夹住的棋子
  • Q命令:结束当前游戏,输出最终棋盘状态

黑白棋的规则:双方轮流在棋盘上落子,落子时必须在水平、垂直或对角线方向上夹住至少一个对方棋子,被夹住的棋子会翻转为当前玩家的颜色。

解题思路

核心逻辑

  1. 棋盘表示:使用8×88 \times 88×8的字符数组存储棋盘状态,'B'表示黑棋,'W'表示白棋,'-'表示空格。

  2. 方向数组:使用预定义的888个方向向量表示八个搜索方向:
    (−1,0), (−1,1), (0,1), (1,1),(1,0), (1,−1), (0,−1), (−1,−1) \begin{aligned} &(-1,0),\; (-1,1),\; (0,1),\; (1,1),\\ &(1,0),\; (1,-1),\; (0,-1),\; (-1,-1) \end{aligned}(1,0),(1,1),(0,1),(1,1),(1,0),(1,1),(0,1),(1,1)

  3. 合法落子检测listMove函数):

    • 遍历棋盘每个位置,若存在当前玩家的棋子,则沿888个方向搜索
    • 遇到对方棋子继续,遇到空格或出界停止
    • 若在某方向上有连续的对方棋子且下一个位置是空格,则该空格为合法落子位置
    • 将合法位置用'*'临时标记,输出后恢复为'-'
  4. 落子与翻转makeMove函数):

    • 在指定位置放置当前玩家的棋子
    • 沿888个方向搜索,统计连续对方棋子的数量
    • 若某方向连续对方棋子后遇到当前玩家的棋子,则将该方向上的所有对方棋子翻转
  5. 无合法落子处理

    • 若当前玩家无合法落子,则自动切换为对方玩家
    • 切换后进行落子操作
  6. 输出格式

    • 不同游戏之间输出一个空行
    • 移动后输出双方棋子数量,格式为Black - xx White - yy

代码实现

// Othello// UVa ID: 220// Verdict: Accepted// Submission Date: 2016-04-30// UVa Run Time: 0.000s//// 版权所有(C)2016,邱秋。metaphysis # yeah dot net#include<bits/stdc++.h>usingnamespacestd;charboard[8][8],player;// board: 棋盘,player: 当前玩家string command;// 存储命令intdirection[8][2]={// 8 个搜索方向{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};// 输出当前棋盘状态voiddisplay(){for(inti=0;i<8;i++){for(intj=0;j<8;j++)cout<<board[i][j];cout<<endl;}}// 列出当前玩家的所有合法落子位置// print = true: 输出结果,print = false: 仅判断是否有合法落子// 返回值: 是否有合法落子boollistMove(boolprint){charanother=player=='B'?'W':'B';// 对方棋子颜色// 遍历所有当前玩家棋子的位置,标记合法落子位置for(intx=0;x<8;x++)for(inty=0;y<8;y++)if(board[x][y]==player){for(inti=0;i<8;i++){intxx=x,yy=y;intdisks=0;// 连续对方棋子的数量xx+=direction[i][0];yy+=direction[i][1];// 沿当前方向搜索,统计连续对方棋子while(xx>=0&&yy>=0&&xx<8&&yy<8){if(board[xx][yy]==another)disks++;elsebreak;xx+=direction[i][0];yy+=direction[i][1];}// 若存在对方棋子,且下一个位置是空格,则为合法落子if(disks>0&&(xx>=0&&yy>=0&&xx<8&&yy<8)&&board[xx][yy]=='-')board[xx][yy]='*';// 临时标记合法位置}}// 收集并输出所有合法落子位置intlegalMoves=0;for(inti=0;i<8;i++)for(intj=0;j<8;j++)if(board[i][j]=='*'){if(print&&legalMoves)cout<<" ";if(print)cout<<"("<<(i+1)<<","<<(j+1)<<")";legalMoves++;board[i][j]='-';// 恢复为空格}// 输出结果信息if(print&&legalMoves)cout<<endl;elseif(print)cout<<"No legal move."<<endl;returnlegalMoves>0;}// 在指定位置落子,并翻转被夹住的棋子voidmakeMove(intx,inty){board[x][y]=player;// 放置当前玩家棋子charanother=player=='B'?'W':'B';for(inti=0;i<8;i++){intxx=x,yy=y;intdisks=0;xx+=direction[i][0];yy+=direction[i][1];// 统计当前方向上连续对方棋子的数量while(xx>=0&&yy>=0&&xx<8&&yy<8){if(board[xx][yy]==another)disks++;elsebreak;xx+=direction[i][0];yy+=direction[i][1];}// 若该方向可翻转,则执行翻转操作if(disks>0&&(xx>=0&&yy>=0&&xx<8&&yy<8)&&board[xx][yy]==player){xx=x;yy=y;while(disks--){xx+=direction[i][0];yy+=direction[i][1];board[xx][yy]=player;// 翻转对方棋子}}}}// 根据命令执行相应操作voidplay(){if(command=="L")// 列出合法落子{listMove(true);}elseif(command.front()=='M')// 执行落子{// 若无合法落子,则切换玩家if(listMove(false)==false)player=player=='B'?'W':'B';// 解析落子坐标(命令格式如 "M35" 表示第3行第5列)intx=command[1]-'0'-1;inty=command[2]-'0'-1;makeMove(x,y);// 执行落子并翻转// 统计黑白棋子数量intblack=0,white=0;for(inti=0;i<8;i++)for(intj=0;j<8;j++)if(board[i][j]=='B')black++;elseif(board[i][j]=='W')white++;// 输出统计结果cout<<"Black -"<<setw(3)<<right<<black;cout<<" White -"<<setw(3)<<right<<white<<endl;// 切换玩家(轮到对方落子)player=player=='B'?'W':'B';}}intmain(){cin.tie(0);cin.sync_with_stdio(false);intgames;boolfirst=true;cin>>games;while(games--){// 读取棋盘初始状态for(inti=0;i<8;i++)for(intj=0;j<8;j++)cin>>board[i][j];// 输出空行分隔不同游戏if(first)first=false;elsecout<<endl;// 读取当前玩家cin>>player;// 处理命令序列,直到遇到 'Q'while(cin>>command,command!="Q")play();// 输出最终棋盘状态display();}return0;}

总结

本题的核心在于准确实现黑白棋的规则模拟:

  1. 合法落子检测需要沿888个方向搜索连续的对方棋子
  2. 落子翻转时需要在确认可翻转后,沿相同方向将棋子全部翻转
  3. 注意处理无合法落子时自动切换玩家的规则

通过清晰的方向向量和规范的搜索逻辑,可以正确完成游戏模拟。

http://www.jsqmd.com/news/820080/

相关文章:

  • 挑选工作效率提升工具,必这4个核心筛选标准
  • ROPfuscator:基于ROP链的代码混淆技术原理与实践
  • 2026年企业IT运维监控厂商选型:中外四大主流可观测方案深度对比
  • 自动驾驶汽车电气系统设计与生成式设计应用
  • 基于 HarmonyOS 6.0 的校园闲置市集应用开发实战:从页面构建到跨端设计深度解析
  • JavaSE基础 | 《循环高级和数组》
  • AutoGen多智能体协作框架:从原理到实战构建AI团队
  • 自建网页时光机:基于Playwright与FastAPI的私有化网页归档系统实战
  • 2026年烟台家电清洗培训怎么选选本地机构还是连锁品牌?可综合多方面评估
  • Godot引擎可变形网格插件:基于弹簧质点模型的物理形变实现
  • 苏州配电工程为什么优先本地一站式厂家?
  • Xenos DLL注入器:Windows系统动态加载完整指南
  • 从JDK8直升JDK21有哪些必须要注意的事情(荣耀典藏版)
  • 2026质量管控新趋势 FMEA避坑指南+六西格玛落地技巧
  • 人工神经网络知识点讲解
  • STM32单片机学习(12)——串口通信相关概念
  • 细胞结构实验室(react 开源)
  • 《三维动画制作》学习心得
  • Kubernetes应用管理新范式:kapp-controller控制器模式详解与实践
  • 零基础录音转日程教程包教包会避坑,看完就能直接上手
  • C++面向对象编程实验:从封装到多态的实战训练与工程化实践
  • AI智能提示词生成器——帮你更高效地使用AI解决问题
  • 终端安全管理(ESM):企业安全的“数字神经中枢“
  • 菲仕技术冲刺港股:年营收16亿,亏6189万 先进制造与京津冀基金是股东
  • 量子计算误差处理技术:从基础原理到工程实践
  • Docker容器化机械臂控制:OpenClaw项目环境部署与实战
  • 读智能涌现: AI时代的思考与探索01数字化3.0
  • Python性能优化实战:Numba JIT编译器原理与高性能计算应用
  • 基于 HarmonyOS 6.0 的校园二手交易页面实战开发:从组件构建到跨端布局优化
  • Ollama 简介