diff --git a/exercises/queen-attack/example.py b/exercises/queen-attack/example.py index 5004b56b84..efec15c71a 100644 --- a/exercises/queen-attack/example.py +++ b/exercises/queen-attack/example.py @@ -1,27 +1,17 @@ -def board(pos1, pos2): - validate_position(pos1, pos2) - x1, y1 = pos1 - x2, y2 = pos2 - b = [['_'] * 8 for i in range(8)] - b[x1][y1] = 'W' - b[x2][y2] = 'B' - return [''.join(r) for r in b] +class Queen(object): + def __init__(self, row, column): + if not 0 <= row <= 7 or not 0 <= column <= 7: + raise ValueError("Invalid queen position: queen out of the board") + self.row = row + self.column = column - -def can_attack(pos1, pos2): - validate_position(pos1, pos2) - x1, y1 = pos1 - x2, y2 = pos2 - dx = x1 - x2 if x1 >= x2 else x2 - x1 - dy = y1 - y2 if y1 >= y2 else y2 - y1 - if dx == dy or dx == 0 or dy == 0: - return True - return False - - -def validate_position(pos1, pos2): - if any(x < 0 or x > 7 for x in pos1 + pos2): - raise ValueError('Invalid queen position: queen out of the board') - if pos1 == pos2: - raise ValueError('Invalid queen position: both queens in the same ' - 'square: {0}'.format(pos1)) + def can_attack(self, another_queen): + dx = abs(self.row - another_queen.row) + dy = abs(self.column - another_queen.column) + if dx == dy == 0: + raise ValueError( + 'Invalid queen position: both queens in the same square') + elif dx == dy or dx == 0 or dy == 0: + return True + else: + return False diff --git a/exercises/queen-attack/queen_attack.py b/exercises/queen-attack/queen_attack.py index 19e6501c0e..bc811e6164 100644 --- a/exercises/queen-attack/queen_attack.py +++ b/exercises/queen-attack/queen_attack.py @@ -1,6 +1,6 @@ -def board(white_position, black_position): - pass +class Queen(object): + def __init__(self, row, column): + pass - -def can_attack(white_position, black_position): - pass + def can_attack(self, another_queen): + pass diff --git a/exercises/queen-attack/queen_attack_test.py b/exercises/queen-attack/queen_attack_test.py index ea5a34e11d..5c1fa73198 100644 --- a/exercises/queen-attack/queen_attack_test.py +++ b/exercises/queen-attack/queen_attack_test.py @@ -1,92 +1,61 @@ import unittest -from queen_attack import board, can_attack +from queen_attack import Queen -# Tests adapted from `problem-specifications//canonical-data.json` @ v2.0.0 +# Tests adapted from `problem-specifications//canonical-data.json` @ v2.1.0 class QueenAttackTest(unittest.TestCase): + # Test creation of Queens with valid and invalid positions def test_queen_valid_position(self): try: - board((1, 1), (2, 2)) + Queen(2, 2) except ValueError: self.fail("Unexpected Exception") def test_queen_negative_row(self): with self.assertRaisesWithMessage(ValueError): - board((1, 1), (-2, 2)) + Queen(-2, 2) def test_queen_invalid_row(self): with self.assertRaisesWithMessage(ValueError): - board((1, 1), (8, 4)) + Queen(8, 4) def test_queen_negative_column(self): with self.assertRaisesWithMessage(ValueError): - board((1, 1), (2, -2)) + Queen(2, -2) def test_queen_invalid_column(self): with self.assertRaisesWithMessage(ValueError): - board((1, 1), (4, 8)) + Queen(4, 8) + # Test the ability of one queen to attack another def test_attack_false(self): - self.assertIs(can_attack((2, 4), (6, 6)), False) + self.assertIs(Queen(2, 4).can_attack(Queen(6, 6)), False) def test_attack_same_row(self): - self.assertIs(can_attack((2, 4), (2, 6)), True) + self.assertIs(Queen(2, 4).can_attack(Queen(2, 6)), True) def test_attack_same_column(self): - self.assertIs(can_attack((4, 5), (2, 5)), True) + self.assertIs(Queen(4, 5).can_attack(Queen(2, 5)), True) def test_attack_diagonal1(self): - self.assertIs(can_attack((2, 2), (0, 4)), True) + self.assertIs(Queen(2, 2).can_attack(Queen(0, 4)), True) def test_attack_diagonal2(self): - self.assertIs(can_attack((2, 2), (3, 1)), True) + self.assertIs(Queen(2, 2).can_attack(Queen(3, 1)), True) def test_attack_diagonal3(self): - self.assertIs(can_attack((2, 2), (1, 1)), True) + self.assertIs(Queen(2, 2).can_attack(Queen(1, 1)), True) def test_attack_diagonal4(self): - self.assertIs(can_attack((2, 2), (5, 5)), True) - - # Tests beyond this point are not part of the canonical data. - - # If either board or can_attack are called with an invalid board position - # they should raise a ValueError with a meaningful error message. - def test_invalid_position_can_attack(self): - with self.assertRaisesWithMessage(ValueError): - can_attack((0, 0), (7, 8)) - - def test_queens_same_position_board(self): - with self.assertRaisesWithMessage(ValueError): - board((2, 2), (2, 2)) + self.assertIs(Queen(2, 2).can_attack(Queen(5, 5)), True) + # Track-specific tests def test_queens_same_position_can_attack(self): with self.assertRaisesWithMessage(ValueError): - can_attack((2, 2), (2, 2)) - - def test_board1(self): - ans = ['________', - '________', - '___W____', - '________', - '________', - '______B_', - '________', - '________'] - self.assertEqual(board((2, 3), (5, 6)), ans) - - def test_board2(self): - ans = ['______W_', - '_______B', - '________', - '________', - '________', - '________', - '________', - '________'] - self.assertEqual(board((0, 6), (1, 7)), ans) + Queen(2, 2).can_attack(Queen(2, 2)) # Utility functions def setUp(self):