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.
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
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])
Specify the file, the size of the squares, and the ratio of the bombs, and execute.
Specify the initial position. The square is displayed. (* The initial position and adjacent squares are set so that no bombs are placed.)
Below, specify the open position.
When cleared, the number of open cells and the elapsed time are displayed and the process ends.
When an unspecified input is received, it loops infinitely as shown in the figure below.
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)]
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.
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)
[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