---
# System prepended metadata

title: Algorithms Project (演算法)

---

# 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
![](https://i.imgur.com/ZRKIivU.png)
