import {Gamesystem} from "./Gamesystem"; import {ProductState} from "./states/ProductState"; import {ProductTransition} from "./transitions/ProductTransition"; import {State} from "./states/State"; import {Transition} from "./transitions/Transition"; import {SimpleState} from "./states/SimpleState"; import {SimpleGamesystem} from "./SimpleGamesystem"; import {GameModel} from "../GameModel"; import {ProductStateTrainer} from "../../../../e2e/game-model/gamesystems/productGamesystems/ProductStateTrainer"; import {ScriptAccountCondition} from "./conditions/ScriptAccountCondition"; export class ProductGamesystem extends Gamesystem { innerGamesystems: Gamesystem, Transition>[] = []; static constructFromSimpleGamesystem(simpleGamesystem: SimpleGamesystem, gameModel: GameModel) { const productGamesystem = new ProductGamesystem(simpleGamesystem.componentName, simpleGamesystem.componentDescription); const parentGamesystem = simpleGamesystem.parentGamesystem; if(simpleGamesystem.states.length > 0) { simpleGamesystem.componentName += "(Child)"; productGamesystem.addChildGamesystem(simpleGamesystem); } if(parentGamesystem != undefined) { parentGamesystem.removeChildGamesystem(simpleGamesystem); parentGamesystem.addChildGamesystem(productGamesystem); } else { gameModel.removeGamesystem(simpleGamesystem); gameModel.addGamesystem(productGamesystem); } return productGamesystem; } createState(innerStates: State[]): ProductState | undefined { if(innerStates.length == this.innerGamesystems.length && this.findProductStateByInnerStates(innerStates)== undefined) { const productState = new ProductState(innerStates); this.states.push(productState); return productState; } else { return undefined; } } createTransition(startingState: ProductState, endingState: ProductState): ProductTransition | undefined { if(startingState == undefined || endingState == undefined || this.existsTransition(startingState, endingState) || !this.existsState(startingState) || !this.existsState(endingState) || startingState.equals(endingState)) { return undefined; } const productTransition = new ProductTransition(startingState, endingState); this.transitions.push(productTransition); return productTransition; } removeState(state: ProductState): boolean { return false; } removeInnerState(state: SimpleState) { } generateFromChildsystems() { //Assume that childsystems that are productsystems are already generated if(this.innerGamesystems.length < 2) { //currently only safe-guard return; } const integratedSystems: Gamesystem[] = [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, rightSystem: Gamesystem, left_temp: boolean, integratedSystems: Gamesystem[]) { 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, rightInnerState: State, left_temp: boolean) { const combinedStateConditions: ScriptAccountCondition[] = leftInnerState.conditions.concat(rightInnerState.conditions) for(let i=0; i[] = []; 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, Transition>) { this.innerGamesystems.push(gamesystem); } removeChildGamesystem(gamesystem: Gamesystem, Transition>) { this.innerGamesystems = this.innerGamesystems.filter(childSystem => childSystem.componentName !== gamesystem.componentName); } findProductStateByInnerStates(innerStates: State[]) { return this.states.find(productState => productState.equalInnerStates(innerStates)); } findChildSystemByName(gamesystemName: string) { const gamesystemQueue: Gamesystem, Transition>[] = []; this.innerGamesystems.forEach(gamesystem => gamesystemQueue.push(gamesystem)); while(gamesystemName.length > 0 ){ const currentGamesystem = gamesystemQueue.shift(); if(currentGamesystem!.componentName === gamesystemName) { return currentGamesystem; } } return undefined; } private existsTransition(startingState: ProductState, endingState: ProductState) { return this.transitions.find(transition => transition.startingState.equals(startingState) && transition.endingState.equals(endingState)) != undefined; } private existsState(state: ProductState) { return this.states.find(s => s.equals(state)) != undefined; } }