編寫前首先得有大致的思路吧,就是第一步幹啥第二部幹啥?以我目前的水平編寫的程序只能在黑框框裡運行。先讓大家提提神 。這個圖是windows裡面的掃雷程序。好!廢話不多,正題開始
game.c一、遊戲的功能函數,統統放在game.c中。
1、那麼我們首先需要列印 「菜單函數」,來提醒玩家要不要玩遊戲?或者玩過一把還想不想玩下一把。
#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"char show_mine[row][col] = { 0 }; //玩家數組char real_mine[row][col] = { 0 }; //設計者數組
void muen() //列印菜單{ printf("*******************************\n"); printf("*****1.play 0.exit*******\n"); printf("*******************************\n");}2、然後就需要雷陣了,這時候你就要明白了,一個雷陣是不夠的,因為玩家贏了或者玩家輸了你要給玩家看一下你的存雷雷陣,所以兩個雷陣是正確的選擇,當然可以不列印你的存雷雷陣,我這裡為了方便兩個雷陣都列印了。好!要有雷陣,就先初始化雷陣 這是我定義的兩個數組。
show_mine[row][col];//玩家數組
real_mine[row][col];//設計者數組
在初始化過程中,有雷的地方用字符1表示,沒有雷的地方用字符0表示。
void init_mine(){ int i = 0; int j = 0; for (int i = 0; i < row; i++) { for (j = 0; j < col; j++) { show_mine[i][j] = '*'; real_mine[i][j] = '0'; } }}3、接下類就是要列印雷陣了。
注意給橫行和豎行都加上1-10數字,可以方便玩家輸入坐標。
void print_player(){ int i = 0; int j = 0; printf("0 "); for (i = 1; i <row - 1; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <row - 2; i++) { printf("%d ", i); for (j = 1; j < col - 1; j++) { printf("%c ", show_mine[i][j]); } printf("\n"); } printf("10 "); for (i = 1; i < row - 1; i++) { printf("%c ", show_mine[10][i]); } printf("\n");}
void print_mine(){ int i = 0; int j = 0; printf("0 "); for (i = 1; i <row - 1; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <row - 2; i++) { printf("%d ", i); for (j = 1; j < col - 1; j++) { printf("%c ", real_mine[i][j]); } printf("\n"); } printf("10 "); for (i = 1; i < row - 1; i++) { printf("%c ", real_mine[10][i]); } printf("\n");}4、接下來該存雷了,我們每一次玩的時候要讓雷出現的地方不一樣,那麼我們就採用隨機值來確定存雷的位置。利用rand()來產生隨機值。Rand()%10產生0-9.然後在加1.就可以產生1-10這10個數,然後就可以產生10個不同的坐標。我的這個程序的雷數是有玩家自己設定的。
void set_mine(int COUNT ){ int x = 0; int y = 0; int count = COUNT; while (count) { int x = rand() % 10 + 1; int y = rand() % 10 + 1; if (real_mine[x][y] == '0') { real_mine[x][y] = '1'; count--; } }}5、檢測一個點周圍雷的個數,然後輸出一個坐標周圍有幾個雷的數量。利用函數實現。
int count_mine(int x, int y)//檢測周圍8個區域雷的個數{ int count = 0; if (real_mine[x - 1][y - 1] == '1') count++; if (real_mine[x - 1][y] == '1') count++; if (real_mine[x - 1][y + 1] == '1') count++; if (real_mine[x][y - 1] == '1') count++; if (real_mine[x][y + 1] == '1') count++; if (real_mine[x + 1][y - 1] == '1') count++; if (real_mine[x + 1][y] == '1') count++; if (real_mine[x + 1][y + 1] == '1') count++; return count;}6、剛開始掃雷,第一次一下子就踩到雷了,那不是掃了玩家的興趣麼,不好玩?那怎麼辦?我來給你說這樣做。第一次如果掃到雷,那就把那顆雷給它移走,移到不是雷的地方。利用函數實現。
void safe_mine(){ int x = 0; int y = 0; char ch = 0; int count = 0; int ret = 1; printf("輸入坐標掃雷\n"); while (1) { scanf_s("%d%d", &x, &y); if ((x >= 1 && x <= 10) && (y >= 1 && y <= 10)) { if (real_mine[x][y] == '1') { real_mine[x][y] = '0'; char ch = count_mine(x, y); show_mine[x][y] = ch + '0'; open_mine(x, y); while (ret) { int x = rand() % 10 + 1; int y = rand() % 10 + 1; if (real_mine[x][y] == '0') { real_mine[x][y] = '1'; ret--; break; } }break; } if (real_mine[x][y] == '0') { char ch = count_mine(x, y); show_mine[x][y] = ch + '0'; open_mine(x, y); break; } } else { printf("輸入錯誤重新輸入\n"); } }}7、掃雷的時候要是周圍沒有雷,那麼還可以展開,一直到周圍有雷的坐標。周圍的坐標和本點的坐標都有關係,不懂看代碼。
void open_mine(int x, int y)//坐標周圍展開函數{ if (real_mine[x - 1][y - 1] == '0') { show_mine[x - 1][y - 1] = count_mine(x - 1, y - 1) + '0';//顯示該坐標周圍雷數 } if (real_mine[x - 1][y] == '0') { show_mine[x - 1][y] = count_mine(x - 1, y) + '0';//顯示該坐標周圍雷數 } if (real_mine[x - 1][y + 1] == '0') { show_mine[x - 1][y + 1] = count_mine(x - 1, y + 1) + '0';//顯示該坐標周圍雷數 } if (real_mine[x][y - 1] == '0') { show_mine[x][y - 1] = count_mine(x, y - 1) + '0';//顯示該坐標周圍雷數 } if (real_mine[x][y + 1] == '0') { show_mine[x][y + 1] = count_mine(x, y + 1) + '0';//顯示該坐標周圍雷數 } if (real_mine[x + 1][y - 1] == '0') { show_mine[x + 1][y - 1] = count_mine(x + 1, y - 1) + '0';//顯示該坐標周圍雷數 } if (real_mine[x + 1][y] == '0') { show_mine[x + 1][y] = count_mine(x + 1, y) + '0';//顯示該坐標周圍雷數 } if (real_mine[x + 1][y + 1] == '0') { show_mine[x + 1][y + 1] = count_mine(x + 1, y + 1) + '0';//顯示該坐標周圍雷數 }}8、然後就是我們的重點重點啦,掃雷函數。注意判斷輸入的坐標是否正確,不正確提示重新輸入。判斷雷的個數和剩餘未知區域的個數,如果相等,則玩家贏。如果點的坐標剛好存雷,那麼玩家就輸了。
int sweep_mine(int COUNT){ int x = 0; int y = 0; int count = 0; printf("輸入坐標掃雷\n"); scanf_s("%d%d", &x, &y); if ((x >= 1 && x <= 10) && (y >= 1 && y <= 10)) { if (real_mine[x][y] == '0') { char ch = count_mine(x, y); show_mine[x][y] = ch + '0'; open_mine(x, y); if (count_show_mine() == COUNT) { print_mine(); printf("玩家贏!\n\n"); return 0; } } else if (real_mine[x][y] == '1') { return 1; }
} else { printf("輸入錯誤重新輸入\n"); } return 0;}9、到最後需要確定遊戲勝利的條件,我們要統計當前狀態玩家棋盤中顯示的剩餘 * 的個數,如果個數等於總雷數時說明掃雷完成,遊戲勝利,定義一個函數實現。
int count_show_mine(){ int count = 0; int i = 0; int j = 0; for (i = 1; i <= row - 2; i++) { for (j = 1; j <= col - 2; j++) { if (show_mine[i][j] == '*') { count++; } }
} return count;}test.c
二、遊戲的主函數,負責調用功能函數,來實現程序。放在test.C中。相當於test.c中是程序的整體構架。
#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"double start, finish;
void game(){
int ret = 0; int COUNT = 0; init_mine(); printf("請輸入雷數:>"); scanf_s("%d",&COUNT); set_mine(COUNT); print_mine(); printf("\n"); print_player(); start = clock(); safe_mine();
if (count_show_mine() == COUNT) { print_mine(); printf("玩家贏!\n\n"); return; }print_player();
while (1) { int ret = sweep_mine(COUNT); if (count_show_mine() == COUNT) { print_mine(); printf("玩家贏!\n\n"); finish = clock(); printf("用時%d 秒\n", (int)(finish - start) / CLOCKS_PER_SEC); break; } if (ret) { printf("被雷炸死\t"); finish = clock(); printf("用時%d 秒\n", (int)(finish - start) / CLOCKS_PER_SEC); print_mine(); break; }print_player(); }}
int main(){ srand((unsigned int)time(NULL)); int input = 0; muen(); do { scanf("%d", &input); switch (input) { case 1:game(); break; case 0:exit(1); break; default: printf("輸入錯誤,重新輸入\n"); break; } muen(); printf("contiue?\n"); } while (1); system("pause"); return 0;}game.h三、頭文件,負責申明各種函數。
#ifndef __GAME_H__#define __GAME__H__
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>
#define row 12#define col 12char show_mine[row][col];char real_mine[row][col];
void muen();void init_mine();void set_mine(int COUNT);int count_mine();void print_player();void print_mine();int sweep_mine(int COUNT);void safe_mine();void open_mine(int x, int y);int count_show_mine();
#endif 在配幾張圖。最後給各位老鐵附上game.c函數整體的原始碼。#define _CRT_SECURE_NO_WARNINGS 1#include"game.h"char show_mine[row][col] = { 0 }; char real_mine[row][col] = { 0 };
void muen() { printf("*******************************\n"); printf("*****1.play 0.exit*******\n"); printf("*******************************\n");}
void init_mine(){ int i = 0; int j = 0; for (int i = 0; i < row; i++) { for (j = 0; j < col; j++) { show_mine[i][j] = '*'; real_mine[i][j] = '0'; } }}
void print_player(){ int i = 0; int j = 0; printf("0 "); for (i = 1; i <row - 1; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <row - 2; i++) { printf("%d ", i); for (j = 1; j < col - 1; j++) { printf("%c ", show_mine[i][j]); } printf("\n"); } printf("10 "); for (i = 1; i < row - 1; i++) { printf("%c ", show_mine[10][i]); } printf("\n");}
void print_mine(){ int i = 0; int j = 0; printf("0 "); for (i = 1; i <row - 1; i++) { printf("%d ", i); } printf("\n"); for (i = 1; i <row - 2; i++) { printf("%d ", i); for (j = 1; j < col - 1; j++) { printf("%c ", real_mine[i][j]); } printf("\n"); } printf("10 "); for (i = 1; i < row - 1; i++) { printf("%c ", real_mine[10][i]); } printf("\n");}
void set_mine(int COUNT ){ int x = 0; int y = 0; int count = COUNT; while (count) { int x = rand() % 10 + 1; int y = rand() % 10 + 1; if (real_mine[x][y] == '0') { real_mine[x][y] = '1'; count--; } }}
int count_mine(int x, int y){ int count = 0; if (real_mine[x - 1][y - 1] == '1') count++; if (real_mine[x - 1][y] == '1') count++; if (real_mine[x - 1][y + 1] == '1') count++; if (real_mine[x][y - 1] == '1') count++; if (real_mine[x][y + 1] == '1') count++; if (real_mine[x + 1][y - 1] == '1') count++; if (real_mine[x + 1][y] == '1') count++; if (real_mine[x + 1][y + 1] == '1') count++; return count;}
void safe_mine(){ int x = 0; int y = 0; char ch = 0; int count = 0; int ret = 1; printf("輸入坐標掃雷\n"); while (1) { scanf_s("%d%d", &x, &y); if ((x >= 1 && x <= 10) && (y >= 1 && y <= 10)) { if (real_mine[x][y] == '1') { real_mine[x][y] = '0'; char ch = count_mine(x, y); show_mine[x][y] = ch + '0'; open_mine(x, y); while (ret) { int x = rand() % 10 + 1; int y = rand() % 10 + 1; if (real_mine[x][y] == '0') { real_mine[x][y] = '1'; ret--; break; } }break; } if (real_mine[x][y] == '0') { char ch = count_mine(x, y); show_mine[x][y] = ch + '0'; open_mine(x, y); break; } } else { printf("輸入錯誤重新輸入\n"); } }}
void open_mine(int x, int y){ if (real_mine[x - 1][y - 1] == '0') { show_mine[x - 1][y - 1] = count_mine(x - 1, y - 1) + '0'; } if (real_mine[x - 1][y] == '0') { show_mine[x - 1][y] = count_mine(x - 1, y) + '0'; } if (real_mine[x - 1][y + 1] == '0') { show_mine[x - 1][y + 1] = count_mine(x - 1, y + 1) + '0'; } if (real_mine[x][y - 1] == '0') { show_mine[x][y - 1] = count_mine(x, y - 1) + '0'; } if (real_mine[x][y + 1] == '0') { show_mine[x][y + 1] = count_mine(x, y + 1) + '0'; } if (real_mine[x + 1][y - 1] == '0') { show_mine[x + 1][y - 1] = count_mine(x + 1, y - 1) + '0'; } if (real_mine[x + 1][y] == '0') { show_mine[x + 1][y] = count_mine(x + 1, y) + '0'; } if (real_mine[x + 1][y + 1] == '0') { show_mine[x + 1][y + 1] = count_mine(x + 1, y + 1) + '0'; }}
int sweep_mine(int COUNT){ int x = 0; int y = 0; int count = 0; printf("輸入坐標掃雷\n"); scanf_s("%d%d", &x, &y); if ((x >= 1 && x <= 10) && (y >= 1 && y <= 10)) { if (real_mine[x][y] == '0') { char ch = count_mine(x, y); show_mine[x][y] = ch + '0'; open_mine(x, y); if (count_show_mine() == COUNT) { print_mine(); printf("玩家贏!\n\n"); return 0; } } else if (real_mine[x][y] == '1') { return 1; }
} else { printf("輸入錯誤重新輸入\n"); } return 0;}
int count_show_mine(){ int count = 0; int i = 0; int j = 0; for (i = 1; i <= row - 2; i++) { for (j = 1; j <= col - 2; j++) { if (show_mine[i][j] == '*') { count++; } }
} return count;}程序的優勢在於:
1、 第一次踩到雷不會死,而會把這顆雷移到別處,保證玩家的興趣。嘿嘿。
2、 可以展開。即選中一點可以展開周圍8個點也沒有雷的坐標,只是8個,我還沒有做到展開再外圈。
3、 可以由玩家自己設定雷的個數,玩家可以挑戰自己。哈哈
4、 可以計時,即遊戲結束,包括輸贏,玩家所用的時間。
原文連結:https://blog.csdn.net/qq_40421919/article/details/79916214