J'ai essayé d'implémenter Mine Sweeper sur un terminal avec python

Déclencheur

Je voulais implémenter une balayeuse de mines sur le terminal, alors je l'ai implémentée. En fait, quand j'ai commencé la programmation, je l'ai implémenté une fois en C, mais ce n'était pas terminé, donc ça sert aussi de revue.

Vue d'ensemble du balayeur de mines

Minesweeper est un jeu vidéo pour une personne inventé dans les années 1980. Le but du jeu est de retirer le mien du champ de mines.

J'ai aussi joué quand j'étais à l'école primaire. (Je vieillis) Au fait, dans quelle mesure savez-vous que vous êtes un élève du primaire maintenant?

En passant, vous pouvez désormais jouer avec Chrome, donc par tous les moyens

Aperçu de la mise en œuvre

Le plan est le même que le site suivant (probablement). [Implémentation de la balayeuse de mines qui peut être lue sur le 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])

Aperçu de l'application

  1. Spécifiez le fichier, la taille des carrés et le rapport des bombes et exécutez.

  2. Spécifiez la position initiale. Le carré s'affiche. (* La position initiale et les cases adjacentes sont définies de sorte qu'aucune bombe ne soit placée.)

  3. Ci-dessous, spécifiez la position ouverte.

  4. Lorsqu'elle est effacée, le nombre de cellules ouvertes et le temps écoulé s'affichent et le processus se termine. image.png

  5. Lorsqu'une entrée non spécifiée est reçue, elle boucle à l'infini comme indiqué dans la figure ci-dessous. image.png

Point Hamari

Génération d'un tableau bidimensionnel

Notez que si vous mettez à jour une liste dans le code ci-dessous, toutes les listes seront mises à jour lorsque vous générerez le tableau bidimensionnel requis au moment de l'implémentation.

Exemple d'échec


    #Un tableau bidimensionnel qui contient la position de la bombe et le nombre de bombes environnantes
    mine_list = [["N"] * args.n]

    #Un tableau à deux dimensions qui indique si une cellule a été ouverte
    opened_ls = [[False] * args.n]

Comme indiqué ci-dessous, je l'ai initialisé avec la notation d'inclusion de liste et je n'ai rien obtenu.

Succès


    #Un tableau bidimensionnel qui contient la position de la bombe et le nombre de bombes environnantes
    mine_list = [["N"] * args.n for i in range(args.n)]

    #Un tableau à deux dimensions qui indique si une cellule a été ouverte
    opened_ls = [[False] * args.n for i in range(args.n)]

Impressions

C'est un jeu simple, mais il ne peut pas être implémenté sans comprendre les bases du programme. C'était donc une bonne occasion de revoir les bases.

Problèmes et points à améliorer

Code Le code complet est ci-dessous. Il a également été publié sur 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):
                #installation de bombes
                if bomb_count >= n_bomb:
                    break
                if random.randint(0, 100) > 100 * (1 - args.bomb_rate):
                    #Exclut la position d'entrée initiale et l'environnement
                    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)

référence

[Implémentation de la balayeuse de mines qui peut être lue sur le 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

J'ai essayé d'implémenter Mine Sweeper sur un terminal avec python
J'ai essayé d'implémenter le perceptron artificiel avec python
J'ai essayé d'implémenter PLSA en Python
J'ai essayé d'implémenter Autoencoder avec TensorFlow
J'ai essayé d'implémenter la permutation en Python
J'ai essayé d'implémenter PLSA dans Python 2
J'ai essayé d'implémenter ADALINE en Python
J'ai essayé d'implémenter PPO en Python
J'ai essayé d'implémenter CVAE avec PyTorch
J'ai essayé de résumer les remarques de tout le monde sur le slack avec wordcloud (Python)
J'ai essayé d'implémenter la lecture de Dataset avec PyTorch
J'ai essayé d'obtenir des données CloudWatch avec Python
J'ai essayé de sortir LLVM IR avec Python
J'ai essayé d'implémenter TOPIC MODEL en Python
J'ai essayé d'automatiser la fabrication des sushis avec python
J'ai essayé d'implémenter le tri sélectif en python
J'ai essayé fp-growth avec python
[Python] J'ai essayé de visualiser la nuit du chemin de fer de la galaxie avec WordCloud!
J'ai essayé d'implémenter PCANet
J'ai essayé avec les 100 meilleurs packages PyPI> J'ai essayé de représenter graphiquement les packages installés sur Python
J'ai essayé gRPC avec Python
J'ai essayé de gratter avec du python
J'ai essayé d'implémenter StarGAN (1)
J'ai essayé d'implémenter et d'apprendre DCGAN avec PyTorch
J'ai essayé de démarrer avec le script python de blender_Part 01
J'ai essayé de toucher un fichier CSV avec Python
J'ai essayé de résoudre Soma Cube avec python
J'ai essayé d'implémenter un pseudo pachislot en Python
J'ai essayé de démarrer avec le script python de blender_Partie 02
J'ai essayé d'implémenter le poker de Drakue en Python
J'ai essayé d'implémenter GA (algorithme génétique) en Python
Je veux AWS Lambda avec Python sur Mac!
J'ai essayé de résoudre le problème avec Python Vol.1
J'ai essayé d'implémenter Grad-CAM avec keras et tensorflow
J'ai essayé d'implémenter SSD avec PyTorch maintenant (Dataset)
J'ai essayé de résoudre la théorie des nombres entiers d'AOJ avec Python
J'ai essayé d'implémenter le tri par fusion en Python avec le moins de lignes possible
J'ai essayé d'implémenter Deep VQE
J'ai essayé webScraping avec python.
J'ai essayé de mettre en place une validation contradictoire
J'ai essayé d'implémenter Realness GAN
Je veux déboguer avec Python
J'ai essayé d'exécuter prolog avec python 3.8.2.
J'ai essayé la communication SMTP avec Python
J'ai essayé d'implémenter une ligne moyenne mobile de volume avec Quantx
J'ai essayé de trouver l'entropie de l'image avec python
J'ai essayé de simuler la propagation de l'infection avec Python
J'ai essayé de créer diverses "données factices" avec Python faker
J'ai essayé différentes méthodes pour envoyer du courrier japonais avec Python
J'ai essayé d'implémenter un automate cellulaire unidimensionnel en Python
J'ai essayé de mettre en œuvre une évasion (type d'évitement de tromperie) avec Quantx
[Python] J'ai essayé de visualiser des tweets sur Corona avec WordCloud
Mayungo's Python Learning Episode 3: J'ai essayé d'imprimer des nombres
J'ai essayé d'implémenter ListNet d'apprentissage de rang avec Chainer
J'ai essayé d'implémenter la fonction d'envoi de courrier en Python
J'ai essayé de mettre en œuvre le chapeau de regroupement de Harry Potter avec CNN