class LifeGame(object): """ Game of life. This class controls a game cycle triggered by timer. Attributes: game_map: GameMap instance. """ def __init__(self, map_rows=10, map_cols=10, life_init_possibility=0.5): self.game_map = GameMap(map_rows, map_cols) self.game_map.reset(life_init_possibility) def print_map(self): """Clear the console, then print the map""" os.system('cls' if os.name == 'nt' else 'clear') self.game_map.print_map() def game_cycle(self): nc_map = self.game_map.get_neighbor_count_map() for row in range(self.game_map.rows): for col in range(self.game_map.cols): nc = nc_map[row][col] if nc < 2 or nc > 3: self.game_map.set(row, col, 0) elif nc == 3: self.game_map.set(row, col, 1) self.print_map()
class TestGameMap(TestCase): def setUp(self): self.gmap = GameMap(4, 3) def test_rows(self): self.assertEqual(4, self.gmap.rows, "invalid rows") def test_cols(self): self.assertEqual(3, self.gmap.cols, "invalid cols") @patch('random.random', new=Mock(side_effect=chain(cycle([0.3, 0.6, 0.9])))) def test_reset(self): self.gmap.reset() for i in range(4): self.assertEqual(1, self.gmap.get(i, 0)) for j in range(1, 3): self.assertEqual(0, self.gmap.get(i, j)) def test_get_set(self): self.assertEqual(0, self.gmap.get(0, 0), "invalid value") self.gmap.set(0, 0, 1) self.assertEqual(1, self.gmap.get(0, 0), "invalid value") def test_get_neighbor_count(self): expected_value = [[8] * 3] * 4 self.gmap.cells = [[1] * 3] * 4 for i in range(4): for j in range(3): self.assertEqual(expected_value[i][j], self.gmap.get_neighbor_count(i, j), '%d,%d' % (i, j)) @patch('game_map.GameMap.get_neighbor_count', new=Mock(return_value=8)) def test_get_neighbor_count_map(self): expected_value = [[8] * 3] * 4 self.assertEqual(expected_value, self.gmap.get_neighbor_count_map()) def test_set_map(self): self.assertRaises(TypeError, self.gmap.set_map, {1, 2, 3}) self.assertRaises(AssertionError, self.gmap.set_map, [[1] * 3] * 3) self.assertRaises(TypeError, self.gmap.set_map, [['1'] * 3] * 4) self.assertRaises(AssertionError, self.gmap.set_map, [[10] * 3] * 4) expected_value = [[1] * 3] * 4 self.gmap.set_map(expected_value) self.assertEqual(expected_value, self.gmap.cells) def test_print_map(self): self.gmap.cells = [[1, 0, 1], [0, 1, 1], [1, 1, 1], [0, 0, 0]] with patch('builtins.print') as mock: self.gmap.print_map() mock.assert_has_calls( [call('1 0 1'), call('0 1 1'), call('1 1 1'), call('0 0 0')])
class LifeGame(object): def __init__(self, map_rows=10, map_cols=10, life_init_possibility=0.5): self.game_map = GameMap(map_rows, map_cols) self.game_map.reset(life_init_possibility) def game_cycle(self): nc_map = self.game_map.get_neighbor_count_map() for row in range(self.game_map.rows): for col in range(self.game_map.cols): nc = nc_map[row][col] if nc < 2 or nc > 3: self.game_map.set(row, col, 0) elif nc == 3: self.game_map.set(row, col, 1)
class LifeGame(object): def __init__(self, map_rows, map_cols, life_init_ratio): """将在主程序中初始化实例""" self.map_rows = map_rows self.map_cols = map_cols self.life_init_ratio = life_init_ratio self.game_map = GameMap(map_rows, map_rows) self.game_map.reset(life_init_ratio) def game_cycle(self): """ 进行一次游戏循环,将在此完成地图的更新 将在计时器触发时被调用 """ temp = self.game_map (rows, cols) = temp.map.shape for i in range(rows): for j in range(cols): neighbors = temp.get_neighbor_count(i, j) if (neighbors >= 4 or neighbors == 1): self.game_map.set(i, j, 0) elif (neighbors == 3): self.game_map.set(i, j, 1) else: continue self.print_map() def print_map(self): """由于暂时没有UI模块,因此先在逻辑模块进行地图的呈现""" # print(self.game_map) (rows, cols) = self.game_map.map.shape print( "===================================================================================" ) for i in range(rows): for j in range(cols): print(self.game_map.map[i, j], end=' ') print("\n")
class LifeGame(object): '''生命游戏''' def __init__(self, map_rows=10, map_cols=10, life_init_possibility=0.5): self.game_map = GameMap(map_rows, map_cols) self.game_map.reset(life_init_possibility) def print_map(self): '''打印结果''' os.system('cls' if os.name == 'nt' else 'clear') self.game_map.print_map() def game_cycle(self): '''生命游戏循环时的赋值''' nc_map = self.game_map.get_neighbor_count_map() for row in range(self.game_map.rows): for col in range(self.game_map.cols): nc = nc_map[row][col] if nc < 2 or nc > 3: self.game_map.set(row, col, 0) elif nc == 3: self.game_map.set(row, col, 1) self.print_map()
class MapWindow: def __init__(self): self.caption = None self.game_map = GameMap() def set_caption(self, language): pg.font.init() font = pg.font.SysFont('Arial', 35, True) if language == 'English': text = eng.ENG_MAPWINDOW_CAPTION else: text = rus.RUS_MAPWINDOW_CAPTION self.caption = font.render(text, True, WHITE) def reset_data(self): self.game_map.reset() def update(self, dt): self.game_map.update(dt) def draw(self, screen): screen.blit(self.caption, (365, 110)) self.game_map.draw(screen)
class TestGameMap(TestCase): def setUp(self): self.game_map = GameMap(4, 3) def test_rows(self): self.assertEqual(4, self.game_map.rows, "Should get correct rows") def test_cols(self): self.assertEqual(3, self.game_map.cols, "Should get correct cols") @patch('random.random', new=Mock(side_effect=chain(cycle([0.3, 0.6, 0.9])))) def test_reset(self): self.game_map.reset() for i in range(0, 4): self.assertEqual(1, self.game_map.get(i, 0)) for j in range(1, 3): self.assertEqual(0, self.game_map.get(i, j)) def test_get_set(self): self.assertEqual(0, self.game_map.get(0, 0), "Cells init to zero") self.game_map.set(0, 0, 1) self.assertEqual(1, self.game_map.get(0, 0), "Should get value set by set") def test_get_neighbor_count(self): expected_value = [[8] * 3] * 4 self.game_map.cells = [[1] * 3] * 4 for i in range(0, 4): for j in range(0, 3): x = self.game_map.get_neighbor_count(i, j) self.assertEqual(expected_value[i][j], x, '(%d,%d)' % (i, j)) @patch('game_map.GameMap.get_neighbor_count', new=Mock(return_value=8)) def test_get_neighbor_count_map(self): expected_value = [[8] * 3] * 4 self.assertEqual(expected_value, self.game_map.get_neighbor_count_map()) def test_set_map(self): self.assertRaises(TypeError, self.game_map.set_map, {(0, 0): 1}) self.assertRaises(AssertionError, self.game_map.set_map, [[1] * 3] * 3) self.assertRaises(TypeError, self.game_map.set_map, [['1'] * 3] * 4) self.assertRaises(AssertionError, self.game_map.set_map, [[2] * 3] * 4) self.game_map.set_map([[1] * 3] * 4) self.assertEqual([[1] * 3] * 4, self.game_map.cells) def test_print_map(self): self.game_map.cells = [[0, 1, 1], [0, 0, 1], [1, 1, 1], [0, 0, 0]] with patch('builtins.print') as mock: self.game_map.print_map() mock.assert_has_calls([ call('0 1 1'), call('0 0 1'), call('1 1 1'), call('0 0 0'), ]) self.game_map.cells = [[1, 1, 1], [1, 1, 1], [1, 1, 1], [1, 1, 1]] with patch('builtins.print') as mock: self.game_map.print_map() mock.assert_has_calls([ call('1 1 1'), call('1 1 1'), call('1 1 1'), call('1 1 1'), ])
class TestGameMap(TestCase): def setUp(self): self.game_map = GameMap(4, 3) def test_init(self): self.assertRaises(TypeError, GameMap, ('a', 3)) self.assertRaises(TypeError, GameMap, (4, 'b')) def test_rows(self): self.assertEqual(4, self.game_map.rows, "Should get correct rows") def test_cols(self): self.assertEqual(3, self.game_map.cols, "Should get correct rows") @mock.patch('random.random', new=mock.Mock(side_effect=chain(cycle([0.3, 0.6, 0.9])))) def test_reset(self): self.game_map.reset() for i in range(0, 4): self.assertEqual(1, self.game_map.get(i, 0)) for j in range(1, 3): self.assertEqual(0, self.game_map.get(i, j)) self.assertRaises(TypeError, self.game_map.reset, possibility='ab') def test_get_set(self): self.assertEqual(0, self.game_map.get(0, 0), "Cells init to 0") self.game_map.set(0, 0, 1) self.assertEqual(1, self.game_map.get(0, 0), "Should get value set by set") self.assertRaises(TypeError, self.game_map.get, ("d3d3f", 0)) self.assertRaises(TypeError, self.game_map.get, (0, 'b')) self.assertRaises(TypeError, self.game_map.set, ('a', 0, 1)) self.assertRaises(TypeError, self.game_map.set, (0, 'b', 1)) self.assertRaises(TypeError, self.game_map.set, (0, 0, 'c')) def test_get_neighbor_count(self): expected_value = [[8] * 3] * 4 self.game_map.cells = [[1] * 3] * 4 for i in range(0, 4): for j in range(0, 3): self.assertEqual(expected_value[i][j], self.game_map.get_neighbor_count(i, j), '(%d %d)' % (i, j)) self.assertRaises(TypeError, self.game_map.get_neighbor_count, ('a', 0)) self.assertRaises(TypeError, self.game_map.get_neighbor_count, (0, 'b')) @mock.patch('game_map.GameMap.get_neighbor_count', new=mock.Mock(return_value=8)) # game_map.GameMap.get_neighbor_count def test_get_neighbor_count_map(self): expected_value = [[8] * 3] * 4 self.assertEqual(expected_value, self.game_map.get_neighbor_count_map()) def test_set_map(self): self.assertRaises(TypeError, self.game_map.set_map, {(0, 0): 1}) self.assertRaises(AssertionError, self.game_map.set_map, [[1] * 3] * 3) self.assertRaises(TypeError, self.game_map.set_map, [['1'] * 3] * 4) self.assertRaises(AssertionError, self.game_map.set_map, [[2] * 3] * 4) self.game_map.set_map([[1] * 3] * 4) self.assertEqual([[1] * 3] * 4, self.game_map.cells) def test_print_map(self): self.game_map.cells = [[0, 1, 1], [0, 0, 1], [1, 1, 1], [0, 0, 0]] with mock.patch('builtins.print') as mock1: self.game_map.print_map() mock1.assert_has_calls([ mock.call('0 1 1'), mock.call('0 0 1'), mock.call('1 1 1'), mock.call('0 0 0'), ])