#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<conio.h>
#include<math.h>
#include<time.h>
#define MaxMapSize 59
#define ViewField 19
#define Beginning_x 1
#define Beginning_y 1
using namespace std;
short sMapSize,sCreatingSize;
double dBreakingRate;
short map[MaxMapSize][MaxMapSize];
short sInvisible[MaxMapSize][MaxMapSize];
short sSelection1 = 0, sSelection2 = 0, sSelection3 = 0;
short sFogMode;
short sLastColor=0;
short i, j, k, l;
struct
{
short x = 1, y = 1;
}
sight;
struct
{
short x, y;
}
Ending;
struct
{
short sDown, sRight;
}Maze[MaxMapSize][MaxMapSize];
short sList[MaxMapSize*MaxMapSize], sAdded[MaxMapSize][MaxMapSize], sVisited[MaxMapSize][MaxMapSize];
short sResult = 0, sJump = 0, sDirection = 0, sTime = 0, sLength = 0;
void HideConsoleCursor(void)
{
CONSOLE_CURSOR_INFO cursor_info = { 1,0 };
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void SetSize(unsigned uCol, unsigned uLine)
{
char cmd[64];
sprintf_s(cmd, "mode con cols=%d lines=%d", uCol, uLine);
system(cmd);
}
void ChangeColor(UINT uBack, UINT uFore)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, uFore + uBack * 0x10);
}
void ColorfulPrint(char cContent , UINT uBack , UINT uFore )
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, uFore + uBack * 0x10);
printf("%c", cContent);
}
void ShowMapSize()
{
printf("\n\t地图大小:");
if (sSelection1 == 0)
{
printf("*");
}
else
{
printf(" ");
}
printf("小 ");
if (sSelection1 == 1)
{
printf("*");
}
else
{
printf(" ");
}
printf("中 ");
if (sSelection1 == 2)
{
printf("*");
}
else
{
printf(" ");
}
printf("大\n\n");
}
void ShowComplexity()
{
printf("\t地图难度:");
if (sSelection2 == 0)
{
printf("*");
}
else
{
printf(" ");
}
printf("易 ");
if (sSelection2 == 1)
{
printf("*");
}
else
{
printf(" ");
}
printf("中 ");
if (sSelection2 == 2)
{
printf("*");
}
else
{
printf(" ");
}
printf("难\n\n");
}
void StartScreen()
{
char cOperation;
ChangeColor(0, 7);
printf("\n\t\t迷宫\n\n\t");
ChangeColor(2, 7);
printf(" ");
ChangeColor(0, 7);
printf(" 地板\n\t");
ChangeColor(8, 7);
printf(" ");
ChangeColor(0, 7);
printf(" 墙壁\n\t");
ChangeColor(5, 7);
printf(" ");
ChangeColor(0, 7);
printf(" 终点(永远在地图右下角)\n\n\t W/w 上\n\tA/a 左 S/s 下 D/d 右\n\n\t空格 确定 \n\tR/r 开启/关闭迷雾模式\n\n\t");
system("pause");
while (1)
{
system("cls");
ShowMapSize();
cOperation = _getch();
if (cOperation == 'A' || cOperation == 'a')
{
sSelection1--;
if (sSelection1 == -1)
{
sSelection1 = 2;
}
}
else if (cOperation == 'D' || cOperation == 'd')
{
sSelection1++;
if (sSelection1 == 3)
{
sSelection1 = 0;
}
}
else if (cOperation == ' ')
{
break;
}
}
switch(sSelection1)
{
case 0:
sMapSize = 19;
sCreatingSize = 9;
break;
case 1:
sMapSize = 39;
sCreatingSize = 19;
break;
case 2:
sMapSize = 59;
sCreatingSize = 29;
break;
}
map[sMapSize - 2][sMapSize - 2] = 2;
Ending.y = sMapSize - 2;
Ending.x = sMapSize - 2;
while (1)
{
system("cls");
ShowMapSize();
ShowComplexity();
cOperation = _getch();
if (cOperation == 'A' || cOperation == 'a')
{
sSelection2--;
if (sSelection2 == -1)
{
sSelection2 = 2;
}
}
else if (cOperation == 'D' || cOperation == 'd')
{
sSelection2++;
if (sSelection2 == 3)
{
sSelection2 = 0;
}
}
else if (cOperation == ' ')
{
break;
}
}
switch (sSelection2)
{
case 0:
dBreakingRate = 0.1;
break;
case 1:
dBreakingRate = 0.05;
break;
case 2:
dBreakingRate = 0.0;
break;
}
while (1)
{
system("cls");
ShowMapSize();
ShowComplexity();
printf("\t迷雾模式:");
if (sSelection3 == 0)
{
printf("*");
}
else
{
printf(" ");
}
printf("关 ");
if (sSelection3 == 1)
{
printf("*");
}
else
{
printf(" ");
}
printf("开\n\n\t");
cOperation = _getch();
if (cOperation == 'A' || cOperation == 'a')
{
sSelection3--;
if (sSelection3 == -1)
{
sSelection3 = 1;
}
}
else if (cOperation == 'D' || cOperation == 'd')
{
sSelection3++;
if (sSelection3 == 2)
{
sSelection3 = 0;
}
}
else if (cOperation == ' ')
{
break;
}
}
if (sSelection3 == 0)
{
sFogMode = 0;
}
else
{
sFogMode = 1;
}
system("pause");
}
void Content()
{
if (i == sight.y && j == sight.x)
{
printf("+ ");
}
else
{
printf(" ");
}
}
void ChangeColorAndShow()
{
if (sInvisible[i][j] == 1)
{
if (sLastColor != 0)
{
ChangeColor(0, 7);
sLastColor = 0;
}
Content();
}
else if (map[i][j] == 0)
{
if (sLastColor != 2)
{
ChangeColor(2, 7);
sLastColor = 2;
}
Content();
}
else if(map[i][j] == 1)
{
if (sLastColor != 8)
{
ChangeColor(8, 7);
sLastColor = 8;
}
Content();
}
else
{
if (sLastColor != 5)
{
ChangeColor(5, 7);
sLastColor = 5;
}
Content();
}
}
void ShowLine()
{
if (sight.x < (ViewField + 1) / 2)
{
ChangeColor(0, 7);
sLastColor = 0;
for (j = sight.x - (ViewField - 1) / 2; j < 0; j++)
{
printf(" ");
}
for (j = 0; j <= sight.x + (ViewField - 1) / 2; j++)
{
ChangeColorAndShow();
}
}
else
{
for (j = sight.x - (ViewField - 1) / 2; j < min(sMapSize, sight.x + (ViewField + 1) / 2); j++)
{
ChangeColorAndShow();
}
}
}
void ShowImage()
{
if (sFogMode == 1)
{
for (i = 0; i < sMapSize; i++)
{
for (j = 0; j < sMapSize; j++)
{
sInvisible[i][j] = 1;
}
}
for (double angle = -45; angle <= 45; angle += 0.5)
{
double tanvalue = tan(angle / 180.0 * 3.141593);
for (double delta = (double)sight.y + 0.5; delta < min((double)sight.y + 0.5 + (double)(ViewField + 1) / 2, sMapSize); delta += 0.1)
{
sInvisible[(int)delta][(int)((delta - (double)sight.y - 0.5) * tanvalue + (double)sight.x + 0.5)] = 0;
if (map[(int)delta][(int)((delta - (double)sight.y - 0.5) * tanvalue + (double)sight.x + 0.5)] == 1)
{
break;
}
}
for (double delta = (double)sight.y + 0.5; delta > max((double)sight.y + 0.5 - (double)(ViewField + 1) / 2, 0.0); delta -= 0.1)
{
sInvisible[(int)delta][(int)((delta - (double)sight.y - 0.5) * tanvalue + (double)sight.x + 0.5)] = 0;
if (map[(int)delta][(int)((delta - (double)sight.y - 0.5) * tanvalue + (double)sight.x + 0.5)] == 1)
{
break;
}
}
for (double delta = (double)sight.x + 0.5; delta < min((double)sight.x + 0.5 + (double)(ViewField + 1) / 2, sMapSize); delta += 0.1)
{
sInvisible[(int)((delta - (double)sight.x - 0.5) * tanvalue + (double)sight.y + 0.5)][(int)delta] = 0;
if (map[(int)((delta - (double)sight.x - 0.5) * tanvalue + (double)sight.y + 0.5)][(int)delta] == 1)
{
break;
}
}
for (double delta = (double)sight.x + 0.5; delta > max((double)sight.x + 0.5 - (double)(ViewField + 1) / 2, 0.0); delta -= 0.1)
{
sInvisible[(int)((delta - (double)sight.x - 0.5) * tanvalue + (double)sight.y + 0.5)][(int)delta] = 0;
if (map[(int)((delta - (double)sight.x - 0.5) * tanvalue + (double)sight.y + 0.5)][(int)delta] == 1)
{
break;
}
}
}
}
system("cls");
if (sight.y < (ViewField + 1) / 2)
{
ChangeColor(0, 7);
sLastColor = 0;
for (i = sight.y - (ViewField - 1) / 2; i < 0; i++)
{
printf("\n");
}
for (i = 0; i <= sight.y + (ViewField - 1) / 2; i++)
{
ShowLine();
if (i != sight.y + (ViewField - 1) / 2)
{
printf("\n");
}
}
}
else if (sight.y>=sMapSize-(ViewField+1)/2)
{
for (i = sight.y - (ViewField - 1) / 2; i < sMapSize; i++)
{
ShowLine();
if (i != sMapSize-1)
{
printf("\n");
}
}
}
else
{
for (i = sight.y - (ViewField - 1) / 2; i < sight.y + (ViewField + 1) / 2; i++)
{
ShowLine();
if (i != sight.y + (ViewField - 1) / 2 )
{
printf("\n");
}
}
}
ChangeColor(0, 7);
sLastColor = 0;
Sleep(50);
}
void Operate()
{
char cOperation;
cOperation = _getch();
if ((cOperation == 'w' || cOperation == 'W') && sight.y != 0 && map[sight.y - 1][sight.x] != 1)
{
sight.y--;
}
else if ((cOperation == 'a' || cOperation == 'A') && sight.x != 0 && map[sight.y][sight.x-1] != 1)
{
sight.x--;
}
else if ((cOperation == 's' || cOperation == 'S') && sight.y != sMapSize - 1 && map[sight.y+1][sight.x] != 1)
{
sight.y++;
}
else if ((cOperation == 'd' || cOperation == 'D') && sight.x != sMapSize - 1 && map[sight.y][sight.x+1] != 1)
{
sight.x++;
}
else if (cOperation == 'r' || cOperation == 'R')
{
if (sFogMode == 0)
{
sFogMode = 1;
}
else
{
sFogMode = 0;
for (i = 0; i < sMapSize; i++)
{
for (j = 0; j < sMapSize; j++)
{
sInvisible[i][j] = 0;
}
}
}
}
}
void MCRemoving()
{
sVisited[i][j] = 1;
for (k = 0; k < sLength; k++) {
if (sList[k] / sCreatingSize == i && sList[k] % sCreatingSize == j)
sList[k] = -1;
}
for (k = 0; k < sLength; k++) {
if (sList[k] == -1) {
for (l = k; l < sLength - 1; l++) {
sList[l] = sList[l + 1];
}
sLength--;
}
}
}
void MapCreating()
{
i = Beginning_y;
j = Beginning_x;
sVisited[i][j] = 1;
while (sResult == 0 && sTime < sCreatingSize * sCreatingSize + 1) {
sJump = 0;
if ((i == 0 || sVisited[i - 1][j] == 1) && (i == sCreatingSize - 1 || sVisited[i + 1][j] == 1) && (j == 0 || sVisited[i][j - 1] == 1) && (j == sCreatingSize - 1 || sVisited[i][j + 1] == 1))
sJump = 1;
else {
sDirection = rand() % 4;
while ((sDirection == 0 && (i == 0 || sVisited[i - 1][j] == 1)) || (sDirection == 1 && (i == sCreatingSize - 1 || sVisited[i + 1][j] == 1)) || (sDirection == 2 && (j == 0 || sVisited[i][j - 1] == 1)) || (sDirection == 3 && (j == sCreatingSize - 1 || sVisited[i][j + 1] == 1)))
sDirection = rand() % 4;
}
if (i > 0 && sVisited[i - 1][j] == 0 && sAdded[i - 1][j] == 0) {
sList[sLength] = (i - 1) * sCreatingSize + j;
sAdded[i - 1][j] = 1;
sLength++;
}
if (i < sCreatingSize - 1 && sVisited[i + 1][j] == 0 && sAdded[i + 1][j] == 0) {
sList[sLength] = (i + 1) * sCreatingSize + j;
sAdded[i + 1][j] = 1;
sLength++;
}
if (j > 0 && sVisited[i][j - 1] == 0 && sAdded[i][j - 1] == 0) {
sList[sLength] = i * sCreatingSize + j - 1;
sAdded[i][j - 1] = 1;
sLength++;
}
if (j < sCreatingSize - 1 && sVisited[i][j + 1] == 0 && sAdded[i][j + 1] == 0) {
sList[sLength] = i * sCreatingSize + j + 1;
sAdded[i][j + 1] = 1;
sLength++;
}
if (sJump == 1) {
i = sList[sLength - 1] / sCreatingSize;
j = sList[sLength - 1] % sCreatingSize;
sDirection = rand() % 4;
while ((sDirection == 0 && (i == 0 || sVisited[i - 1][j] == 0)) || (sDirection == 1 && (i == sCreatingSize - 1 || sVisited[i + 1][j] == 0)) || (sDirection == 2 && (j == 0 || sVisited[i][j - 1] == 0)) || (sDirection == 3 && (j == sCreatingSize - 1 || sVisited[i][j + 1] == 0)))
sDirection = rand() % 4;
switch (sDirection) {
case 0:
Maze[i - 1][j].sDown = 1;
break;
case 1:
Maze[i][j].sDown = 1;
break;
case 2:
Maze[i][j - 1].sRight = 1;
break;
case 3:
Maze[i][j].sRight = 1;
break;
}
MCRemoving();
}
else {
switch (sDirection) {
case 0:
i--;
Maze[i][j].sDown = 1;
break;
case 1:
Maze[i][j].sDown = 1;
i++;
break;
case 2:
j--;
Maze[i][j].sRight = 1;
break;
case 3:
Maze[i][j].sRight = 1;
j++;
break;
}
MCRemoving();
sResult = 1;
for (k = 0; k < sCreatingSize; k++) {
for (l = 0; l < sCreatingSize; l++) {
if (sVisited[k][l] == 0) {
sResult = 0;
break;
}
}
}
}
sTime++;
}
for (i = 0; i < (int)(dBreakingRate * (float)sCreatingSize * (float)sCreatingSize);)
{
j = rand() % (sCreatingSize - 1);
k = rand() % (sCreatingSize - 1);
l = rand() % 2;
if (l == 0 && Maze[j][k].sDown == 0)
{
Maze[j][k].sDown = 1;
i++;
}
else if (l == 1 && Maze[j][k].sRight == 0)
{
Maze[j][k].sRight = 1;
i++;
}
}
for (j = 0; j < sMapSize; j++)
{
map[0][j] = 1;
}
for (i = 0; i < sCreatingSize; i++)
{
map[i * 2][0] = 1;
map[i * 2 + 1][0] = 1;
for (j = 0; j < sCreatingSize; j++)
{
if (Maze[i][j].sRight == 0)
{
map[i*2+1][j*2+2] = 1;
}
if (Maze[i][j].sDown == 0)
{
map[i * 2 + 2][j * 2 + 1] = 1;
}
if (i == sCreatingSize - 1|| !(Maze[i][j].sDown == 1 && Maze[i][j].sRight == 1 && Maze[i][j+1].sDown == 1 && Maze[i + 1][j].sRight == 1))
map[i * 2 + 2][j * 2 + 2] = 1;
}
}
map[sCreatingSize * 2][0] = 1;
}
void EndScreen()
{
printf("\n\n\t\t恭喜过关\n\t");
system("pause");
}
int main(void)
{
srand((unsigned)time(NULL));
SetSize(ViewField * 2, ViewField);
SetConsoleTitle(L"迷宫");
HideConsoleCursor();
StartScreen();
MapCreating();
while (sight.y != Ending.y||sight.x!=Ending.x)
{
ShowImage();
Operate();
}
EndScreen();
return 0;
}
|