Last active
August 29, 2015 13:56
-
-
Save IshitaTakeshi/9054260 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# -*- coding: utf-8 -*- | |
# | |
# マインスイーパー | |
# コマンドライン引数にヨコ、タテ、地雷の数を渡してあげると動きます | |
# 入力を求められるので掘りたいマスの座標をスペースで区切って渡してあげてください | |
# | |
import sys | |
import random | |
#you should write comments in English even if it is not published | |
#don't be afraid of making mistakes | |
#so many pep8 errors are in this code. if you want to use python for | |
#a long time, you should read PEP8 | |
#http://www.python.org/dev/peps/pep-0008/ | |
#and pep8 command is very convenience. I recommend. | |
class MineSweeper(object): | |
def __init__(self, width, height, mines): | |
# 地雷のリスト | |
self.mines = [] | |
for _ in range(mines): | |
self.mines.append(Cell(ismine=True)) | |
#in this case, it is more readable if an argument is specified with | |
#the name | |
# 通常のセルのリスト | |
self.normals = [] | |
for _ in range(width * height - mines): | |
self.normals.append(Cell(ismine=False)) | |
# マップを表現する2次元リスト | |
#self.grid = self.mines + self.normals | |
#this is confusing because actually this is a 1d list | |
#but you say this is a 2d list | |
#I noticed this will be reshaped | |
mines = self.mines + self.normals | |
random.shuffle(mines) | |
#in PEP8, the max characters num per line is 79 | |
#1d to 2d here | |
#I felt your way is long but this way is still not clear enough | |
self.grid = [] | |
for line in range(height): | |
self.grid.append(mines[width*line: width*(line+1)]) | |
#self.grid = [mines[i:i+width] for i in | |
# range(0, width * height, width)] | |
# ダミーのセルを追加 | |
for row in self.grid: | |
row.append(Cell(ismine=False)) | |
self.grid.append([Cell(ismine=False)] * (width + 1)) | |
for x in range(width): | |
for y in range(height): | |
cell = self.grid[x][y] | |
# セルの座標 | |
cell.x, cell.y = x, y | |
# セルの周囲のセル | |
cell.mines_around.append(self.grid[x-1][y-1]) | |
cell.mines_around.append(self.grid[x-1][y]) | |
cell.mines_around.append(self.grid[x-1][y+1]) | |
cell.mines_around.append(self.grid[x][y-1]) | |
cell.mines_around.append(self.grid[x][y+1]) | |
cell.mines_around.append(self.grid[x+1][y-1]) | |
cell.mines_around.append(self.grid[x+1][y]) | |
cell.mines_around.append(self.grid[x+1][y+1]) | |
# セルの周囲の地雷の数 | |
#cell.n_mines_around = len(list(filter(lambda x: x.ismine, cell.mines_around))) | |
#this way is much clearer, right? | |
nmines = 0 | |
for m in cell.mines_around: | |
if(m.ismine): | |
nmines += 1 | |
cell.n_mines_around = nmines | |
def dig(self, x, y): | |
self.grid[x][y].dig() | |
if self.count_remain() == 0: | |
print('CLEAR ;)') | |
sys.exit() | |
return | |
def count_remain(self): | |
count = 0 | |
for m in self.normals: | |
if(m.isdigged): | |
count += 1 | |
return count | |
#return len(list(filter(lambda x: not x.isdigged, self.normals))) | |
class Cell(object): | |
"""マス目1つを表すクラス""" | |
def __init__(self, ismine): | |
self.ismine = ismine | |
self.isdigged = False | |
self.x = 0 | |
self.y = 0 | |
#self.mines_around = 0 | |
#"mines" means mine objects so `type(mines[0])` should be `Cell` | |
#"n_mines" means number of mines so type(n_mines) should be int | |
self.n_mines_around = 0 | |
#so the name of this variable sould be `mines_around` | |
#self.arounds = [] | |
self.mines_around = [] | |
def dig(self): | |
if self.isdigged: | |
return | |
self.isdigged = True | |
if self.ismine: | |
#I suppose Notimplementederror shouldn't be used in this | |
#case... | |
raise NotImplementedError | |
elif self.n_mines_around == 0: | |
for cell in self.mines_around: | |
cell.dig() | |
if __name__ == '__main__': | |
# やっつけ仕事 | |
width = int(sys.argv[1]) | |
height = int(sys.argv[2]) | |
mines = int(sys.argv[3]) | |
game = MineSweeper(width, height, mines) | |
#Python 3 doesn't allow the format like '%d' % num | |
#"some strings {}".format(num) is recommended" | |
while True: | |
print(' |' + '|'.join(map(lambda x: "{:02d}".format(x), | |
range(len(game.grid[0]) - 1))) + '|') | |
for y in range(len(game.grid)-1): | |
sys.stdout.write("{:02d}|".format(y)) | |
for x in range(len(game.grid[y])- 1): | |
if game.grid[x][y].isdigged: | |
if game.grid[x][y].n_mines_around != 0: | |
sys.stdout.write("{:2d}".format( | |
game.grid[x][y].n_mines_around)) | |
else: | |
sys.stdout.write(' ') | |
#elif game.grid[x][y].ismine: | |
# sys.stdout.write(' *') | |
else: | |
#sys.stdout.write('%2d' % game.grid[x][y].mines_around) | |
sys.stdout.write('XX') | |
sys.stdout.write('|') | |
sys.stdout.write("{:02d}\n".format(y)) | |
#yeah this line is dirty as you say. | |
#use the for statement, not lambda. | |
print(' |' + '|'.join(map(lambda x: "{:02d}".format(x), | |
range(len(game.grid[0])-1))) + '|') | |
game.dig(*map(lambda x: int(x), input().split())) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment