Introduce ProductSystemGenerator
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				E2E Testing / test (push) Successful in 1m32s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	E2E Testing / test (push) Successful in 1m32s
				
			This commit is contained in:
		
							parent
							
								
									ef9f24544a
								
							
						
					
					
						commit
						45c5da7c50
					
				@ -8,6 +8,7 @@ import {SimpleGamesystem} from "./SimpleGamesystem";
 | 
				
			|||||||
import {GameModel} from "../GameModel";
 | 
					import {GameModel} from "../GameModel";
 | 
				
			||||||
import {ScriptAccountCondition} from "./conditions/ScriptAccountCondition";
 | 
					import {ScriptAccountCondition} from "./conditions/ScriptAccountCondition";
 | 
				
			||||||
import {ScriptAccountAction} from "./actions/ScriptAccountAction";
 | 
					import {ScriptAccountAction} from "./actions/ScriptAccountAction";
 | 
				
			||||||
 | 
					import {ProductSystemGenerator} from "./productSystemGenerator/ProductSystemGenerator";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class ProductGamesystem extends Gamesystem<ProductState, ProductTransition> {
 | 
					export class ProductGamesystem extends Gamesystem<ProductState, ProductTransition> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -66,202 +67,8 @@ export class ProductGamesystem extends Gamesystem<ProductState, ProductTransitio
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  generateFromChildsystems() {
 | 
					  generateFromChildsystems() {
 | 
				
			||||||
    //Assume that childsystems that are productsystems are already generated
 | 
					    const productGenerator = new ProductSystemGenerator(this);
 | 
				
			||||||
    if(this.innerGamesystems.length < 2) {
 | 
					    productGenerator.generateFromChildsystems();
 | 
				
			||||||
      //currently only safe-guard
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    const integratedSystems: Gamesystem<any, any>[] = [this.innerGamesystems[0], this.innerGamesystems[1]];
 | 
					 | 
				
			||||||
    if(this.innerGamesystems[0] instanceof ProductGamesystem) {
 | 
					 | 
				
			||||||
      this.innerGamesystems[0].generateFromChildsystems();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(this.innerGamesystems[1] instanceof ProductGamesystem) {
 | 
					 | 
				
			||||||
      this.innerGamesystems[1].generateFromChildsystems();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    let gamesystem: ProductGamesystem  = ProductGamesystem.generateFromChildsystems(this.innerGamesystems[0], this.innerGamesystems[1], false, integratedSystems);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for(let i=2; i<this.innerGamesystems.length; i++) {
 | 
					 | 
				
			||||||
      if(this.innerGamesystems[i] instanceof ProductGamesystem) {
 | 
					 | 
				
			||||||
        (this.innerGamesystems[i] as ProductGamesystem).generateFromChildsystems();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      integratedSystems.push(this.innerGamesystems[i]);
 | 
					 | 
				
			||||||
      gamesystem = ProductGamesystem.generateFromChildsystems(gamesystem, this.innerGamesystems[i], true, integratedSystems);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    this.states = gamesystem.states;
 | 
					 | 
				
			||||||
    this.transitions = gamesystem.transitions;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  static generateFromChildsystems(leftSystem: Gamesystem<any, any>, rightSystem: Gamesystem<any, any>, left_temp: boolean, integratedSystems: Gamesystem<any, any>[]) {
 | 
					 | 
				
			||||||
    const productGamesystem = new ProductGamesystem("Temporary Gamesystem", "");
 | 
					 | 
				
			||||||
    integratedSystems.forEach(integratedSystem => productGamesystem.addChildGamesystem(integratedSystem));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    leftSystem.states.forEach(leftState => {
 | 
					 | 
				
			||||||
      rightSystem.states.forEach(rightState => {
 | 
					 | 
				
			||||||
        for(let i=0; i<leftState.outgoingTransitions.length; i++) {
 | 
					 | 
				
			||||||
          for(let j=0; j<rightState.outgoingTransitions.length; j++) {
 | 
					 | 
				
			||||||
            const startingState = productGamesystem.generateBinaryProductState(leftState, rightState, left_temp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(startingState != undefined) {
 | 
					 | 
				
			||||||
              const endingState_right = productGamesystem.generateBinaryProductState(leftState, rightState.outgoingTransitions[j].endingState, left_temp);
 | 
					 | 
				
			||||||
              if(endingState_right != undefined) {
 | 
					 | 
				
			||||||
                const transition_right = productGamesystem.createTransition(startingState, endingState_right);
 | 
					 | 
				
			||||||
                if(transition_right != undefined) {
 | 
					 | 
				
			||||||
                  transition_right.scriptAccountActions = [...rightState.outgoingTransitions[j].scriptAccountActions]
 | 
					 | 
				
			||||||
                  transition_right.scriptAccountConditions = [... rightState.outgoingTransitions[j].scriptAccountConditions]
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              const endingState_left = productGamesystem.generateBinaryProductState(leftState.outgoingTransitions[i].endingState, rightState, left_temp);
 | 
					 | 
				
			||||||
              if(endingState_left != undefined) {
 | 
					 | 
				
			||||||
                const transition_left = productGamesystem.createTransition(startingState, endingState_left);
 | 
					 | 
				
			||||||
                if(transition_left != undefined) {
 | 
					 | 
				
			||||||
                  transition_left.scriptAccountActions = [... leftState.outgoingTransitions[i].scriptAccountActions]
 | 
					 | 
				
			||||||
                  transition_left.scriptAccountConditions = [...leftState.outgoingTransitions[i].scriptAccountConditions]
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              const endingState_left_right = productGamesystem.generateBinaryProductState(leftState.outgoingTransitions[i].endingState, rightState.outgoingTransitions[j].endingState, left_temp);
 | 
					 | 
				
			||||||
              if(endingState_left_right != undefined) {
 | 
					 | 
				
			||||||
                const leftConditions = leftState.outgoingTransitions[i].scriptAccountConditions;
 | 
					 | 
				
			||||||
                const rightConditions = rightState.outgoingTransitions[j].scriptAccountConditions;
 | 
					 | 
				
			||||||
                if(!this.contradictCombinedConditions(leftConditions, rightConditions)) {
 | 
					 | 
				
			||||||
                  const transition_left_right = productGamesystem.createTransition(startingState, endingState_left_right)!;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                  if(transition_left_right != undefined) {
 | 
					 | 
				
			||||||
                    transition_left_right.scriptAccountActions = this.generateCombinedActions(leftState.outgoingTransitions[i].scriptAccountActions, rightState.outgoingTransitions[j].scriptAccountActions)
 | 
					 | 
				
			||||||
                    transition_left_right.scriptAccountConditions = this.generateCombinedConditions(leftState.outgoingTransitions[i].scriptAccountConditions, rightState.outgoingTransitions[j].scriptAccountConditions)
 | 
					 | 
				
			||||||
                  }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          if(rightState.outgoingTransitions.length == 0) {
 | 
					 | 
				
			||||||
            const startingState = productGamesystem.generateBinaryProductState(leftState, rightState, left_temp);
 | 
					 | 
				
			||||||
            const endingState = productGamesystem.generateBinaryProductState(leftState.outgoingTransitions[i].endingState, rightState, left_temp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(startingState != undefined && endingState != undefined) {
 | 
					 | 
				
			||||||
              const transition = productGamesystem.createTransition(startingState, endingState);
 | 
					 | 
				
			||||||
              if(transition != undefined) {
 | 
					 | 
				
			||||||
                transition.scriptAccountActions = [... leftState.outgoingTransitions[i].scriptAccountActions]
 | 
					 | 
				
			||||||
                transition.scriptAccountConditions = [...leftState.outgoingTransitions[i].scriptAccountConditions]
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(leftState.outgoingTransitions.length == 0) {
 | 
					 | 
				
			||||||
          for(let j=0; j<rightState.outgoingTransitions.length; j++) {
 | 
					 | 
				
			||||||
            const startingState = productGamesystem.generateBinaryProductState(leftState, rightState, left_temp);
 | 
					 | 
				
			||||||
            const endingState = productGamesystem.generateBinaryProductState(leftState, rightState.outgoingTransitions[j].endingState, left_temp);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(startingState != undefined && endingState != undefined) {
 | 
					 | 
				
			||||||
              const transition = productGamesystem.createTransition(startingState, endingState);
 | 
					 | 
				
			||||||
              if(transition != undefined) {
 | 
					 | 
				
			||||||
                transition.scriptAccountActions = [... rightState.outgoingTransitions[j].scriptAccountActions]
 | 
					 | 
				
			||||||
                transition.scriptAccountConditions = [...rightState.outgoingTransitions[j].scriptAccountConditions]
 | 
					 | 
				
			||||||
              }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      })
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return productGamesystem;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  private static generateCombinedActions(leftActions: ScriptAccountAction[], rightActions: ScriptAccountAction[]) {
 | 
					 | 
				
			||||||
    const combinedActions: ScriptAccountAction[] = []
 | 
					 | 
				
			||||||
    for(let i=0; i<leftActions.length; i++) {
 | 
					 | 
				
			||||||
      for(let j=0; j<rightActions.length; j++) {
 | 
					 | 
				
			||||||
        const combinedAction = leftActions[i].combineActions(rightActions[j])
 | 
					 | 
				
			||||||
        if(combinedAction == undefined) {
 | 
					 | 
				
			||||||
          if(!combinedActions.includes(leftActions[i])) {
 | 
					 | 
				
			||||||
            combinedActions.push(leftActions[i])
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          if(!combinedActions.includes(rightActions[j])) {
 | 
					 | 
				
			||||||
            combinedActions.push(rightActions[j])
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          combinedActions.push(combinedAction)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return combinedActions;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  private static generateCombinedConditions(leftConditions: ScriptAccountCondition[], rightConditions: ScriptAccountCondition[]) {
 | 
					 | 
				
			||||||
    const combinedConditions: ScriptAccountCondition[] = [];
 | 
					 | 
				
			||||||
    for(let i=0; i<leftConditions.length; i++) {
 | 
					 | 
				
			||||||
      for(let j=0; j<rightConditions.length; j++) {
 | 
					 | 
				
			||||||
        const combinedCondition = leftConditions[i].combineCondition(rightConditions[j]);
 | 
					 | 
				
			||||||
        if(combinedCondition == undefined) {
 | 
					 | 
				
			||||||
          if(!combinedConditions.includes(leftConditions[i])) {
 | 
					 | 
				
			||||||
            combinedConditions.push(leftConditions[i])
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          if(!combinedConditions.includes(rightConditions[j])) {
 | 
					 | 
				
			||||||
            combinedConditions.push(rightConditions[j])
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
          combinedConditions.push(combinedCondition)
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return combinedConditions;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  private static contradictCombinedConditions(leftConditions: ScriptAccountCondition[], rightConditions: ScriptAccountCondition[]): boolean {
 | 
					 | 
				
			||||||
    for(let i=0; i<leftConditions.length; i++) {
 | 
					 | 
				
			||||||
      for(let j=0; j<rightConditions.length; j++) {
 | 
					 | 
				
			||||||
        if(leftConditions[i].isContradicting(rightConditions[j])) {
 | 
					 | 
				
			||||||
          return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return false;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  generateBinaryProductState(leftInnerState: State<any>, rightInnerState: State<any>, left_temp: boolean) {
 | 
					 | 
				
			||||||
    const combinedStateConditions: ScriptAccountCondition[] = leftInnerState.conditions.concat(rightInnerState.conditions)
 | 
					 | 
				
			||||||
    for(let i=0; i<combinedStateConditions.length; i++) {
 | 
					 | 
				
			||||||
      for(let j=0; j<combinedStateConditions.length; j++) {
 | 
					 | 
				
			||||||
        if(combinedStateConditions[i].isContradicting(combinedStateConditions[j])) {
 | 
					 | 
				
			||||||
          return undefined
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let innerStates: State<any>[] = [];
 | 
					 | 
				
			||||||
    if(!left_temp) {
 | 
					 | 
				
			||||||
      innerStates = [leftInnerState, rightInnerState];
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      const left_inner_product_state = leftInnerState as ProductState;
 | 
					 | 
				
			||||||
      left_inner_product_state.innerStates.forEach(state => innerStates.push(state));
 | 
					 | 
				
			||||||
      innerStates.push(rightInnerState);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let binary_productState = this.findProductStateByInnerStates(innerStates);
 | 
					 | 
				
			||||||
    if(binary_productState == undefined) {
 | 
					 | 
				
			||||||
      binary_productState =  this.createState(innerStates)!;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let productInitial = true;
 | 
					 | 
				
			||||||
    binary_productState.innerStates.forEach(innerState => productInitial = productInitial && innerState.initial)
 | 
					 | 
				
			||||||
    binary_productState!.initial = productInitial
 | 
					 | 
				
			||||||
    binary_productState.conditions = combinedStateConditions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return binary_productState!;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  addChildGamesystem(gamesystem: Gamesystem<State<any>, Transition<any>>) {
 | 
					  addChildGamesystem(gamesystem: Gamesystem<State<any>, Transition<any>>) {
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					import {Transition} from "../transitions/Transition";
 | 
				
			||||||
 | 
					import {State} from "../states/State";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class ProductGenerationData {
 | 
				
			||||||
 | 
					  states: State<any>[]
 | 
				
			||||||
 | 
					  transitions: Transition<any>[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(states: State<any>[], transitions: Transition<any>[]) {
 | 
				
			||||||
 | 
					    this.states = states;
 | 
				
			||||||
 | 
					    this.transitions = transitions;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					import {ProductState} from "../states/ProductState";
 | 
				
			||||||
 | 
					import {ProductTransition} from "../transitions/ProductTransition";
 | 
				
			||||||
 | 
					import {ProductGenerationData} from "./ProductGenerationData";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class ProductGeneratorResult {
 | 
				
			||||||
 | 
					  states: ProductState[];
 | 
				
			||||||
 | 
					  transitions: ProductTransition[]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(states: ProductState[], transitions: ProductTransition[]) {
 | 
				
			||||||
 | 
					    this.states = states;
 | 
				
			||||||
 | 
					    this.transitions = transitions;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  get productGenerationData(): ProductGenerationData {
 | 
				
			||||||
 | 
					    return new ProductGenerationData(this.states, this.transitions)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,234 @@
 | 
				
			|||||||
 | 
					import {ScriptAccountCondition} from "../conditions/ScriptAccountCondition";
 | 
				
			||||||
 | 
					import {ScriptAccountAction} from "../actions/ScriptAccountAction";
 | 
				
			||||||
 | 
					import {ProductState} from "../states/ProductState";
 | 
				
			||||||
 | 
					import {State} from "../states/State";
 | 
				
			||||||
 | 
					import {Transition} from "../transitions/Transition";
 | 
				
			||||||
 | 
					import {ProductGamesystem} from "../ProductGamesystem";
 | 
				
			||||||
 | 
					import {ProductGeneratorResult} from "./ProductGeneratorResult";
 | 
				
			||||||
 | 
					import {Gamesystem} from "../Gamesystem";
 | 
				
			||||||
 | 
					import {ProductGenerationData} from "./ProductGenerationData";
 | 
				
			||||||
 | 
					import {ProductTransition} from "../transitions/ProductTransition";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export class ProductSystemGenerator {
 | 
				
			||||||
 | 
					  productGamesystem: ProductGamesystem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  constructor(productGamesystem: ProductGamesystem) {
 | 
				
			||||||
 | 
					    this.productGamesystem = productGamesystem;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  generateFromChildsystems(): void {
 | 
				
			||||||
 | 
					    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.generateFromBinaryChildsystems(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.generateFromBinaryChildsystems(leftData, rightData);
 | 
				
			||||||
 | 
					        this.assignGeneratedStatesAndTransitions(generationResult)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      this.assignGeneratedStatesAndTransitions(initialGenerationResult)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected prepareChildsystemForGeneration(childsystem: Gamesystem<any, any>) {
 | 
				
			||||||
 | 
					    if(childsystem instanceof ProductGamesystem) {
 | 
				
			||||||
 | 
					      childsystem.generateFromChildsystems()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return new ProductGenerationData(childsystem.states, childsystem.transitions)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected generateFromBinaryChildsystems(leftSystemData: ProductGenerationData, rightSystemData: ProductGenerationData): ProductGeneratorResult {
 | 
				
			||||||
 | 
					    const generatedProductStates: ProductState[] = []
 | 
				
			||||||
 | 
					    const generatedProductTransitions: ProductTransition[] = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    leftSystemData.states.forEach(leftState => {
 | 
				
			||||||
 | 
					      rightSystemData.states.forEach(rightState => {
 | 
				
			||||||
 | 
					        for(let i=0; i<leftState.outgoingTransitions.length; i++) {
 | 
				
			||||||
 | 
					          for(let j=0; j<rightState.outgoingTransitions.length; j++) {
 | 
				
			||||||
 | 
					            const startingState = this.generateBinaryProductState(leftState, rightState, generatedProductStates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(startingState != undefined) {
 | 
				
			||||||
 | 
					              const endingState_right = this.generateBinaryProductState(leftState, rightState.outgoingTransitions[j].endingState, generatedProductStates);
 | 
				
			||||||
 | 
					              if(endingState_right != undefined) {
 | 
				
			||||||
 | 
					                this.generateBinaryProductTransition(startingState, endingState_right, rightState.outgoingTransitions[j], generatedProductTransitions);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              const endingState_left = this.generateBinaryProductState(leftState.outgoingTransitions[i].endingState, rightState, generatedProductStates);
 | 
				
			||||||
 | 
					              if(endingState_left != undefined) {
 | 
				
			||||||
 | 
					                this.generateBinaryProductTransition(startingState, endingState_left, leftState.outgoingTransitions[i], generatedProductTransitions)
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              const endingState_left_right = this.generateBinaryProductState(leftState.outgoingTransitions[i].endingState, rightState.outgoingTransitions[j].endingState, generatedProductStates);
 | 
				
			||||||
 | 
					              if(endingState_left_right != undefined) {
 | 
				
			||||||
 | 
					                this.generateBinaryProductTransitionMulti(startingState, endingState_left_right, leftState.outgoingTransitions[i], rightState.outgoingTransitions[j], generatedProductTransitions);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if(rightState.outgoingTransitions.length == 0) {
 | 
				
			||||||
 | 
					            const startingState = this.generateBinaryProductState(leftState, rightState, generatedProductStates);
 | 
				
			||||||
 | 
					            const endingState = this.generateBinaryProductState(leftState.outgoingTransitions[i].endingState, rightState, generatedProductStates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(startingState != undefined && endingState != undefined) {
 | 
				
			||||||
 | 
					              this.generateBinaryProductTransition(startingState, endingState, leftState.outgoingTransitions[i], generatedProductTransitions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(leftState.outgoingTransitions.length == 0) {
 | 
				
			||||||
 | 
					          for(let j=0; j<rightState.outgoingTransitions.length; j++) {
 | 
				
			||||||
 | 
					            const startingState = this.generateBinaryProductState(leftState, rightState, generatedProductStates);
 | 
				
			||||||
 | 
					            const endingState = this.generateBinaryProductState(leftState, rightState.outgoingTransitions[j].endingState, generatedProductStates);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(startingState != undefined && endingState != undefined) {
 | 
				
			||||||
 | 
					              this.generateBinaryProductTransition(startingState, endingState, rightState.outgoingTransitions[j], generatedProductTransitions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return new ProductGeneratorResult(generatedProductStates, generatedProductTransitions);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected assignGeneratedStatesAndTransitions(generationResult: ProductGeneratorResult): void {
 | 
				
			||||||
 | 
					    this.productGamesystem.states = generationResult.states;
 | 
				
			||||||
 | 
					    this.productGamesystem.transitions = generationResult.transitions;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected generateBinaryProductTransition(startingState: ProductState, endingState: ProductState, usedTransition: Transition<any>, generatedTransitions: ProductTransition[]) {
 | 
				
			||||||
 | 
					    const transition = new ProductTransition(startingState, endingState);
 | 
				
			||||||
 | 
					    transition.scriptAccountActions = [... usedTransition.scriptAccountActions];
 | 
				
			||||||
 | 
					    transition.scriptAccountConditions = [... usedTransition.scriptAccountConditions];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(generatedTransitions.find(generatedTransition => generatedTransition.startingState.equals(startingState) && generatedTransition.endingState.equals(endingState)) == undefined) {
 | 
				
			||||||
 | 
					      generatedTransitions.push(transition)
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      console.log(transition)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected generateBinaryProductTransitionMulti(startingState: ProductState, endingState: ProductState, leftTransition: Transition<any>, rightTransition: Transition<any>, generatedTransitions: ProductTransition[]) {
 | 
				
			||||||
 | 
					    const leftConditions = leftTransition.scriptAccountConditions;
 | 
				
			||||||
 | 
					    const rightConditions = rightTransition.scriptAccountConditions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(!this.contradictCombinedConditions(leftConditions, rightConditions)) {
 | 
				
			||||||
 | 
					      const transition = new ProductTransition(startingState, endingState)
 | 
				
			||||||
 | 
					      transition.scriptAccountActions = this.generateCombinedActions(leftTransition.scriptAccountActions, rightTransition.scriptAccountActions);
 | 
				
			||||||
 | 
					      transition.scriptAccountConditions = this.generateCombinedConditions(leftTransition.scriptAccountConditions, rightTransition.scriptAccountConditions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if(generatedTransitions.find(generatedTransition => generatedTransition.startingState.equals(startingState) && generatedTransition.endingState.equals(endingState)) == undefined) {
 | 
				
			||||||
 | 
					        generatedTransitions.push(transition)
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        console.log(transition)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected generateBinaryProductState(leftState: State<any>, rightState: State<any>, generatedStates: ProductState[]): ProductState | undefined {
 | 
				
			||||||
 | 
					    const combinedStateConditions: ScriptAccountCondition[] = leftState.conditions.concat(rightState.conditions);
 | 
				
			||||||
 | 
					    for(let i=0; i<combinedStateConditions.length; i++) {
 | 
				
			||||||
 | 
					      for(let j=0; j<combinedStateConditions.length; j++) {
 | 
				
			||||||
 | 
					        if(combinedStateConditions[i].isContradicting(combinedStateConditions[j])) {
 | 
				
			||||||
 | 
					          return undefined
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let innerStates: State<any>[] = []
 | 
				
			||||||
 | 
					    if(leftState instanceof ProductState) {
 | 
				
			||||||
 | 
					      innerStates = leftState.innerStates
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      innerStates = [leftState]
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(rightState instanceof ProductState) {
 | 
				
			||||||
 | 
					      innerStates = innerStates.concat(rightState.innerStates)
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      innerStates = innerStates.concat(rightState)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let binaryProductState: ProductState | undefined = this.findGeneratedProductState(innerStates, generatedStates);
 | 
				
			||||||
 | 
					    if(binaryProductState == undefined) {
 | 
				
			||||||
 | 
					      binaryProductState = new ProductState(innerStates);
 | 
				
			||||||
 | 
					      generatedStates.push(binaryProductState)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //binaryProductState.determineInitialProperty()
 | 
				
			||||||
 | 
					    binaryProductState.conditions = combinedStateConditions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return binaryProductState;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected findGeneratedProductState(innerStates: State<any>[], productStates: ProductState[]) {
 | 
				
			||||||
 | 
					    return productStates.find(productState => productState.equalInnerStates(innerStates));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected generateCombinedActions(leftActions: ScriptAccountAction[], rightActions: ScriptAccountAction[]): ScriptAccountAction[] {
 | 
				
			||||||
 | 
					    const combinedActions: ScriptAccountAction[] = []
 | 
				
			||||||
 | 
					    for(let i=0; i<leftActions.length; i++) {
 | 
				
			||||||
 | 
					      for(let j=0; j<rightActions.length; j++) {
 | 
				
			||||||
 | 
					        const combinedAction = leftActions[i].combineActions(rightActions[j])
 | 
				
			||||||
 | 
					        if(combinedAction == undefined) {
 | 
				
			||||||
 | 
					          if(!combinedActions.includes(leftActions[i])) {
 | 
				
			||||||
 | 
					            combinedActions.push(leftActions[i])
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if(!combinedActions.includes(rightActions[j])) {
 | 
				
			||||||
 | 
					            combinedActions.push(rightActions[j])
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          combinedActions.push(combinedAction)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return combinedActions;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected generateCombinedConditions(leftConditions: ScriptAccountCondition[], rightConditions: ScriptAccountCondition[]): ScriptAccountCondition[] {
 | 
				
			||||||
 | 
					    const combinedConditions: ScriptAccountCondition[] = [];
 | 
				
			||||||
 | 
					    for(let i=0; i<leftConditions.length; i++) {
 | 
				
			||||||
 | 
					      for(let j=0; j<rightConditions.length; j++) {
 | 
				
			||||||
 | 
					        const combinedCondition = leftConditions[i].combineCondition(rightConditions[j]);
 | 
				
			||||||
 | 
					        if(combinedCondition == undefined) {
 | 
				
			||||||
 | 
					          if(!combinedConditions.includes(leftConditions[i])) {
 | 
				
			||||||
 | 
					            combinedConditions.push(leftConditions[i])
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          if(!combinedConditions.includes(rightConditions[j])) {
 | 
				
			||||||
 | 
					            combinedConditions.push(rightConditions[j])
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          combinedConditions.push(combinedCondition)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return combinedConditions;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  protected contradictCombinedConditions(leftConditions: ScriptAccountCondition[], rightConditions: ScriptAccountCondition[]): boolean {
 | 
				
			||||||
 | 
					    for(let i=0; i<leftConditions.length; i++) {
 | 
				
			||||||
 | 
					      for(let j=0; j<rightConditions.length; j++) {
 | 
				
			||||||
 | 
					        if(leftConditions[i].isContradicting(rightConditions[j])) {
 | 
				
			||||||
 | 
					          return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user