1.先看效果图:
这些图片的素材都是自制的,如果感觉图片不适可以自己替换。雷的数量我设置是25个,在头文件中可以自行设置。在这之前要在编译器中加一个图形库easyx.h,这个可以在网上下载,不然其中的函数就会报错。由于本人英语水平有限,有些函数定义存在拼音拼写,请多多担待。
2.全部代码如下:
main.cpp
//#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
/*int count_mine(int x, int y);
void avoid_mine();
void open_mine(int x, int y);
int sweep_mine();
int count_show_mine();*/
int main(){
/*int n;
printf("输入1开始游戏,输入0结束游戏\n");
scanf("%d", &n);
*/
initgraph(300, 500);
int n;
MOUSEMSG m;
IMAGE bk;
loadimage(&bk, "扫雷素材自制\\bk.png", 300, 500, true);
Lbutton play = creat_Btn(50, 250, 90, 25, "开始");
Lbutton over = creat_Btn(160, 250, 90, 25, "退出");
while (1){
m = GetMouseMsg();
BeginBatchDraw();
putimage(0, 0, &bk);
draw_button(play);
draw_button(over);
EndBatchDraw();
if (inButton(play, m) && m.uMsg == WM_LBUTTONDOWN)
{
free(play);
free(over);
closegraph();
n = 1;
break;
}
else if(inButton(over,m)&&m.uMsg==WM_LBUTTONDOWN){
free(play);
free(over);
closegraph();
n = 0;
break;
}
}
switch (n){
case 0:
return 0;
break;
case 1:
if (Game()){
// printf_s("踩到雷了\n");
closegraph();
}
else {
//printf_s("通关游戏\n");
closegraph();
}
break;
}
return 0;
}
game.cpp
#include"game.h"
char show_mine[row][col];//玩家的地图
char real_mine[row][col];//后台(真正的)地图
IMAGE one, two, three, four, five, six, seven, eight, mine, bk, yes,no, zero;
HWND win1;
int ii[mn+1], jj[mn+1]; //存放雷的位置
int Game(){
win1 = initgraph(win_w, win_h);
srand((unsigned int)time(NULL));
init_mine();
set_mine();
init_tu();
//print_player();
//print_mine();
int nm = mn;
avoid_mine();
if (sweep_mine())
{
while (nm>=0){
put_tu();
if (nm > 0){
show_mine[ii[nm]][jj[nm]] = '#';
Sleep(100);
}
nm--;
}
/*mciSendString("open 奥利给.mp3", 0, 0, 0);
mciSendString("play 奥利给.mp3", 0, 0, 0);*/
mciSendString("open 神话.mp3", 0, 0, 0);
mciSendString("play 神话.mp3", 0, 0, 0);
MessageBox(win1, "踩雷了", "game over", MB_OK);
mciSendString("close 神话.mp3", 0, 0, 0);
//mciSendString("close 奥利给.mp3", 0, 0, 0);
return 1;
}
else{
while (nm>=0){
put_tu();
if (nm >= 0){
show_mine[ii[nm]][jj[nm]] = '#';
Sleep(100);
}
nm--;
}
/*mciSendString("open 牛逼.mp3", 0, 0, 0);
mciSendString("play 牛逼.mp3", 0, 0, 0);*/
MessageBox(win1, "赢了", "win", MB_OK);
//mciSendString("close 牛逼.mp3", 0, 0, 0);
return 0;
}
}
Lbutton creat_Btn(int x, int y, int w, int h,const char *str){
Lbutton btn = (Lbutton)malloc(sizeof(Button));
assert(btn);
btn->x = x;
btn->y = y;
btn->width=w;
btn->height=h;
btn->color = RGB(100, 100, 100);
int length = strlen(str) + 1;
btn->text = (char*)malloc(sizeof(char)+length);
assert(btn->text);
strcpy_s(btn->text, length, str);
return btn;
}
void draw_button(Lbutton btn){ //画按钮
setfillcolor(btn->color);
fillrectangle(btn->x, btn->y, btn->x+btn->width,btn->y+ btn->height);
settextcolor(RED);
setbkmode(TRANSPARENT);
settextstyle(25, 0, "楷体");
int textw = textwidth(btn->text);
int texth = textheight(btn->text);
int xx = btn->x + (btn->width - textw) / 2;
int yy = btn->y + (btn->height - texth) / 2;
outtextxy(xx, yy,btn->text);
outtextxy(125, 200, "扫雷");
}
int inButton(Lbutton btn,MOUSEMSG m){
if (m.x > btn->x&&m.y > btn->y&&m.x < btn->x + btn->width&&m.y < btn->y + btn->height)
{
btn->color = RGB(100, 50, 50);
return 1;
}
btn->color = RGB(100, 100, 100);
return 0;
}
void init_mine(){ //初始化
int i, j;
for (i = 1; i < row - 1; i++)
for (j = 1; j < col - 1; j++){
show_mine[i][j] = '*';
real_mine[i][j] = '0';
}
}
void init_tu(){
loadimage(&one, "扫雷素材自制\\1.png", tu_w, tu_h, true);
loadimage(&two, "扫雷素材自制\\2.png", tu_w, tu_h, true);
loadimage(&three, "扫雷素材自制\\3.png", tu_w, tu_h, true);
loadimage(&four, "扫雷素材自制\\4.png", tu_w, tu_h, true);
loadimage(&five, "扫雷素材自制\\5.png", tu_w, tu_h, true);
loadimage(&six, "扫雷素材自制\\6.png", tu_w, tu_h, true);
loadimage(&seven, "扫雷素材自制\\7.png", tu_w, tu_h, true);
loadimage(&eight, "扫雷素材自制\\8.png", tu_w, tu_h, true);
loadimage(&mine, "扫雷素材自制\\雷.png", tu_w, tu_h, true);
loadimage(&bk, "扫雷素材自制\\背景.png", tu_w, tu_h, true);
loadimage(&yes, "扫雷素材自制\\yes.png", tu_w, tu_h, true);
loadimage(&zero, "扫雷素材自制\\0.png", tu_w, tu_h, true);
loadimage(&no, "扫雷素材自制\\no.png", tu_w, tu_h, true);
}
void put_tu(){
int i, j;
for (i = 1; i < row - 1; i++)
for (j = 1; j < col - 1; j++){
if (show_mine[i][j] == '*'){
putimage((j- 1)*tu_w, (i - 1)*tu_h, &bk);
}
else if (show_mine[i][j] == '1'){
putimage((j - 1)*tu_w, (i - 1)*tu_h, &one);
}
else if (show_mine[i][j] == '2'){
putimage((j - 1)*tu_w, (i - 1)*tu_h, &two);
}
else if (show_mine[i][j] == '3'){
putimage((j - 1)*tu_w, (i- 1)*tu_h, &three);
}
else if (show_mine[i][j] == '4'){
putimage((j - 1)*tu_w, (i - 1)*tu_h, &four);
}
else if (show_mine[i][j] == '5'){
putimage((j - 1)*tu_w, (i - 1)*tu_h, &five);
}
else if (show_mine[i][j] == '6'){
putimage((j - 1)*tu_w, (i - 1)*tu_h, &six);
}
else if (show_mine[i][j] == '7'){
putimage((j - 1)*tu_w, (i - 1)*tu_h, &seven);
}
else if (show_mine[i][j] == '8'){
putimage((j - 1)*tu_w, (i - 1)*tu_h, &eight);
}
else if (show_mine[i][j] == '#'){
putimage((j - 1)*tu_w, (i- 1)*tu_h, &mine);
}
else if (show_mine[i][j] == '0'){
putimage((j - 1)*tu_w, (i - 1)*tu_h, &zero);
}
else if (show_mine[i][j] == '!')
putimage((j - 1)*tu_w, (i - 1)*tu_h, &yes);
else if (show_mine[i][j] == '@')
putimage((j - 1)*tu_w, (i - 1)*tu_h, &no);
}
}
/*void print_player(){ //打印玩家地图
int i, j;
printf("0 ");
for (i = 1; i < col - 1; i++)
printf("%d ", i);
printf("\n");
for (i = 1; i < row - 1; i++){
if (i<10)
printf("%d ", i);
else printf("%d ", i);
for (j = 1; j < col - 1; j++){
printf("%c ", show_mine[i][j]);
}
printf("\n");
}
printf("\n");
printf("\n");
}
void print_mine(){ //打印后台数据
int i, j;
printf("0 ");
for (i = 1; i < col - 1; i++)
printf("%d ", i);
printf("\n");
for (i = 1; i < row - 1; i++){
if (i < 10)
printf("%d ", i);
else printf("%d ", i);
for (j = 1; j < col - 1; j++){
printf("%c ", real_mine[i][j]);
}
printf("\n");
}
printf("\n");
printf("\n");
}*/
void set_mine() //布雷
{
int i, j;
int n = 0;
int count = mn;
while (count){
i = rand() % (row - 2) + 1;
j = rand() % (col - 2) + 1;
if (real_mine[i][j] == '0'){
ii[n] = i;
jj[n] = j;
n++;
real_mine[i][j] = '1';
}
count--;
}
}
int count_mine(int x, int y){ //计算八个方向的雷数
int count = 0;
int i = x, j = y;
if (real_mine[i - 1][j] == '1')//上
count++;
if (real_mine[i + 1][j] == '1')//下
count++;
if (real_mine[i][j - 1] == '1')//左
count++;
if (real_mine[i][j + 1] == '1')//右
count++;
if (real_mine[i - 1][j - 1] == '1')//左上
count++;
if (real_mine[i - 1][j + 1] == '1')//右上
count++;
if (real_mine[i + 1][j - 1] == '1')//左下
count++;
if (real_mine[i + 1][j + 1] == '1')//右下
count++;
return count;
}
void avoid_mine(){
int i, j;
MOUSEMSG m;
/*printf_s("请输入:");
scanf_s("%d,%d", &j, &i);
printf_s("\n");*/
while (1){
put_tu();
m = GetMouseMsg();
i= m.y / tu_w + 1;
j= m.x / tu_h + 1;
if ( m.uMsg == WM_LBUTTONDOWN){
if (real_mine[i][j] == '1'){
real_mine[i][j] = '0';
show_mine[i][j] = '0' + count_mine(i, j);
open_mine(i, j);
while (1){
int xx = rand() % (row - 2) + 1;
int yy = rand() % (col - 2) + 1;
if (real_mine[xx][yy] == '0')
{
real_mine[xx][yy] = '1';
return;
}
}
}
else{
show_mine[i][j] = '0' + count_mine(i, j);
open_mine(i, j);
return;
}
}
//print_player();
//print_mine();
}
}
void open_mine(int x, int y){ //打开无雷的区域
int i = x, j = y;
if (real_mine[i - 1][j] == '0'){//上
show_mine[i - 1][j] = '0'+count_mine(i-1,j);
}
if (real_mine[i + 1][j] == '0'){//下
show_mine[i + 1][j] = '0' + count_mine(i + 1, j);
}
if (real_mine[i][j - 1] == '0'){//左
show_mine[i][j - 1] = '0' + count_mine(i , j-1);
}
if (real_mine[i][j + 1] == '0'){//右
show_mine[i][j + 1] = '0' + count_mine(i , j+1);
}
if (real_mine[i - 1][j - 1] == '0'){//左上
show_mine[i - 1][j - 1] = '0';
}
if (real_mine[i - 1][j + 1] == '0'){//右上
show_mine[i - 1][j + 1] = '0';
}
if (real_mine[i + 1][j - 1] == '0'){//左下
show_mine[i + 1][j - 1] = '0';
}
if (real_mine[i + 1][j + 1] == '0'){//右下
show_mine[i + 1][j + 1] = '0';
}
}
int sweep_mine(){//扫雷
int i, j;
MOUSEMSG m;
while (1){
put_tu();
/*printf_s("请输入:");
scanf_s("%d,%d", &i, &j);
printf_s("\n");*/
m = GetMouseMsg();
i= m.y / tu_w + 1;
j = m.x / tu_h + 1;
if (show_mine[i][j] == '*'&&m.uMsg==WM_RBUTTONDOWN )
show_mine[i][j] = '!';
else if (show_mine[i][j] == '!'&&m.uMsg == WM_RBUTTONDOWN)
show_mine[i][j] = '@';
else if (show_mine[i][j] == '@'&&m.uMsg == WM_RBUTTONDOWN)
show_mine[i][j] = '*';
if (show_mine[i][j] == '*' && m.uMsg == WM_LBUTTONDOWN){
if (real_mine[i][j] == '0'){
show_mine[i][j] = '0' + count_mine(i, j);//显示此位置四周的雷数
open_mine(i, j); //打开四周的无雷区域
if (count_show_mine() == 1)
return 0;
}
else if (real_mine[i][j] == '1')
{
show_mine[i][j] = '#';
return 1;
}
}
FlushMouseMsgBuffer();
}
/*print_player();
print_mine();*/
}
int count_show_mine(){
int i, j;
int count = 0;
for (i = 1; i < row - 1; i++)
for (j = 1; j < col - 1; j++){
if (show_mine[i][j] == '*')
count++;
}
if (count == mn) //如果位置区域的数量等于雷数量 返回1
return 1;
return 0;
}
game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<assert.h>
#include<conio.h>
#include<graphics.h>
#include<Windows.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")
#define win_w 800
#define win_h 600
#define row 17
#define col 22
#define tu_w 40
#define tu_h 40
#define mn 25//雷的个数
typedef struct button{ //创建存放按钮的信息
int x;
int y;
int width;
int height;
COLORREF color;
char* text;
}Button, *Lbutton;
void init_mine();
//void print_player();
//void print_mine();
void set_mine();
int count_mine(int x, int y);
void avoid_mine();
void open_mine(int x, int y);
int sweep_mine();
int count_show_mine();
void init_tu();//加载图片
void put_tu();//打印地图
int Game();//开始游戏
Lbutton creat_Btn(int x, int y, int w, int h, const char *str);//创建按钮
void draw_button(Lbutton btn); //画
int inButton(Lbutton btn,MOUSEMSG m);//判断鼠标是否在对应位置