Compare commits

...

8 Commits

Author SHA1 Message Date
0979d2c678 Merge pull request 'isolated-state-generation' (#39) from isolated-state-generation into assymetric-template-relation-systems
All checks were successful
E2E Testing / test (push) Successful in 1m32s
Reviewed-on: #39
2024-04-19 20:03:10 +02:00
Sebastian Böckelmann
48478d340a Fix gamesystem undefined error in gamesystem-editor
All checks were successful
E2E Testing / test (push) Successful in 1m31s
2024-04-19 20:01:22 +02:00
Sebastian Böckelmann
5b1e711a11 Change symmetric default values to be false
Some checks failed
E2E Testing / test (push) Failing after 1m29s
2024-04-19 19:56:04 +02:00
Sebastian Böckelmann
0104df8084 Add generated isolated states to already generated states
Some checks failed
E2E Testing / test (push) Failing after 1m31s
2024-04-19 19:53:31 +02:00
Sebastian Böckelmann
7cb02030d9 Generate only symmetric isolated states
All checks were successful
E2E Testing / test (push) Successful in 1m36s
2024-04-19 17:52:50 +02:00
Sebastian Böckelmann
87a0dd775e Generate isolated states only on demand
All checks were successful
E2E Testing / test (push) Successful in 1m40s
2024-04-19 17:50:03 +02:00
Sebastian Böckelmann
ee970db716 Generate isolated template States
Some checks failed
E2E Testing / test (push) Failing after 1m43s
2024-04-19 17:45:58 +02:00
Sebastian Böckelmann
3d9db9b143 Generate isolated states
Some checks failed
E2E Testing / test (push) Failing after 1m43s
2024-04-19 17:42:25 +02:00
14 changed files with 247 additions and 6 deletions

View File

@ -1,6 +1,14 @@
<div *ngIf="isGamesystemTemplate()">
<mat-checkbox [(ngModel)]="convertGamesystemToTemplate(gamesystem)!.symmetric">Gamesystem is symmetric template</mat-checkbox>
</div>
<app-simple-gamesystem-editor *ngIf="isSimpleGamesystem()" [templateElement]="templateElement" [simpleGamesystem]="convertGamesystemToSimpleGamesystem()" [scriptAccunts]="scriptAccounts"></app-simple-gamesystem-editor> <app-simple-gamesystem-editor *ngIf="isSimpleGamesystem()" [templateElement]="templateElement" [simpleGamesystem]="convertGamesystemToSimpleGamesystem()" [scriptAccunts]="scriptAccounts"></app-simple-gamesystem-editor>
<app-product-gamesystem-editor *ngIf="!isSimpleGamesystem()" [templateElement]="templateElement" [gamesystem]="convertGamesystemToProductGamesystem()" <app-product-gamesystem-editor *ngIf="!isSimpleGamesystem()" [templateElement]="templateElement" [gamesystem]="convertGamesystemToProductGamesystem()"
(onOpenGamesystemEditor)="onOpenGamesystemEditor($event)"></app-product-gamesystem-editor> (onOpenGamesystemEditor)="onOpenGamesystemEditor($event)"></app-product-gamesystem-editor>
<mat-expansion-panel *ngIf="gamesystem != undefined">
<mat-expansion-panel-header>
<mat-panel-title>Product Generation Settings</mat-panel-title>
</mat-expansion-panel-header>
<div *ngIf="isGamesystemTemplate()">
<mat-checkbox [(ngModel)]="convertGamesystemToTemplate(gamesystem)!.symmetric">Use symmetric Productgenerators</mat-checkbox>
</div>
<mat-checkbox [(ngModel)]="gamesystem!.generateIsolatedStates">Generate Isolated ProductStates</mat-checkbox>
</mat-expansion-panel>

View File

@ -1,3 +1,4 @@
<app-product-state-editor [templateElement]="templateElement" [gamesystem]="gamesystem" (onOpenGamesystemEditor)="onOpenGamesystemEditor($event)"></app-product-state-editor> <app-product-state-editor [templateElement]="templateElement" [gamesystem]="gamesystem" (onOpenGamesystemEditor)="onOpenGamesystemEditor($event)"></app-product-state-editor>
<div id="productStateEditor"> <div id="productStateEditor">
<app-product-transition-editor [templateElement]="templateElement" [gamesystem]="gamesystem" (onOpenGamesystem)="onOpenGamesystemEditor($event)"></app-product-transition-editor> <app-product-transition-editor [templateElement]="templateElement" [gamesystem]="gamesystem" (onOpenGamesystem)="onOpenGamesystemEditor($event)"></app-product-transition-editor>

View File

@ -1,4 +1,4 @@
import {Component, EventEmitter, Input, Output} from '@angular/core'; import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import { import {
ProductTransitionEditorComponent ProductTransitionEditorComponent
} from "../transition-editor/product-transition-editor/product-transition-editor.component"; } from "../transition-editor/product-transition-editor/product-transition-editor.component";
@ -13,12 +13,15 @@ import {TemplateElement} from "../../../project/game-model/templates/TemplateEle
templateUrl: './product-gamesystem-editor.component.html', templateUrl: './product-gamesystem-editor.component.html',
styleUrl: './product-gamesystem-editor.component.scss' styleUrl: './product-gamesystem-editor.component.scss'
}) })
export class ProductGamesystemEditorComponent { export class ProductGamesystemEditorComponent implements OnInit{
@Input() gamesystem: ProductGamesystem | undefined @Input() gamesystem: ProductGamesystem | undefined
@Input() templateElement: TemplateElement | undefined @Input() templateElement: TemplateElement | undefined
@Output("onOpenGamesystemEditor") openGamesystemEditorEmitter = new EventEmitter<SimpleGamesystem>(); @Output("onOpenGamesystemEditor") openGamesystemEditorEmitter = new EventEmitter<SimpleGamesystem>();
ngOnInit() {
}
onOpenGamesystemEditor(gamesystem: SimpleGamesystem) { onOpenGamesystemEditor(gamesystem: SimpleGamesystem) {
this.openGamesystemEditorEmitter.emit(gamesystem); this.openGamesystemEditorEmitter.emit(gamesystem);
} }

View File

@ -50,6 +50,7 @@ export class ProductStateEditorComponent implements OnInit{
if(this.templateElement == undefined) { if(this.templateElement == undefined) {
this.datasource.data = this.gamesystem!.states; this.datasource.data = this.gamesystem!.states;
} else if(this.gamesystem instanceof ProductTemplateSystem) { } else if(this.gamesystem instanceof ProductTemplateSystem) {
console.log("Product Template System: ", this.gamesystem!.stateMap.get(this.templateElement))
this.datasource.data = this.gamesystem!.stateMap.get(this.templateElement)! this.datasource.data = this.gamesystem!.stateMap.get(this.templateElement)!
} }

View File

@ -22,6 +22,7 @@ export class CharacterRelation implements TemplateElement{
if((gamesystem instanceof SimpleTemplateGamesystem || gamesystem instanceof ProductTemplateSystem) && !this.isGamesystemCharacterRelationSpecific(gamesystem.componentName)) { if((gamesystem instanceof SimpleTemplateGamesystem || gamesystem instanceof ProductTemplateSystem) && !this.isGamesystemCharacterRelationSpecific(gamesystem.componentName)) {
const templateGamesystem = new ProductTemplateSystem(gamesystem.componentName, gamesystem.componentDescription, TemplateType.CHARACTER_RELATION); const templateGamesystem = new ProductTemplateSystem(gamesystem.componentName, gamesystem.componentDescription, TemplateType.CHARACTER_RELATION);
templateGamesystem.symmetric = gamesystem.symmetric templateGamesystem.symmetric = gamesystem.symmetric
templateGamesystem.generateIsolatedStates = gamesystem.generateIsolatedStates
templateGamesystem.addChildGamesystem(gamesystem); templateGamesystem.addChildGamesystem(gamesystem);
templateGamesystem.addChildGamesystem(gamesystem); templateGamesystem.addChildGamesystem(gamesystem);
this.characterRelationGamesystems.push(templateGamesystem); this.characterRelationGamesystems.push(templateGamesystem);

View File

@ -8,6 +8,8 @@ export abstract class Gamesystem<S, T> extends ModelComponent{
states: S[] = []; states: S[] = [];
transitions: T[] = []; transitions: T[] = [];
parentGamesystem: ProductGamesystem | undefined parentGamesystem: ProductGamesystem | undefined
generateIsolatedStates: boolean = false
constructor(gamesystemName: string, gamesystemDescription: string) { constructor(gamesystemName: string, gamesystemDescription: string) {
super(gamesystemName, gamesystemDescription, ModelComponentType.GAMESYTEM); super(gamesystemName, gamesystemDescription, ModelComponentType.GAMESYTEM);
} }

View File

@ -11,6 +11,7 @@ import {ScriptAccountAction} from "./actions/ScriptAccountAction";
import {ProductSystemGenerator} from "./productSystemGenerator/ProductSystemGenerator"; import {ProductSystemGenerator} from "./productSystemGenerator/ProductSystemGenerator";
import {TemplateType} from "../templates/TemplateType"; import {TemplateType} from "../templates/TemplateType";
import {ProductTemplateSystem} from "../templates/productGamesystem/ProductTemplateSystem"; import {ProductTemplateSystem} from "../templates/productGamesystem/ProductTemplateSystem";
import {IsolatedProductStateGenerator} from "./productSystemGenerator/IsolatedProductStateGenerator";
export class ProductGamesystem extends Gamesystem<ProductState, ProductTransition> { export class ProductGamesystem extends Gamesystem<ProductState, ProductTransition> {
@ -74,6 +75,11 @@ export class ProductGamesystem extends Gamesystem<ProductState, ProductTransitio
generateFromChildsystems() { generateFromChildsystems() {
const productGenerator = new ProductSystemGenerator(this); const productGenerator = new ProductSystemGenerator(this);
productGenerator.generateFromChildsystems(); productGenerator.generateFromChildsystems();
if(this.generateIsolatedStates) {
const isolatedStatesGenerator = new IsolatedProductStateGenerator(this);
isolatedStatesGenerator.generateIsolatedProductStates();
}
} }
addChildGamesystem(gamesystem: Gamesystem<State<any>, Transition<any>>) { addChildGamesystem(gamesystem: Gamesystem<State<any>, Transition<any>>) {

View File

@ -0,0 +1,54 @@
import {ProductSystemGenerator} from "./ProductSystemGenerator";
import {ProductGenerationData} from "./ProductGenerationData";
import {ProductGeneratorResult} from "./ProductGeneratorResult";
import {ProductState} from "../states/ProductState";
export class IsolatedProductStateGenerator extends ProductSystemGenerator {
generateIsolatedProductStates() {
if(this.productGamesystem.innerGamesystems.length < 2) return;
const leftInitialData = this.prepareChildsystemForGeneration(this.productGamesystem.innerGamesystems[0])
const rightInitialData = this.prepareChildsystemForGeneration(this.productGamesystem.innerGamesystems[1])
const initialGenerationResult = this.generateBinaryIsolatedProductStates(leftInitialData, rightInitialData);
if(this.productGamesystem.innerGamesystems.length > 2) {
for(let i=2; i<this.productGamesystem.innerGamesystems.length; i++) {
const leftData = initialGenerationResult.productGenerationData;
const rightData = this.prepareChildsystemForGeneration(this.productGamesystem.innerGamesystems[i]);
const generationResult = this.generateBinaryIsolatedProductStates(leftData, rightData);
this.assignGeneratedStatesAndTransitions(generationResult)
}
} else {
this.assignGeneratedStatesAndTransitions(initialGenerationResult)
}
}
protected assignGeneratedStatesAndTransitions(generationResult: ProductGeneratorResult) {
this.productGamesystem.states = this.productGamesystem.states.concat(generationResult.states);
console.log("Generation-Result: ", this.productGamesystem.states)
}
protected generateBinaryIsolatedProductStates(leftSystemData: ProductGenerationData, rightSystemData: ProductGenerationData): ProductGeneratorResult {
const generatedProductStates: ProductState[] = []
leftSystemData.states.forEach(leftState => {
if(leftState.outgoingTransitions.length == 0 && leftState.incomingTransitions.length == 0) {
rightSystemData.states.forEach(rightState => {
if(rightState.outgoingTransitions.length == 0 && rightState.incomingTransitions.length == 0) {
const leftConditions = this.getStateConditions(leftState, true);
const rightConditions = this.getStateConditions(rightState, true);
if(!this.contradictCombinedConditions(leftConditions, rightConditions)) {
this.generateBinaryProductState(leftState, rightState, generatedProductStates);
}
}
})
}
})
return new ProductGeneratorResult(generatedProductStates, []);
}
}

View File

@ -0,0 +1,48 @@
import {IsolatedTemplateStateGenerator} from "./IsolatedTemplateStateGenerator";
import {ProductGenerationData} from "./ProductGenerationData";
import {ProductGeneratorResult} from "./ProductGeneratorResult";
import {ProductState} from "../states/ProductState";
import {SimpleState} from "../states/SimpleState";
import {State} from "../states/State";
import {ScriptAccountCondition} from "../conditions/ScriptAccountCondition";
export class IsolatedSymmetricTemplateStateGenerator extends IsolatedTemplateStateGenerator{
protected generateBinaryIsolatedProductStates(leftSystemData: ProductGenerationData, rightSystemData: ProductGenerationData): ProductGeneratorResult {
console.log("Calling test")
console.log(leftSystemData.states)
console.log(rightSystemData.states)
const generatedProductStates: ProductState[] = []
leftSystemData.states.forEach(leftState => {
if(leftState.outgoingTransitions.length == 0 && leftState.incomingTransitions.length == 0) {
rightSystemData.states.forEach(rightState => {
console.log("LeftState is isolated")
if(leftState.equals(rightState)) {
if(rightState.outgoingTransitions.length == 0 && rightState.incomingTransitions.length == 0) {
const leftConditions = this.getStateConditions(leftState, true);
const rightConditions = this.getStateConditions(rightState, true);
if(!this.contradictCombinedConditions(leftConditions, rightConditions)) {
this.generateBinaryProductState(leftState, rightState, generatedProductStates);
}
}
}
if(leftState.equals(rightState) && rightState.outgoingTransitions.length == 0 && rightState.incomingTransitions.length == 0) {
const leftConditions = this.getStateConditions(leftState, true);
const rightConditions = this.getStateConditions(rightState, true);
if(!this.contradictCombinedConditions(leftConditions, rightConditions)) {
const generatedState = this.generateBinaryProductState(leftState, rightState, generatedProductStates);
console.log(generatedProductStates)
}
}
})
}
})
return new ProductGeneratorResult(generatedProductStates, []);
}
}

View File

@ -0,0 +1,66 @@
import {IsolatedProductStateGenerator} from "./IsolatedProductStateGenerator";
import {Transition} from "../transitions/Transition";
import {SimpleTemplateTransition} from "../../templates/simpleGamesystem/SimpleTemplateTransition";
import {State} from "../states/State";
import {ScriptAccountCondition} from "../conditions/ScriptAccountCondition";
import {SimpleTemplateState} from "../../templates/simpleGamesystem/SimpleTemplateState";
import {Character} from "../../characters/Character";
import {CharacterRelation} from "../../characters/CharacterRelation";
import {TemplateElement} from "../../templates/TemplateElement";
import {ProductTemplateSystem} from "../../templates/productGamesystem/ProductTemplateSystem";
import {ProductGeneratorResult} from "./ProductGeneratorResult";
import {state, transition} from "@angular/animations";
export class IsolatedTemplateStateGenerator extends IsolatedProductStateGenerator {
templateElement: TemplateElement
constructor(productGamesystem: ProductTemplateSystem, templateElement: TemplateElement) {
super(productGamesystem);
this.templateElement = templateElement;
}
protected assignGeneratedStatesAndTransitions(generationResult: ProductGeneratorResult) {
const templateSystem = this.productGamesystem as ProductTemplateSystem;
const nonIsolatedStates = templateSystem.stateMap.get(this.templateElement)!
const states = nonIsolatedStates.concat(generationResult.states);
templateSystem.stateMap.set(this.templateElement, states)
}
protected getTransitionConditions(transition: Transition<any>, leftSystem: boolean) {
const templateElement = this.determineTemplateElement(leftSystem)!;
if(transition instanceof SimpleTemplateTransition && transition.conditionMap.has(templateElement)) {
return transition.conditionMap.get(templateElement)!
}
return transition.scriptAccountConditions;
}
protected getTransitionActions(transition: Transition<any>, leftSystem: boolean) {
const templateElement = this.determineTemplateElement(leftSystem)!;
if(transition instanceof SimpleTemplateTransition && transition.actionMap.has(templateElement)) {
return transition.actionMap.get(templateElement)!
} else {
return transition.scriptAccountActions;
}
}
protected getStateConditions(state: State<any>, leftSystem: boolean): ScriptAccountCondition[] {
const templateElement = this.determineTemplateElement(leftSystem)!
if(state instanceof SimpleTemplateState && state.conditionMap.has(templateElement)) {
return state.conditionMap.get(templateElement)!
} else {
return state.conditions
}
}
private determineTemplateElement(leftSystem: boolean) {
if(this.templateElement instanceof Character) {
return this.templateElement;
} else if(this.templateElement instanceof CharacterRelation) {
return leftSystem ? this.templateElement.firstCharacter : this.templateElement.secondCharacter;
}
}
}

View File

@ -10,6 +10,10 @@ import {TemplateProductSystemGenerator} from "../../gamesystems/productSystemGen
import { import {
SymmetricProductTemplateGenerator SymmetricProductTemplateGenerator
} from "../../gamesystems/productSystemGenerator/SymmetricProductTemplateGenerator"; } from "../../gamesystems/productSystemGenerator/SymmetricProductTemplateGenerator";
import {IsolatedTemplateStateGenerator} from "../../gamesystems/productSystemGenerator/IsolatedTemplateStateGenerator";
import {
IsolatedSymmetricTemplateStateGenerator
} from "../../gamesystems/productSystemGenerator/IsolatedSymmetricTemplateStateGenerator";
export class ProductTemplateSystem extends ProductGamesystem implements TemplateGamesystem{ export class ProductTemplateSystem extends ProductGamesystem implements TemplateGamesystem{
@ -28,10 +32,25 @@ export class ProductTemplateSystem extends ProductGamesystem implements Template
if(this.symmetric) { if(this.symmetric) {
const symmetricGenerator = new SymmetricProductTemplateGenerator(this, templateElement); const symmetricGenerator = new SymmetricProductTemplateGenerator(this, templateElement);
symmetricGenerator.generateFromChildsystems() symmetricGenerator.generateFromChildsystems()
if(this.generateIsolatedStates) {
const isolatedTemplateStateGenerator = new IsolatedSymmetricTemplateStateGenerator(this, templateElement);
isolatedTemplateStateGenerator.generateIsolatedProductStates();
console.log(this.states)
console.log("Generate symmetric isolated states")
} else {
console.log("Do not generate symmetric isolated states")
}
} else { } else {
const productTemplateGenerator = new TemplateProductSystemGenerator(this, templateElement); const productTemplateGenerator = new TemplateProductSystemGenerator(this, templateElement);
productTemplateGenerator.generateFromChildsystems() productTemplateGenerator.generateFromChildsystems()
if(this.generateIsolatedStates) {
const isolatedTemplateStateGenerator = new IsolatedTemplateStateGenerator(this, templateElement);
isolatedTemplateStateGenerator.generateIsolatedProductStates();
} }
}
} }

View File

@ -10,7 +10,7 @@ import {TemplateType} from "../TemplateType";
export class SimpleTemplateGamesystem extends SimpleGamesystem implements TemplateGamesystem { export class SimpleTemplateGamesystem extends SimpleGamesystem implements TemplateGamesystem {
templateType: TemplateType templateType: TemplateType
symmetric: boolean = true symmetric: boolean = false
constructor(gamesystemName: string, gamesystemDescription: string, templateType: TemplateType) { constructor(gamesystemName: string, gamesystemDescription: string, templateType: TemplateType) {
super(gamesystemName, gamesystemDescription); super(gamesystemName, gamesystemDescription);

View File

@ -17,6 +17,18 @@
{ {
"stateLabel": "Fester Freund", "stateLabel": "Fester Freund",
"conditionMap": [] "conditionMap": []
},
{
"stateLabel": "Eltern",
"conditionMap": []
},
{
"stateLabel": "Geschwister",
"conditionMap": []
},
{
"stateLabel": "Großeltern",
"conditionMap": []
} }
], ],
"transitions": [ "transitions": [
@ -45,6 +57,7 @@
"actionMap": [] "actionMap": []
} }
], ],
"generateIsolatedStates": true,
"symmetric": true "symmetric": true
} }
] ]

View File

@ -19,6 +19,24 @@
"conditions": [], "conditions": [],
"stateLabel": "Fester Freund", "stateLabel": "Fester Freund",
"stateDescription": "" "stateDescription": ""
},
{
"initial": false,
"conditions": [],
"stateLabel": "Eltern",
"stateDescription": ""
},
{
"initial": false,
"conditions": [],
"stateLabel": "Geschwister",
"stateDescription": ""
},
{
"initial": false,
"conditions": [],
"stateLabel": "Großeltern",
"stateDescription": ""
} }
], ],
"transitions": [ "transitions": [
@ -47,6 +65,7 @@
"endingState": "Feind" "endingState": "Feind"
} }
], ],
"generateIsolatedStates": true,
"symmetric": true, "symmetric": true,
"templateType": 1 "templateType": 1
} }