All pastes #1647940 Raw Edit

minefield3.py

public python v1 · immutable
#1647940 ·published 2009-10-29 16:09 UTC
rendered paste body
import unittestclass Cell(object):    def __init__(self, containsMine):        self.containsMine = containsMine        self.dug = False            def dig(self):        self.dug = True    def toBePlayedYet(self):        return not self.containsMine and not self.dugclass MineField(object):    @classmethod    def fromStrings(cls, *rows):        return cls([[Cell(ch != '.') for ch in row] for row in rows])        def __init__(self, rows):        self.rows = rows        self.gameOver = False        self.win = True            def dig(self, row, col):        thisCell = self.rows[row][col]        if thisCell.containsMine:            self._looseGame()            return        if thisCell.dug:            return        thisCell.dig()        self._digNeighborCells(row, col)        if self._noFreeCellsLeft():            self._winGame()                def _noFreeCellsLeft(self):        for row in self.rows:            for cell in row:                if cell.toBePlayedYet():                    return False        return True    def _digNeighborCells(self, row, col):        for neighborRow, neighborCol in self.getDiggingNeighborsCoordinates(row, col):            neighbor = self.rows[neighborRow][neighborCol]            if not neighbor.containsMine:                self.dig(neighborRow, neighborCol)                def isCellDug(self, row, col):        return self.rows[row][col].dug                def _looseGame(self):        self.gameOver = True        self.win = False        def _winGame(self):        self.gameOver = True        self.win = True            def getDiggingNeighborsCoordinates(self, row, col):        return list(self._iterDiggingNeighborsCoordinates(row, col))        def _iterDiggingNeighborsCoordinates(self, row, col):        if row-1 >= 0:            yield (row-1, col)        if col-1 >= 0:            yield (row, col-1)        if row+1 < self.numRows:            yield (row+1, col)        if col+1 < self.numCols:            yield (row, col+1)                def getCountingNeighborsCoordinates(self, row, col):        return list(self._iterCountingNeighborsCoordinates(row, col))        def _iterCountingNeighborsCoordinates(self, centerRow, centerCol):        for row, col in self._iterAllCountingNeighbors(centerRow, centerCol):            if (row >= 0 and row < self.numRows                and col >= 0 and col < self.numCols):                yield row, col        def _iterAllCountingNeighbors(self, row, col):        yield row-1, col        yield row-1, col-1        yield row, col-1        yield row+1, col-1        yield row+1, col        yield row+1, col+1        yield row, col+1        yield row-1, col+1                @property    def numRows(self):        return len(self.rows)                @property    def numCols(self):        return len(self.rows[0])        def getNumberOfMinesAround(self, centerRow, centerCol):        numMines = 0        for row, col in self.getCountingNeighborsCoordinates(centerRow, centerCol):            if self.rows[row][col].containsMine:                numMines += 1        return numMines        def toString(self):        return ''.join(self._iterCellStrings())        def _iterCellStrings(self):        for rowNum in xrange(self.numRows):            for colNum in xrange(self.numCols):                yield self._renderCell(rowNum, colNum)    def _renderCell(self, rowNum, colNum):        cell = self.rows[rowNum][colNum]        if not cell.dug:            return '#'        numMines = self.getNumberOfMinesAround(rowNum, colNum)        if numMines == 0:            return '.'        else:            return str(numMines)        class MineFieldTestCase(unittest.TestCase):    def test_one_cell_with_no_mine_dig_the_cell_and_win(self):        f = MineField.fromStrings('.')        self.assertFalse(f.isCellDug(0,0))        f.dig(0,0)        self.assertTrue(f.gameOver)        self.assertTrue(f.win)        self.assertTrue(f.isCellDug(0,0))    def test_one_cell_with_one_mine_dig_the_cell_and_loose(self):        f = MineField.fromStrings('X')        f.dig(0,0)        self.assertTrue(f.gameOver)        self.assertFalse(f.win)    def test_4_cells_with_3_mines_dig_the_free_cell_and_win(self):        f = MineField.fromStrings('.X',                                   'XX')        f.dig(0,0)        self.assertTrue(f.gameOver)        self.assertTrue(f.win)        self.assertEquals(f.getNumberOfMinesAround(0,0), 3)    def test_4_cells_with_2_mines_dig_top_left_and_find_both_dug(self):        f = MineField.fromStrings('.X',                                   '.X')        f.dig(0,0)        self.assertTrue(f.isCellDug(0,0))        self.assertTrue(f.isCellDug(1,0))        self.assertFalse(f.isCellDug(0,1))        self.assertFalse(f.isCellDug(1,1))        self.assertTrue(f.gameOver)        self.assertTrue(f.win)        self.assertEquals(f.getNumberOfMinesAround(0,0), 2)    def test_9_cells_with_1_mine_in_the_middle_dig_top_left_and_find_all_dug_but_mine(self):        f = MineField.fromStrings('...',                                   '.X.',                                  '...')        f.dig(0,0)        self.assertTrue(f.isCellDug(0,0))        self.assertTrue(f.isCellDug(1,0))        self.assertTrue(f.isCellDug(2,0))        self.assertTrue(f.isCellDug(2,1))        self.assertTrue(f.isCellDug(2,2))        self.assertTrue(f.isCellDug(1,2))        self.assertTrue(f.isCellDug(0,2))        self.assertTrue(f.isCellDug(0,1))        self.assertFalse(f.isCellDug(1,1))        self.assertTrue(f.gameOver)        self.assertTrue(f.win)        self.assertEquals(f.getNumberOfMinesAround(0,0), 1)    def test_9_cells_with_3_mine_acting_as_barrier_in_the_middle_dig_top_left_keep_playing(self):        f = MineField.fromStrings('.X.',                                   '.X.',                                  '.X.')        f.dig(0,0)        self.assertFalse(f.gameOver)        self.assertEquals(f.getNumberOfMinesAround(0,0), 2)        self.assertEquals(f.getNumberOfMinesAround(1,0), 3)    def test_real_game(self):        f = MineField.fromStrings('..X..',                                   '..XXX',                                  '.....',                                  '.....')        f.dig(0,0)        self.assertEquals(f.toString(), ''.join(['.2###',                                                 '.2###',                                                 '.1232',                                                 '.....',                                                 ]))        class NeighborsTestCase(unittest.TestCase):    def setUp(self):        self.f = MineField.fromStrings('...',                                        '...',                                       '...')    def test_9_cells_cell_in_the_middle_has_8_counting_neighbors(self):        neighbors = self.f.getCountingNeighborsCoordinates(1,1)        self.assertEquals(neighbors, [(0,1), (0,0), (1,0), (2,0), (2,1), (2,2), (1,2), (0, 2)])            def test_9_cells_cell_in_the_middle_has_4_digging_neighbors(self):        neighbors = self.f.getDiggingNeighborsCoordinates(1,1)        self.assertEquals(neighbors, [(0,1), (1,0), (2,1), (1,2)])    def test_9_cells_cell_left_has_3_digging_neighbors(self):        neighbors = self.f.getDiggingNeighborsCoordinates(1,0)        self.assertEquals(neighbors, [(0,0), (2,0), (1,1)])    def test_9_cells_cell_top_has_3_digging_neighbors(self):        neighbors = self.f.getDiggingNeighborsCoordinates(0,1)        self.assertEquals(neighbors, [(0,0), (1,1), (0,2)])    def test_9_cells_cell_right_has_3_digging_neighbors(self):        neighbors = self.f.getDiggingNeighborsCoordinates(1,2)        self.assertEquals(neighbors, [(0,2), (1,1), (2,2)])    def test_9_cells_cell_top_left_has_2_digging_neighbors(self):        neighbors = self.f.getDiggingNeighborsCoordinates(0,0)        self.assertEquals(neighbors, [(1,0), (0,1)])if __name__ == '__main__':    unittest.main()