I tried to implement Minesweeper on terminal with python

Trigger

I wanted to implement Minesweeper on the terminal, so I implemented it. Actually, when I started programming, I implemented it once in C, but it was not completed, so it also serves as a review.

Overview of Minesweeper

Minesweeper is a one-person computer game invented in the 1980s. The purpose of the game is to remove mines from the minefield.

I also played when I was in elementary school. (I'm getting older) By the way, how much do you know that you are an elementary school student now?

By the way, I can play with Chrome now, so by all means

Implementation overview

The outline is the same as the following site (probably). [Implementation of Minesweeper that can be played on the terminal](https://qiita.com/ta-ka/items/40b56722da43d1ba2e26#open%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89 % E3% 81% AE% E5% 86% 8D% E5% B8% B0])

App overview

  1. Specify the file, the size of the squares, and the ratio of the bombs, and execute.

  2. Specify the initial position. The square is displayed. (* The initial position and adjacent squares are set so that no bombs are placed.)

  3. Below, specify the open position.

  4. When cleared, the number of open cells and the elapsed time are displayed and the process ends. image.png

  5. When an unspecified input is received, it loops infinitely as shown in the figure below. image.png

Hamari point

Generation of two-dimensional array

Note that if you update one list in the code below, all the lists will be updated when you generate the two-dimensional array required at the time of implementation.

Failure example


    #A two-dimensional array that holds the position of the bomb and the number of surrounding bombs
    mine_list = [["N"] * args.n]

    #A two-dimensional array that holds whether a cell has been opened
    opened_ls = [[False] * args.n]

As shown below, I initialized it with list comprehension notation and got nothing.

Success story


    #A two-dimensional array that holds the position of the bomb and the number of surrounding bombs
    mine_list = [["N"] * args.n for i in range(args.n)]

    #A two-dimensional array that holds whether a cell has been opened
    opened_ls = [[False] * args.n for i in range(args.n)]

Impressions

It's a simple game, but it can't be implemented without understanding the basics of the program. Therefore, it was a good opportunity to review the basics.

Issues and points for improvement

Code The whole code is below. It was also released on Github.


import argparse
import random
import copy
import itertools
import time

def main(args):
    def chk():
        if args.n > 99:
            args.n = 99
        if args.bomb_rate >= 1 or args.bomb_rate <= 0:
            args.bomb_rate = 0.5
        return args

    def create_mine_map(init_w, init_h):
        def num_bomb(mine_list, iw, ih):
            num_bomb = 0
            for i in range(-1, 2):
                for j in range(-1, 2):
                    if iw+i < 0 or iw+i >= args.n or ih+j < 0 or ih+j >= args.n:
                        continue
                    elif mine_list[iw+i][ih+j] == "B":
                        num_bomb += 1
            return num_bomb

        mine_list = [["N"] * args.n for i in range(args.n)]
        # add bomb
        n_bomb = int((args.n ** 2) * args.bomb_rate)
        bomb_count = 0
        for bomb_w in range(args.n):
            for bomb_h in range(args.n):
                #bomb installation
                if bomb_count >= n_bomb:
                    break
                if random.randint(0, 100) > 100 * (1 - args.bomb_rate):
                    #Excludes initial input position and surroundings
                    if bomb_w != init_w and bomb_h != init_h and \
                        bomb_w != init_w - 1 and bomb_h != init_h - 1 and \
                            bomb_w != init_w + 1 and bomb_h != init_h + 1:
                                mine_list[bomb_w][bomb_h] = "B"
                                bomb_count += 1

        # increment around bomb
        for i in range(args.n):
            for j in range(args.n):
                if mine_list[i][j] == "N":
                    mine_list[i][j] = num_bomb(mine_list, i, j)
        return mine_list, bomb_count

    def open_map(mine_list, open_w, open_h, opened_ls):
        if mine_list[open_w][open_h] == "B":
            opened_ls = [[True] * args.n for i in range(args.n)]
            return opened_ls

        opened_ls[open_w][open_h] = True

        if mine_list[open_w][open_h] == 0:
            for i in range(-1, 2):
                for j in range(-1, 2):
                    if open_w + i < 0 or open_w + i >= args.n or open_h + j < 0 or open_h + j >= args.n:
                        continue
                    elif not opened_ls[open_w + i][open_h + j]:
                        opened_ls = open_map(mine_list, open_w + i, open_h + j, opened_ls)
        return opened_ls

    def plt_mine(mine_list, opened_ls, play_mode=True):
        h = args.n
        mine_list_cp = copy.deepcopy(mine_list)
        print(*["="]*(args.n+2))
        if play_mode:
            for i in range(h):
                for j in range(h):
                    if not opened_ls[i][j]:
                        mine_list_cp[i][j] = "-"
            print("PLOT MAP")
        else:
            print("PLOT MAP (All Opened)")

        print(" ", " ", *list(range(0, args.n)))
        print(*["="]*(args.n + 2))

        for i in range(h):
            print(i, ":", *mine_list_cp[:][i])

    "chk args"
    args = chk()

    "while wait input(w, h)"
    while True:
        try:
            init_w, init_h = map(int, input("input w h ({} ~ {}) >> ".format(0, args.n - 1)).split())        

            if init_w >= 0 and init_w < args.n and init_h >= 0 and init_h < args.n:
                break
            else:
                print("Over" + str(args.n))

        except ValueError:
            print("input 2 numbers. 0 0")

    "create mine"
    opened_ls = [[False] * args.n for i in range(args.n)]
    mine_list, n_bomb = create_mine_map(init_w, init_h)
    opened_ls = open_map(mine_list, init_w, init_h, opened_ls)

    "plot mine"
    plt_mine(mine_list, opened_ls, play_mode=args.debug)

    "while wait input(w, h)"
    init_time = time.time()
    init_opend_num = sum(list(itertools.chain.from_iterable(opened_ls)))

    while True:

        if all(list(itertools.chain.from_iterable(opened_ls))):
            print("!!!!!!!!BOMBED!!!!!!!!")
            break

        elif sum(list(itertools.chain.from_iterable(opened_ls))) == args.n**2 - n_bomb:
            end_time = time.time()
            print("!!!!!!!!CLEARD!!!!!!!!")
            print("YOUR TIME:{:0=3.2f}".format(end_time - init_time))
            print("OPEND:{}".format(args.n**2 - init_opend_num - n_bomb))
            break

        try:
            open_w, open_h = map(int, input("input w h ({} ~ {}) >> ".format(0, args.n - 1)).split())
    
            if open_w >= 0 and open_w < args.n and open_h >= 0 and open_h < args.n:
                "update mine"
                opened_ls = open_map(mine_list, open_w, open_h, opened_ls)

                "plot mine"
                plt_mine(mine_list, opened_ls, play_mode=args.debug)

            else:
                print("Over " + str(args.n))

        except ValueError:
            print("input 2 numbers. 0 0")

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("-n", type=int, default=8, help="create (n, n) size")
    parser.add_argument("-b", "--bomb_rate", type=float, default=0.1, help="how many bomb in the mine.")
    parser.add_argument("-d", "--debug", action="store_false")
    args = parser.parse_args()
    main(args)

reference

[Implementation of Minesweeper that can be played on the terminal](https://qiita.com/ta-ka/items/40b56722da43d1ba2e26#open%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89 % E3% 81% AE% E5% 86% 8D% E5% B8% B0])

Recommended Posts

I tried to implement Minesweeper on terminal with python
I tried to implement an artificial perceptron with python
I tried to implement PLSA in Python
I tried to implement Autoencoder with TensorFlow
I tried to implement permutation in Python
I tried to implement PLSA in Python 2
I tried to implement ADALINE in Python
I tried to implement PPO in Python
I tried to implement CVAE with PyTorch
I tried to summarize everyone's remarks on slack with wordcloud (Python)
I tried to implement reading Dataset with PyTorch
I tried to get CloudWatch data with Python
I tried to output LLVM IR with Python
I tried to implement TOPIC MODEL in Python
I tried to automate sushi making with python
I tried to implement selection sort in python
I tried fp-growth with python
[Python] I tried to visualize the night on the Galactic Railroad with WordCloud!
I tried to implement PCANet
I tried with the top 100 PyPI packages> I tried to graph the packages installed on Python
I tried gRPC with Python
I tried scraping with python
I tried to implement StarGAN (1)
I tried to implement and learn DCGAN with PyTorch
I tried to get started with blender python script_Part 01
I tried to touch the CSV file with Python
I tried to draw a route map with Python
I tried to solve the soma cube with python
I tried to implement a pseudo pachislot in Python
I tried to get started with blender python script_Part 02
I tried to implement Dragon Quest poker in Python
I tried to implement time series prediction with GBDT
I tried to implement GA (genetic algorithm) in Python
I tried to automatically generate a password with Python3
I want to AWS Lambda with Python on Mac!
I tried to solve the problem with Python Vol.1
I tried to analyze J League data with Python
I tried to implement Grad-CAM with keras and tensorflow
I tried to implement SSD with PyTorch now (Dataset)
I tried to solve AOJ's number theory with Python
I tried to implement merge sort in Python with as few lines as possible
I tried to implement Deep VQE
I tried web scraping with python.
I tried to implement adversarial validation
I tried to implement hierarchical clustering
I tried to implement Realness GAN
I want to debug with Python
I tried running prolog with python 3.8.2.
I tried SMTP communication with Python
I tried to implement a volume moving average with Quantx
I tried to find the entropy of the image with python
I tried to simulate how the infection spreads with Python
I tried to make various "dummy data" with Python faker
I tried various methods to send Japanese mail with Python
I tried to implement a one-dimensional cellular automaton in Python
I tried to implement breakout (deception avoidance type) with Quantx
[Python] I tried to visualize tweets about Corona with WordCloud
Mayungo's Python Learning Episode 3: I tried to print numbers with print
I tried to implement ListNet of rank learning with Chainer
I tried to implement the mail sending function in Python
I tried to implement Harry Potter sort hat with CNN