# Algorithms Project (演算法)
###### tags: emPLANT+, 第一年 法國 UniLaSalle, 上學期
## Game of life: Minesweeper (踩地雷遊戲)
2021/11/22(一) 繳交
```
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <windows.h>
bool turn = TRUE;
int inputMines() //Function to ask how many mines to start with
{
int nb;
printf("Please enter a number of initial mines :\n ");
scanf("%d", &nb);
while(nb >= 100 || nb < 0)
{
printf("Please enter a number below 100 and over 0 :\n ");
scanf("%d", &nb);
}
return nb;
}
int randomNumberBetweenBoundaries(int min, int max) //Function that gives a random number between the arguments.
{
return rand()%(max-min+1)+min;
}
void display(int PlayerGrid[10][10]) //Function that displays the player grid (#3)
{
int i, j;
system("cls"); /// To add back for final version !! ///
printf(" 1 2 3 4 5 6 7 8 9 10 \n");
printf(" ____________________ \n");
for(i = 0; i < 10; i++)
{
if (i == 9)
{
printf("%d|", i+1);
}
else
{
printf(" %d|", i+1);
}
for(j = 0; j < 10; j++)
{
if(PlayerGrid[i][j] == 0)
{
printf(" ");
}
if (PlayerGrid[i][j] == -1)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0A);
printf(". ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
if (PlayerGrid[i][j] == -2)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0E);
printf("# ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
//if(PlayerGrid[i][j] >= 1)
//{
// printf("%d ", PlayerGrid[i][j]);
//}
if (PlayerGrid[i][j] == 1)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x04);
printf ("1 ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
if (PlayerGrid[i][j] == 2)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x01);
printf ("2 ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
if (PlayerGrid[i][j] == 3)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x05);
printf ("3 ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
if (PlayerGrid[i][j] == 4)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x01);
printf ("4 ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
if (PlayerGrid[i][j] == 5)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x01);
printf ("5 ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
if (PlayerGrid[i][j] == 6)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x02);
printf ("6 ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
if (PlayerGrid[i][j] == 7)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x03);
printf ("7 ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
if (PlayerGrid[i][j] == 8)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x04);
printf ("8 ");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
}
}
printf("\n");
}
}
int inputLine() //Ask the user to enter a chosen cell line (# 4,5,6)
{
int a; //a is line
printf("Please enter your cell line : \n");
scanf("%d", &a);
while (a > 10 || a < 1) //To check if the coordinates are right and ask the user to enter a new number
{
printf("Please enter number of line below 11 or above 0: \n");
scanf("%d", &a);
}
a--;
return a;
}
int inputColumn() //Ask the user to enter a chosen cell column (# 4,5,6)
{
int b; //b is a column
printf("Please enter your cell column : \n");
scanf("%d", &b);
while (b > 10 || b < 1) //To check if the coordinates are right and ask the user to enter a new number
{
printf("Please enter number of column below 11 or above 0: \n");
scanf("%d", &b);
}
b--;
return b;
}
int nbOfNeighboors(int a, int b, int SecretGrid[10][10]) //Function that counts neighbours of ONE cell (#2)
{
int totalNeighboors = 0;
if(a > 0 && SecretGrid[a-1][b] == -1)
{
totalNeighboors++;
}
if(a > 0 && b < 9 && SecretGrid[a-1][b+1] == -1)
{
totalNeighboors++;
}
if(b < 9 && SecretGrid[a][b+1] == -1)
{
totalNeighboors++;
}
if(a < 9 && b < 9 && SecretGrid[a+1][b+1] == -1)
{
totalNeighboors++;
}
if(a < 9 && SecretGrid[a+1][b] == -1)
{
totalNeighboors++;
}
if(a < 9 && b > 0 && SecretGrid[a+1][b-1] == -1)
{
totalNeighboors++;
}
if(b > 0 && SecretGrid[a][b-1] == -1)
{
totalNeighboors++;
}
if(a > 0 && b > 0 && SecretGrid[a-1][b-1] == -1)
{
totalNeighboors++;
}
return totalNeighboors;
}
void Open(int SecretGrid[10][10], int PlayerGrid[10][10], int a, int b) //Clear all empty spaces
{
//SecretGrid[a][b] is the # of mines around
if (SecretGrid[a][b] == 0) //In this case, we know we can clear all neighbouring cells. This means the recursion of the function will see all of them and displays their values.
{
PlayerGrid[a][b] = SecretGrid[a][b];
if(a > 0 && PlayerGrid[a-1][b] == -1)
{
Open(SecretGrid, PlayerGrid, a-1, b);
}
if(a > 0 && b < 9 && PlayerGrid[a-1][b+1] == -1)
{
Open(SecretGrid, PlayerGrid, a-1, b+1);
}
if(b < 9 && PlayerGrid[a][b+1] == -1)
{
Open(SecretGrid, PlayerGrid, a, b+1);
}
if(a < 9 && b < 9 && PlayerGrid[a+1][b+1] == -1)
{
Open(SecretGrid, PlayerGrid, a+1, b+1);
}
if(a < 9 && PlayerGrid[a+1][b] == -1)
{
Open(SecretGrid, PlayerGrid, a+1, b);
}
if(a < 9 && b > 0 && PlayerGrid[a+1][b-1] == -1)
{
Open(SecretGrid, PlayerGrid, a+1, b-1);
}
if(b > 0 && PlayerGrid[a][b-1] == -1)
{
Open(SecretGrid, PlayerGrid, a, b-1);
}
if(a > 0 && b > 0 && PlayerGrid[a-1][b-1] == -1)
{
Open(SecretGrid, PlayerGrid, a-1, b-1);
}
}
else //This means the cell is a number, not an empty space, and we can't be sure what's around, so we just clear it. The first part of the function deals with the rest.
{
PlayerGrid[a][b] = SecretGrid[a][b];
}
//Open(SecretGrid, PlayerGrid, a, b);
}
int winCheck1(int SecretGrid[10][10], int PlayerGrid[10][10], int nbOfMines) // all mines are cover by flags
{
int ClearedMinesCounter = 0, i, j;
for(j = 0; j < 10; j++)
{
for(i = 0; i < 10; i++)
{
if (SecretGrid[i][j] == -1 && PlayerGrid[i][j] == -2)
{
ClearedMinesCounter++;
}
}
}
if(nbOfMines == ClearedMinesCounter)
{
return TRUE;
}
else
{
return FALSE;
}
}
int winCheck2(int PlayerGrid[10][10], int nbOfMines) // the number of mines and flags are the same
{
int FlagCounter = 0, i, j;
for(j = 0; j < 10; j++)
{
for(i = 0; i < 10; i++)
{
if (PlayerGrid[i][j] == -2)
{
FlagCounter++;
}
}
}
if (FlagCounter == nbOfMines)
{
return TRUE;
}
else
{
return FALSE;
}
}
int winCheck3(int PlayerGrid[10][10]) // the unrealed cell equal to 0
{
int RevealCounter = 0, i, j;
for(j = 0; j < 10; j++)
{
for(i = 0; i < 10; i++)
{
if (PlayerGrid[i][j] == -1)
{
RevealCounter++;
}
}
}
if (RevealCounter == 0)
{
return TRUE;
}
else
{
return FALSE;
}
}
int menu()
{
printf("1. Start new game \n");
printf("2. Credit \n");
printf("3. Rules \n");
printf("4. Exit \n");
printf("Please input 1/2/3/4 : \n");
int choice = 0;
scanf("%d", &choice);
return choice;
}
int main()
{
char username, usercountry, userage;
int choice;
printf("What's your name ? \n");
scanf("%c", &username);
printf("What's your nationality ? \n");
scanf("%c", &usercountry);
printf("How old are you ? \n");
scanf("%c", &userage);
bool menuchoice = TRUE;
while(menuchoice == TRUE)
{
choice = menu();
if (choice == 1)
{
menuchoice = FALSE;
}
else if (choice == 2)
{
printf(" -- Credits -- \n");
printf("\n");
printf("\n");
printf(" Kübra Ilga, Turkey \n");
printf("\n");
printf(" Grégoire Basseville, France \n");
printf("\n");
printf(" Hayat Yasin, Ethiopia \n");
printf("\n");
printf(" Ayu Laksmi, Indonesia \n");
printf("\n");
printf(" Lin, Ni-Jung, Taiwan \n");
printf("\n");
}
else if (choice == 3)
{
printf("The numbers on the board represent how many bombs are adjacent to a square.\nexample, if a square has a '3' on it, then there are 3 bombs next to that square.\nThe bombs could be above, below, right left, or diagonal to the square.\nAvoid all the bombs and expose all the empty spaces to win Minesweeper.\nTip: Use the numbers to determine where you know a bomb is.\n");
}
else if (choice == 4)
{
menuchoice = FALSE;
turn = FALSE;
}
else
{
return FALSE;
}
}
srand(time(NULL));
int nbOfMines, x, y, SecretGrid[10][10], PlayerGrid[10][10], i, j, line, column, PlayerAnswer;
nbOfMines = inputMines();
printf("Number of initial mines : %d \n", nbOfMines);
for(i = 0; i < 10; i++) //Set the player grid as a full uncleared board
{
for(j = 0; j < 10; j++)
{
PlayerGrid[i][j] = -1;
}
}
for(i = 0; i < 10; i++) //Set the secret grid as a full empty board
{
for(j = 0; j < 10; j++)
{
SecretGrid[i][j] = 0;
}
}
int counterOfMines;
for(counterOfMines = 0; counterOfMines < nbOfMines; counterOfMines++) //Places the correct number of mines in the secret grid (#1)
{
x = randomNumberBetweenBoundaries(0, 9);
y = randomNumberBetweenBoundaries(0, 9);
while(SecretGrid[x][y] == -1)
{
x = randomNumberBetweenBoundaries(0, 9);
y = randomNumberBetweenBoundaries(0, 9);
}
SecretGrid[x][y] = -1;
}
for(i = 0; i < 10; i++) //Apply the neighour counter (#2)
{
for(j = 0; j < 10; j++)
{
if (SecretGrid[i][j] != -1)
{
SecretGrid[i][j] = nbOfNeighboors(i, j, SecretGrid);
}
}
}
//Test the secret grid
//for(i = 0; i < 10; i++)
//{
// for(j = 0; j < 10; j++)
// {
// printf(" %d ", SecretGrid[i][j]);
// }
//printf("\n");
//}
// ---------- Game start ----------
while(turn == TRUE)
{
display(PlayerGrid);
line = inputLine(); //Player input
column = inputColumn();
printf("What do you want to do, here ? \n"); //Check what the player wants to do
printf("To reveal this square, type 1 \n");
printf("To place a flag, type 2 \n");
scanf("%d", &PlayerAnswer);
if (PlayerAnswer == 1) //In case of reveal
{
while (PlayerGrid[line][column] != -1) //Checks wether the square has been tried already or not ONLY IF THE PLAYER WANTS TO CLEAR IT (#6)
{
printf("This cell has already been cleared, please try again ! \n");
line = inputLine();
column = inputColumn();
}
if (SecretGrid[line][column] == -1)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0E);
printf("*** \n");
printf(" ** **\n");
printf("** **\n");
printf("** ** **** \n");
printf("** ** ** ****\n");
printf("** ** * ** **\n");
printf ("** * * ** *** **\n");
printf ("** * * ** ** *\n");
printf ("** ** ** ** **\n");
printf (" ** ** **\n");
printf(" * *\n");
printf(" * *\n");
printf(" * 0 0 *\n");
printf("* / @ X *\n");
printf ("* X__/ X__/ *\n");
printf(" * W *\n");
printf(" ** ** \n");
printf(" *****\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x04);
printf(" \\ \\ / / __ \\| | | | | | / __ \\ / ____| ____|\n");
printf(" _____\\ \\_/ / | | | | | | | | | | | | (___ | |__ ______ \n");
printf(" |______\\ /| | | | | | | | | | | | |\\___ \\| __|______|\n");
printf(" | | | |__| | |__| | | |___| |__| |____) | |____ \n");
printf(" |_| \\____/ \\____/ |______\\____/|_____/|______| \n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
turn = FALSE;
//menu = TRUE;
}
else
{
Open(SecretGrid, PlayerGrid, line, column);
}
}
else if (PlayerAnswer == 2) //In case of flag
{
if (PlayerGrid[line][column] == -2) //Want to removed a previous flag
{
PlayerGrid[line][column] = -1;
printf("You removed this flag \n");
}
else if (PlayerGrid[line][column] == -1) //Want to place a new flag
{
PlayerGrid[line][column] = -2;
printf("You placed a flag \n");
}
else
{
printf("You cannot interact with this square \n"); //Just in case
}
}
else
{
printf("Your answer has to be 1 or 2. \n"); //In case the user enters something else
}
if (winCheck1(SecretGrid, PlayerGrid, nbOfMines) && winCheck2(PlayerGrid, nbOfMines))
{
turn = FALSE;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0B); //lightblue
printf(" .'\\ /`.\n");
printf(" .'.-.`-'.-.`.\n");
printf(" ..._: .-. .-. :_...\n");
printf(" .' '-.");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F);
printf("(o ) (o )");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0B);
printf(".-' `.\n");
printf(" : _ _ _`");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x04); //red
printf("~(_)~");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0B); //lightblue
printf("`_ _ _ :\n"); //remember \n to start from new line
printf(": /: ' .-=_ _=-. ` ;\\ :\n");
printf(": :|-.._ ' ` _..-|: :\n");
printf(" : `:| |`:-:-.-:-:'| |:' :\n");
printf(" `. `.| | | | | | |.' .'\n");
printf(" `. `-:_| | |_:-' .'\n");
printf(" `-._ ```` _.-'\n");
printf(" ``-------''\n");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0A); //green
printf("__ _______ _ _ _ _ _____ _ _ _ _ _ \n");
printf("\\ \\ / / _ | | | | | | | |_ _| \\ | | | | |\n");
printf(" \\ V /| | | | | | | | | | | | | | \\| | | | |\n");
printf(" \\ / | | | | | | | | |/\\| | | | | . ` | | | |\n");
printf(" | | \\ \\_/ / |_| | \\ /\\ /_| |_| |\\ |_|_|_|\n");
printf(" \\_/ \\___/ \\___/ \\/ \\/ \\___/\\_| \\_(_|_|_)\n"); //after print remember to return the color into white
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 0x0F); //to return the color into white(normal)
//menu = TRUE;
}
}
return 0;
}
```
Algorithmics 最終成績: Module 20
