童年回忆--扫雷(包括标记功能和递归展开)--万字讲解让你学会扫雷制作

news2024/11/18 0:12:35

在这里插入图片描述

  • 魔王的介绍:😶‍🌫️一名双非本科大一小白。
  • 魔王的目标:🤯努力赶上周围卷王的脚步。
  • 魔王的主页:🔥🔥🔥大魔王.🔥🔥🔥
    在这里插入图片描述
    ❤️‍🔥大魔王与你分享:人生人山人海人来人往,自己自尊自爱自由自在。

在这里插入图片描述


文章目录

  • 一、前言
  • 二、文件介绍
  • 三、代码实现
    • 1.创建基本的框架
    • 2.#define定义常量
    • 3.创建和初始化二维数组
    • 4.埋雷
    • 5.打印雷盘
    • 6.玩家标记
    • 7.玩家下棋
  • 四、总代码如下
    • `game.h`
    • `game.c`
    • `test.c`
    • 效果展示图
  • 五、总结

一、前言

小时候我们在家里刚买电脑的时候,网络还不是很发达(两三年纪吧),每次断网我们都除了电脑自带的那一点单机游戏外没什么玩的,其中最好玩的便是扫雷,那么你可以用代码实现扫雷吗?这里我们添加了两个功能:第一个是标记功能,如果确定为雷我们可以标记为!,如果不确定,我们可以标记为?,第二个功能是递归展开:我们知道如果我们我们所点的那个位置一周都不是雷,那么它会自动扩开,如果我们点的地方有雷,那么会显示出周围雷的个数,如果想尝试玩一下,点击扫雷可以跳转过去,那么接下来就学习以下如何代码实现吧!

二、文件介绍

test.c:测试文件
game.c:源文件,进行函数的定义
game.h:头文件(只进行声明)

我们用测试文件调用game.h声明、game.c文件中实现的函数,这就是三个文件的关系。

为了使三者联系起来,我们需要让两个源文件(.c)文件都包含头文件,这样他们中的函数就可以一起使用了。

三、代码实现

1.创建基本的框架

void menu()
{
	printf("************************\n");
	printf("******** 1.play ********\n");
	printf("******** 0.exit ********\n");
	printf("************************\n");
}
void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:> ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}

	} while (input);
	
}

int main()
{
	test();
	return 0;
}

2.#define定义常量

因为我们在点击一个位置后如果附近有雷,那么就需要显示周围有几个雷,所以我们需要访问这个位置一周的内容,所以如果我们创建的表格大小和玩的时候打印出来的一样大,那么当访问边上那些位置周围雷的个数时,就会数组越界,所以我们如果要下99雷盘,我们需要让行和列都宽一个位置,也就是创建1111的雷盘,不过打印的话只打印中间的9*9格。所以为了方便我们先定义常量。

#define ROW 9

#define COL 9

#define ROWS ROW+2

#define COLS COL+2

#define mine_num 10

3.创建和初始化二维数组

和三子棋一样,我们要实现选中那个位置出现什么效果,只能是通过二维数组,让二位数组里的元素发生变化,在玩家视角就是自己操作了这个地方,我们需要创建两个二维数组,一个是布置雷区的二维数组,只在后台存在,并不显示出来,另一个则是给玩家展示的二维数组,至于为什么是两个,有很多原因,最容易说的就是:总不能把布置的雷展示给玩家吧,这样还怎么玩,不就开挂了。所以规定:让埋雷区初始化为字符0,展示区初始化为字符*,字符0是因为我们想用一个函数来初始化这两个雷盘,传的参数只需要最后传的字符不一样(一个是字符0,一个是字符*),其他都是一样的,所以为了方便之后的操作(两个雷盘间的联系),我们把两个数组都定义为char类型。


//初始化
void init_board(char board[ROWS][ROWS], int rows, int cols, char a)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			board[i][j] = a;
		}
	}
}
char mine[ROWS][COLS];
char show[ROWS][COLS];
//初始化雷区
init_board(mine, ROWS,COLS,'0');
//初始化展示区
init_board(show,ROWS,COLS, '*');

4.埋雷

在上篇智能三子棋博客中已经用到了随机数生成函数,点击智能三子棋可以跳转到该博客,里面有随机数的讲解。雷盘里我们初始化的是字符0,我们把埋雷的地方初始化为字符1,到计算的时候只需要让某个位置一周(8个)的数字字符相加减去7个字符0即可得到表示该位置有多少个雷的数字字符。

//放雷
void put_mine(char mine[ROWS][COLS], int rows, int cols)
{
	int num = 0;
	for (num = 0; num < mine_num; num++)
	{
		while (1)
		{
			int i = rand() % ROW + 1;
			int j = rand() % COL + 1;
			if (mine[i][j] == '0')
			{
				mine[i][j] = '1';
				break;
			}
		}
	}
}
//埋雷
put_mine(mine,ROWS, COLS);

5.打印雷盘

做完这些操作,我们就需要让玩家看到雷盘了,打印的时候因为行与列比较多,所以我们进行了排序,让玩家一看就知道自己要选择的地方的坐标。

//打印
void print_board(char board[ROWS][COLS], int rows, int cols)
{
	int i = 0;
	printf("   ");//为了对其每行,因为每行的开头加了下标,所以要先空出来下标所占的位置
	for (i = 1; i < cols-1; i++)//打印每列的下标
	{
		printf("%d ", i);
	}
	printf("\n");
	printf("   ");//为了对其每行,因为每行的开头加了下标,所以要先空出来下标所占的位置
	for (i = 1; i < cols-1; i++)//让每列的下标和其下面的元素隔开
	{
		printf("- ");
	}
	printf("\n");
	for (i = 1; i < rows-1; i++)
	{
		printf("%d| ", i);//标记每行
		int j = 0;
		for (j = 1; j < cols-1; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}
//打印雷盘
//print_board(mine, ROWS, COLS);//上帝视角,打印雷区
//printf("\n");
print_board(show, ROWS, COLS);

6.玩家标记

显示出展示区后玩家就开始下棋了,每次玩家在下棋前,我们都要问是否进行标记,然后标记一次后继续问是要标记还是要退出标记进行扫雷。标记的时候我们需要先判断玩家选择的位置是否在范围内(1~9),然后还要判断是否该位置已经被扫过了(如果没被扫过,该位置坐标只能是’*‘,’!‘,’?')

//玩家标记
void mark_board(char show[ROWS][COLS], int rows, int cols)
{
	int flag = 0;
	while (1)
	{
		printf("选择标记方式:按1标记为雷(!),按2标记为不确定(?),按3取消标记(*),选择4进入排雷环节\n");
		printf("请玩家选择标记方式:> ");
		scanf("%d", &flag);
		if (flag == 1)
		{
			int i = 0;
			int j = 0;
			printf("玩家选择标记位置:> ");
			scanf("%d %d", &i, &j);
			if (i > 0 && i <= ROW && j > 0 && j <= COL)
			{
				if (show[i][j] != '*'&&show[i][j]!='?')
				{
					printf("该位置已经扫过或者已经被标记了该种符号,请重新选择\n");
					continue;
				}
				show[i][j] = '!';
			}
		}
		else if (flag == 2)
		{
			int i = 0;
			int j = 0;
			printf("玩家选择:> ");
			scanf("%d %d", &i, &j);
			if (i > 0 && i <= ROW && j > 0 && j <= COL)
			{
				if (show[i][j] != '*' && show[i][j] != '!')
				{
					printf("该位置已经扫过或者已经被标记了该种符号,请重新选择\n");
					continue;
				}
				show[i][j] = '?';
			}
		}

		else if (flag == 3)//取消标记,变为原来的*
		{
			int i = 0;
			int j = 0;
			printf("玩家选择:> ");
			scanf("%d %d", &i, &j);
			if (i > 0 && i <= ROW && j > 0 && j <= COL)
			{
				if (show[i][j] == '?' || show[i][j] == '!')
				{
					show[i][j] = '*';
				}
				else
				{
					printf("该位置已经扫过或者已经被标记了该种符号,请重新选择\n");
					continue;
				}
			}
		}

		else if (flag == 4)
			return;
		else
			printf("选择错误,请重新选择\n");
		system("cls");
		print_board(show, ROWS, COLS);
	}
}
mark_board(show, ROWS, COLS);//每次输入前的标记环节

7.玩家下棋

因为玩家下棋和递归展开、判断周围雷个数以及输赢是连起来的,所以这个部分比较多。

  • 当扫的雷的个数等于(玩家看到的整个雷盘的个数减去雷的个数)的时候,如果程序还没有结束(也就是这期间没被炸死),那么就说明玩家扫雷成功,游戏胜利。
  • 玩家在进行选择排雷位置时,选择的位置需要合理(1~9),然后还需要没被扫过。
  • 当玩家选择的位置一周都没有雷时,该位置由*变为空格(也就是说只有这个位置一周都没有雷,才变为空格,并且展开一周,否则变为周围雷的个数),并且周围全部展开(每展开一个都要让扫雷的个数+1,否则就不能胜利了),然后继续判断,直到附近有雷时,显示出雷的个数。
  • 当玩家选择的坐标正好是雷时,游戏结束,扫雷失败。
  • 我们第三个所提到的展开一片所用到的就是递归:当我们输入的坐标周围不是雷时,展开周围的全部然后再在周围的这八个里面依次判断是否符合,如果符合就变为空格并且继续展开一篇,如果周围有雷,就不再展开,该位置变为周围雷的个数。
  • 上面的这个如果不经处理就会导致死循环,因为我们选的这个如果周围没雷,就会展开一片,那么这一片又与我们选的这个相邻,那么又会回去判断我们选择的这个位置,然后就这样重复,最终会导致内存崩了。所以我们在进行递归时加一个限制条件,它必须是!、?或*才可以,因为如果是数字字符或空格,说明这个地方已经判断过了,那么就不能再判断这个位置。
    判断周围雷的个数时,因为我们最终想要的是一个数字字符形式,所以我们在让要判断的这个位置周围雷的个数时,我们需要让周围相加减去7个字符0,而不是8个。
  • 我们在表达某个位置一周的坐标的时候,采取的是遍历法,用两个for循环找到这个位置一周的坐标并判断他们是显示数字还是再展开一片。
  • 递归展开是根据安 度 因的扫雷博客自己写出来的,点击安度因可以跳转过去。

//周围雷个数
char around_mine(char mine[ROWS][COLS], int i, int j)
{
	return mine[i][j - 1] + mine[i][j + 1] + mine[i + 1][j] + mine[i - 1][j] + mine[i - 1][j - 1] + mine[i + 1][j + 1] + mine[i - 1][j + 1] + mine[i + 1][j - 1] - 7 * '0';
	//一共是8个字符0,但因为我们要用到一个,所以减掉7个,用的那一个是因为我们想以字符数字的形式赋过去,因为数组是字符类型的
}

//递归展开
void recursion(char mine[ROWS][COLS], char show[ROWS][COLS], int i, int j, int* p)
{
	int x = 0;
	int y = 0;
	for (x = -1; x <= 1; x++)
	{
		for (y = -1; y <= 1; y++)
		{
			if (x + i > 0 && x + i <= ROW && y + j > 0 && y + j <= COL)//防止越界
			{
				if (mine[i + x][j + y] == '0' && (show[i + x][j + y] == '*' || show[i + x][j + y] == '?' || show[i + x][j + y] == '!'))
				{
					(*p)++;
					if (around_mine(mine, i + x, j + y) == '0')
					{
						show[i + x][j + y] = ' ';
						recursion(mine, show, i + x, j + y, p);
					}
					else
					{
						show[i + x][j + y] = around_mine(mine, i + x, j + y);
						//recursion(mine, show, i + x, j + y, p);
					}
				}
				else
					continue;

			}
		}
	}
}

//玩家选择坐标
int player_option(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols,int* p)
{
	int i = 0;
	int j = 0;
	printf("玩家选择:> ");
	scanf("%d %d", &i, &j);
	if (i > 0 && i <= ROW && j > 0 && j <= COL)
	{
		if (mine[i][j] == '1')
		{
			return 0;
		}
		if (show[i][j] == '*'||show[i][j]=='!'||show[i][j]=='?')
		{
			(*p)++; 
			show[i][j] = around_mine(mine, i, j);
			if (show[i][j] == '0')
			{
				show[i][j] = ' ';
				recursion(mine, show, i, j, p);//递归展开
			}
			/*else
				recursion(mine, show, i, j, p);*/
			return 1;
		}
		else
		{
			printf("该位置已经排过,请重新选择位置\n");
			Sleep(1500);
			return 1;
		}
	}
}

//玩家进行标记和排雷
int num = 0;
int ret = 0;
while (num<ROW*COL-mine_num)//当重复的次数为所有非雷个数后跳出循环,胜利
{
	mark_board(show, ROWS, COLS);//每次输入前的标记环节
	ret = player_option(mine, show, ROWS, COLS, &num);
	system("cls");
	print_board(show, ROWS, COLS);
	if (ret == 0)
	{
		printf("很遗憾,你被炸死了,雷区如下:\n");
		print_board(mine, ROWS, COLS);//让玩家死后看到这盘扫雷游戏中雷都在哪里
		break;
	}
	//print_board(show, ROWS, COLS);
}
if (num == ROW * COL - mine_num)
	printf("恭喜你扫除了全部的雷!!!\n");

四、总代码如下

game.h

#pragma once

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <windows.h>

#define ROW 9

#define COL 9

#define ROWS ROW+2

#define COLS COL+2

#define mine_num 10

//初始化
void init_board(char board[ROWS][ROWS], int rows, int cols, char a);

//埋雷
void put_mine(char mine[ROWS][COLS],int rows, int cols);

//打印
void print_board(char board[ROWS][COLS], int rows, int cols);

//玩家选择坐标
int player_option(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols);

//玩家标记
void mark_board(char show[ROWS][COLS], int rows, int cols);

game.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

//初始化
void init_board(char board[ROWS][ROWS], int rows, int cols, char a)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			board[i][j] = a;
		}
	}
}

//放雷
void put_mine(char mine[ROWS][COLS], int rows, int cols)
{
	int num = 0;
	for (num = 0; num < mine_num; num++)
	{
		while (1)
		{
			int i = rand() % ROW + 1;
			int j = rand() % COL + 1;
			if (mine[i][j] == '0')
			{
				mine[i][j] = '1';
				break;
			}
		}
	}
}

//打印
void print_board(char board[ROWS][COLS], int rows, int cols)
{
	int i = 0;
	printf("   ");//为了对其每行,因为每行的开头加了下标,所以要先空出来下标所占的位置
	for (i = 1; i < cols-1; i++)//打印每列的下标
	{
		printf("%d ", i);
	}
	printf("\n");
	printf("   ");//为了对其每行,因为每行的开头加了下标,所以要先空出来下标所占的位置
	for (i = 1; i < cols-1; i++)//让每列的下标和其下面的符号隔开
	{
		printf("- ");
	}
	printf("\n");
	for (i = 1; i < rows-1; i++)
	{
		printf("%d| ", i);//标记每行
		int j = 0;
		for (j = 1; j < cols-1; j++)
		{
			printf("%c ", board[i][j]);
		}
		printf("\n");
	}
}

//周围雷个数
char around_mine(char mine[ROWS][COLS], int i, int j)
{
	return mine[i][j - 1] + mine[i][j + 1] + mine[i + 1][j] + mine[i - 1][j] + mine[i - 1][j - 1] + mine[i + 1][j + 1] + mine[i - 1][j + 1] + mine[i + 1][j - 1] - 7 * '0';
	//一共是8个字符0,但因为我们要用到一个,所以减掉7个,用的那一个是因为我们想以字符数字的形式赋过去,因为数组是字符类型的
}

//递归展开
void recursion(char mine[ROWS][COLS], char show[ROWS][COLS], int i, int j, int* p)
{
	int x = 0;
	int y = 0;
	for (x = -1; x <= 1; x++)
	{
		for (y = -1; y <= 1; y++)
		{
			if (x + i > 0 && x + i <= ROW && y + j > 0 && y + j <= COL)//防止越界
			{
				if (mine[i + x][j + y] == '0' && (show[i + x][j + y] == '*' || show[i + x][j + y] == '?' || show[i + x][j + y] == '!'))
				{
					(*p)++;
					if (around_mine(mine, i + x, j + y) == '0')
					{
						show[i + x][j + y] = ' ';
						recursion(mine, show, i + x, j + y, p);
					}
					else
					{
						show[i + x][j + y] = around_mine(mine, i + x, j + y);
						//recursion(mine, show, i + x, j + y, p);
					}
				}
				else
					continue;

			}
		}
	}
}


//玩家选择坐标
int player_option(char mine[ROWS][COLS], char show[ROWS][COLS], int rows, int cols,int* p)
{
	int i = 0;
	int j = 0;
	printf("玩家选择:> ");
	scanf("%d %d", &i, &j);
	if (i > 0 && i <= ROW && j > 0 && j <= COL)
	{
		if (mine[i][j] == '1')
		{
			return 0;
		}
		if (show[i][j] == '*'||show[i][j]=='!'||show[i][j]=='?')
		{
			(*p)++; 
			show[i][j] = around_mine(mine, i, j);
			if (show[i][j] == '0')
			{
				show[i][j] = ' ';
				recursion(mine, show, i, j, p);//递归展开
			}
			/*else
				recursion(mine, show, i, j, p);*/
			return 1;
		}
		else
		{
			printf("该位置已经排过,请重新选择位置\n");
			Sleep(1500);
			return 1;
		}
	}
}

//玩家标记
void mark_board(char show[ROWS][COLS], int rows, int cols)
{
	int flag = 0;
	while (1)
	{
		printf("选择标记方式:按1标记为雷(!),按2标记为不确定(?),按3取消标记(*),选择4进入排雷环节\n");
		printf("请玩家选择标记方式:> ");
		scanf("%d", &flag);

		if (flag == 1)
		{
			int i = 0;
			int j = 0;
			printf("玩家选择标记位置:> ");
			scanf("%d %d", &i, &j);
			if (i > 0 && i <= ROW && j > 0 && j <= COL)
			{
				if (show[i][j] != '*'&&show[i][j]!='?')
				{
					printf("该位置已经扫过或者已经被标记了该种符号,请重新选择\n");
					continue;
				}
				show[i][j] = '!';
			}
		}
		else if (flag == 2)
		{
			int i = 0;
			int j = 0;
			printf("玩家选择:> ");
			scanf("%d %d", &i, &j);
			if (i > 0 && i <= ROW && j > 0 && j <= COL)
			{
				if (show[i][j] != '*' && show[i][j] != '!')
				{
					printf("该位置已经扫过或者已经被标记了该种符号,请重新选择\n");
					continue;
				}
				show[i][j] = '?';
			}
		}

		else if (flag == 3)
		{
			int i = 0;
			int j = 0;
			printf("玩家选择:> ");
			scanf("%d %d", &i, &j);
			if (i > 0 && i <= ROW && j > 0 && j <= COL)
			{
				if (show[i][j] == '?' || show[i][j] == '!')
				{
					show[i][j] = '*';
				}
				else
				{
					printf("该位置已经扫过或者已经被标记了该种符号,请重新选择\n");
					continue;
				}
			}
		}

		else if (flag == 4)
			return;
		else
			printf("选择错误,请重新选择\n");
		system("cls");
		print_board(show, ROWS, COLS);
	}
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()
{
	printf("************************\n");
	printf("******** 1.play ********\n");
	printf("******** 0.exit ********\n");
	printf("************************\n");
}
void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];

	//初始化雷区
	init_board(mine, ROWS,COLS,'0');
	//初始化展示区
	init_board(show,ROWS,COLS, '*');
	
	//埋雷
	put_mine(mine,ROWS, COLS);

	//打印雷盘
	//print_board(mine, ROWS, COLS);//上帝视角,打印雷区
	//printf("\n");
	print_board(show, ROWS, COLS);

	//玩家进行标记和排雷
	int num = 0;
	int ret = 0;
	while (num<ROW*COL-mine_num)//当重复的次数为所有非雷个数后跳出循环,胜利
	{
		mark_board(show, ROWS, COLS);//每次输入前的标记环节
		ret = player_option(mine, show, ROWS, COLS, &num);
		system("cls");
		print_board(show, ROWS, COLS);
		if (ret == 0)
		{
			printf("很遗憾,你被炸死了,雷区如下:\n");
			print_board(mine, ROWS, COLS);//让玩家死后看到这盘扫雷游戏中雷都在哪里
			break;
		}
		//print_board(show, ROWS, COLS);
	}
	if (num == ROW * COL - mine_num)
		printf("恭喜你扫除了全部的雷!!!\n");
}

void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:> ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏\n");
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}

	} while (input);
	
}

int main()
{
	srand((unsigned int)time(NULL));
	test();
	return 0;
}

效果展示图

请添加图片描述

五、总结

在这里插入图片描述

💘原创不易,还希望各位佬佬支持一下 \textcolor{colourful}{💘原创不易,还希望各位佬佬支持一下} 💘原创不易,还希望各位佬佬支持一下

💓点赞,你的认可是我创作的动力! \textcolor{red}{💓点赞,你的认可是我创作的动力!} 💓点赞,你的认可是我创作的动力!

💕收藏,你的青睐是我努力的方向! \textcolor{orange}{💕收藏,你的青睐是我努力的方向!} 💕收藏,你的青睐是我努力的方向!

💞评论,你的意见是我进步的财富! \textcolor{aqua}{💞评论,你的意见是我进步的财富!} 💞评论,你的意见是我进步的财富!

✨请点击下面进入主页关注大魔王
如果感觉对你有用的话,就点我进入主页关注我吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/349007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第九章:创建用户和用户权限

Windows&#xff1a;创建用户&#xff1a;第一种方法创建用户&#xff1a;先点右上角的工具&#xff0c;然后点击AD用户和计算机双击skills.com打开目录&#xff0c;再双击Users&#xff0c;进入文件夹中在右框中右击空白处&#xff0c;新建用户填充好用户信息后点击下一步然后…

Sophos防火墙日志管理

每天&#xff0c;Sophos防火墙都会生成大量的syslog数据&#xff0c;很难独自监控它们。借助EventLog Analyzer&#xff0c;您可以存档系统日志以满足合规性要求&#xff0c;并进行彻底的取证调查&#xff0c;以在发生任何问题&#xff08;例如网络入侵&#xff09;时获得宝贵的…

MySQL用户管理

文章目录MySQL用户管理用户用户信息创建用户修改用户密码删除用户数据库的权限MySQL中的权限给用户授权回收权限MySQL用户管理 与Linux操作系统类似&#xff0c;MySQL中也有超级用户和普通用户之分。如果一个用户只需要访问MySQL中的某一个数据库&#xff0c;甚至数据库中的某…

Unity 资源插件 Agents Navigation 3.1.1.unitypackage

Unity 插件 Agents Navigation 3.1.1.unitypackage 描述 这个软件包包括高性能、模块化和可扩展的代理导航。它是以 DOTS 为核心开发的&#xff0c;因此充分利用了 Unity 的最新技术栈&#xff0c;如 SIMD 数学、Jobs、Burst 编译器和 EntityComponentSystem。此外&#xff0c;…

【ASP.NET】原生JavaScript加Asp.net实现多图片上传

记录一下&#xff0c;Javascript加asp.net实现多文件上传的方法。首先看一下要实现的功能&#xff0c;图片比文字描述更直观。 一、前台代码 前台代码代码分为三个部分&#xff0c;一是HTML代码&#xff0c;二是Style样式代码&#xff0c;三是Javascript代码。 1.html代码 …

亿级高并发电商项目-- 实战篇 --万达商城项目 八(安装FastDFS、安装Nginx、文件服务模块、文件上传功能、商品功能与秒杀商品等功能)

专栏&#xff1a;高并发---分布式项目 &#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是小童&#xff0c;Java开发工程师&#xff0c;CSDN博客博主&#xff0c;Java领域新星创作者 &#x1f4d5;系列专栏&#xff1a;前端、Java、Java中间件大全、微信小程序、微信支…

C语言进阶——自定义类型:枚举、联合

&#x1f307;个人主页&#xff1a;_麦麦_ &#x1f4da;今日名言&#xff1a;如果不去遍历世界&#xff0c;我们就不知道什么是我们精神和情感的寄托&#xff0c;但我们一旦遍历了世界&#xff0c;却发现我们再也无法回到那美好的地方去了。当我们开始寻求&#xff0c;我们就已…

2023春招java面试题及答案

2023春招java面试题及答案总结1.以下Dubbo服务负载均衡策略中&#xff0c;哪一个策略的功能是相同参数的请求总是发到同一个提供者&#xff08;&#xff09;2.如下代码&#xff1a;请问编译运行的结果是什么&#xff1f;3.给出如下代码&#xff1a;请问编译运行的结果是什么&am…

英国访问学者邀请函范例

下面是知识人网访问学者老师分享的一个英国访问学者邀请函范例&#xff0c;邀请函不要复杂&#xff0c;提供签证官想看到的东西即可。Chen xxxDate of Birth: September 1th , 19xxSchool of Computer and InformationXXXX UniversityNo.X South RoadXXX city, XXX Province, 1…

1.Unity之Shader新手入门

Unity Shader着色器的基本概念如何使用Unity Shader着色器示例&#xff1a;如何使用Unity Shader着色器创建复杂的效果总结 什么是Unity中的Shader着色器&#xff1f; Shader着色器是用来控制物体外观的编程代码&#xff0c;它可以改变物体的颜色、纹理、光照、凹凸等&#xf…

智慧校园综合解决方案

在网络和信息技术的普及和国家教育信息化建设的推动下&#xff0c;以计算机网络为基础&#xff0c;以信息和知识资源的共享为手段&#xff0c;强调合作、分享、传承精神的网络化、数字化、智能化有机结合的新型教育、学习和研究的教育环境建设显得尤为重要。 智慧校园是利用信息…

leaflet 纯CSS的marker标记,不用图片来表示(072)

第072个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中使用纯CSS来打造marker的标记。这里用到的是L.divIcon来引用CSS来构造新icon,然后在marker的属性中引用。 这里必须要注意的是css需要是全局性质的,不能被scoped转义为其他随机的css。 直接复制下面的 v…

【SPSS】频数分析和基本描述统计量详细操作教程(附实战案例)

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

记录--『uni-app、小程序』蓝牙连接、读写数据全过程

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 本文简介 这是一次真实的 蓝牙收发数据 的全过程讲解。 本文使用 uni-app Vue3 的方式进行开发&#xff0c;以手机app的方式运行(微信小程序同样可行)。 uni-app 提供了 蓝牙 和 低功耗蓝牙 的 api &…

深圳硬件黑客松活动,开放报名!

开源社KAIYUANSHE近期微信公众号订阅功能做调整啦&#xff01;没有被星标的账号在信息流里可能不显示大图了&#xff01;快星标⭐我们&#xff0c;就可以及时看到发布的文章啦&#xff01;STEP01 点击右上角标志STEP02 点击【设为星标】近年来&#xff0c;创客文化越来越受到人…

figma通过什么方式可以转换为sketch

Figma 如何转为 Sketch 文件&#xff1f;巧了&#xff0c;刚好我对这个问题很熟悉&#xff0c;作为一个使用过 Figma 也使用过 Sketch 的人来说&#xff0c;我还蛮希望两个软件能够互相打通的&#xff0c;不过不管是 Figma 也好还是 Sketch 也好&#xff0c;两个设计软件&#…

含泪吐槽学C++的血与泪

含泪吐槽学C的血与泪 C在各位程序猿眼里并不陌生&#xff0c;但凡学习过C的人&#xff0c;都极有可能被它曾经蹂躏得不要不要的&#xff0c;而我就是其中一个。 文章目录1 我和C的那段血泪史2 再次与C重逢3 我想和你再来一次4 柳暗花明友情推荐5 福利赠书活动6 一个彩蛋大家好&…

FLUXNET数据下载具体步骤

一、FLUXNET数据介绍 全球长期通量观测网络概念最早起源于1993年&#xff0c;由国际地圈-生物圈计划首次提出&#xff0c;国际科学委员会在1995年的La Thuile研讨会上对此概念进行正式讨论&#xff0c;在这次会议上&#xff0c;通量观测委员会讨论了进行长期通量观测的可能性以…

KubeSphere

文章目录一、概述二、最小化安装 KubeSphere2.1 前提2.2 安装 nfs 服务器一、概述 KubeSphere是在Kubernetes之上构建的以应用为中心的企业级分布式容器平台&#xff0c;提供简单易用的操作界面以及向导式操作方式&#xff0c;在降低用户使用容器调度平台学习成本的同时&#…

超详细,Java 设计模式汇总(三)

装饰者模式 装饰者模式一般指装饰模式。 装饰模式指的是在不必改变原类文件和使用继承的情况下&#xff0c;动态地扩展一个对象的功能。它是通过创建一个包装对象&#xff0c;也就是装饰来包裹真实的对象。 装饰者模式&#xff08;Decorator Pattern&#xff09;允许向一个现…