Skip to content

Instantly share code, notes, and snippets.

@zelark
Last active August 29, 2015 14:25
Show Gist options
  • Save zelark/44c708a6a7d8433c19b5 to your computer and use it in GitHub Desktop.
Save zelark/44c708a6a7d8433c19b5 to your computer and use it in GitHub Desktop.
All you need to play with it is Python 3
from random import sample
class Cell:
BOMB = 'B'
FLAG = 'F'
def __init__(self):
self.status = 0
self.content = 0
def __str__(self):
if self.isOpened():
ret = str(self.content)
elif self.isFlagged():
ret = Cell.FLAG
else:
ret = '#'
return ret
def __repr__(self):
return str(self.content)
def open(self):
self.status = 1
def mark(self):
self.status = 2
def setBomb(self):
self.content = Cell.BOMB
def incCounterOfBombs(self):
self.content += 1
def isClosed(self):
return True if self.status == 0 else False
def isOpened(self):
return True if self.status == 1 else False
def isFlagged(self):
return True if self.status == 2 else False
def isQuestioned(self):
return True if self.status == 3 else False
def hasBomb(self):
return True if self.content == Cell.BOMB else False
def hasZero(self):
return True if self.content == 0 else False
def hasNonZero(self):
return True if self.content in range(1,9) else False
class SocialCell(Cell):
def __init__(self):
self.neighbors = []
super().__init__()
def addNeighbor(self, cell):
self.neighbors.append(cell)
def getNeighbors(self):
return self.neighbors
def incNeighbors(self):
for neighbor in self.neighbors:
neighbor.content += 1
class Game:
boards = {
'small': (9, 9, 10),
'medium': (16, 16, 40),
'large': (16, 30, 81),
'test': (9, 9, 50)}
shifts = (
(0, -1), (1, -1), (1, 0), (1, 1),
(0, 1), (-1, 1), (-1, 0), (-1, -1))
def __init__(self, board):
self.gameOver = False
self.height, self.width, self.bombCount = self.boards[board]
self.size = self.width * self.height
self.gameBoard = []
for i in range(self.size):
self.gameBoard.append(SocialCell())
def showBoard(self, godMode=False):
for offset, cell in enumerate(self.gameBoard):
if offset % self.width == 0:
print("\n{:>2} | ".format(offset // self.width), end=' ')
if not godMode:
print("{}".format(cell), end=' ')
else:
print("{}".format(cell.__repr__()), end=' ')
print()
def showGameInfo(self):
print("height: {}\nwidth: {}\nbombs count: {}"
.format(self.height, self.width, self.bombCount))
def checkWin(self):
counterOfOpened = 0
for cell in self.gameBoard:
if cell.isOpened() and not cell.hasBomb():
counterOfOpened += 1
return True if self.size - self.bombCount == counterOfOpened else False
def checkGameOver(self):
return self.gameOver
def checkInBoard(self, x, y):
if x in range(self.width) and y in range(self.height):
return True
else:
return False
def getCell(self, x, y):
offset = self.getOffsetByLocation(x, y)
return self.gameBoard[offset]
def openCell(self, x, y):
if self.checkInBoard(x, y):
cell = self.getCell(x, y).open()
if cell.hasZero():
self.openArea(cell)
elif cell.hasBomb():
self.gameOver = True
def markCell(self, x, y):
if self.checkInBoard(x, y):
self.getCell(x, y).mark()
def getOffsetByLocation(self, x, y):
return y * self.width + x
def getLocationByOffset(self, offset):
return (offset % self.width, offset // self.width)
def setBombs(self):
for offset in sample(range(0, self.size-1), self.bombCount):
self.gameBoard[offset].setBomb()
def calcBoards(self):
for cell in self.gameBoard:
if cell.hasBomb():
cell.incNeighbors()
def makeFriends(self):
for offset, cell in enumerate(self.gameBoard):
x, y = self.getLocationByOffset(offset)
self.findNeighbors(cell, x, y)
def findNeighbors(self, cell, x, y):
for dx, dy in self.shifts:
offset = self.getOffsetByLocation(x+dx, y+dy)
if (self.checkInBoard(x+dx, y+dy)
and not self.gameBoard[offset].hasBomb()):
cell.addNeighbor(self.gameBoard[offset])
def openArea(self, cell):
if cell.hasNonZero():
return
for neighbor in cell.getNeighbors():
if not neighbor.isOpened():
neighbor.open()
self.openArea(neighbor)
def main():
game = Game('small')
game.showGameInfo()
game.setBombs()
game.makeFriends()
game.calcBoards()
game.showBoard()
while True:
try:
text = input('>> ')
except (EOFError, KeyboardInterrupt):
print()
break
if not text:
continue
try:
mode, y, x = text.split()
except ValueError:
mode, y, x = text, '', ''
if x.isdigit() and y.isdigit():
x = int(x)
y = int(y)
elif mode == 'i' or mode == 'info':
game.showGameInfo()
continue
elif mode == 'b' or mode == 'board':
game.showBoard()
continue
elif mode == 'gm':
game.showBoard(godMode=True)
continue
elif mode == 'h' or mode == 'help':
print(
"\nh, help - this help"
"\ni, info - the info about the game"
"\nb, board - show the board"
"\no, open y x - open a cell with y and x"
"\nm, mark y x - mark a cell with y and x as a bomb")
else:
continue
if mode == 'o' or mode == 'open':
game.openCell(x, y)
game.showBoard()
if game.checkWin():
print("[GameBot]: You win!")
if game.checkGameOver():
print("[GameBot]: You lose.")
elif mode == 'm' or mode == 'mark':
game.markCell(x, y)
game.showBoard()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment