Advertisement
boook

PRESS ESC IN GAME

Jun 6th, 2016
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.25 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2. #include <conio.h>
  3. #include<windows.h>
  4. #define a first
  5. #define b second
  6. #define mp make_pair
  7. /// cksh.h
  8.  
  9. void SetColor(int f,int b)
  10. {SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),b*16+f);}
  11. void gotoxy(int xpos, int ypos)
  12. {
  13.   COORD scrn;
  14.   HANDLE hOuput = GetStdHandle(STD_OUTPUT_HANDLE);
  15.   scrn.X = ypos,scrn.Y = xpos;
  16.   SetConsoleCursorPosition(hOuput,scrn);
  17. }
  18. void show()
  19. {
  20.   HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
  21.   CONSOLE_CURSOR_INFO cci;
  22.   cci.bVisible = TRUE,cci.dwSize = 25;
  23.   SetConsoleCursorInfo(hcon, &cci);
  24. }
  25. void hide()
  26. {
  27.   HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
  28.   CONSOLE_CURSOR_INFO cci;
  29.   cci.bVisible = FALSE,cci.dwSize = 25;
  30.   SetConsoleCursorInfo(hcon, &cci);
  31. }
  32. void clrscr()
  33. {   system("CLS");}
  34. int getkey()
  35. {
  36.     int ch=getch();
  37.     if(ch==224)
  38.     {
  39.         ch=getch();
  40.         //if(ch==27)//ESC
  41.         if(ch==72)return 0; //up
  42.         if(ch==75)return 1; //left
  43.         if(ch==77)return 2; //right
  44.         if(ch==80)return 3; //down
  45.     }
  46.     return -1;
  47. }
  48. /// PIC_MAKER
  49. using namespace std;
  50. typedef pair<int,int> PII;
  51. const char U=' ',V='#';
  52. const int HMAX=10000,WMAX=5000;
  53. int CURL=6;///5(very) ~ 10(low)
  54. int base=5,range=20; ///for pace
  55. const int BCOL=15; ///地板顏色
  56. const int WCOL=4; ///牆壁顏色
  57. const int SCOL=10; ///自己顏色
  58. const int MCOL=2; ///moving wall顏色
  59. const int TOP=1; ///地圖從第幾行開始印
  60. const int BLANK=2; ///間距
  61. const int INF=100000000,m[4][2]={{-1,0},{0,-1},{0,1},{1,0}}; ///上 左 右 下
  62. int H=23,W=39;
  63. int pit_base=1,pit_range=1; ///最少幾個洞,範圍
  64. int pc_speed=80; ///電腦移速,越大越快
  65. char p[HMAX][WMAX];
  66. deque<int> way;
  67. class MAZE
  68. {
  69.     public:
  70.     void solve()
  71.     {
  72.         way.clear();
  73.         for(int i=0;i<H;i++)for(int j=0;j<W;j++)step[i][j]=INF;
  74.         PII A=mp(1,1),B;
  75.         step[1][1]=0;
  76.         from[1][1]=0;
  77.         Q.push_back(A);
  78.         while(!Q.empty())
  79.         {
  80.             A=Q.front();Q.pop_front();
  81.             for(int i=0;i<4;i++)
  82.             {
  83.                 B=mp(A.a+m[i][0],A.b+m[i][1]);
  84.                 if(p[B.a][B.b]==V)continue;
  85.                 if(step[A.a][A.b]+1>=step[B.a][B.b])continue;
  86.                 from[B.a][B.b]=i;
  87.                 step[B.a][B.b]=step[A.a][A.b]+1;
  88.                 Q.push_back(B);
  89.             }
  90.         }
  91.         PII now=mp(H-2,W-2);
  92.         while(!(now.a==1&&now.b==1))
  93.         {
  94.             way.push_front(from[now.a][now.b]);
  95.             int w=3-from[now.a][now.b];
  96.             now.a+=m[w][0];
  97.             now.b+=m[w][1];
  98.         }
  99.         way.push_front(2);
  100.         way.push_back(2);
  101.     }
  102.     void make_pic()
  103.     {
  104.         pre(),Build();
  105.         while(check())reBuild(),Build();
  106.     }
  107.     void put()
  108.     {
  109.         for(int i=0;i<H;i++)
  110.         {
  111.             for(int j=0;j<W;j++)
  112.                 printf("%c",p[i][j]);puts("");
  113.         }
  114.     }
  115.     void dig_hole()
  116.     {
  117.         int pit=pit_base+rand()%pit_range;
  118.         vector<PII> vd;
  119.         for(int i=1;i<H-1;i++)
  120.             for(int j=1;j<W-1;j++)
  121.                 if(p[i][j]==V)vd.push_back(mp(i,j));
  122.         while(pit-- && vd.size())
  123.         {
  124.             int q=rand()%(vd.size());
  125.             PII now=vd[q];
  126.             vd.erase(vd.begin()+q,vd.begin()+q+1);
  127.             if(N_dig_hole(now))pit++;
  128.             else p[now.a][now.b]=U;
  129.         }
  130.     }
  131.     private:
  132.     int step[HMAX][WMAX];
  133.     int from[HMAX][WMAX];
  134.     deque<PII> Q;
  135.     vector<PII> v; /// what need to do
  136.     PII st,en;
  137.     void pre()
  138.     {
  139.         st=mp(1,0),en=mp(H-2,W-1);
  140.         for(int i=0;i<H;i++)for(int j=0;j<W;j++)p[i][j]=U;
  141.         for(int i=0;i<W;i++)p[0][i]=p[H-1][i]=V;
  142.         for(int j=0;j<H;j++)p[j][0]=p[j][W-1]=V;
  143.         p[st.a][st.b]=U,p[en.a][en.b]=U;
  144.         p[0][0]=U,p[0][W-1]=U,p[H-1][0]=U,p[H-1][W-1]=U;
  145.         for(int i=0;i<H;i++)
  146.             for(int j=0;j<W;j++)
  147.                 if(i%2==0 && j%2==0 && p[i][j]==V)v.push_back(mp(i,j));
  148.         p[0][0]=V,p[0][W-1]=V,p[H-1][0]=V,p[H-1][W-1]=V;
  149.     }
  150.     bool CAN_GO(PII now,int dir)
  151.     {
  152.         int x=now.a+m[dir][0]*2,y=now.b+m[dir][1]*2;
  153.         if(m[dir][0]==0)return (p[x][y]!=V && p[x-1][y]!=V && p[x+1][y]!=V);
  154.         return (p[x][y]!=V && p[x][y-1]!=V && p[x][y+1]!=V);
  155.     }
  156.     bool check()
  157.     {
  158.         for(int i=1;i<H-1;i++)
  159.             for(int j=1;j<W-1;j++)
  160.                 if(p[i][j]==U && p[i-1][j]==U && p[i][j-1]==U && p[i-1][j-1]==U)return 1;
  161.         return 0;
  162.     }
  163.     void reBuild()
  164.     {
  165.         for(int i=1;i<H-1;i++)
  166.             for(int j=1;j<W-1;j++)
  167.                 if(i%2==0 && j%2==0 && p[i][j]==V )v.push_back(mp(i,j));
  168.     }
  169.     void Build()  /// 都是偶數可以轉彎
  170.     {
  171.         srand(time(NULL));
  172.         while(v.size())
  173.         {
  174.             int q=rand()%((int)v.size()),dir,pace;
  175.             PII now=v[q];
  176.             v.erase(v.begin()+q,v.begin()+q+1);
  177.             if(now.a==0)dir=3;
  178.             else if(now.b==0)dir=2;
  179.             else if(now.a==H-1)dir=0;
  180.             else if(now.b==W-1)dir=1;
  181.             else dir=rand()%4;
  182.             pace=rand()%range+base;
  183.             while(pace--)
  184.             {
  185.                 if(CAN_GO(now,dir)==0)
  186.                 {
  187.                     if(now.a%2==1 || now.b%2==1)break;
  188.                     if((dir+1)%4!=3-dir && CAN_GO(now,(dir+1)%4))dir=(dir+1)%4;
  189.                     else if((dir+2)%4!=3-dir && CAN_GO(now,(dir+2)%4))dir=(dir+2)%4;
  190.                     else if((dir+3)%4!=3-dir && CAN_GO(now,(dir+3)%4))dir=(dir+3)%4;
  191.                     else break;
  192.                 }
  193.                 now.a+=m[dir][0],now.b+=m[dir][1],p[now.a][now.b]=V;
  194.                 if(!(now.a%2 || now.b%2))
  195.                 {
  196.                     int x=rand()%CURL;
  197.                     if(x==0)dir=(dir+1)%4;
  198.                     else if(x==1)dir=(dir+3)%4;
  199.                 }
  200.             }
  201.         }
  202.     }
  203.     bool N_dig_hole(PII k)
  204.     {
  205.         if(p[k.a-1][k.b-1]!=V && p[k.a-1][k.b]!=V && p[k.a][k.b-1]!=V)return 1;
  206.         if(p[k.a-1][k.b]!=V && p[k.a][k.b+1]!=V && p[k.a-1][k.b+1]!=V)return 1;
  207.         if(p[k.a+1][k.b]!=V && p[k.a][k.b-1]!=V && p[k.a+1][k.b-1]!=V)return 1;
  208.         if(p[k.a+1][k.b]!=V && p[k.a][k.b+1]!=V && p[k.a+1][k.b+1]!=V)return 1;
  209.         return 0;
  210.     }
  211. };
  212.  
  213. ///以下為重要宣告=============================================
  214.  
  215. MAZE maze;
  216.  
  217. ///以下為小工具系列===========================================
  218. void init()
  219. {
  220.     maze.make_pic();
  221.     maze.dig_hole();
  222. //    maze.solve();
  223. }
  224.  
  225. bool inside(int x,int y)
  226. {
  227.     if(x<0||x>=H)return false;
  228.     if(y<0||y>=W)return false;
  229.     return true;
  230. }
  231.  
  232. void print_box(int x, int y,int col)
  233. {
  234.     SetColor(0,col);
  235.     gotoxy(x+TOP,y*2);
  236.     printf(" ");
  237.     SetColor(15,0);
  238. }
  239.  
  240. void show_bar()
  241. {
  242.     printf("===================================爆肝迷宮===================================\n");
  243. }
  244.  
  245. void show_maze()
  246. {
  247.     for(int i=0;i<H;i++)
  248.     {
  249.         for(int j=0;j<W;j++)
  250.         {
  251.             if(p[i][j]==U)print_box(i,j,BCOL);
  252.             if(p[i][j]==V)print_box(i,j,WCOL);
  253.         }
  254.         printf("\n");
  255.     }
  256.     SetColor(15,0);
  257. }
  258.  
  259. void show_info(int s)
  260. {
  261.     gotoxy(H+TOP,0);
  262.     printf("使用步數: %d",s);
  263. }
  264.  
  265. void setHW(int _a,int _b,int _M)
  266. {
  267.     H=rand()%_M+_a,W=rand()%_M+_b;
  268.     if(!(H%2))H++;
  269.     if(!(W%2))W++;
  270. }
  271.  
  272. int decide(int x,int y,int w)
  273. {
  274.     vector<int> v;
  275.     int xx,yy;
  276.     for(int i=0;i<4;i++)
  277.     {
  278.         xx=x+m[i][0],yy=y+m[i][1];
  279.         if(p[xx][yy]==U)v.push_back(i);
  280.     }
  281.     xx=x+m[w][0],yy=y+m[w][1];
  282.     if(p[xx][yy]==U)return w;
  283.     if(v.size()==1)return v[0];
  284.     int z=rand()%v.size();
  285.     z=v[z];
  286.     v.clear();
  287.     vector<int>().swap(v);
  288.     return z;
  289. }
  290.  
  291. void finish_game(int winner)
  292. {
  293.     clrscr();
  294.     show_bar();
  295. }
  296.  
  297. ///以下為遊戲模式系列===========================================
  298.  
  299. void user_play()
  300. {
  301.     int nx=TOP,ny=0,s=0;
  302.     hide();
  303.     clrscr();
  304.     show_bar();
  305.     show_maze();
  306.     show_info(s);
  307.     print_box(nx,ny,SCOL);
  308.     while(!(nx==(H-2)&&ny==(W-1)))
  309.     {
  310.         if(kbhit())
  311.         {
  312.             int w=getkey();
  313.             if(w==-1)return;
  314.             if(p[nx+m[w][0]][ny+m[w][1]]==U)
  315.             {
  316.                 print_box(nx,ny,BCOL);
  317.                 nx+=m[w][0],ny+=m[w][1];
  318.                 print_box(nx,ny,SCOL);
  319.                 show_info(++s);
  320.             }
  321.         }
  322.     }
  323.     gotoxy(H+1,0);
  324.     printf("YOU WIN\n");
  325. }
  326.  
  327. void pc_play()
  328. {
  329.     int nx=1,ny=0,s=0;
  330.     maze.solve();
  331.     hide();
  332.     clrscr();
  333.     show_bar();
  334.     show_maze();
  335.     show_info(s);
  336.     print_box(nx,ny,SCOL);
  337.     while(!(nx==(H-2)&&ny==(W-1)))
  338.     {
  339.         Sleep(200-pc_speed*2);
  340.         int w=way.front();way.pop_front();
  341.         print_box(nx,ny,BCOL);
  342.         nx+=m[w][0],ny+=m[w][1];
  343.         print_box(nx,ny,SCOL);
  344.         show_info(++s);
  345.         SetColor(15,0);
  346.     }
  347.     gotoxy(H+1,0);
  348.     printf("YOU WIN\n");
  349. }
  350.  
  351. void user_vs_pc()
  352. {
  353.     int nx=1,ny=0,mx=H-2,my=W-1;
  354.     maze.solve();
  355.     hide();
  356.     clrscr();
  357.     show_bar();
  358.     show_maze();
  359.     print_box(nx,ny,SCOL);
  360.     print_box(mx,my,MCOL);
  361.     while(true)
  362.     {
  363.         int z=-1;
  364.         if(nx==(H-2)&&ny==(W-1))break;
  365.         if(mx==1&&my==0)break;
  366.         if(kbhit())
  367.         {
  368.             int w=getkey();
  369.             if(w==-1)return;
  370.             if(p[nx+m[w][0]][ny+m[w][1]]==U)
  371.             {
  372.                 print_box(mx,my,BCOL);
  373.                 int z=3-way.back();way.pop_back();
  374.                 mx+=m[z][0],my+=m[z][1];
  375.                 print_box(mx,my,MCOL);
  376.                 print_box(nx,ny,BCOL);
  377.                 nx+=m[w][0],ny+=m[w][1];
  378.                 print_box(nx,ny,SCOL);
  379.             }
  380.         }
  381.     }
  382. }
  383.  
  384. void random_go()
  385. {
  386.     int nx=1,ny=0,mx=H-2,my=W-2,z;
  387.     hide();
  388.     clrscr();
  389.     show_bar();
  390.     show_maze();
  391.     print_box(nx,ny,SCOL);
  392.     print_box(mx,my,MCOL);
  393.     while(true)
  394.     {
  395.         if(nx==(H-2)&&ny==(W-1))break;
  396.         if(kbhit())
  397.         {
  398.             int w=getkey();
  399.             if(w==-1)return;
  400.             if(p[nx+m[w][0]][ny+m[w][1]]==U)
  401.             {
  402.                 print_box(mx,my,BCOL);
  403.                 z=decide(mx,my,z);
  404.                 mx+=m[z][0],my+=m[z][1];
  405.                 print_box(mx,my,MCOL);
  406.                 print_box(nx,ny,BCOL);
  407.                 nx+=m[w][0],ny+=m[w][1];
  408.                 print_box(nx,ny,SCOL);
  409.             }
  410.         }
  411.     }
  412. }
  413.  
  414. ///以下為選單系列===========================================
  415.  
  416. void settings()
  417. {
  418.     while(true)
  419.     {
  420.         int chs,n;
  421.         clrscr();
  422.         printf("\n\t----> BY SETTING\n\n");
  423.         printf("\t\t選擇調整以下選項:\n");
  424.         printf("\t\t  1. 高度(%d)\n",H);
  425.         printf("\t\t  2. 寬度(%d)\n",W);
  426.         printf("\t\t  3. 解數(%d)\n",pit_base+1);
  427.         printf("\t\t  4. 電腦移動速度(%d)\n",pc_speed);
  428.         printf("\t\t  5. 返回\n");
  429.         printf("\n\t\t\tType What You Need:");
  430.         scanf("%d",&chs);
  431.         printf("\t\t\t\t\t");
  432.         if(chs==1)
  433.         {
  434.             do
  435.             {
  436.                 printf("->");
  437.                 scanf("%d",&n);
  438.                 if(n%2==0)printf("輸入必須為奇數!!!\n");
  439.                 else if(n<7)printf("輸入最小值為7\n");
  440.                 else {H=n;break;}
  441.             }while(true);
  442.         }
  443.         if(chs==2)
  444.         {
  445.             do
  446.             {
  447.                 printf("->");
  448.                 scanf("%d",&n);
  449.                 if(n%2==0)printf("輸入必須為奇數!!!\n");
  450.                 else if(n<7)printf("輸入最小值為7\n");
  451.                 else {W=n;break;}
  452.             }while(true);
  453.         }
  454.         if(chs==3)
  455.         {
  456.             do
  457.             {
  458.                 printf("->");
  459.                 scanf("%d",&n);
  460.                 if(n<1)printf("迷宮至少要有一個解\n");
  461.                 else {pit_base=n-1;break;}
  462.             }while(true);
  463.         }
  464.         if(chs==4)
  465.         {
  466.             do
  467.             {
  468.                 printf("->");
  469.                 scanf("%d",&n);
  470.                 if(n<1||n>100)printf("輸入必須在1~100之內\n");
  471.                 else {pc_speed=n;break;}
  472.             }while(true);
  473.         }
  474.         if(chs==5)return;
  475.     }
  476. }
  477.  
  478. void grade_set()
  479. {
  480.     int G;
  481.     puts("\n\n\t想改變遊戲的難度嗎?\n\t\t想在迷宮中脫穎而出嗎?\n\t\t\t想知道??是什麼意思嗎?");
  482.     printf("\n\t\t  1.佑而猿 2.泰鹼擔 3.游典南 4.鍾登難 5.珍難受");
  483.     printf("\n\t\t   Type What You Need:  ");
  484.     scanf("%d",&G);
  485.     if(G==1) /// 幼兒園
  486.     {
  487.         setHW(8,10,6);
  488.         base=range=pit_range=pit_base=CURL=H*100;
  489.     }
  490.     else if(G==2)
  491.     {
  492.         setHW(6,14,6);
  493.         base=range=10000,pit_range=pit_base=5,CURL=15;
  494.     }
  495.     else if(G==3)
  496.     {
  497.         setHW(16,18,6);
  498.         base=range=55,pit_range=pit_base=2,CURL=20;
  499.     }
  500.     else if(G==4)
  501.     {
  502.         setHW(21,23,6);
  503.         base=range=35,pit_range=pit_base=1,CURL=4;
  504.     }
  505.     else if(G==5)
  506.     {
  507.         setHW(25,40,2);
  508.         base=range=5,pit_range=pit_base=1,CURL=-1;
  509.     }
  510.  
  511. }
  512. void menu()
  513. {
  514.     init();
  515.     while(true)
  516.     {
  517.         show();
  518.         clrscr();
  519.         int chs;
  520.         show_bar();
  521.         printf("\t0. <RE S ET> 迷宮重置\n");
  522.         printf("\t1. <U S E R> 鍵盤走迷宮\n");
  523.         printf("\t2. < P C > 電腦走迷宮\n");
  524.         printf("\t3. < FIGHT > 跟聰明的電腦打\n");
  525.         printf("\t4. < CRAZY > 跟沒腦袋的電腦打\n");
  526.         printf("\t5. <SETTING> 設定\n");
  527.         printf("\t6. < ? ? > 等級調整\n");
  528.         printf("\n\t\t Type What You Need:  ");
  529.         scanf("%d",&chs);
  530.         if(chs==0)init();
  531.         if(chs==1)user_play();
  532.         if(chs==2)pc_play();
  533.         if(chs==3)user_vs_pc();
  534.         if(chs==4)random_go();
  535.         if(chs==5)settings(),init();
  536.         if(chs==6)grade_set(),init();
  537.     }
  538. }
  539.  
  540. int main()
  541. {
  542.     menu();
  543.     return 0;
  544. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement