At an interview, I was asked to build a python program, using TDD, which would output the results of a minesweeper game. Not a fully functional game, just a small program that would take an array of bomb locations and print out a map of the board with all values exposed.
So, if you have a 3×3 board, and there is a bomb in each corner, it would print out something like this:
x 2 x 2 4 2 x 2 x
Or if you have a 3×3 board and there is only a bomb in the upper left corner, it would print out something like this:
x 1 0 1 1 0 0 0 0
I did not complete the task in the allotted time, but it was a fun programming exercise and I hope illuminating to the interviewers. I actually took it home and finished it up. Here’s the full text of the program:
class Board: def __init__(self, size = 1, bomblocations = []): self._size = size self._bomblocations = bomblocations def size(self): return self._size def _bombLocation(self,location): for onebomblocation in self._bomblocations: if onebomblocation == location: return 'x' def _isOnBoard(self,location): if location[0] =self._size: return False if location[1] >=self._size: return False return True def whatsAt(self,location): if self._bombLocation(location) == 'x': return 'x' if not self._isOnBoard(location): return None return self._numberOfBombsAdjacent(location) def _numberOfBombsAdjacent(self,location): bombcount = 0 # change x, then y currx = location[0] curry = location[1] for xincrement in [-1,0,1]: xtotest = currx + xincrement for yincrement in [-1,0,1]: ytotest = curry + yincrement #print 'testing: '+ str(xtotest) + ', '+str(ytotest)+ ', '+str(bombcount) if not self._isOnBoard([xtotest,ytotest]): continue if self._bombLocation([xtotest,ytotest]) == 'x': bombcount += 1 return bombcount def printBoard(self): x = 0 while x < self._size: y = 0 while y < self._size: print self.whatsAt([x,y]), y += 1 x += 1 print def main(): board = Board(15,[[0,1],[1,2],[2,4],[2,5],[3,5],[5,5]]) board.printBoard() if __name__ == "__main__": main()
And the tests:
import unittest import app class TestApp(unittest.TestCase): def setUp(self): pass def test_board_creation(self): newboard = app.Board() self.assertIsNotNone(newboard) def test_default_board_size(self): newboard = app.Board() self.assertEqual(1, newboard.size()) def test_constructor_board_size(self): newboard = app.Board(3) self.assertEqual(3, newboard.size()) def test_board_with_bomb(self): newboard = app.Board(3,[[0,0]]) self.assertEqual('x', newboard.whatsAt([0,0])) def test_board_with_n_bombs(self): newboard = app.Board(4,[[0,0],[3,3]]) self.assertEqual('x', newboard.whatsAt([0,0])) self.assertEqual('x', newboard.whatsAt([3,3])) def test_board_with_bomb_check_other_spaces_separated_bombs(self): newboard = app.Board(4,[[0,0],[3,3]]) self.assertEqual(1, newboard.whatsAt([0,1])) self.assertEqual(1, newboard.whatsAt([1,0])) self.assertEqual(1, newboard.whatsAt([1,1])) self.assertEqual(0, newboard.whatsAt([1,2])) self.assertEqual(0, newboard.whatsAt([2,1])) self.assertEqual(1, newboard.whatsAt([3,2])) self.assertEqual(1, newboard.whatsAt([2,3])) self.assertEqual(1, newboard.whatsAt([2,2])) def test_check_other_spaces_contiguous_bombs(self): newboard = app.Board(4,[[0,1],[0,0]]) self.assertEqual(1, newboard.whatsAt([0,2])) self.assertEqual(2, newboard.whatsAt([1,0])) self.assertEqual(0, newboard.whatsAt([2,1])) def test_off_the_board(self): newboard = app.Board(3,[[0,0],[1,2]]) self.assertEqual(None, newboard.whatsAt([3,3]))
This was written in python 2.7, and reminded me of the pleasure of small, from the ground up software (as opposed to gluing together libraries to achieve business objectives, which is what I do a lot of nowadays).