This commit is contained in:
Lukas Wölfer
2019-04-19 20:40:18 +02:00
parent 0483a839df
commit f65cdc42e5
3 changed files with 44 additions and 23 deletions

View File

@@ -78,7 +78,6 @@ class Board:
result <<= 5
result |= card.identifier()
result <<= 1
if self.flower_gone:
result |= 1
@@ -87,7 +86,8 @@ class Board:
result <<= 4
result |= goal_count
# Max stack size is 13 (4 random cards from the start, plus a stack from 9 to 1]
# Max stack size is 13
# (4 random cards from the start, plus a stack from 9 to 1)
# So 4 bits are sufficient
for stack in self.field:
assert len(stack) == len(stack) & 0b1111
@@ -118,8 +118,8 @@ class Board:
special_cards[SpecialCard.Hua] += 1
for card in itertools.chain(
self.bunker, itertools.chain.from_iterable(
stack for stack in self.field if stack), ):
self.bunker, itertools.chain.from_iterable(
stack for stack in self.field if stack), ):
if isinstance(card, tuple):
special_cards[card[0]] += 4 # pylint: disable=E1136
elif isinstance(card, SpecialCard):

View File

@@ -83,10 +83,15 @@ class MoveAction:
source_id: int
destination_id: int
def _shift(self, action_board: board.Board, source: int, dest: int) -> None:
def _shift(
self,
action_board: board.Board,
source: int,
dest: int) -> None:
"""Shift a card from the field id 'source' to field id 'dest'"""
for stack_offset, card in enumerate(self.cards, start=-len(self.cards)):
for stack_offset, card in enumerate(
self.cards, start=-len(self.cards)):
assert action_board.field[source][stack_offset] == card
if action_board.field[dest]:
@@ -102,7 +107,8 @@ class MoveAction:
if dest_card.number != self.cards[0].number + 1:
raise AssertionError()
action_board.field[source] = action_board.field[source][: -len(self.cards)]
action_board.field[source] = action_board.field[
source][:-len(self.cards)]
action_board.field[dest].extend(self.cards)
def apply(self, action_board: board.Board) -> None:
@@ -143,7 +149,8 @@ class DragonKillAction:
def undo(self, action_board: board.Board) -> None:
"""Undo action"""
assert action_board.bunker[self.destination_bunker_id] == (self.dragon, 4)
assert action_board.bunker[self.destination_bunker_id] == (
self.dragon, 4)
assert len(self.source_stacks) == 4
for position, index in self.source_stacks:
if position == board.Position.Field:
@@ -164,7 +171,8 @@ class HuaKillAction:
def apply(self, action_board: board.Board) -> None:
"""Do action"""
assert not action_board.flower_gone
assert action_board.field[self.source_field_id][-1] == board.SpecialCard.Hua
assert (action_board.field[self.source_field_id][-1]
== board.SpecialCard.Hua)
action_board.field[self.source_field_id].pop()
action_board.flower_gone = True
@@ -175,4 +183,5 @@ class HuaKillAction:
action_board.flower_gone = False
Action = Union[MoveAction, DragonKillAction, HuaKillAction, BunkerizeAction, GoalAction]
Action = Union[MoveAction, DragonKillAction,
HuaKillAction, BunkerizeAction, GoalAction]

View File

@@ -5,7 +5,7 @@ from . import board_actions
def possible_huakill_action(
search_board: board.Board
search_board: board.Board
) -> Iterator[board_actions.HuaKillAction]:
"""Check if the flowercard can be eliminated"""
for index, stack in enumerate(search_board.field):
@@ -14,7 +14,7 @@ def possible_huakill_action(
def possible_dragonkill_actions(
search_board: board.Board
search_board: board.Board
) -> Iterator[board_actions.DragonKillAction]:
"""Enumerate all possible dragon kills"""
possible_dragons = [
@@ -30,7 +30,8 @@ def possible_dragonkill_actions(
possible_dragons = new_possible_dragons
for dragon in possible_dragons:
bunker_dragons = [i for i, d in enumerate(search_board.bunker) if d == dragon]
bunker_dragons = [i for i, d in
enumerate(search_board.bunker) if d == dragon]
field_dragons = [
i for i, f in enumerate(search_board.field) if f if f[-1] == dragon
]
@@ -45,7 +46,8 @@ def possible_dragonkill_actions(
][0]
source_stacks = [(board.Position.Bunker, i) for i in bunker_dragons]
source_stacks.extend([(board.Position.Field, i) for i in field_dragons])
source_stacks.extend([(board.Position.Field, i)
for i in field_dragons])
yield board_actions.DragonKillAction(
dragon=dragon,
@@ -55,10 +57,12 @@ def possible_dragonkill_actions(
def possible_bunkerize_actions(
search_board: board.Board
search_board: board.Board
) -> Iterator[board_actions.BunkerizeAction]:
"""Enumerates all possible card moves from the field to the bunker"""
open_bunker_list = [i for i, x in enumerate(search_board.bunker) if x is None]
open_bunker_list = [
i for i, x in enumerate(
search_board.bunker) if x is None]
if not open_bunker_list:
return
@@ -68,12 +72,15 @@ def possible_bunkerize_actions(
if not stack:
continue
yield board_actions.BunkerizeAction(
card=stack[-1], source_id=index, destination_id=open_bunker, to_bunker=True
card=stack[-1],
source_id=index,
destination_id=open_bunker,
to_bunker=True
)
def possible_debunkerize_actions(
search_board: board.Board
search_board: board.Board
) -> Iterator[board_actions.BunkerizeAction]:
"""Enumerates all possible card moves from the bunker to the field"""
bunker_number_cards = [
@@ -92,12 +99,15 @@ def possible_debunkerize_actions(
if other_stack[-1].number != card.number + 1:
continue
yield board_actions.BunkerizeAction(
card=card, source_id=index, destination_id=other_index, to_bunker=False
card=card,
source_id=index,
destination_id=other_index,
to_bunker=False
)
def possible_goal_move_actions(
search_board: board.Board
search_board: board.Board
) -> Iterator[board_actions.GoalAction]:
"""Enumerates all possible moves from anywhere to the goal"""
field_cards = [
@@ -153,9 +163,10 @@ def _get_cardstacks(search_board: board.Board) -> List[List[board.Card]]:
def possible_field_move_actions(
search_board: board.Board
search_board: board.Board
) -> Iterator[board_actions.MoveAction]:
"""Enumerate all possible move actions from one field stack to another field stack"""
"""Enumerate all possible move actions
from one field stack to another field stack"""
for index, stack in enumerate(_get_cardstacks(search_board)):
if not stack:
continue
@@ -170,7 +181,8 @@ def possible_field_move_actions(
)
def possible_actions(search_board: board.Board) -> Iterator[board_actions.Action]:
def possible_actions(
search_board: board.Board) -> Iterator[board_actions.Action]:
"""Enumerate all possible actions on the current search_board"""
yield from possible_huakill_action(search_board)
yield from possible_dragonkill_actions(search_board)