C语言走迷宫游戏(非随机地图)

制作地图,需要先了解二维数组

1.二维数组的输出

#include<stdio.h>
#define N 3
int main()
{
    int s[N][N] = { 1,2,3,4,5,6,7,8,9 },i;
    for (i = 0; i < N; i++)
    {
        for (int j = 0; j< N; j++)
        {
            printf("%d\t", s[i][j]);
        }
        printf("\n");
    }


    return 0;
}

2.二维数组主对角线元素求和

#include<stdio.h>
#define N 3
int main()
{
        int s[N][N] = { 1,2,3,4,5,6,7,8,9 }, i,s1=0;
        for (i = 0; i < N; i++)
        {
        for (int j = 0; j < N; j++)
        {
            if (i == j)
                s1 += s[i][j];
        }
        }
             printf("%d", s1);


            return 0;
}

3.数组转置

#include<stdio.h>
int main()
{
    int a[2][3] = { 1,2,3,4,5,6 },b[3][2], i,j;
    printf("转置前:\n");
    for (i = 0; i < 2; i++)
    {
        for (j = 0; j < 3; j++)
        {
            printf("%d\t", a[i][j]);
        }
        printf("\n");
    }
    printf("\n");
    printf("转置后: \n");
    for (i = 0; i <2 ; i++)
    {
        
        for (j=0;j<3 ;j++ )
        {
            b[j][i] = a[i][j];
            
        
        }
    }
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 2; j++)
        {
            printf("%d\t", b[i][j]);
        }
        printf("\n");
    }
    return 0;
}

4.求最大元素值的行标和列标

#include<stdio.h>

int main()
{
    int s[3][4] = { 1,2,3,4,9,8,7,6,-10,10,-5,2 };
     int max = s[0][0],H=0,L=0;
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            if (s[i][j] > max)
            {
                max = s[i][j];
                H = i;
                L = j;
            }
                
        }
    }printf("max=%d\nH=%d\tL=%d\n",max,H,L);
    return 0;
}

编写走迷宫代码前需要了解:

一、GetStdHandle(STD_OUTPUT_HANDLE)用于** 获取标准输出设备的句柄** ,通常在Windows操作系统中,这个设备是控制台窗口。使用GetStdHandle函数时,

需要包含windows.h头文件,并且在调用该函数时传入预定义的常量STD_OUTPUT_HANDLE作为参数。函数执行后会返回一个句柄(HANDLE类型),这个句柄代表了当前进程的标准输出设备,

即控制台窗口。通过这个句柄,可以对控制台窗口进行一系列的操作,如设置光标位置改变文本颜色等。具体如下:

    • *包含头文件 :在程序的开头包含windows.h头文件,以便使用GetStdHandle函数和相关的数据类型及常量。
    • *获取句柄 :使用GetStdHandle函数并传入STD_OUTPUT_HANDLE作为参数,以获取标准输出设备的句柄。
    • *使用句柄 :获取到句柄后,可以使用SetConsoleCursorPosition等其他Windows API函数来操作控制台窗口。例如,可以设置光标的位置,改变输出文本的颜色或格式等。

二、COORD是一个结构体,用于表示控制台中的一个坐标位置。

在Windows编程中,COORD结构体通过包含windows.h头文件来使用,它定义了控制台输出的位置。这个结构体包含两个成员:X和Y,分别代表光标在控制台窗口中的横纵坐标位置。

具体来说,可以通过以下步骤来设置和使用COORD结构体:

  1. 包含头文件:在使用COORD之前,需要包含windows.h头文件。
  2. 设置句柄:通过GetStdHandle函数获取到标准输出设备的句柄。
  3. 设置坐标:创建一个COORD变量,并设置其X和Y值来指定光标位置。
  4. 应用设置:调用SetConsoleCursorPosition函数,传入句柄和COORD结构体来移动光标。

此外,在R语言中,coord系列函数用于改变图形的坐标系统,例如coord_cartesian、coord_polar等,这些函数只影响图形的展示效果,而不影响实际的数据值。

三、/SetConsoleCursorPosition是一个Windows API函数,它的主要作用是在控制台窗口中设置光标的位置。这个函数接收两个参数:第一个参数是控制台屏幕缓冲区的句柄,可以通过GetStdHandle函数获取;第二个参数是一个COORD结构体变量,其中包含了光标的坐标信息。通过修改这个结构体的X和Y值,即可控制光标在控制台窗口中的具体位置。

1.引入头文件windows.h。

2.调用GetStdHandle(STD_OUTPUT_HANDLE)来获取标准输出设备的句柄。

3.定义一个COORD类型的变量,设定其X和Y成员的值来确定光标的新位置。

4.调用SetConsoleCursorPosition函数,传入上面获得的句柄和COORD变量作为参数。

示例

1.使用GetStdHandle(STD_OUTPUT_HANDLE)函数设置光标位置的示例代码:

#include <windows.h>
#include<stdio.h>
int main()
{
    // 获取标准输出设备的句柄
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

    // 设置光标位置
    COORD pos;
    pos.X = 10; // 横坐标为10
    pos.Y = 5;  // 纵坐标为5
    SetConsoleCursorPosition(hOut, pos);

    // 输出文本
    printf("Hello World!");

    return 0;
}

2.使用GetStdHandle(STD_OUTPUT_HANDLE)函数改变输出文本颜色的示例代码:

#include <windows.h>//#include <windows.h>:包含了Windows操作系统的头文件,其中定义了一些系统函数和常量。
#include<stdio.h>//
int main()
{
    // 获取标准输出设备的句柄
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//声明一个名为hOut的句柄变量,用于表示标准输出设备的句柄.GetStdHandle函数用于获取标准输出设备的句柄。

    // 设置文本颜色为红色
    WORD color = FOREGROUND_RED | FOREGROUND_INTENSITY;//定义一个WORD类型的变量color,存储了要设置的文本颜色。其中,FOREGROUND_RED表示红色,FOREGROUND_INTENSITY表示高亮度。
    SetConsoleTextAttribute(hOut, color);//调用SetConsoleTextAttribute函数,将标准输出设备的文本颜色设置为红色。

    // 输出文本
    printf("Hello World!");

    return 0;
}

3.使用SetConsoleCursorPosition(hWnd,pos)将光标移动到控制台窗口的(5,6)位置的示例代码:

#include <windows.h>
#include<stdio.h>
int main() {
    // 获取控制台屏幕缓冲区的句柄
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

    // 定义COORD结构体变量并设置X和Y的值
    COORD pos;
    pos.X = 5;
    pos.Y = 6;

    // 调用SetConsoleCursorPosition函数移动光标
    SetConsoleCursorPosition(hOut, pos);
    printf("hello world");
    return 0;
}

将走迷宫代码板块化

1.绘制地图和定义打印地图函数

char map[HIGHT][WIDE] = { "kA*********",
                          "***AAA*AAA*",
                          "AAA**A****A",
                          "*A**AAA*AA*",
                          "***********",
                          "AAAAA*AA*AA",
                          "**A****AA*A",
                          "***A*AA***A",
                          "*A******A*P" };
void drawmap()
{
    for (int i = 0; i < 9; i++)
    {
        WORD color = FOREGROUND_BLUE | FOREGROUND_INTENSITY;//地图颜色修改:蓝色
        SetConsoleTextAttribute(hOut, color);
        puts(map[i]);
    }

}

2.定义函数,光标移动

void moveCursor(int x, int y) {
    Pos.X = x;
    Pos.Y = y;
    SetConsoleCursorPosition(hOut, Pos);
}

3.主函数部分(包含游戏主体循环)

int main()
{
    
    drawmap();//调用函数,打印出地图
    moveCursor(0, 0);//调用函数,用于更新光标的位置
   //游戏循环主体
    while (1)//死循环,直到找到出口后才跳出循环
    {
        
        char input = _getch();

        switch (input)
        {
        case 'w':
            if (Pos.Y>0&&map[Pos.Y-1 ][Pos.X ] != 'A')//判断光标是否具有移动的条件,不能穿过墙和地图边界
            {
                moveCursor(Pos.X,Pos.Y-1);
            }
            break;

        case 's':
            if (Pos.Y<HIGHT-1&&map[Pos.Y +1][Pos.X] != 'A')
            {
              
                moveCursor(Pos.X, Pos.Y +1);
              
            }
            break;
        case 'a':
            if (Pos.X >0&&map[Pos.Y][Pos.X-1] != 'A')
            {
               
                moveCursor(Pos.X-1, Pos.Y);
              
            }
            break;
        case 'd':
            if (Pos.X <WIDE-2&&map[Pos.Y][Pos.X+1] != 'A')
            {
                
                moveCursor(Pos.X+1, Pos.Y);
               
            }
            break;
        }
        if (map[Pos.Y][Pos.X ]=='P')
            break;
    }
    system("cls");
    WORD color = FOREGROUND_RED | FOREGROUND_INTENSITY;//字体颜色修改:红色
    SetConsoleTextAttribute(hOut, color);
    printf("成功!!");

    return 0;
}

4.结合上述环节,写出走迷宫代码(无计时器)(人物未可视化)(未加入操作说明)

#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<stdlib.h>
#define HIGHT 9
#define WIDE 12
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//初始化控制台窗口句柄
COORD Pos;//存储光标在控制台窗口中的位置。
//绘制地图(A为墙  *为可移动区域)
char map[HIGHT][WIDE] = { "kA*********",
                          "***AAA*AAA*",
                          "AAA**A****A",
                          "*A**AAA*AA*",
                          "***********",
                          "AAAAA*AA*AA",
                          "**A****AA*A",
                          "***A*AA***A",
                          "*A******A*P" };

//定义函数,功能:打印地图
void drawmap()
{
    for (int i = 0; i < 9; i++)
    {
        WORD color = FOREGROUND_BLUE | FOREGROUND_INTENSITY;//地图颜色修改:蓝色
        SetConsoleTextAttribute(hOut, color);
        puts(map[i]);
    }

}




//定义函数,功能:移动光标
void moveCursor(int x, int y) {
    Pos.X = x;
    Pos.Y = y;
    SetConsoleCursorPosition(hOut, Pos);
}



int main()
{
    
    drawmap();//调用函数,打印出地图
    moveCursor(0, 0);//调用函数,用于更新光标的位置
   //游戏循环主体
    while (1)//死循环,直到找到出口后才跳出循环
    {
        
        char input = _getch();

        switch (input)
        {
        case 'w':
            if (Pos.Y>0&&map[Pos.Y-1 ][Pos.X ] != 'A')//判断光标是否具有移动的条件,不能穿过墙和地图边界
            {
                moveCursor(Pos.X,Pos.Y-1);
            }
            break;

        case 's':
            if (Pos.Y<HIGHT-1&&map[Pos.Y +1][Pos.X] != 'A')
            {
              
                moveCursor(Pos.X, Pos.Y +1);
              
            }
            break;
        case 'a':
            if (Pos.X >0&&map[Pos.Y][Pos.X-1] != 'A')
            {
               
                moveCursor(Pos.X-1, Pos.Y);
              
            }
            break;
        case 'd':
            if (Pos.X <WIDE-2&&map[Pos.Y][Pos.X+1] != 'A')
            {
                
                moveCursor(Pos.X+1, Pos.Y);
               
            }
            break;
        }
        if (map[Pos.Y][Pos.X ]=='P')
            break;
    }
    system("cls");
    WORD color = FOREGROUND_RED | FOREGROUND_INTENSITY;//字体颜色修改:红色
    SetConsoleTextAttribute(hOut, color);
    printf("成功!!");

    return 0;
}

扩展:人物可视化、加入操作说明、(加入计时器------>需要新增头文件 #include)

#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<stdlib.h>
#include<time.h>
#define HIGHT 9
#define WIDE 12
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
COORD Pos;//初始化控制台窗口句柄
//存储光标在控制台窗口中的位置。
//绘制地图(A为墙  *为可移动区域)
char map[HIGHT][WIDE] = { "kA*********",
                          "***AAA*AAA*",
                          "AAA**A****A",
                          "*A**AAA*AA*",
                          "***********",
                          "AAAAA*AA*AA",
                          "**A****AA*A",
                          "***A*AA***A",
                          "*A******A*P" };

//定义函数,功能:打印地图
void drawmap()
{
    for (int i = 0; i < 9; i++)
    {
        WORD color = FOREGROUND_BLUE | FOREGROUND_INTENSITY;//地图颜色修改:蓝色
        SetConsoleTextAttribute(hOut, color);
        puts(map[i]);
    }

}




//定义函数,功能:移动光标
void moveCursor(int x, int y) {
    Pos.X = x;
    Pos.Y = y;
    SetConsoleCursorPosition(hOut, Pos);
    WORD color = FOREGROUND_RED | FOREGROUND_INTENSITY;
    SetConsoleTextAttribute(hOut, color);
    printf("k");
}
void moveCursor1(int x, int y) 
 {
    Pos.X = x;
    Pos.Y = y;
    SetConsoleCursorPosition(hOut, Pos);
    WORD color = FOREGROUND_BLUE | FOREGROUND_INTENSITY;
    SetConsoleTextAttribute(hOut, color);
    printf("*");
  }


int main()
{
    
    drawmap();//调用函数,打印出地图
    printf("\n");
    printf("\n");
    printf("\n");
    WORD color1 = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
    SetConsoleTextAttribute(hOut, color1);
    printf("操作说明:* --通道; A--墙壁; P--终点;  \nA--当前所在位置'a'--left  'd'--right  'w'--up  's'--down");
    moveCursor(0, 0);//调用函数,用于更新光标的位置
   //计时器
    clock_t startTime=0, endTime;
    double elapsedTime;
    //游戏循环主体
    while (1)//死循环,直到找到出口后才跳出循环
    {

        char input = _getch();

        switch (input)
        {
        case 'w':
            if (Pos.Y > 0 && map[Pos.Y - 1][Pos.X] != 'A')//判断光标是否具有移动的条件,不能穿过墙和边界
            {
                moveCursor1(Pos.X, Pos.Y);
                moveCursor(Pos.X, Pos.Y - 1);
            }
            break;

        case 's':
            if (Pos.Y < HIGHT - 1 && map[Pos.Y + 1][Pos.X] != 'A')
            {
                moveCursor1(Pos.X, Pos.Y);
                moveCursor(Pos.X, Pos.Y + 1);
                

            }
            break;
        case 'a':
            if (Pos.X > 0 && map[Pos.Y][Pos.X - 1] != 'A')
            {
                moveCursor1(Pos.X, Pos.Y);
                moveCursor(Pos.X - 1, Pos.Y);

            }
            break;
        case 'd':
            if (Pos.X < WIDE - 2 && map[Pos.Y][Pos.X + 1] != 'A')
            {
                moveCursor1(Pos.X, Pos.Y);
                moveCursor(Pos.X + 1, Pos.Y);

            }
            break;
        }
        if (map[Pos.Y][Pos.X] == 'P')
            break;
    }
    system("cls");
    endTime = clock();
    elapsedTime = (double)(endTime - startTime) / CLOCKS_PER_SEC;
    WORD color = FOREGROUND_RED | FOREGROUND_INTENSITY;//字体颜色修改:红色
    SetConsoleTextAttribute(hOut, color);
    printf("成功!!用时%f s", elapsedTime);

    return 0;
}

任意迷宫地图转换

使用Photoshop将走迷宫图片转换为字符格式的步骤如下:

打开图片:启动Photoshop软件,然后打开包含迷宫的图片文件。

选择工具:使用选框工具(快捷键M)来框选出迷宫的墙壁部分。

填充颜色:选择油漆桶工具(快捷键G),并设置前景色为黑色(#)。然后在选区内点击以填充墙壁部分。

如果需要填充空地部分,可以更改前景色为白色(.)或其他代表空地的字符,并重复此步骤。

调整字符:如果需要将现有字符转换为与迷宫图中的特定样式相匹配的字符,可以使用文字工具(快捷键T)来输入新字符,

并通过自由变换(快捷键Ctrl + T)调整其大小和位置以匹配原图。

保存结果:完成转换后,可以将文件另存为新名称,以便在C语言程序中使用。

此外,如果迷宫图片中的墙壁和空地颜色对比明显,也可以使用图像处理软件的阈值功能来快速将图片转换为黑白两色,从而简化转换为字符格式的过程。

需要注意的是,以上步骤是基于将迷宫图片简化为黑白两色的情况。如果迷宫图片中有更多的颜色或者更复杂的图案,可能需要更细致的操作来确保转换的准确性。

未使用GetStdHandle(STD_OUTPUT_HANDLE)、SetConsoleCursorPosition(hWnd,pos)和结构体COORD的走迷宫简易代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>

int main()
{
    char map[100][100] = { "AAAAAAAAAA",
                           "A*   A   A",
                           "AAA AA A A",
                           "A A    A A",
                           "A    A A E ",
                           "AAAAAAAAAA" };
    int startx=1, starty=1, endx=9, endy=4;
    
    int x = startx, y = starty;
    while (1)
    {
        if (x == endx && y == endy)
            break;
        for (int i = 0; i < 6; i++)
            puts(map[i]);
        char ch = _getch();
        if (ch == 'w')
        {
            if (map[y - 1][x] != 'A')
            {
                map[y][x] = ' ';
                y--;
                map[y][x] = '*';
            }
        }
        if (ch == 's')
        {
            if (map[y + 1][x] != 'A')
            {
                map[y][x] = ' ';
                y++;
                map[y][x] = '*';
            }
        }
        if (ch == 'a')
        {
            if (map[y][x-1] != 'A')
            {
                map[y][x] = ' ';
                x--;
                map[y][x] = '*';
            }
        }
        if (ch == 'd')
        {
            if (map[y][x+1] != 'A')
            {
                map[y][x] = ' ';
                x++;
                map[y][x] = '*';
            }
        }
        system("cls");
    }
    system("cls");
    printf("成功\n");
    system("pause");
}

  • 25
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值