import models/SimpleClassDiagrams as SCD
include "primitives.alh"
include "object_operations.alh"

SCD RPGame{
    Class Tile {
        $
        Element associations
        Element back_associations
        Element association
        String destination
        associations = allOutgoingAssociationInstances(model, name, "tile_left")
        while (0 < list_len(associations)):
            association = set_pop(associations)
            destination = readAssociationDestination(model, association)
            back_associations = allOutgoingAssociationInstances(model, destination, "tile_right")
            if (list_len(back_associations) < 1):
                return "Left link does not have a right link back"!
            else:
                association = set_pop(back_associations)
                destination = readAssociationDestination(model, association)
                if (destination != name):
                    return "Right link does not have a left link back to the same tile"!
        associations = allOutgoingAssociationInstances(model, name, "tile_right")
        while (0 < list_len(associations)):
            association = set_pop(associations)
            destination = readAssociationDestination(model, association)
            back_associations = allOutgoingAssociationInstances(model, destination, "tile_left")
            if (list_len(back_associations) < 1):
                return "Right link does not have a left link back"!
            else:
                association = set_pop(back_associations)
                destination = readAssociationDestination(model, association)
                if (destination != name):
                    return "Right link does not have a left link back to the same tile"!
        associations = allOutgoingAssociationInstances(model, name, "tile_top")
        while (0 < list_len(associations)):
            association = set_pop(associations)
            destination = readAssociationDestination(model, association)
            back_associations = allOutgoingAssociationInstances(model, destination, "tile_bottom")
            if (list_len(back_associations) < 1):
                return "Top link does not have a bottom link back"!
            else:
                association = set_pop(back_associations)
                destination = readAssociationDestination(model, association)
                if (destination != name):
                    return "Top link does not have a bottom link back to the same tile"!
        associations = allOutgoingAssociationInstances(model, name, "tile_bottom")
        while (0 < list_len(associations)):
            association = set_pop(associations)
            destination = readAssociationDestination(model, association)
            back_associations = allOutgoingAssociationInstances(model, destination, "tile_top")
            if (list_len(back_associations) < 1):
                return "Bottom link does not have a top link back"!
            else:
                association = set_pop(back_associations)
                destination = readAssociationDestination(model, association)
                if (destination != name):
                    return "Bottom link does not have a top link back to the same tile"!
        return "OK"!
        $
    }
    Association tile_left (Tile, Tile){
        source_upper_cardinality = 1
        target_upper_cardinality = 1
    }
    Association tile_right (Tile, Tile){
        source_upper_cardinality = 1
        target_upper_cardinality = 1
    }
    Association tile_top (Tile, Tile){
        source_upper_cardinality = 1
        target_upper_cardinality = 1
    }
    Association tile_bottom (Tile, Tile){
        source_upper_cardinality = 1
        target_upper_cardinality = 1
    }
    Class Scene {}
    Association Scene_has_tiles (Scene, Tile){
        source_lower_cardinality = 1
        source_upper_cardinality = 1
        target_lower_cardinality = 1
    }
    Class Item {}
    Association Item_on_tile (Item, Tile){
        source_upper_cardinality = 1
        target_lower_cardinality = 1
        target_upper_cardinality = 1
    }
    Class Goal : Item {}
    Class Character {}
    Association Character_on_tile (Character, Tile){
        source_upper_cardinality = 1
        target_lower_cardinality = 1
        target_upper_cardinality = 1
    }
    Class Hero : Character {}
}

export RPGame to models/RPGame

RPGame my_game {
    Scene scene {}
    Hero link {}
    Goal goal {}
    Tile tile_00 {}
    Tile tile_01 {}
    Tile tile_10 {}
    Tile tile_11 {}
    Scene_has_tiles (scene, tile_00) {}
    Scene_has_tiles (scene, tile_01) {}
    Scene_has_tiles (scene, tile_10) {}
    Scene_has_tiles (scene, tile_11) {}
    Character_on_tile (link, tile_00) {}
    Item_on_tile (goal, tile_11) {}
    tile_left (tile_01, tile_00) {}
    tile_right (tile_00, tile_01) {}
    tile_left (tile_11, tile_10) {}
    tile_right (tile_10, tile_11) {}
    tile_top (tile_10, tile_00) {}
    tile_bottom (tile_00, tile_10) {}
    tile_top (tile_11, tile_01) {}
    tile_bottom (tile_01, tile_11) {}
}

export my_game to models/my_game
