Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include<bits/stdc++.h>
- #include <conio.h>
- #include<windows.h>
- #define a first
- #define b second
- #define mp make_pair
- /// cksh.h
- void SetColor(int f,int b)
- {SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),b*16+f);}
- void gotoxy(int xpos, int ypos)
- {
- COORD scrn;
- HANDLE hOuput = GetStdHandle(STD_OUTPUT_HANDLE);
- scrn.X = ypos,scrn.Y = xpos;
- SetConsoleCursorPosition(hOuput,scrn);
- }
- void show()
- {
- HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_CURSOR_INFO cci;
- cci.bVisible = TRUE,cci.dwSize = 25;
- SetConsoleCursorInfo(hcon, &cci);
- }
- void hide()
- {
- HANDLE hcon = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_CURSOR_INFO cci;
- cci.bVisible = FALSE,cci.dwSize = 25;
- SetConsoleCursorInfo(hcon, &cci);
- }
- void clrscr()
- { system("CLS");}
- int getkey()
- {
- int ch=getch();
- if(ch==224)
- {
- ch=getch();
- //if(ch==27)//ESC
- if(ch==72)return 0; //up
- if(ch==75)return 1; //left
- if(ch==77)return 2; //right
- if(ch==80)return 3; //down
- }
- return -1;
- }
- /// PIC_MAKER
- using namespace std;
- typedef pair<int,int> PII;
- const char U=' ',V='#';
- const int HMAX=10000,WMAX=5000;
- int CURL=6;///5(very) ~ 10(low)
- int base=5,range=20; ///for pace
- const int BCOL=15; ///地板顏色
- const int WCOL=4; ///牆壁顏色
- const int SCOL=10; ///自己顏色
- const int MCOL=2; ///moving wall顏色
- const int TOP=1; ///地圖從第幾行開始印
- const int BLANK=2; ///間距
- const int INF=100000000,m[4][2]={{-1,0},{0,-1},{0,1},{1,0}}; ///上 左 右 下
- int H=23,W=39;
- int pit_base=1,pit_range=1; ///最少幾個洞,範圍
- int pc_speed=80; ///電腦移速,越大越快
- char p[HMAX][WMAX];
- deque<int> way;
- class MAZE
- {
- public:
- void solve()
- {
- way.clear();
- for(int i=0;i<H;i++)for(int j=0;j<W;j++)step[i][j]=INF;
- PII A=mp(1,1),B;
- step[1][1]=0;
- from[1][1]=0;
- Q.push_back(A);
- while(!Q.empty())
- {
- A=Q.front();Q.pop_front();
- for(int i=0;i<4;i++)
- {
- B=mp(A.a+m[i][0],A.b+m[i][1]);
- if(p[B.a][B.b]==V)continue;
- if(step[A.a][A.b]+1>=step[B.a][B.b])continue;
- from[B.a][B.b]=i;
- step[B.a][B.b]=step[A.a][A.b]+1;
- Q.push_back(B);
- }
- }
- PII now=mp(H-2,W-2);
- while(!(now.a==1&&now.b==1))
- {
- way.push_front(from[now.a][now.b]);
- int w=3-from[now.a][now.b];
- now.a+=m[w][0];
- now.b+=m[w][1];
- }
- way.push_front(2);
- way.push_back(2);
- }
- void make_pic()
- {
- pre(),Build();
- while(check())reBuild(),Build();
- }
- void put()
- {
- for(int i=0;i<H;i++)
- {
- for(int j=0;j<W;j++)
- printf("%c",p[i][j]);puts("");
- }
- }
- void dig_hole()
- {
- int pit=pit_base+rand()%pit_range;
- vector<PII> vd;
- for(int i=1;i<H-1;i++)
- for(int j=1;j<W-1;j++)
- if(p[i][j]==V)vd.push_back(mp(i,j));
- while(pit-- && vd.size())
- {
- int q=rand()%(vd.size());
- PII now=vd[q];
- vd.erase(vd.begin()+q,vd.begin()+q+1);
- if(N_dig_hole(now))pit++;
- else p[now.a][now.b]=U;
- }
- }
- private:
- int step[HMAX][WMAX];
- int from[HMAX][WMAX];
- deque<PII> Q;
- vector<PII> v; /// what need to do
- PII st,en;
- void pre()
- {
- st=mp(1,0),en=mp(H-2,W-1);
- for(int i=0;i<H;i++)for(int j=0;j<W;j++)p[i][j]=U;
- for(int i=0;i<W;i++)p[0][i]=p[H-1][i]=V;
- for(int j=0;j<H;j++)p[j][0]=p[j][W-1]=V;
- p[st.a][st.b]=U,p[en.a][en.b]=U;
- p[0][0]=U,p[0][W-1]=U,p[H-1][0]=U,p[H-1][W-1]=U;
- for(int i=0;i<H;i++)
- for(int j=0;j<W;j++)
- if(i%2==0 && j%2==0 && p[i][j]==V)v.push_back(mp(i,j));
- p[0][0]=V,p[0][W-1]=V,p[H-1][0]=V,p[H-1][W-1]=V;
- }
- bool CAN_GO(PII now,int dir)
- {
- int x=now.a+m[dir][0]*2,y=now.b+m[dir][1]*2;
- if(m[dir][0]==0)return (p[x][y]!=V && p[x-1][y]!=V && p[x+1][y]!=V);
- return (p[x][y]!=V && p[x][y-1]!=V && p[x][y+1]!=V);
- }
- bool check()
- {
- for(int i=1;i<H-1;i++)
- for(int j=1;j<W-1;j++)
- if(p[i][j]==U && p[i-1][j]==U && p[i][j-1]==U && p[i-1][j-1]==U)return 1;
- return 0;
- }
- void reBuild()
- {
- for(int i=1;i<H-1;i++)
- for(int j=1;j<W-1;j++)
- if(i%2==0 && j%2==0 && p[i][j]==V )v.push_back(mp(i,j));
- }
- void Build() /// 都是偶數可以轉彎
- {
- srand(time(NULL));
- while(v.size())
- {
- int q=rand()%((int)v.size()),dir,pace;
- PII now=v[q];
- v.erase(v.begin()+q,v.begin()+q+1);
- if(now.a==0)dir=3;
- else if(now.b==0)dir=2;
- else if(now.a==H-1)dir=0;
- else if(now.b==W-1)dir=1;
- else dir=rand()%4;
- pace=rand()%range+base;
- while(pace--)
- {
- if(CAN_GO(now,dir)==0)
- {
- if(now.a%2==1 || now.b%2==1)break;
- if((dir+1)%4!=3-dir && CAN_GO(now,(dir+1)%4))dir=(dir+1)%4;
- else if((dir+2)%4!=3-dir && CAN_GO(now,(dir+2)%4))dir=(dir+2)%4;
- else if((dir+3)%4!=3-dir && CAN_GO(now,(dir+3)%4))dir=(dir+3)%4;
- else break;
- }
- now.a+=m[dir][0],now.b+=m[dir][1],p[now.a][now.b]=V;
- if(!(now.a%2 || now.b%2))
- {
- int x=rand()%CURL;
- if(x==0)dir=(dir+1)%4;
- else if(x==1)dir=(dir+3)%4;
- }
- }
- }
- }
- bool N_dig_hole(PII k)
- {
- 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;
- 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;
- 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;
- 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;
- return 0;
- }
- };
- ///以下為重要宣告=============================================
- MAZE maze;
- ///以下為小工具系列===========================================
- void init()
- {
- maze.make_pic();
- maze.dig_hole();
- // maze.solve();
- }
- bool inside(int x,int y)
- {
- if(x<0||x>=H)return false;
- if(y<0||y>=W)return false;
- return true;
- }
- void print_box(int x, int y,int col)
- {
- SetColor(0,col);
- gotoxy(x+TOP,y*2);
- printf(" ");
- SetColor(15,0);
- }
- void show_bar()
- {
- printf("===================================爆肝迷宮===================================\n");
- }
- void show_maze()
- {
- for(int i=0;i<H;i++)
- {
- for(int j=0;j<W;j++)
- {
- if(p[i][j]==U)print_box(i,j,BCOL);
- if(p[i][j]==V)print_box(i,j,WCOL);
- }
- printf("\n");
- }
- SetColor(15,0);
- }
- void show_info(int s)
- {
- gotoxy(H+TOP,0);
- printf("使用步數: %d",s);
- }
- void setHW(int _a,int _b,int _M)
- {
- H=rand()%_M+_a,W=rand()%_M+_b;
- if(!(H%2))H++;
- if(!(W%2))W++;
- }
- int decide(int x,int y,int w)
- {
- vector<int> v;
- int xx,yy;
- for(int i=0;i<4;i++)
- {
- xx=x+m[i][0],yy=y+m[i][1];
- if(p[xx][yy]==U)v.push_back(i);
- }
- xx=x+m[w][0],yy=y+m[w][1];
- if(p[xx][yy]==U)return w;
- if(v.size()==1)return v[0];
- int z=rand()%v.size();
- z=v[z];
- v.clear();
- vector<int>().swap(v);
- return z;
- }
- void finish_game(int winner)
- {
- clrscr();
- show_bar();
- }
- ///以下為遊戲模式系列===========================================
- void user_play()
- {
- int nx=TOP,ny=0,s=0;
- hide();
- clrscr();
- show_bar();
- show_maze();
- show_info(s);
- print_box(nx,ny,SCOL);
- while(!(nx==(H-2)&&ny==(W-1)))
- {
- if(kbhit())
- {
- int w=getkey();
- if(w==-1)return;
- if(p[nx+m[w][0]][ny+m[w][1]]==U)
- {
- print_box(nx,ny,BCOL);
- nx+=m[w][0],ny+=m[w][1];
- print_box(nx,ny,SCOL);
- show_info(++s);
- }
- }
- }
- gotoxy(H+1,0);
- printf("YOU WIN\n");
- }
- void pc_play()
- {
- int nx=1,ny=0,s=0;
- maze.solve();
- hide();
- clrscr();
- show_bar();
- show_maze();
- show_info(s);
- print_box(nx,ny,SCOL);
- while(!(nx==(H-2)&&ny==(W-1)))
- {
- Sleep(200-pc_speed*2);
- int w=way.front();way.pop_front();
- print_box(nx,ny,BCOL);
- nx+=m[w][0],ny+=m[w][1];
- print_box(nx,ny,SCOL);
- show_info(++s);
- SetColor(15,0);
- }
- gotoxy(H+1,0);
- printf("YOU WIN\n");
- }
- void user_vs_pc()
- {
- int nx=1,ny=0,mx=H-2,my=W-1;
- maze.solve();
- hide();
- clrscr();
- show_bar();
- show_maze();
- print_box(nx,ny,SCOL);
- print_box(mx,my,MCOL);
- while(true)
- {
- int z=-1;
- if(nx==(H-2)&&ny==(W-1))break;
- if(mx==1&&my==0)break;
- if(kbhit())
- {
- int w=getkey();
- if(w==-1)return;
- if(p[nx+m[w][0]][ny+m[w][1]]==U)
- {
- print_box(mx,my,BCOL);
- int z=3-way.back();way.pop_back();
- mx+=m[z][0],my+=m[z][1];
- print_box(mx,my,MCOL);
- print_box(nx,ny,BCOL);
- nx+=m[w][0],ny+=m[w][1];
- print_box(nx,ny,SCOL);
- }
- }
- }
- }
- void random_go()
- {
- int nx=1,ny=0,mx=H-2,my=W-2,z;
- hide();
- clrscr();
- show_bar();
- show_maze();
- print_box(nx,ny,SCOL);
- print_box(mx,my,MCOL);
- while(true)
- {
- if(nx==(H-2)&&ny==(W-1))break;
- if(kbhit())
- {
- int w=getkey();
- if(w==-1)return;
- if(p[nx+m[w][0]][ny+m[w][1]]==U)
- {
- print_box(mx,my,BCOL);
- z=decide(mx,my,z);
- mx+=m[z][0],my+=m[z][1];
- print_box(mx,my,MCOL);
- print_box(nx,ny,BCOL);
- nx+=m[w][0],ny+=m[w][1];
- print_box(nx,ny,SCOL);
- }
- }
- }
- }
- ///以下為選單系列===========================================
- void settings()
- {
- while(true)
- {
- int chs,n;
- clrscr();
- printf("\n\t----> BY SETTING\n\n");
- printf("\t\t選擇調整以下選項:\n");
- printf("\t\t 1. 高度(%d)\n",H);
- printf("\t\t 2. 寬度(%d)\n",W);
- printf("\t\t 3. 解數(%d)\n",pit_base+1);
- printf("\t\t 4. 電腦移動速度(%d)\n",pc_speed);
- printf("\t\t 5. 返回\n");
- printf("\n\t\t\tType What You Need:");
- scanf("%d",&chs);
- printf("\t\t\t\t\t");
- if(chs==1)
- {
- do
- {
- printf("->");
- scanf("%d",&n);
- if(n%2==0)printf("輸入必須為奇數!!!\n");
- else if(n<7)printf("輸入最小值為7\n");
- else {H=n;break;}
- }while(true);
- }
- if(chs==2)
- {
- do
- {
- printf("->");
- scanf("%d",&n);
- if(n%2==0)printf("輸入必須為奇數!!!\n");
- else if(n<7)printf("輸入最小值為7\n");
- else {W=n;break;}
- }while(true);
- }
- if(chs==3)
- {
- do
- {
- printf("->");
- scanf("%d",&n);
- if(n<1)printf("迷宮至少要有一個解\n");
- else {pit_base=n-1;break;}
- }while(true);
- }
- if(chs==4)
- {
- do
- {
- printf("->");
- scanf("%d",&n);
- if(n<1||n>100)printf("輸入必須在1~100之內\n");
- else {pc_speed=n;break;}
- }while(true);
- }
- if(chs==5)return;
- }
- }
- void grade_set()
- {
- int G;
- puts("\n\n\t想改變遊戲的難度嗎?\n\t\t想在迷宮中脫穎而出嗎?\n\t\t\t想知道??是什麼意思嗎?");
- printf("\n\t\t 1.佑而猿 2.泰鹼擔 3.游典南 4.鍾登難 5.珍難受");
- printf("\n\t\t Type What You Need: ");
- scanf("%d",&G);
- if(G==1) /// 幼兒園
- {
- setHW(8,10,6);
- base=range=pit_range=pit_base=CURL=H*100;
- }
- else if(G==2)
- {
- setHW(6,14,6);
- base=range=10000,pit_range=pit_base=5,CURL=15;
- }
- else if(G==3)
- {
- setHW(16,18,6);
- base=range=55,pit_range=pit_base=2,CURL=20;
- }
- else if(G==4)
- {
- setHW(21,23,6);
- base=range=35,pit_range=pit_base=1,CURL=4;
- }
- else if(G==5)
- {
- setHW(25,40,2);
- base=range=5,pit_range=pit_base=1,CURL=-1;
- }
- }
- void menu()
- {
- init();
- while(true)
- {
- show();
- clrscr();
- int chs;
- show_bar();
- printf("\t0. <RE S ET> 迷宮重置\n");
- printf("\t1. <U S E R> 鍵盤走迷宮\n");
- printf("\t2. < P C > 電腦走迷宮\n");
- printf("\t3. < FIGHT > 跟聰明的電腦打\n");
- printf("\t4. < CRAZY > 跟沒腦袋的電腦打\n");
- printf("\t5. <SETTING> 設定\n");
- printf("\t6. < ? ? > 等級調整\n");
- printf("\n\t\t Type What You Need: ");
- scanf("%d",&chs);
- if(chs==0)init();
- if(chs==1)user_play();
- if(chs==2)pc_play();
- if(chs==3)user_vs_pc();
- if(chs==4)random_go();
- if(chs==5)settings(),init();
- if(chs==6)grade_set(),init();
- }
- }
- int main()
- {
- menu();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement