diff --git a/board/event/handler/internal/board_handler.py b/board/event/handler/internal/board_handler.py index 492b1a4..20f6edf 100644 --- a/board/event/handler/internal/board_handler.py +++ b/board/event/handler/internal/board_handler.py @@ -1,6 +1,6 @@ import asyncio from event import EventBroker -from board.data import Point, Tile +from board.data import Point, Tile, Tiles from board.data.handler import BoardHandler from cursor.data import Color from message import Message @@ -18,7 +18,9 @@ MovableResultPayload, ClickType, InteractionEvent, - TileStateChangedPayload + TilesOpenedPayload, + SingleTileOpenedPayload, + FlagSetPayload ) @@ -74,6 +76,7 @@ async def receive_try_pointing(message: Message[TryPointingPayload]): Point(pointer.x+1, pointer.y-1) ) + # 포인팅한 칸 포함 3x3칸 중 열린 칸이 존재하는지 확인 pointable = False for tile in tiles.data: t = Tile.from_int(tile) @@ -94,12 +97,12 @@ async def receive_try_pointing(message: Message[TryPointingPayload]): publish_coroutines.append(EventBroker.publish(pub_message)) - cursor_pos = message.payload.cursor_position - if not pointable: await asyncio.gather(*publish_coroutines) return + cursor_pos = message.payload.cursor_position + # 인터랙션 범위 체크 if \ pointer.x < cursor_pos.x - 1 or \ @@ -110,7 +113,7 @@ async def receive_try_pointing(message: Message[TryPointingPayload]): return # 보드 상태 업데이트하기 - tile = Tile.from_int(tiles.data[4]) # 3x3칸 중 가운데 + tile = Tile.from_int(tiles.data[4]) # 3x3칸 중 가운데 = 포인팅한 타일 click_type = message.payload.click_type if tile.is_open: @@ -124,26 +127,51 @@ async def receive_try_pointing(message: Message[TryPointingPayload]): await asyncio.gather(*publish_coroutines) return - tile.is_open = True + if tile.number is None: + # 빈 칸. 주변 칸 모두 열기. + start_p, end_p, tiles = BoardHandler.open_tiles_cascade(pointer) + tiles.hide_info() + tile_str = tiles.to_str() + + pub_message = Message( + event=InteractionEvent.TILES_OPENED, + payload=TilesOpenedPayload( + start_p=start_p, + end_p=end_p, + tiles=tile_str + ) + ) + publish_coroutines.append(EventBroker.publish(pub_message)) + else: + tile = BoardHandler.open_tile(pointer) + + tile_str = Tiles(data=bytearray([tile.data])).to_str() + + pub_message = Message( + event=InteractionEvent.SINGLE_TILE_OPENED, + payload=SingleTileOpenedPayload( + position=pointer, + tile=tile_str + ) + ) + publish_coroutines.append(EventBroker.publish(pub_message)) # 깃발 꽂기/뽑기 case ClickType.SPECIAL_CLICK: - color = message.payload.color - - tile.is_flag = not tile.is_flag - tile.color = color if tile.is_flag else None - - BoardHandler.update_tile(pointer, tile) - - pub_message = Message( - event=InteractionEvent.TILE_STATE_CHANGED, - payload=TileStateChangedPayload( - position=pointer, - tile=tile - ) - ) - - publish_coroutines.append(EventBroker.publish(pub_message)) + flag_state = not tile.is_flag + color = message.payload.color if flag_state else None + + _ = BoardHandler.set_flag_state(p=pointer, state=flag_state, color=color) + + pub_message = Message( + event=InteractionEvent.FLAG_SET, + payload=FlagSetPayload( + position=pointer, + is_set=flag_state, + color=color, + ) + ) + publish_coroutines.append(EventBroker.publish(pub_message)) await asyncio.gather(*publish_coroutines) diff --git a/board/event/handler/test/board_handler_test.py b/board/event/handler/test/board_handler_test.py index 4535de6..8692dff 100644 --- a/board/event/handler/test/board_handler_test.py +++ b/board/event/handler/test/board_handler_test.py @@ -19,7 +19,9 @@ CheckMovablePayload, MovableResultPayload, InteractionEvent, - TileStateChangedPayload + SingleTileOpenedPayload, + TilesOpenedPayload, + FlagSetPayload ) import unittest @@ -220,7 +222,7 @@ async def test_try_pointing_pointable_closed_general_click(self, mock: AsyncMock await BoardEventHandler.receive_try_pointing(message) - # pointing-result, tile-state-changed 발행하는지 확인 + # pointing-result, single-tile-opened 발행하는지 확인 self.assertEqual(len(mock.mock_calls), 2) # pointing-result @@ -236,12 +238,12 @@ async def test_try_pointing_pointable_closed_general_click(self, mock: AsyncMock self.assertTrue(got.payload.pointable) self.assertEqual(got.payload.pointer, pointer) - # tile-state-changed - got: Message[PointingResultPayload] = mock.mock_calls[1].args[0] + # single-tile-opened + got: Message[SingleTileOpenedPayload] = mock.mock_calls[1].args[0] self.assertEqual(type(got), Message) - self.assertEqual(got.event, InteractionEvent.TILE_STATE_CHANGED) + self.assertEqual(got.event, InteractionEvent.SINGLE_TILE_OPENED) # payload 확인 - self.assertEqual(type(got.payload), TileStateChangedPayload) + self.assertEqual(type(got.payload), SingleTileOpenedPayload) self.assertEqual(got.payload.position, pointer) expected_tile = Tile.create( @@ -251,10 +253,11 @@ async def test_try_pointing_pointable_closed_general_click(self, mock: AsyncMock color=None, number=1 ) - fetched_tile = Tile.from_int(BoardHandler.fetch(start=pointer, end=pointer).data[0]) + tiles = BoardHandler.fetch(start=pointer, end=pointer) + fetched_tile = Tile.from_int(tiles.data[0]) self.assertEqual(fetched_tile, expected_tile) - self.assertEqual(got.payload.tile, expected_tile) + self.assertEqual(got.payload.tile, tiles.to_str()) @patch("event.EventBroker.publish") async def test_try_pointing_pointable_closed_general_click_race(self, mock: AsyncMock): @@ -282,7 +285,7 @@ async def sleep(_): BoardEventHandler.receive_try_pointing(message) ) - # 첫번째: pointing-result, tile-state-changed 두번째: pointing-result 발행하는지 확인 + # 첫번째: pointing-result, single-tile-opened 두번째: pointing-result 발행하는지 확인 self.assertEqual(len(mock.mock_calls), 3) @patch("event.EventBroker.publish") @@ -338,7 +341,7 @@ async def test_try_pointing_pointable_closed_special_click(self, mock: AsyncMock await BoardEventHandler.receive_try_pointing(message) - # pointing-result, tile-state-changed 발행하는지 확인 + # pointing-result, flag-set 발행하는지 확인 self.assertEqual(len(mock.mock_calls), 2) # pointing-result @@ -354,13 +357,15 @@ async def test_try_pointing_pointable_closed_special_click(self, mock: AsyncMock self.assertTrue(got.payload.pointable) self.assertEqual(got.payload.pointer, pointer) - # tile-state-changed - got: Message[PointingResultPayload] = mock.mock_calls[1].args[0] + # flag-set + got: Message[FlagSetPayload] = mock.mock_calls[1].args[0] self.assertEqual(type(got), Message) - self.assertEqual(got.event, InteractionEvent.TILE_STATE_CHANGED) + self.assertEqual(got.event, InteractionEvent.FLAG_SET) # payload 확인 - self.assertEqual(type(got.payload), TileStateChangedPayload) + self.assertEqual(type(got.payload), FlagSetPayload) self.assertEqual(got.payload.position, pointer) + self.assertEqual(got.payload.color, color) + self.assertTrue(got.payload.is_set) expected_tile = Tile.create( is_open=False, @@ -373,7 +378,6 @@ async def test_try_pointing_pointable_closed_special_click(self, mock: AsyncMock fetched_tile = Tile.from_int(BoardHandler.fetch(start=pointer, end=pointer).data[0]) self.assertEqual(fetched_tile, expected_tile) - self.assertEqual(got.payload.tile, expected_tile) @patch("event.EventBroker.publish") async def test_try_pointing_pointable_closed_special_click_already_flag(self, mock: AsyncMock): @@ -394,7 +398,7 @@ async def test_try_pointing_pointable_closed_special_click_already_flag(self, mo await BoardEventHandler.receive_try_pointing(message) - # pointing-result, tile-state-changed 발행하는지 확인 + # pointing-result, flag-set 발행하는지 확인 self.assertEqual(len(mock.mock_calls), 2) # pointing-result @@ -410,13 +414,15 @@ async def test_try_pointing_pointable_closed_special_click_already_flag(self, mo self.assertTrue(got.payload.pointable) self.assertEqual(got.payload.pointer, pointer) - # tile-state-changed - got: Message[PointingResultPayload] = mock.mock_calls[1].args[0] + # flag-set + got: Message[FlagSetPayload] = mock.mock_calls[1].args[0] self.assertEqual(type(got), Message) - self.assertEqual(got.event, InteractionEvent.TILE_STATE_CHANGED) + self.assertEqual(got.event, InteractionEvent.FLAG_SET) # payload 확인 - self.assertEqual(type(got.payload), TileStateChangedPayload) + self.assertEqual(type(got.payload), FlagSetPayload) self.assertEqual(got.payload.position, pointer) + self.assertIsNone(got.payload.color) + self.assertFalse(got.payload.is_set) expected_tile = Tile.create( is_open=False, @@ -429,7 +435,6 @@ async def test_try_pointing_pointable_closed_special_click_already_flag(self, mo fetched_tile = Tile.from_int(BoardHandler.fetch(start=pointer, end=pointer).data[0]) self.assertEqual(fetched_tile, expected_tile) - self.assertEqual(got.payload.tile, expected_tile) @patch("event.EventBroker.publish") async def test_try_pointing_not_pointable(self, mock: AsyncMock):