Esempio n. 1
0
def parser(situation: model.Situation) -> t_world:
    log = _logger.getChild("parser")
    world = t_world(
        fields_={},
        switches=situation.switches)
    log.info("parser()")
    log.debug("IN situation.orders: %s", dip_eval.LogList(situation.orders, prefix="\n-o "))
    # umkremepeln: wir betrachten Felder, die sich gegenseitig angreifen.
    for o in situation.orders:
        if world.get_field(o.current):  # schon drin
            raise LookupError(f"fieldname {o.current} twice in current.")
        field = t_field_from_order(o)
        # add
        world.set_field(field)
    # the world representation needs empty explicit empty fields for destinations.
    all_currents = { f.name  for f in world.get_fields() }
    all_dests = { f.dest  for f in world.get_fields() }
    log.debug("adding needed empty destination fields: %s", all_dests - all_currents)
    for dest in all_dests - all_currents:
        world.set_field(t_field_empty(dest))
    # change nmoves to cmoves
    field : t_field
    for field, dest_field in world.get_fields_dests(lambda f: f.order in { t_order.convoy } ):
        if field.order in { t_order.nmove }:
            log.debug("- changing nmove to cmove for field:%s because of dest:%s", field, dest_field)
            field.order = t_order.cmove
            field.add_event("$cmove")
    # result
    log.debug("OUT world.fields: %s", dip_eval.LogList(world.get_fields()))
    return world
Esempio n. 2
0
def writer(world: t_world) -> model.ConflictResolution:
    log = _logger.getChild("writer")
    orders: List[model.OrderResult] = []
    f: t_field
    log.info("writer()")
    log.debug("IN world.fields: %s", dip_eval.LogList(world.get_fields()))
    # moves
    for f in world.get_fields():
        if f.player == NO_PLAYER:
            continue  # empty fields that were just destinations
        order = order_from_t_order(f.order)
        orr = model.OrderResult(
                nation=f.player,
                utype=f.original_order.utype if f.original_order else '?',
                current=f.name,
                order=order,
                dest=f.dest,  # TODO or xref? or original.dest?
                succeeds=False  if not f.succeeds else None,
                dislodged=True  if f.dislodged else None,
                original=f.original_order
            )
        orders.append(orr)
    # figure out pattfields. TODO: alpha
    efields = { f.name  for f in world.get_fields(lambda f: f.player == NO_PLAYER) }
    ufields = { f.dest  for f in world.get_fields(lambda f: f.order in {t_order.umove}) }
    sfields = { f.dest  for f in world.get_fields(lambda f: f.order in {t_order.nmove, t_order.cmove}) }
    hfields = { f.name  for f in world.get_fields(lambda f: f.order in {t_order.hsupport, t_order.msupport, t_order.none }) }
    # .. (all empty fields and fields with blocked moved) minus (destination of moves) minus (hold fields ignoring empty fields)
    pattfields = (efields | ufields) - sfields - (hfields - efields)
    #
    log.debug("OUT conflict_resolution.orders: %s, ", dip_eval.LogList(orders, prefix="\n-r "))
    log.debug("OUT conflict_resolution.pattfields: %s, ", pattfields)
    return model.ConflictResolution(orders=orders, pattfields=pattfields)
Esempio n. 3
0
def k4_evaluation(world: t_world):
    log = _logger.getChild("k4_evaluation")
    log.info("k4_evaluation")
    # prepare
    # - aliases for brevity
    hsupport, msupport, cmove, nmove, umove = t_order.hsupport, t_order.msupport, t_order.cmove, t_order.nmove, t_order.umove
    #
    # {mark k4 felds}
    ifield: t_field
    dest_field: t_field
    for ifield, dest_field in world.get_fields_dests(
            lambda f: f.order in {cmove, nmove, umove}):
        if dest_field.fcategory == 0:
            dest_field.fcategory = 4
            dest_field.add_event('$k4f')
    #
    # {mark k4 moves and supports}
    for ifield, dest_field in world.get_fields_dests(
            lambda f: f.order in {hsupport, msupport, cmove, nmove}):
        if dest_field.fcategory == 4:
            ifield.category = 4
            ifield.add_event('$k4c')
    eval_common.cut_supports(world,
                             category=4,
                             relevant_moves={cmove, nmove, umove})
    eval_common.count_supporters(world, category=4)
    #
    # units block each other in a chain.
    # - guard protects against accidental forever-loop, which should not happen;
    #   assuming there will never be chains of blocking units longer then this.
    guard = 1000  # programming error guard
    changed_flag: bool = True
    while changed_flag:
        # {evaluate conflicts}
        for ifield in world.get_fields(lambda f: f.fcategory == 4):
            log.debug(". resolve conflict at field: %s", ifield.__log__())
            eval_common.resolve_conflict_at_field(world, ifield)
        # {mark k4 moves which fail now, but succeeded in the previous iteration}
        changed_flag = False
        for ifield in world.get_fields(lambda f: f.category == 4 and f.order in
                                       {cmove, nmove} and not f.succeeds):
            ifield.order = t_order.none
            ifield.add_event("$chain4")
            changed_flag = True
        guard -= 1
        if guard <= 0:
            raise OverflowError(
                "programming error (likely) or blocking-chain too long (unlikely)"
            )
        log.debug("_ evaluate conflicts loop. changed:%s. fields: %s",
                  changed_flag, dip_eval.LogList(world.get_fields()))
    #
    log.debug("DONE k4. fields: %s", dip_eval.LogList(world.get_fields()))
    return
Esempio n. 4
0
def k1_evaluation(world: t_world):
    log = _logger.getChild("k1_evaluation")
    log.info("k1_evaluation")
    # prepare
    # - aliases for brevity
    hsupport, msupport, cmove, nmove, umove, convoy = t_order.hsupport, t_order.msupport, t_order.cmove, t_order.nmove, t_order.umove, t_order.convoy
    #
    # {mark k1 fields}
    ifield : t_field
    dest_field : t_field
    for ifield in world.get_fields(lambda f: f.order in { convoy }):
        ifield.fcategory = 1
        ifield.add_event('$k1f')
    #
    # {mark k1 moves and supports}
    for ifield, dest_field in world.get_fields_dests(lambda f: f.order in { hsupport, msupport, nmove }):
        if dest_field.fcategory == 1:
            ifield.category = 1
            ifield.add_event('$k1c')
    log.debug("k1 moves and support marks. fields: %s", dip_eval.LogList(world.get_fields(lambda f: f.category == 1)))
    eval_common.cut_supports(world, category=1, relevant_moves={nmove})
    eval_common.count_supporters(world, category=1)
    log.debug("k1 cuts and supports. fields: %s", dip_eval.LogList(world.get_fields(lambda f: f.category == 1)))
    #
    # {evaluate conflicts}
    for ifield in world.get_fields(lambda f: f.category==1):
        eval_common.resolve_conflict_at_field(world, ifield)
    eval_common.change_moves_to_umoves(world, category=1)
    #
    # {evaluate dislodgements of convoyers}
    for ifield, dest_field in world.get_fields_dests(lambda f: f.category==1 and f.order in {nmove}):
        dest_field.order = t_order.none
        dest_field.add_event("$cdsl")
        log.debug("k1 blocked dislodged convoyer field:%s because of %s", dest_field, ifield)
    #
    # {check convoy routes}
    for ifield in world.get_fields(lambda f: f.order in {cmove}):
        my_convoyers = {
            jfield.name
            for jfield in world.get_fields()
            if jfield.order in {convoy} and jfield.xref == ifield.name
        }
        if not convoy_route_valid(world=world, field=ifield, convoyer_names=my_convoyers):
            ifield.order = t_order.none
            ifield.add_event("$criv") # convoy route invalid
            log.debug("k1 invalid convoy route for field:%s via %s", ifield, my_convoyers)
    #
    log.debug("DONE k1. fields: %s", dip_eval.LogList(world.get_fields()))
    return
Esempio n. 5
0
def k2_evaluation(world: t_world):
    log = _logger.getChild("k2_evaluation")
    log.info("k2_evaluation")
    # prepare
    # - aliases for brevity
    hsupport, msupport, cmove, nmove, umove = t_order.hsupport, t_order.msupport, t_order.cmove, t_order.nmove, t_order.umove
    # - k2_relevant_moves
    k2_relevant_moves = { nmove }
    if world.switches.convoy_cuts:
        k2_relevant_moves.add(cmove)
    #
    # {mark k2 fields}
    ifield : t_field
    dest_field : t_field
    for ifield, dest_field in world.get_fields_dests(lambda f: f.order in { msupport }):
        if dest_field.order in k2_relevant_moves and dest_field.dest==ifield.name:
            ifield.fcategory = 2
            ifield.add_event('$k2f')
    # .. {it may seem to be wrong that no check is included, whether
    #   both units belong to different players, but this case does no harm}
    #
    # {mark k2 moves and supports}
    for ifield, dest_field in world.get_fields_dests(lambda f: f.order in { hsupport, msupport, cmove, nmove }):
        if dest_field.fcategory == 2:
            ifield.category = 2
            ifield.add_event('$k2c')
    log.debug("k2 moves and support marks. fields: %s", dip_eval.LogList(world.get_fields(lambda f: f.category == 2)))
    eval_common.cut_supports(world, category=2, relevant_moves={cmove, nmove, umove})
    eval_common.count_supporters(world, category=2)
    log.debug("k2 cuts and supports. fields: %s", dip_eval.LogList(world.get_fields(lambda f: f.category == 2)))
    #
    # {evaluate conflicts}
    for ifield in world.get_fields(lambda f: f.fcategory==2):
        log.debug("k2 resolve_conflict_at_field: %s", ifield)
        eval_common.resolve_conflict_at_field(world, ifield)
    #
    # {change unsuccessfull critical k2 moves to nops}
    for ifield, dest_field in world.get_fields_dests(lambda f: f.category==2 and f.order in k2_relevant_moves and not f.succeeds):
        if dest_field.order in {msupport} and dest_field.dest==ifield.name:
            ifield.order = t_order.none
            ifield.add_event("$ck2n")
    eval_common.change_moves_to_umoves(world, category=2)
    #
    log.debug("DONE k2. fields: %s", dip_eval.LogList(world.get_fields()))
    return
Esempio n. 6
0
def k0_evaluation(world: t_world):
    log = _logger.getChild("k0_evaluation")
    log.info("k0_evaluation")
    #
    # {count the supports for fields which aren't attacked (920112)}
    eval_common.cut_supports(world, 0,
                             {t_order.cmove, t_order.nmove, t_order.umove})
    eval_common.count_supporters(world, 0)
    #
    log.debug("DONE k0. fields: %s", dip_eval.LogList(world.get_fields()))
    return
Esempio n. 7
0
def k3_evaluation(world: t_world):
    log = _logger.getChild("k3_evaluation")
    log.info("k3_evaluation")
    # prepare
    # - aliases for brevity
    hsupport, msupport, cmove, nmove, umove = t_order.hsupport, t_order.msupport, t_order.cmove, t_order.nmove, t_order.umove
    # - rule interpretation switches
    _ri97 = world.switches.rule_interpretation_IX_7
    #
    # {mark k3 fields}
    ifield: t_field
    dest_field: t_field
    for ifield, dest_field in world.get_fields_dests(
            lambda f: f.order in {nmove}):
        if dest_field.order in {nmove} and dest_field.dest == ifield.name:
            ifield.fcategory = 3
            ifield.add_event('$k3f')
            log.debug("k3. conflict at border identified of fields:%s and:%s",
                      ifield, dest_field)
    #
    # {mark k3 moves and supports}
    for ifield, dest_field in world.get_fields_dests(
            lambda f: f.order in {hsupport, msupport, cmove, nmove}):
        if dest_field.fcategory == 3:
            ifield.category = 3
            ifield.add_event('$k3c')
    eval_common.cut_supports(world,
                             category=3,
                             relevant_moves={cmove, nmove, umove})
    eval_common.count_supporters(world, category=3)
    #
    # {evaluate conflicts pairwise}
    for ifield, dest_field in world.get_fields_dests(
            lambda f: f.category == 3):
        if ifield.name < dest_field.name:
            eval_common.resolve_conflict_at_border(world, ifield, dest_field)
            # {choose n to be not the looser of the border conflict}
            n: t_field
            m: t_field
            if ifield.succeeds:
                n, m = ifield, dest_field
            else:
                m, n = ifield, dest_field
            if n.succeeds:
                # {does n not only win at the order but also at the target field?}
                m.add_event("$nwin")
                eval_common.resolve_conflict_at_field(world, m)
                if n.succeeds or _ri97 > 0:
                    # {the weaker move has no effect}
                    m.add_event("$mlooseA")
                    m.order = t_order.none
                    eval_common.resolve_conflict_at_field(world, n)
                else:
                    # {the weaker move will not succeed}
                    m.add_event("$mlooseB")
                    eval_common.resolve_conflict_at_field(world, n)
                    m.succeeds = False
            else:
                # {draw at border}
                m.add_event("$bdraw")
                if _ri97 == 2:
                    # {the opposing moves have no effect}
                    m.add_event("$bdraw2m")
                    n.add_event("$bdraw2n")
                    m.order = t_order.none
                    eval_common.resolve_conflict_at_field(world, n)
                    n.order = t_order.none
                    eval_common.resolve_conflict_at_field(world, m)
                else:
                    # {the opposing moves will not succeed}
                    m.add_event("$bdrawXm")
                    n.add_event("$bdrawXn")
                    eval_common.resolve_conflict_at_field(world, n)
                    m.succeeds = False
                    eval_common.resolve_conflict_at_field(world, m)
                    n.succeeds = False
                pass  # end if _ri97 == 2 else
            pass  # end if n.succeeds else
        pass  # end if ifield.name < ifield.dest
    #
    eval_common.change_moves_to_umoves(world, category=3)
    #
    log.debug("DONE k3. fields: %s", dip_eval.LogList(world.get_fields()))
    return