def test_two_separate_circular_movements(self): pieces = [ Fleet(Nations.TURKEY, self.territories.ANKARA), Army(Nations.TURKEY, self.territories.CONSTANTINOPLE), Army(Nations.TURKEY, self.territories.SMYRNA), Army(Nations.FRANCE, self.territories.BREST), Army(Nations.FRANCE, self.territories.PICARDY), Army(Nations.FRANCE, self.territories.PARIS), ] orders = [ Move(Nations.TURKEY, self.territories.ANKARA, self.territories.CONSTANTINOPLE), Move(Nations.TURKEY, self.territories.CONSTANTINOPLE, self.territories.SMYRNA), Move(Nations.TURKEY, self.territories.SMYRNA, self.territories.ANKARA), Move(Nations.FRANCE, self.territories.BREST, self.territories.PICARDY), Move(Nations.FRANCE, self.territories.PICARDY, self.territories.PARIS), Move(Nations.FRANCE, self.territories.PARIS, self.territories.BREST), ] self.state.register(*pieces, *orders) self.state.post_register_updates() result = find_circular_movements(orders) self.assertEqual(len(result), 2) self.assertTrue(all([o in result[0] for o in orders[:3]])) self.assertTrue(all([o in result[1] for o in orders[3:]]))
def test_five_army_circular_movement(self): pieces = [ Fleet(Nations.TURKEY, self.territories.ANKARA), Army(Nations.TURKEY, self.territories.CONSTANTINOPLE), Army(Nations.TURKEY, self.territories.SMYRNA), Army(Nations.TURKEY, self.territories.ARMENIA), Army(Nations.TURKEY, self.territories.SYRIA), ] orders = [ Move(Nations.TURKEY, self.territories.ANKARA, self.territories.CONSTANTINOPLE), Move(Nations.TURKEY, self.territories.CONSTANTINOPLE, self.territories.SMYRNA), Move(Nations.TURKEY, self.territories.SMYRNA, self.territories.SYRIA), Move(Nations.TURKEY, self.territories.SYRIA, self.territories.ARMENIA), Move(Nations.TURKEY, self.territories.ARMENIA, self.territories.ANKARA), ] self.state.register(*pieces, *orders) self.state.post_register_updates() result = find_circular_movements(orders) self.assertEqual(len(result), 1) self.assertTrue(all([o in result[0] for o in orders]))
def test_two_separate_circular_movements(self): Fleet(self.state, 0, Nations.TURKEY, self.territories.ANKARA), Army(self.state, 0, Nations.TURKEY, self.territories.CONSTANTINOPLE), Army(self.state, 0, Nations.TURKEY, self.territories.SMYRNA), Army(self.state, 0, Nations.FRANCE, self.territories.BREST), Army(self.state, 0, Nations.FRANCE, self.territories.PICARDY), Army(self.state, 0, Nations.FRANCE, self.territories.PARIS), orders = [ Move(self.state, 0, Nations.TURKEY, self.territories.ANKARA, self.territories.CONSTANTINOPLE), Move(self.state, 0, Nations.TURKEY, self.territories.CONSTANTINOPLE, self.territories.SMYRNA), Move(self.state, 0, Nations.TURKEY, self.territories.SMYRNA, self.territories.ANKARA), Move(self.state, 0, Nations.FRANCE, self.territories.BREST, self.territories.PICARDY), Move(self.state, 0, Nations.FRANCE, self.territories.PICARDY, self.territories.PARIS), Move(self.state, 0, Nations.FRANCE, self.territories.PARIS, self.territories.BREST), ] result = find_circular_movements(orders) self.assertEqual(len(result), 2) self.assertTrue(all([o in result[0] for o in orders[:3]])) self.assertTrue(all([o in result[1] for o in orders[3:]]))
def test_head_to_head(self): Fleet(self.state, 0, Nations.TURKEY, self.territories.ANKARA), Army(self.state, 0, Nations.TURKEY, self.territories.CONSTANTINOPLE), orders = [ Move(self.state, 0, Nations.TURKEY, self.territories.ANKARA, self.territories.CONSTANTINOPLE), Move(self.state, 0, Nations.TURKEY, self.territories.CONSTANTINOPLE, self.territories.ANKARA), ] result = find_circular_movements(orders) self.assertEqual(len(result), 0)
def test_head_to_head(self): pieces = [ Fleet(Nations.TURKEY, self.territories.ANKARA), Army(Nations.TURKEY, self.territories.CONSTANTINOPLE), ] orders = [ Move(Nations.TURKEY, self.territories.ANKARA, self.territories.CONSTANTINOPLE), Move(Nations.TURKEY, self.territories.CONSTANTINOPLE, self.territories.ANKARA), ] self.state.register(*pieces, *orders) self.state.post_register_updates() result = find_circular_movements(orders) self.assertEqual(len(result), 0)
def test_three_army_circular_movement(self): Fleet(self.state, 0, Nations.TURKEY, self.territories.ANKARA), Army(self.state, 0, Nations.TURKEY, self.territories.CONSTANTINOPLE), Army(self.state, 0, Nations.TURKEY, self.territories.SMYRNA) orders = [ Move(self.state, 0, Nations.TURKEY, self.territories.ANKARA, self.territories.CONSTANTINOPLE), Move(self.state, 0, Nations.TURKEY, self.territories.CONSTANTINOPLE, self.territories.SMYRNA), Move(self.state, 0, Nations.TURKEY, self.territories.SMYRNA, self.territories.ANKARA), ] result = find_circular_movements(orders) self.assertEqual(len(result), 1) self.assertTrue(all([o in result[0] for o in orders]))
def process(state): """ Processes all orders in a turn. """ orders = state.orders pieces = state.pieces for order in orders: order.update_legal_decision() moves = [o for o in orders if o.is_move] supports = [o for o in orders if o.is_support] convoys = [o for o in orders if o.is_convoy] illegal_moves = [m for m in moves if m.legal_decision == Outcomes.ILLEGAL] # set illegal moves to fail. for m in illegal_moves: m.move_decision = Outcomes.FAILS unresolved_pieces = [ p for p in pieces if p.dislodged_decision == Outcomes.UNRESOLVED ] unresolved_supports = [ s for s in supports if s.support_decision == Outcomes.UNRESOLVED ] unresolved_convoys = [ c for c in convoys if c.piece.dislodged_decision == Outcomes.UNRESOLVED ] while unresolved_convoys: unresolved_supports = [ s for s in supports if s.support_decision == Outcomes.UNRESOLVED ] unresolved_moves = [ m for m in moves if m.move_decision == Outcomes.UNRESOLVED ] for move in unresolved_moves: move.update_move_decision() for support in unresolved_supports: support.update_support_decision() for piece in unresolved_pieces: piece.update_dislodged_decision() # resolve fleet movements unresolved_convoys = [ c for c in convoys if c.piece.dislodged_decision == Outcomes.UNRESOLVED ] # refresh after convoys resolved unresolved_moves = [ m for m in moves if m.move_decision == Outcomes.UNRESOLVED ] depth = 0 while unresolved_moves or unresolved_pieces or unresolved_supports: if depth == 10: circular_movements = find_circular_movements(moves) for l in circular_movements: for move in l: move.move_decision = Outcomes.MOVES for move in unresolved_moves: move.update_move_decision() unresolved_supports = [ s for s in supports if s.support_decision == Outcomes.UNRESOLVED ] for support in unresolved_supports: support.update_support_decision() for piece in unresolved_pieces: piece.update_dislodged_decision() unresolved_moves = [ m for m in moves if m.move_decision == Outcomes.UNRESOLVED ] unresolved_pieces = [ p for p in pieces if p.dislodged_decision == Outcomes.UNRESOLVED ] depth += 1 return orders
def test_empty_input(self): orders = [] result = find_circular_movements(orders) self.assertEqual(len(result), 0)
def process(state): """ Processes all orders in a turn. """ orders = state.orders pieces = state.pieces for order in orders: order.check_legal() moves = [o for o in orders if o.is_move] retreats = [o for o in orders if o.is_retreat] supports = [o for o in orders if o.is_support] convoys = [o for o in orders if o.is_convoy] builds = [o for o in orders if o.is_build] disbands = [o for o in orders if o.is_disband] illegal_retreats = [r for r in retreats if r.illegal] # set illegal retreats to fail. for r in illegal_retreats: r.outcome = Outcomes.FAILS illegal_moves = [m for m in moves if m.illegal] # set illegal moves to fail. for m in illegal_moves: m.outcome = Outcomes.FAILS unresolved_pieces = [ p for p in pieces if p.dislodged_decision == Outcomes.UNRESOLVED ] unresolved_supports = [ s for s in supports if s.outcome == Outcomes.UNRESOLVED ] unresolved_convoys = [ c for c in convoys if c.piece.dislodged_decision == Outcomes.UNRESOLVED ] while unresolved_convoys: unresolved_supports = [ s for s in supports if s.outcome == Outcomes.UNRESOLVED ] unresolved_moves = [ m for m in moves if m.outcome == Outcomes.UNRESOLVED ] for move in unresolved_moves: move.resolve() for support in unresolved_supports: support.resolve() for piece in unresolved_pieces: piece.update_dislodged_decision() for convoy in unresolved_convoys: convoy.resolve() # resolve fleet movements unresolved_convoys = [ c for c in convoys if c.outcome == Outcomes.UNRESOLVED ] # refresh after convoys resolved unresolved_moves = [m for m in moves if m.outcome == Outcomes.UNRESOLVED] depth = 0 unresolved_retreats = [ r for r in retreats if r.outcome == Outcomes.UNRESOLVED ] while unresolved_moves or unresolved_pieces or unresolved_supports or unresolved_retreats: unresolved_retreats = [ r for r in retreats if r.outcome == Outcomes.UNRESOLVED ] for r in unresolved_retreats: r.resolve() if depth == 10: circular_movements = find_circular_movements(moves) for li in circular_movements: for move in li: move.outcome = Outcomes.SUCCEEDS for move in [m for m in moves if m.outcome == Outcomes.UNRESOLVED]: move.resolve() unresolved_supports = [ s for s in supports if s.outcome == Outcomes.UNRESOLVED ] for support in unresolved_supports: support.resolve() for piece in unresolved_pieces: piece.update_dislodged_decision() unresolved_moves = [ m for m in moves if m.outcome == Outcomes.UNRESOLVED ] unresolved_pieces = [ p for p in pieces if p.dislodged_decision == Outcomes.UNRESOLVED ] depth += 1 # Check update bounce_occurred_during_turn on all territories for territory in state.territories: attacks = [o for o in orders if o.is_move and o.target == territory] bounce_occurred = False for attack in attacks: if attack.legal and attack.outcome == Outcomes.FAILS and \ attack.path_decision() == Outcomes.PATH: bounce_occurred = True territory.bounce_occurred = bounce_occurred # Check all dislodged pieces for pieces which can't retreat dislodged_pieces = [ p for p in state.pieces if p.dislodged_decision == Outcomes.DISLODGED ] for piece in dislodged_pieces: if not piece.can_retreat(): piece.destroyed = True piece.destroyed_message = ( 'Destroyed because piece cannot retreat to any neighboring ' 'territories.') for o in [*builds, *disbands]: if o.legal: o.outcome = Outcomes.SUCCEEDS else: o.outcome = Outcomes.FAILS if state.phase == Phase.RETREAT: for piece in state.pieces: if piece.retreating and (piece.order.outcome == Outcomes.FAILS): piece.destroyed = True piece.destroyed_message = ( 'Destroyed because piece must retreat but retreat order failed.' ) # TODO test # TODO split into sub function # Set captured_by for territories if fall orders if state.season == Season.FALL and state.phase == Phase.ORDER: # Find all pieces that are not dislodged non_dislodged_pieces = [p for p in state.pieces if not p.dislodged] for piece in non_dislodged_pieces: # Ignore pieces that move successfully if piece.order.is_move and piece.order.outcome == Outcomes.SUCCEEDS: continue if piece.nation != getattr(piece.territory, 'controlled_by', False): if not (piece.territory.is_sea): piece.territory.captured_by = piece.nation # Find all successful move orders successful_move_orders = [ m for m in state.orders if m.is_move and m.outcome == Outcomes.SUCCEEDS ] for move in successful_move_orders: if move.piece.nation != getattr(move.target, 'controlled_by', False): if not (move.target.is_sea): move.target.captured_by = move.piece.nation # Determine the next season, phase and year. state.next_season, state.next_phase, state.next_year = \ get_next_season_phase_and_year(state) return state
def process(state): """ Processes all orders in a turn. """ orders = state.orders pieces = state.pieces for order in orders: order.check_legal() moves = [o for o in orders if o.is_move] retreats = [o for o in orders if o.is_retreat] supports = [o for o in orders if o.is_support] convoys = [o for o in orders if o.is_convoy] builds = [o for o in orders if o.is_build] illegal_retreats = [r for r in retreats if r.illegal] # set illegal retreats to fail. for r in illegal_retreats: r.outcome = Outcomes.FAILS illegal_moves = [m for m in moves if m.illegal] # set illegal moves to fail. for m in illegal_moves: m.outcome = Outcomes.FAILS unresolved_pieces = [p for p in pieces if p.dislodged_decision == Outcomes.UNRESOLVED] unresolved_supports = [s for s in supports if s.outcome == Outcomes.UNRESOLVED] unresolved_convoys = [c for c in convoys if c.piece.dislodged_decision == Outcomes.UNRESOLVED] while unresolved_convoys: unresolved_supports = [s for s in supports if s.outcome == Outcomes.UNRESOLVED] unresolved_moves = [m for m in moves if m.outcome == Outcomes.UNRESOLVED] for move in unresolved_moves: move.resolve() for support in unresolved_supports: support.resolve() for piece in unresolved_pieces: piece.update_dislodged_decision() # resolve fleet movements unresolved_convoys = [c for c in convoys if c.piece.dislodged_decision == Outcomes.UNRESOLVED] # refresh after convoys resolved unresolved_moves = [m for m in moves if m.outcome == Outcomes.UNRESOLVED] depth = 0 unresolved_retreats = [r for r in retreats if r.outcome == Outcomes.UNRESOLVED] while unresolved_moves or unresolved_pieces or unresolved_supports or unresolved_retreats: unresolved_retreats = [r for r in retreats if r.outcome == Outcomes.UNRESOLVED] for r in unresolved_retreats: r.resolve() if depth == 10: circular_movements = find_circular_movements(moves) for l in circular_movements: for move in l: move.outcome = Outcomes.SUCCEEDS for move in [m for m in moves if m.outcome == Outcomes.UNRESOLVED]: move.resolve() unresolved_supports = [s for s in supports if s.outcome == Outcomes.UNRESOLVED] for support in unresolved_supports: support.resolve() for piece in unresolved_pieces: piece.update_dislodged_decision() unresolved_moves = [m for m in moves if m.outcome == Outcomes.UNRESOLVED] unresolved_pieces = [p for p in pieces if p.dislodged_decision == Outcomes.UNRESOLVED] depth += 1 # Check update bounce_occurred_during_turn on all territories for territory in state.territories: attacks = [o for o in orders if o.is_move and o.target == territory] bounce_occurred = False for attack in attacks: if attack.legal and attack.outcome == Outcomes.FAILS and \ attack.path_decision() == Outcomes.PATH: bounce_occurred = True territory.bounce_occurred = bounce_occurred # Check all dislodged pieces for pieces which can't retreat dislodged_pieces = [p for p in state.pieces if p.dislodged_decision == Outcomes.DISLODGED] for piece in dislodged_pieces: if not piece.can_retreat(): piece.destroyed = True piece.destroyed_message = ( 'Destroyed because piece cannot retreat to any neighboring ' 'territories.' ) for build in builds: if build.legal: build.outcome = Outcomes.SUCCEEDS else: build.outcome = Outcomes.FAILS return orders