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.
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
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])
Spécifiez le fichier, la taille des carrés et le rapport des bombes et exécutez.
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.)
Ci-dessous, spécifiez la position ouverte.
Lorsqu'elle est effacée, le nombre de cellules ouvertes et le temps écoulé s'affichent et le processus se termine.
Lorsqu'une entrée non spécifiée est reçue, elle boucle à l'infini comme indiqué dans la figure ci-dessous.
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)]
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.
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)
[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