"""Focused tactical and protocol regressions; run directly with Python 3.""" import contextlib import io from pathlib import Path import sys import unittest sys.path.insert(0, str(Path(__file__).resolve().parent)) import bot class BrainTests(unittest.TestCase): def setUp(self): bot.N = 15 bot.board.clear() def stones(self, points, colour=1): bot.board.update((p, colour) for p in points) def test_first_move(self): self.assertEqual(bot.move(), (7, 7)) def test_exact_five_in_every_direction(self): for dx, dy in bot.DIRECTIONS: bot.board.clear() self.stones([(7 + i * dx, 7 + i * dy) for i in (-2, -1, 1, 2)]) self.assertTrue(bot.evaluate((7, 7), 1)[0]) self.assertEqual(bot.move(), (7, 7)) def test_overline_is_not_win(self): self.stones([(x, 7) for x in (3, 4, 5, 7, 8)]) self.assertFalse(bot.evaluate((6, 7), 1)[0]) def test_win_before_block(self): self.stones([(x, 4) for x in range(4)], 1) self.stones([(x, 10) for x in range(4)], 2) self.assertEqual(bot.move(), (4, 4)) def test_block_opponent_broken_five(self): self.stones([(x, 7) for x in (3, 4, 6, 7)], 2) self.assertEqual(bot.move(), (5, 7)) def test_open_line_beats_closed(self): self.stones([(6, 7), (8, 7)]) open_score = bot.evaluate((7, 7), 1)[1] self.stones([(5, 7)], 2) self.assertGreater(open_score, bot.evaluate((7, 7), 1)[1]) def test_gap_four_has_winning_completion(self): self.stones([(5, 7), (8, 7), (9, 7)]) _, offsets, _ = bot.line_value(bot.line_at(6, 7, 1, 1, 0)) self.assertIn(1, offsets) def test_open_four_has_two_winning_points(self): self.stones([(5, 7), (6, 7), (8, 7)]) _, offsets, _ = bot.line_value(bot.line_at(7, 7, 1, 1, 0)) self.assertEqual(offsets, {-3, 2}) def test_edge_is_closed(self): self.stones([(0, 7), (1, 7)]) _, offsets, _ = bot.line_value(bot.line_at(2, 7, 1, 1, 0)) self.assertFalse(offsets) self.assertNotEqual(bot.line_at(2, 7, 1, 1, 0)[0], '.') def test_snapshot_restart_and_blocked_cells(self): commands = 'START 15\nBEGIN\nBOARD\n0,0,3\n1,0,2\nDONE\nRESTART\nBEGIN\nEND\n' out = io.StringIO() old_stdin = sys.stdin try: sys.stdin = io.StringIO(commands) with contextlib.redirect_stdout(out): bot.main() finally: sys.stdin = old_stdin lines = out.getvalue().splitlines() self.assertEqual(lines[0:2], ['OK', '7,7']) self.assertNotIn(lines[2], ['0,0', '1,0']) self.assertEqual(lines[3:], ['OK', '7,7']) self.assertEqual(bot.board, {(7, 7): 1}) def test_board_replaces_previous_position(self): self.stones([(14, 14)], 2) old_stdin = sys.stdin try: sys.stdin = io.StringIO('BOARD\n0,0,3\n1,0,2\nDONE\nEND\n') with contextlib.redirect_stdout(io.StringIO()): bot.main() finally: sys.stdin = old_stdin self.assertNotIn((14, 14), bot.board) self.assertEqual(bot.board[(0, 0)], 3) self.assertEqual(bot.board[(1, 0)], 2) self.assertEqual(len(bot.board), 3) if __name__ == '__main__': unittest.main()