制作地图,需要先了解二维数组
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结构体:
- 包含头文件:在使用COORD之前,需要包含windows.h头文件。
- 设置句柄:通过GetStdHandle函数获取到标准输出设备的句柄。
- 设置坐标:创建一个COORD变量,并设置其X和Y值来指定光标位置。
- 应用设置:调用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");
}