Ich wollte eine Minenräummaschine auf dem Terminal implementieren, also habe ich sie implementiert. Als ich mit dem Programmieren anfing, habe ich es tatsächlich einmal in C implementiert, aber es wurde nicht abgeschlossen, sodass es auch als Überprüfung dient.
Minesweeper ist ein Ein-Personen-Computerspiel, das in den 1980er Jahren erfunden wurde. Der Zweck des Spiels ist es, meine aus dem Minenfeld zu entfernen.
Ich habe auch gespielt, als ich in der Grundschule war. (Ich werde älter) Übrigens, wie viel wissen Sie, dass Sie jetzt Grundschüler sind?
Übrigens können Sie jetzt mit Chrome spielen, also [auf jeden Fall](https://www.google.com/search?q=Minesweeper&oq=min&aqs=chrome.1.69i57j69i59l2j0l2j69i61j69i60l2.2095j0j7&sourceid=chrome&ie
Der Umriss entspricht (wahrscheinlich) der folgenden Site. [Mine Sweeper-Implementierung, die auf dem Terminal abgespielt werden kann](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])
Geben Sie die Datei, die Größe der Quadrate und das Verhältnis der Bomben an und führen Sie sie aus.
Geben Sie die Ausgangsposition an. Das Quadrat wird angezeigt. (* Es ist so eingestellt, dass keine Bomben an der Ausgangsposition und auf angrenzenden Feldern platziert werden.)
Geben Sie unten die offene Position an.
Nach dem Löschen werden die Anzahl der offenen Zellen und die verstrichene Zeit angezeigt und der Vorgang endet.

Wenn eine nicht spezifizierte Eingabe empfangen wird, wird sie wie in der folgenden Abbildung gezeigt unendlich wiederholt.

Beachten Sie, dass beim Aktualisieren einer Liste im folgenden Code alle Listen aktualisiert werden, wenn Sie das zum Zeitpunkt der Implementierung erforderliche zweidimensionale Array generieren.
Fehlerbeispiel
    #Eine zweidimensionale Anordnung, die die Position der Bombe und die Anzahl der umgebenden Bomben enthält
    mine_list = [["N"] * args.n]
    #Ein zweidimensionales Array, das angibt, ob eine Zelle geöffnet wurde
    opened_ls = [[False] * args.n]
Wie unten gezeigt, habe ich es mit der Listeneinschlussnotation initialisiert und nichts bekommen.
Erfolgsgeschichte
    #Eine zweidimensionale Anordnung, die die Position der Bombe und die Anzahl der umgebenden Bomben enthält
    mine_list = [["N"] * args.n for i in range(args.n)]
    #Ein zweidimensionales Array, das angibt, ob eine Zelle geöffnet wurde
    opened_ls = [[False] * args.n for i in range(args.n)]
Es ist ein einfaches Spiel, aber es kann nicht implementiert werden, ohne die Grundlagen des Programms zu verstehen. Daher war es eine gute Gelegenheit, die Grundlagen zu überprüfen.
Code Der vollständige Code ist unten. Es wurde auch auf [Github] veröffentlicht (https://github.com/hirogithu/minsweeper_on_terminal).
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):
                #Bombeninstallation
                if bomb_count >= n_bomb:
                    break
                if random.randint(0, 100) > 100 * (1 - args.bomb_rate):
                    #Schließt die anfängliche Eingabeposition und Umgebung aus
                    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)
[Mine Sweeper-Implementierung, die auf dem Terminal abgespielt werden kann](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