Skip to content

Instantly share code, notes, and snippets.

@IshitaTakeshi
Last active August 29, 2015 13:56
Show Gist options
  • Save IshitaTakeshi/9054260 to your computer and use it in GitHub Desktop.
Save IshitaTakeshi/9054260 to your computer and use it in GitHub Desktop.
#!/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