约瑟夫问题模拟算法可视化程序_C++精灵库算法可视化程序

先看视频更好理解,约瑟夫问题模拟算法可视化程序_C++精灵库算法可视化程序(抖音C++精灵库官方账号):

https://www.douyin.com/video/7602999293472984355

场景设定:在肖申克监狱的院子里,一群囚犯围成一个圈,正在进行一个奇特的"游戏"。安迪(Andy)和瑞德(Red)站在一旁,观察着这一切。

瑞德(Red):嘿,安迪,你看那边那群家伙在搞什么名堂啊?

安迪(Andy):哦,瑞德,这是他们在玩"约瑟夫游戏"。每次报数到3的人就得"出局",就像是一种残酷的淘汰赛。

瑞德(Red):听起来挺有意思的。那他们是怎么开始的?

安迪(Andy):你看,他们从0号开始,每个人按顺序报数。1,2,3------报到3的那位兄弟就得"阵亡"了。

瑞德(Red):(笑)"阵亡"?这词用得真贴切。那第一个"阵亡"的是谁?

安迪(Andy):(指着屏幕)看,是2号。他刚报完"3",就"阵亡"了。现在轮到5号接着报数。

瑞德(Red):(点头)嗯,5号接着报"1",然后8号报"2",1号报"3"------他又"阵亡"了。

安迪(Andy):没错,就这样一轮一轮地淘汰。每次"阵亡"的人都会变成半透明,就像魂魄出窍一样。

瑞德(Red):(大笑)魂魄出窍!这话说得我都有点毛骨悚然了。那现在轮到谁了?

安迪(Andy):现在是6号报"3",他也"阵亡"了。游戏继续,直到所有人都"阵亡"。

瑞德(Red):(惊叹)哇,这游戏真是既刺激又残酷。那最后的"阵亡"顺序是怎样的?

安迪(Andy):(指着屏幕上的序列)你看,最终的"阵亡"顺序是:2、5、8、1、6、0、7、4、9、3。每个人按照这个顺序一一"阵亡"。

瑞德(Red):(感叹)真是精妙的设计。这游戏不仅考验智力,还考验心理承受能力。

安迪(Andy):(微笑)是啊,瑞德。在这肖申克的院子里,我们总能找到各种方式来打发时间,甚至在"阵亡"中找到乐趣。

瑞德(Red):(大笑)安迪,你总是能用最乐观的心态来看待一切。来,我们再去看看他们怎么玩下一个轮次吧!

旁白:在肖申克的高墙之内,这群囚犯用"约瑟夫游戏"找到了一丝丝生活的乐趣。而安迪和瑞德,也在这游戏中,找到了彼此间的默契与友谊。这就是肖申克的故事,一个关于希望与自由的故事。

程序所有代码如下:

复制代码
// 约瑟夫问题模拟算法可视化程序,本程序需C++精灵库V1.0.3。
// 下面拟有10个人,报到3的出队,索引从0开始,从它开始报数。
#include "sprites.h"  //包含C++精灵库 
using namespace std;
Screen screen;
int main(){        //主功能块 
   screen.bgcolor("black");   
   //bubble0.png是红色的圆圈,上面有0,这些圆圈是用另一个程序生成的,如果没有,请自行生成
   //bubble1.png是橙色的圆圈,上面有1,其它依次类推,圆形颜色的色相相隔36。
   vector<string>shapes = {"res/bubble0.png","res/bubble1.png","res/bubble2.png","res/bubble3.png","res/bubble4.png","res/bubble5.png","res/bubble6.png","res/bubble7.png","res/bubble8.png","res/bubble9.png"};
   vector<Sprite*> persons;
   for(int i=0;i<10;i++){   //生成10个角色,用不同颜色的圆圈代替
       Sprite* j = new Sprite(shapes[i]);
       j->setheading(360-i*36+90);  j->penup();
       j->fd(160);j->setflag("alive");j->seth(0);
       persons.push_back(j);
   }   
   Sprite bao{"blank"};                 //在最上面写报数的数字的1,2,3的
   bao.penup().sety(330).color("red");
   Sprite pen{"blank"};                 //无造型的角色,用于报告谁出队了
   pen.penup().sety(250).color("magenta");
   
   //新建箭头造型的角色ptr
   Sprite ptr{"res/pointer_blue.png"}; //在中间的蓝色的指示器,谁报到3了,就会出队,先把角色变成透明效果来表示
   ptr.seth(90);                      //初始方向指向0号角色(红色的上面写0的圆圈)
   bool diedflag[10]={false};      //描述是否出队的布尔数组
   int baoshu= 0;   //报数器
   int cntdied = 0;  //统计出队的人数
   vector<int> seq;        //保存出队顺序
   while(cntdied<10){
       for(int i=0;i<10;i++){          
          if(diedflag[i]==true)continue; //此人已死,下一个
          baoshu++;            
          ptr.setheading(360-i*36+90);
          bao.cleartxts(1).write(to_string(baoshu),40); //最上面显示1,2,3
          delay(1);
          if(baoshu==3){          
             seq.push_back(i);
             persons[i]->setalpha(50);  //透明,表示已死
             string s = "编号" + to_string(i) +"已死";
             pen.cleartxts(1).write(s,33).wait(1);
             diedflag[i]=true; baoshu=0;  cntdied++; //死亡人数增加1
             pen.cleartxts(1);
          }
       }
   }
   bao.cleartxts(1).write("出队序列",40);
   //最终出队顺序是2 5 8 1 6 0 7 4 9 3  ,下面可视化的显示这个序列 
   for(int i=0;i<10;i++){
      persons[seq[i]]->stamp();   //在原位置盖图章
      persons[seq[i]]->setalpha(255);        //恢复alpha通道为255
      persons[seq[i]]->go(-200 + i*50,250);  //定位到上面去排成一行,从而可视化显示出队序列
   } 
   screen.done();     //完成了
   return 0;    //返回0
}