Created
August 6, 2018 14:03
-
-
Save technillogue/43fed0b275153e73efa6e4be9740ee64 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
| from random import shuffle | |
| class Cell: | |
| def __init__(self, board, y, x): | |
| self.board = board | |
| self.y = y | |
| self.x = x | |
| self.mine = False | |
| self.flag = False | |
| self.revealed = False | |
| self.adjacent = 0 | |
| self.neighbours = [] | |
| def render(self): | |
| if self.revealed: | |
| if self.adjacent: | |
| return str(self.adjacent) | |
| else: | |
| return " " | |
| elif self.flag: | |
| return "F" | |
| else: | |
| return "X" | |
| def reveal(self): | |
| if not self.revealed: | |
| self.revealed = True | |
| if self.mine: | |
| return "loss" | |
| if not self.board.mines: | |
| self.board.place_mines() | |
| if not self.adjacent: | |
| for neighbour in self.neighbours: | |
| neighbour.reveal() | |
| def count_adjacent(self): | |
| i = j = (-1, 0, 1) | |
| for y_shift in i: | |
| for x_shift in j: | |
| exclude = ( | |
| (self.y == 0 and y_shift == -1) or | |
| (self.x == 0 and x_shift == -1) or | |
| (x_shift == 0 and y_shift == 0) | |
| ) | |
| if exclude: | |
| continue | |
| try: | |
| other = self.board.board[self.y + y_shift][self.x + y_shift] | |
| self.adjacent += int(other.mine) | |
| self.neighbours.append(other) | |
| except IndexError: | |
| pass | |
| class Board: | |
| def __init__(self, n=8): | |
| self.board = [[Cell(self, i, j) for i in range(n)] for j in range(n)] | |
| self.n = n | |
| self.mines = [] | |
| def render(self): | |
| print " " + "".join(map(str, range(self.n))) | |
| for n, line in enumerate (self.board): | |
| print str(n) + "".join([cell.render() for cell in line]) | |
| def place_mines(self, mines=10): | |
| cells = [cell for line in self.board for cell in line if not cell.revealed] | |
| shuffle(cells) | |
| self.mines = cells[:mines] | |
| for cell in self.mines: | |
| cell.mine = True | |
| for line in self.board: | |
| for cell in line: | |
| cell.count_adjacent() | |
| def move(self): | |
| action = raw_input("action?") | |
| flag = False | |
| if action.startswith("F"): | |
| action = action[1:] | |
| flag = True | |
| try: | |
| x, y = map(int, action.split(",", 1)) | |
| cell = self.board[y][x] | |
| except IndexError: | |
| print "out of bounds (indexed from 0)" | |
| return self.move() | |
| except ValueError: | |
| print "invalid command: just enter X,Y cordinates to reveal,\ | |
| prefix with F to flag" | |
| return self.move() | |
| if flag: | |
| cell.flag = True | |
| else: | |
| return cell.reveal() | |
| def play(self): | |
| print("no prefix to reveal, prefix with F to flag, followed by X,Y cordinates") | |
| while 1: | |
| self.render() | |
| if self.move() == "loss": | |
| print "you loose!" | |
| return False | |
| else: | |
| win = True | |
| for line in self.board: | |
| for cell in line: | |
| # cell is revealed, isn't a mine [doesn't disqualify] | |
| # cell is hidden, is a mine [doesn't disqualy] | |
| # cell is hidden but isn't a mine [disqualfied] | |
| if (not cell.revealed and not cell.mine): | |
| win = False | |
| if win: | |
| print "you win!" | |
| return True | |
| if __name__ == "__main__": | |
| board = Board() | |
| board.play() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment