这是一个普通的WIN32扫雷程序
这是一个普通的扫雷程序
- 项目介绍
- 效果图
- 1、数据结构
- 2、地雷的生成
- 3、图形的绘制
- 4、按下鼠标的判断逻辑
- 5、搜索周围砖块的逻辑
- 6、画面的绘制
- 关键头文件和源文件
项目介绍
这是一个Win32 C++编写的 扫雷程序
效果图
1、数据结构
一个地雷矩阵和一个玩家操作矩阵
- 地雷矩阵 [二维数组],存储地雷信息和空格周围的地雷数
- 玩家矩阵 [二维数组],存储玩家的操作行为
//数值意义int MineField_Width; //雷区的宽度int MineField_Length; //雷区的高度
//创建int ** MineField = nullptr; //雷区矩阵int ** PlayerField = nullptr;//玩家矩阵,0:未知,1:点开,2:falg,3:unknownMineField = new int*[MineField_Length];PlayerField = new int*[MineField_Length];//创建矩阵for (int i = 0; i < MineField_Length; i++){MineField[i] = new int[MineField_Width];PlayerField[i] = new int[MineField_Width];}//初始化for (int i = 0; i < MineField_Length; i++)for (int j = 0; j < MineField_Width; j++){MineField[i][j] = 0;PlayerField[i][j] = 0;}
2、地雷的生成
- 地雷坐标 基于随机数生成
//矩阵尺寸和获取地雷数量
int * Randperm(int Num, int amount)
{vector<int> temp;int *random = new int[amount];for (int i = 0; i <= Num; i++)temp.push_back(i);random_shuffle(temp.begin(), temp.end());//打乱顺序for (int i = 0; i < temp.size() && i < amount; i++)random[i] = temp[i];return random;
}
- 每次运行程序 改变种子 来让每次生成的雷阵不同
srand((unsigned int)time(0));//用于初始化随机数种子
3、图形的绘制
- 图形接口的选择 GDI+、OpenGL、DirectX2D
- 扫雷只需要实现图片在某位置的显示即可
自己画的
4、按下鼠标的判断逻辑
- 按下的位置是否是砖块
- 按下的砖块是否已经触发过
- 地雷是否已经被引爆
- 是鼠标的 左键、右键、中键
- 如果能按下,是不是地雷
- 是地雷,全部引爆
- 不是地雷,找出周围的同样不是地雷的砖块
5、搜索周围砖块的逻辑
void Spread(int x, int y)
{//上if (x - 1 >= 0 && PlayerField[x - 1][y] == 0 && MineField[x - 1][y] >= 0){PlayerField[x - 1][y] = 1;if (MineField[x - 1][y] == 0)Spread(x - 1, y);}//下if (x + 1 < MineField_Length&&PlayerField[x + 1][y] == 0 && MineField[x + 1][y] >= 0){PlayerField[x + 1][y] = 1;if (MineField[x + 1][y] == 0)Spread(x + 1, y);}//左if (y - 1 >= 0 && PlayerField[x][y - 1] == 0 && MineField[x][y - 1] >= 0){PlayerField[x][y - 1] = 1;if (MineField[x][y - 1] == 0)Spread(x, y - 1);}//右if (y + 1 < MineField_Width&&PlayerField[x][y + 1] == 0 && MineField[x][y + 1] >= 0){PlayerField[x][y + 1] = 1;if (MineField[x][y + 1] == 0)Spread(x, y + 1);}
}
6、画面的绘制
//绘制砖块
//StartX ,StartY 绘制的位置for (int i = 0; i < a_MineField->GetMineField_Length(); i++){for (int j = 0; j < a_MineField->GetMineField_Width(); j++){switch (a_MineField->GetPlayerPoint(i, j)){case 0:frame = /*未知砖块*/; break;case 1://挖开switch (a_MineField->GetMinePoint(i, j)){case -1:frame = /*地雷砖块*/; break;case 0:frame = /*空白砖块*/; break;default:frame = a_MineField->GetMinePoint(i, j) - 1;//我个人的资源存放逻辑}break;case 2:frame =/*旗子砖块*/; break;case 3:frame = /*问号砖块*/; break;}sprites1->Draw(frame, StartX + spacing * j, StartY, (float)block_size);}StartY += /*图片尺寸*/;}
关键头文件和源文件
//.h
#pragma once#include <algorithm>//获取随机数用
#include <vector>
class Gamemap {int MineField_Width; //雷区的宽度int MineField_Length; //雷区的高度int MineAmount; //地雷数量int FlagUseage; //旗帜使用数量int ** MineField = nullptr; //雷区矩阵int ** PlayerField = nullptr; //玩家矩阵,0:未知,1:点开,2:falg,3:unknownbool Explode;
public:Gamemap(int Field_Lv, int MineAmount_Lv);~Gamemap();void CreateMap();int GetMineField_Width();int GetMineField_Length();int GetMinePoint(int x, int y);int GetPlayerPoint(int x, int y);bool GetExplode();bool judgeWin();//判断是否获胜void Spread(int x, int y);void ShowMines();int Flag_left();void useFlag();void cancelFlag();void Player_act(int x, int y, int value);void ItExplode();static int* Randperm(int Num, int amount);
};
//=================================================================================================
//.cpp
#include "GameMap.h"Gamemap::Gamemap(int Field_Lv, int MineAmount_Lv)
{MineField_Width = 0;MineField_Length = 0;MineAmount = 0;FlagUseage = 0;FlagUseage = 0;Explode = false;//设置地图尺寸switch (Field_Lv){case 1:MineField_Width = 10;MineField_Length = 10;break;case 2:MineField_Width = 15;MineField_Length = 12;break;case 3:MineField_Width = 20;MineField_Length = 15;break;case 4:MineField_Width = 30;MineField_Length = 20;break;}//计算地雷数量MineAmount = MineField_Length * MineField_Width * (MineAmount_Lv * 6 + 9) / 100;//*10+5,最高难度约33%//创建矩阵MineField = new int*[MineField_Length];PlayerField = new int*[MineField_Length];//创建矩阵for (int i = 0; i < MineField_Length; i++){MineField[i] = new int[MineField_Width];PlayerField[i] = new int[MineField_Width];}//初始化for (int i = 0; i < MineField_Length; i++)for (int j = 0; j < MineField_Width; j++){MineField[i][j] = 0;PlayerField[i][j] = 0;}CreateMap();
}void Gamemap::CreateMap()
{//获取地雷int *mines = Randperm((MineField_Length * MineField_Width - 1), MineAmount);//布雷for (int i = 0; i < MineAmount; i++)MineField[mines[i] / MineField_Width][mines[i] % MineField_Width] = -1;free(mines);//释放资源//计算数字for (int i = 0; i < MineField_Length; i++)for (int j = 0, temp; j < MineField_Width; j++){temp = 0;if (MineField[i][j] != -1){if (i - 1 >= 0 && j - 1 >= 0 && MineField[i - 1][j - 1] == -1)temp++;if (i - 1 >= 0 && j + 1 < MineField_Width && MineField[i - 1][j + 1] == -1)temp++;if (j - 1 >= 0 && MineField[i][j - 1] == -1)temp++;if (j + 1 < MineField_Width && MineField[i][j + 1] == -1)temp++;if (i - 1 >= 0 && MineField[i - 1][j] == -1)temp++;if (i + 1 < MineField_Length && MineField[i + 1][j] == -1)temp++;if (i + 1 < MineField_Length && j - 1 >= 0 && MineField[i + 1][j - 1] == -1)temp++;if (i + 1 < MineField_Length && j + 1 < MineField_Width && MineField[i + 1][j + 1] == -1)temp++;MineField[i][j] = temp;}}
}Gamemap::~Gamemap()
{for (int i = 0; i < MineField_Length; i++){delete[] MineField[i];delete[] PlayerField[i];}delete[] MineField;delete[] PlayerField;
}int Gamemap::GetMineField_Width()
{return MineField_Width;
}int Gamemap::GetMineField_Length()
{return MineField_Length;
}int Gamemap::GetMinePoint(int x, int y)
{return MineField[x][y];
}int Gamemap::GetPlayerPoint(int x, int y)
{return PlayerField[x][y];
}bool Gamemap::GetExplode()
{return Explode;
}using namespace std;bool Gamemap::judgeWin()
{for (int i = 0; i < MineField_Length; i++)for (int j = 0; j < MineField_Width; j++){if (MineField[i][j] == -1 && PlayerField[i][j] != 2)return false;elseif (MineField[i][j] != -1 && PlayerField[i][j] != 1)return false;}return true;
}void Gamemap::Spread(int x, int y)
{//上if (x - 1 >= 0 && PlayerField[x - 1][y] == 0 && MineField[x - 1][y] >= 0){PlayerField[x - 1][y] = 1;if (MineField[x - 1][y] == 0)Spread(x - 1, y);}//下if (x + 1 < MineField_Length&&PlayerField[x + 1][y] == 0 && MineField[x + 1][y] >= 0){PlayerField[x + 1][y] = 1;if (MineField[x + 1][y] == 0)Spread(x + 1, y);}//左if (y - 1 >= 0 && PlayerField[x][y - 1] == 0 && MineField[x][y - 1] >= 0){PlayerField[x][y - 1] = 1;if (MineField[x][y - 1] == 0)Spread(x, y - 1);}//右if (y + 1 < MineField_Width&&PlayerField[x][y + 1] == 0 && MineField[x][y + 1] >= 0){PlayerField[x][y + 1] = 1;if (MineField[x][y + 1] == 0)Spread(x, y + 1);}
}void Gamemap::ShowMines()
{for (int i = 0; i < MineField_Length; i++)for (int j = 0; j < MineField_Width; j++){if (MineField[i][j] == -1)PlayerField[i][j] = 2;elsePlayerField[i][j] = 1;}FlagUseage = MineAmount;
}int Gamemap::Flag_left()
{return ( MineAmount - FlagUseage);
}void Gamemap::useFlag()
{FlagUseage++;
}void Gamemap::cancelFlag()
{FlagUseage--;
}void Gamemap::Player_act(int x, int y, int value)
{PlayerField[x][y] = value;
}void Gamemap::ItExplode()
{Explode = true;for (int i = 0; i < MineField_Length; i++)for (int j = 0; j < MineField_Width; j++){if (MineField[i][j] == -1)PlayerField[i][j] = 1;}
}
//rand()随机数,random_shuffle()乱序
int * Gamemap::Randperm(int Num, int amount)
{vector<int> temp;int *random = new int[amount];int i;for (i = 0; i <= Num; i++)temp.push_back(i);random_shuffle(temp.begin(), temp.end());for (i = 0; i < temp.size() && i < amount; i++)random[i] = temp[i];return random;
}//=================================================================================================
//.h
#pragma once
#include"game_level.h"
#include"GameMap.h"#define block_size 0.70
#define sprite1_width 48
#define sprite1_height 48
#define sprite2_width 32
#define sprite2_height 56//起始绘图位置
#define DrawX 13
#define DrawY 17
//绘制间隔
#define spacing 36
class Level1 :public game_level
{SpriteSheet * sprites1 =NULL;SpriteSheet * sprites2 =NULL;int frame = 0;int StartX = 0,StartY = 0;//绘图点int n[3] = {0,0,0};//用于存储数字Gamemap* a_MineField = NULL;int Field_Lv = 1; //雷区尺寸int MineAmount_Lv = 1; //地雷数量级别public:void Load() override;void Unload() override;void Render() override;void Update() override;void LBUTTONDOWN(int mouseX,int mouseY) override;void RBUTTONDOWN(int mouseX, int mouseY) override;void MBUTTONDOWN(int mouseX, int mouseY) override;void ReStartLevel() override;void Cheating() override;void ChangeDifficulty(int degree)override;void ChangeSize(int degree)override;void ChangeMineLevel(int target);//更改难度:地雷数量void ChangeFieldLevel(int target);//改变地图尺寸
};//=================================================================================================
//.cpp#include "Level1.h"
#include "game_controller.h"
#include "../Resource.h"void Level1::Load()
{sprites1 = new SpriteSheet(L"../game_res/扫雷地砖.myres", graphics, sprite1_width, sprite1_height);sprites2 = new SpriteSheet(L"../game_res/数码管数字.myres", graphics, sprite2_width, sprite2_height);frame = 0;StartX = 0;StartY = 0;Field_Lv = 1;MineAmount_Lv = 1;a_MineField = new Gamemap(Field_Lv, MineAmount_Lv);}
void Level1::Unload()
{delete sprites1;delete sprites2;delete a_MineField;sprites1 = NULL;sprites2 = NULL;a_MineField = NULL;
}
void Level1::Render()
{//画面部分//灰色画布graphics->ClearScreen(0.9f, 0.9f, 0.9f);//扫雷//开始绘制位置StartX = DrawX;StartY = DrawY;//绘制顶部//选择绘制的脸if (a_MineField->GetExplode())frame = 12;elseframe = 11;switch (Field_Lv){case 1:sprites1->Draw(frame, StartX + 155, StartY, 1); break;case 2:sprites1->Draw(frame, StartX + 245, StartY, 1); break;case 3:sprites1->Draw(frame, StartX + 335, StartY, 1); break;case 4:sprites1->Draw(frame, StartX + 515, StartY, 1); break;}//计算显示的剩余旗子数n[0] = (a_MineField->Flag_left()) / 100;n[1] = (a_MineField->Flag_left()) % 100 / 10;n[2] = (a_MineField->Flag_left()) % 10;for (int i = 0; i < 3; i++) sprites2->Draw(n[i], StartX + sprite2_width * i, StartY - 5, 1);//绘制砖块StartY += 60;for (int i = 0; i < a_MineField->GetMineField_Length(); i++){for (int j = 0; j < a_MineField->GetMineField_Width(); j++){switch (a_MineField->GetPlayerPoint(i, j)){case 0:frame = 14; break;//未知case 1://挖开switch (a_MineField->GetMinePoint(i, j)){case -1:frame = 8; break;//地雷case 0:frame = 13; break;//空白default:frame = a_MineField->GetMinePoint(i, j) - 1;//资源里就是这么存放的}break;case 2:frame = 9; break;//旗子case 3:frame = 10; break;//问号}sprites1->Draw(frame, StartX + spacing * j, StartY, (float)block_size);}StartY += 36;}
}
void Level1::Update()//暂时用不着
{}
void Level1::ChangeMineLevel(int target)
{switch (MineAmount_Lv){case 1:EnableMenuItem(GetMenu(hWnd), IDM_MINE_AMOUNT_LV1, MF_ENABLED); break;case 2:EnableMenuItem(GetMenu(hWnd), IDM_MINE_AMOUNT_LV2, MF_ENABLED); break;case 3:EnableMenuItem(GetMenu(hWnd), IDM_MINE_AMOUNT_LV3, MF_ENABLED); break;case 4:EnableMenuItem(GetMenu(hWnd), IDM_MINE_AMOUNT_LV4, MF_ENABLED); break;}switch (target){case 1:EnableMenuItem(GetMenu(hWnd), IDM_MINE_AMOUNT_LV1, MF_GRAYED); break;case 2:EnableMenuItem(GetMenu(hWnd), IDM_MINE_AMOUNT_LV2, MF_GRAYED); break;case 3:EnableMenuItem(GetMenu(hWnd), IDM_MINE_AMOUNT_LV3, MF_GRAYED); break;case 4:EnableMenuItem(GetMenu(hWnd), IDM_MINE_AMOUNT_LV4, MF_GRAYED); break;}MineAmount_Lv = target;//重置ReStartLevel();DrawMenuBar(hWnd); //重新显示窗口菜单
}
void Level1::ChangeFieldLevel(int target)
{//变更菜单栏switch (Field_Lv){case 1:EnableMenuItem(GetMenu(hWnd), IDM_MINEFIELD_LV1, MF_ENABLED); break;case 2:EnableMenuItem(GetMenu(hWnd), IDM_MINEFIELD_LV2, MF_ENABLED); break;case 3:EnableMenuItem(GetMenu(hWnd), IDM_MINEFIELD_LV3, MF_ENABLED); break;case 4:EnableMenuItem(GetMenu(hWnd), IDM_MINEFIELD_LV4, MF_ENABLED); break;}switch (target){case 1:EnableMenuItem(GetMenu(hWnd), IDM_MINEFIELD_LV1, MF_GRAYED); break;case 2:EnableMenuItem(GetMenu(hWnd), IDM_MINEFIELD_LV2, MF_GRAYED); break;case 3:EnableMenuItem(GetMenu(hWnd), IDM_MINEFIELD_LV3, MF_GRAYED); break;case 4:EnableMenuItem(GetMenu(hWnd), IDM_MINEFIELD_LV4, MF_GRAYED); break;}Field_Lv = target;ReStartLevel();//重置SetWindowPos(hWnd, HWND_TOP, 0, 0, 40 + a_MineField->GetMineField_Width() * spacing, 146 + a_MineField->GetMineField_Length() * spacing, SWP_NOMOVE);graphics->ResizeRenderTarget(hWnd);DrawMenuBar(hWnd); //重新显示窗口菜单
}
void Level1::LBUTTONDOWN(int mouseX, int mouseY)
{//在区域内if (!a_MineField->GetExplode())if ((mouseX - DrawX) > 0 && (mouseX - DrawX) < spacing * a_MineField->GetMineField_Width() && (mouseY - 60 - DrawY) > 0 && (mouseY - 60 - DrawY) < spacing * a_MineField->GetMineField_Length())if (a_MineField->GetPlayerPoint((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing) != 1)//非公开状态{if (a_MineField->GetPlayerPoint((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing) == 2)//插着旗a_MineField->cancelFlag();a_MineField->Player_act((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing, 1);//此处判断扩散和是否爆炸//爆炸!if (a_MineField->GetMinePoint((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing) == -1)a_MineField->ItExplode();else{if (a_MineField->GetMinePoint((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing) == 0)//扩散a_MineField->Spread((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing);if (a_MineField->Flag_left() == 0 && a_MineField->judgeWin())//此处判断是否获胜MessageBox(hWnd, L"成功排雷!", L"恭喜!", 0);}}//点击脸图重新开始switch (Field_Lv){case 1:case 2:case 3:if (79 + Field_Lv * 90 < mouseX && mouseX < 127 + Field_Lv * 90 && DrawY < mouseY && mouseY < DrawY + sprite1_height)ReStartLevel();break;case 4:if (169 + Field_Lv * 90 < mouseX && mouseX < 217 + Field_Lv * 90 && DrawY < mouseY && mouseY < DrawY + sprite1_height)ReStartLevel();break;}
}
void Level1::RBUTTONDOWN(int mouseX, int mouseY)
{if (!a_MineField->GetExplode())if ((mouseX - DrawX) > 0 && (mouseX - DrawX) < spacing * a_MineField->GetMineField_Width() && (mouseY - 60 - DrawY) > 0 && (mouseY - 60 - DrawY) < spacing * a_MineField->GetMineField_Length()){if (a_MineField->GetPlayerPoint((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing) == 2)//去除旗帜{a_MineField->Player_act((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing, 0);a_MineField->cancelFlag();}elseif (a_MineField->Flag_left() > 0 && a_MineField->GetPlayerPoint((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing) != 1){a_MineField->Player_act((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing, 2);a_MineField->useFlag();if (a_MineField->Flag_left() == 0 && a_MineField->judgeWin())//此处判断是否获胜MessageBox(hWnd, L"成功排雷!", L"恭喜!", 0);}}
}
void Level1::MBUTTONDOWN(int mouseX, int mouseY)
{if (!a_MineField->GetExplode())if ((mouseX - DrawX) > 0 && (mouseX - DrawX) < spacing * a_MineField->GetMineField_Width() && (mouseY - 60 - DrawY) > 0 && (mouseY - 60 - DrawY) < spacing * a_MineField->GetMineField_Length()){switch (a_MineField->GetPlayerPoint((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing)){case 2://旗子a_MineField->cancelFlag();case 0://隐藏状态a_MineField->Player_act((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing, 3);break;case 3:a_MineField->Player_act((mouseY - 60 - DrawY) / spacing, (mouseX - DrawX) / spacing, 0);}}
}
void Level1::ReStartLevel()
{a_MineField->~Gamemap();a_MineField = new Gamemap(Field_Lv, MineAmount_Lv);
}
void Level1::Cheating()
{a_MineField->ShowMines();
}
void Level1::ChangeDifficulty(int degree)
{ChangeMineLevel(degree);
}
void Level1::ChangeSize(int degree)
{ChangeFieldLevel(degree);
}
这是一个普通的WIN32扫雷程序相关推荐
- 一个友好的扫雷程序————C初学者都能会的简单扫雷(一)
一.思路整理 (一).两个数组,我们设定两个数组来存放和显示,数组ying[][]用来存放 0和1,其中0代表无雷,1代表有雷.先进行数组初始化,开始时将数组内元素全部赋值为0 数组xian[][]用 ...
- 一个友好的扫雷程序———————C初学者都能学会的简单扫雷(二)
一.优化内容的理解 在前篇的基础上做一下两点扩展和一些细节优化 1.第一次点击,不炸死(如果哪个倒霉蛋第一下就点到了雷,我得让电脑偷偷把这个雷挪走) 2.如果坐标周围没雷,可以实现展开.展开的意思: ...
- 第一个 Win32 窗口程序
第一个 Win32 窗口程序 程序骨架 int WinMain(){ // 设计窗口外观及交互响应,注册,申请专利RegisterClass(...) ;// 生产窗口 CreateWindow(.. ...
- 创建一个最简单的win32应用程序
创建一个最简单的win32应用程序 使用的是vs2013 中文版 首先创建一个win32 应用程序 工程 也可以使用快捷键 Ctrl+Shift +N 创建的工程名字是 HelloApp 下一步 建立 ...
- 如何从一个普通的屌丝逆袭为一个程序员屌丝?(连载)
零.题记 屌丝逆袭亘古不变的话题,芸芸众生津津乐道的话题,如何从一个普通的屌丝逆袭呢?如果你早个20年问这个问题,可能是去学土木工程,就好像现在众屌丝纷纷涌向了计算机的相关行业.无疑,高新技术是最能刺 ...
- 我只是一个普通的程序员08【下】
我只是一个普通的程序员08-终章下 卢日寒在本命编码被破坏后,意识模糊,一生的经历不断在眼前浮现,小镇生活,进入软帝学院,在代码大陆与张麻子,李天,赵干被称为四大天才,万人敬仰.修行java中吃的各种 ...
- CSDN初体验,尝试完成一个自动扫雷程序
零.简介 本文主要为本人初次接触CSDN,尝试着自己去创作一些东西,虽然可能看来很简单,但这也是我学习的过程. 本次我想实现的主要是实现自动化win7扫雷的过程,我玩win7版本的扫雷也已经有上千局了 ...
- 构建meteor应用程序_我构建了一个渐进式Web应用程序并将其发布在3个应用程序商店中。 这是我学到的。...
构建meteor应用程序 by JudahGabriel Himango 犹大(Gabriel Himango) 我构建了一个渐进式Web应用程序并将其发布在3个应用程序商店中. 这是我学到的. (I ...
- 用 PHP-GTK2 做 Win32 GUI 程序
PHP通常是做为服务器端脚本执行,如果告诉你PHP可以编写普通的GUI程序,你应该很感兴趣.下面介绍的PHP-GTK就是PHP的GUI扩展.GTK是一个业界标准的图形库,具有良好的移植性.如果你用过l ...
最新文章
- [转载]数据库设计三大范式应用实例剖析
- ADO.NET 快速入门(一):ADO.NET 概述
- Spring Cloud的全局封装实践
- ITK:将itk :: CovariantVectors的点积
- LNMP 出现 No input file specified. 的解决方法
- CentOS6.7安装elasticsearch5.4 以及kibana
- MySQL基础总结(一)
- (转)网站推广优化教程100条(SEO,网站关键字优化,怎么优化网站,如何优化网站关键字)...
- leetcode刷题:火柴拼正方形
- sqlserver基本增删查语句
- 文件大小图形化软件 SpaceSniffer(转载)
- python面试笔试题
- lattice diamond/radiant license申请
- Anki 批量编辑替换插件
- 几何布朗 matlab,几何布朗运动
- 程序员来聊一聊信用卡(二)——对信用卡的一些基本认识
- Markdown 插入目录索引、更改目录名称方法
- 闲鱼直播flutter化实践
- 光耦电流传输比(CTR)的理解
- H5拍照、选择图片上传组件核心