# 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)