Poprawki optymalizacyjne; dodanie ostrzeżeń

This commit is contained in:
2021-11-13 15:27:26 +01:00
parent 8e9da4c498
commit 28c9813133
8 changed files with 414 additions and 253 deletions
+23 -40
View File
@@ -100,7 +100,14 @@
"
v-model="store.chosenCargo"
>
<option :value="null">brak</option>
<option
:value="null"
v-if="!store.chosenCar || !store.chosenCar.loadable"
>
brak dostępnych ładunków
</option>
<option :value="null" v-else>próżny</option>
<option
v-for="cargo in store.chosenCar?.cargoList"
:value="cargo"
@@ -118,45 +125,26 @@
<script lang="ts">
import { ICarWagon, ILocomotive, IStore } from "@/types";
import { defineComponent, inject } from "vue";
import { computed } from "@vue/reactivity";
import statsMixin from "@/mixins/StatsMixin";
function isILocomotive(
function isLocomotive(
vehicle: ILocomotive | ICarWagon
): vehicle is ILocomotive {
return (vehicle as ILocomotive).power !== undefined;
}
export default defineComponent({
mixins: [statsMixin],
setup() {
const store = inject("Store") as IStore;
return {
store,
totalMass: computed(() =>
store.stockList.reduce(
(acc, stock) =>
acc +
(stock.cargo ? stock.cargo.totalMass : stock.mass) * stock.count,
0
)
),
totalLength: computed(() =>
store.stockList.reduce(
(acc, stock) => acc + stock.length * stock.count,
0
)
),
maxSpeed: computed(() =>
store.stockList.reduce(
(acc, stock) =>
stock.maxSpeed < acc || acc == 0 ? stock.maxSpeed : acc,
0
)
),
locoDataList: inject("locoDataList") as ILocomotive[],
carDataList: inject("carDataList") as ICarWagon[],
isTrainPassenger: inject("isTrainPassenger") as boolean,
totalLength: inject("totalLength") as number,
totalMass: inject("totalMass") as number,
maxStockSpeed: inject("maxStockSpeed") as number,
maxAllowedSpeed: inject("maxAllowedSpeed") as number,
};
},
@@ -242,18 +230,13 @@ export default defineComponent({
if (!vehicle) return;
if (vehicle.length + this.totalLength > 650) {
alert("Maksymalna długość składu to 650m!");
return;
}
const previousStock =
this.store.stockList.length > 0
? this.store.stockList[this.store.stockList.length - 1]
: null;
if (
isILocomotive(vehicle) &&
isLocomotive(vehicle) &&
previousStock &&
previousStock.type == vehicle.type
) {
@@ -262,7 +245,7 @@ export default defineComponent({
}
if (
!isILocomotive(vehicle) &&
!isLocomotive(vehicle) &&
previousStock &&
previousStock.type == vehicle.type &&
previousStock.cargo?.id == this.store.chosenCargo?.id
@@ -277,18 +260,18 @@ export default defineComponent({
length: vehicle.length,
mass: vehicle.mass,
maxSpeed: vehicle.maxSpeed,
isLoco: isILocomotive(vehicle),
isLoco: isLocomotive(vehicle),
cargo:
!isILocomotive(vehicle) && vehicle.loadable && this.store.chosenCargo
!isLocomotive(vehicle) && vehicle.loadable && this.store.chosenCargo
? this.store.chosenCargo
: undefined,
count: 1,
imgSrc: vehicle.imageSrc,
useType: isILocomotive(vehicle) ? vehicle.power : vehicle.useType,
useType: isLocomotive(vehicle) ? vehicle.power : vehicle.useType,
};
if (
isILocomotive(vehicle) &&
isLocomotive(vehicle) &&
this.store.stockList.length > 0 &&
!this.store.stockList[0].isLoco
)
@@ -317,7 +300,7 @@ export default defineComponent({
pointer-events: none;
}
}
@media screen and (max-width: 800px) {
flex-direction: column;
}
+57 -37
View File
@@ -36,9 +36,23 @@
<div class="stock-list_specs">
Masa: <span class="text--accent">{{ totalMass }}</span> t | Długość:
<span class="text--accent">{{ totalLength }}</span>
m | Vmax składu:
<span class="text--accent">{{ maxSpeed }} </span> km/h
m
</div>
<div class="warnings">
<div class="warning" v-if="warnings.locoNotSuitable.value">
Lokomotywy EP07 i EP08 przeznaczone jedynie do ruchu pasażerskiego!
</div>
<div class="warning" v-if="warnings.trainTooLong.value">
Ten skład jest za długi!
</div>
<div class="warning" v-if="warnings.trainTooHeavy.value">
Ten skład jest za ciężki!
</div>
</div>
<ul>
<li v-if="store.stockList.length == 0" class="list-empty">
<div class="item-content">Lista pojazdów jest pusta!</div>
@@ -97,42 +111,28 @@
</template>
<script lang="ts">
import { defineComponent, inject } from "vue";
import { IStore } from "@/types";
import { computed } from "@vue/reactivity";
import statsMixin from "@/mixins/StatsMixin";
import { ComputedRef, defineComponent, inject } from "vue";
import { ICarWagon, ILocomotive, IStore } from "@/types";
export default defineComponent({
mixins: [statsMixin],
setup() {
const store = inject("Store") as IStore;
return {
store,
totalMass: computed(() =>
store.stockList.reduce(
(acc, stock) =>
acc +
(stock.cargo ? stock.cargo.totalMass : stock.mass) * stock.count,
0
)
),
totalLength: computed(() =>
store.stockList.reduce(
(acc, stock) => acc + stock.length * stock.count,
0
)
),
maxSpeed: computed(() =>
store.stockList.reduce(
(acc, stock) =>
stock.maxSpeed < acc || acc == 0 ? stock.maxSpeed : acc,
0
)
),
locoDataList: inject("locoDataList") as ILocomotive[],
carDataList: inject("carDataList") as ICarWagon[],
isTrainPassenger: inject("isTrainPassenger") as boolean,
totalLength: inject("totalLength") as number,
totalMass: inject("totalMass") as number,
maxStockSpeed: inject("maxStockSpeed") as number,
maxAllowedSpeed: inject("maxAllowedSpeed") as number,
warnings: inject("warnings") as {
locoNotSuitable: ComputedRef<boolean>;
trainTooLong: ComputedRef<boolean>;
trainTooHeavy: ComputedRef<boolean>;
},
};
},
@@ -189,11 +189,6 @@ export default defineComponent({
},
addStock(index: number) {
if (this.store.stockList[index].length + this.totalLength > 650) {
alert("Maksymalna długość składu to 650m!");
return;
}
this.store.stockList[index].count++;
},
@@ -228,6 +223,18 @@ export default defineComponent({
},
downloadStock() {
if (
this.warnings.locoNotSuitable.value ||
this.warnings.trainTooLong.value ||
this.warnings.trainTooHeavy.value
) {
const allowDownload = confirm(
"Jazda tym pociągiem może być niezgodna z regulaminem symulatora! Czy na pewno chcesz kontynuować?"
);
if (!allowDownload) return;
}
const fileName = prompt("Nazwij plik:", "sklad");
if (!fileName) return;
@@ -286,7 +293,7 @@ export default defineComponent({
e.preventDefault();
},
onImageLoad(ev: Event) {
onImageLoad() {
this.store.imageLoading = false;
},
},
@@ -313,6 +320,19 @@ export default defineComponent({
}
}
.warnings {
margin-top: 0.5em;
}
.warning {
padding: 0.25em;
margin-top: 0.5em;
background: $accentColor;
color: black;
font-weight: bold;
}
.spacer {
flex: 2 1 10%;
}
+9
View File
@@ -0,0 +1,9 @@
export const enum EVehicleUseType {
LOCO_ELECTRICAL = 'loco-e',
LOCO_DIESEL = "loco-s",
EMU = "loco-ezt",
DMU = "loco-szt",
CAR_PASSENGER = "car-passenger",
CAR_CARGO = "car-cargo"
}
+9 -17
View File
@@ -1,24 +1,16 @@
import { createApp } from "vue";
import App from "./App.vue";
import { ICargo, ICarWagon, ILocomotive, IStock, IStore } from "./types";
import { reactive } from "@vue/reactivity";
const Store: IStore = reactive({
chosenCar: null as ICarWagon | null,
chosenLoco: null as ILocomotive | null,
chosenCargo: null as ICargo | null,
showSupporter: false,
imageLoading: false,
chosenLocoPower: "loco-e",
chosenCarUseType: "car-passenger",
stockList: [] as IStock[],
cargoOptions: [] as any[][],
})
import { Store, locoDataList, carDataList, totalLength, totalMass, maxAllowedSpeed, maxStockSpeed, isTrainPassenger, warnings } from "./store";
createApp(App)
.provide('Store', Store)
.provide('locoDataList', locoDataList)
.provide('carDataList', carDataList)
.provide('totalMass', totalMass)
.provide('totalLength', totalLength)
.provide('maxStockSpeed', maxStockSpeed)
.provide('maxAllowedSpeed', maxAllowedSpeed)
.provide('isTrainPassenger', isTrainPassenger)
.provide('warnings', warnings)
.mount("#app");
-147
View File
@@ -1,147 +0,0 @@
import { IVehicleData, ILocomotive, ICarWagon, IStore } from "@/types";
import { defineComponent, inject } from "@vue/runtime-core";
import { computed } from "@vue/reactivity";
import vehicleDataJSON from "@/data/vehicleData.json";
import vehiclePropsJSON from "@/data/vehicleProps.json";
export default defineComponent({
setup() {
return {
store: inject("Store") as IStore
}
},
computed: {
locoDataList() {
return Object.keys(vehicleDataJSON).reduce(
(acc, vehicleTypeKey) => {
if (!vehicleTypeKey.startsWith("loco")) return acc;
const locoVehiclesData = (vehicleDataJSON as IVehicleData)[
vehicleTypeKey
];
locoVehiclesData.forEach((loco) => {
if (loco[4] && !this.store.showSupporter) return;
const locoType = loco[0] as string;
let length = 0,
mass = 0;
// Elektrowozy
if (vehicleTypeKey.startsWith("loco-e")) {
// 32m dla ET41, reszta 16
length = locoType.startsWith("ET") ? 32 : 16;
// 80t dla wszystkich EU06, EP08
mass = 80;
// 83t dla: EU07 o nr większych niż 300 & dla wszystkich EP07 oprócz nr 135,242,1002,1048
const locoNumber = Number(locoType.split("-")[1]);
if (
(locoType.startsWith("EU") && locoNumber > 300) ||
(locoType.startsWith("EP") &&
![242, 135, 1002, 1048].includes(locoNumber))
) {
mass = 83;
}
}
// Spalinowozy
if (vehicleTypeKey.startsWith("loco-s")) {
length = 14;
mass = 74;
}
// EZT
if (vehicleTypeKey.startsWith("loco-ezt")) {
// EN57
length = 65;
mass = 126;
// EN71
if (locoType.startsWith("EN71")) {
length = 86;
mass = 182;
}
// 2xEN57
if (locoType.startsWith("2EN57")) {
length = 130;
mass = 253;
}
}
// SZT
if (vehicleTypeKey.startsWith("loco-szt")) {
length = 14;
mass = 23;
}
acc.push({
power: vehicleTypeKey,
type: loco[0] as string,
constructionType: loco[1] as string,
cabinType: loco[2] as string,
maxSpeed: Number(loco[3] as string),
supportersOnly: loco[4] as boolean,
imageSrc: loco[5] as string,
length,
mass,
});
});
return acc;
},
[] as ILocomotive[]
);
},
carDataList() {
return Object.keys(vehicleDataJSON).reduce(
(acc, vehicleTypeKey) => {
if (!vehicleTypeKey.startsWith("car")) return acc;
const carVehiclesData = (vehicleDataJSON as IVehicleData)[
vehicleTypeKey
];
carVehiclesData.forEach((car) => {
if (car[3] && !this.store.showSupporter) return;
const carPropsData = vehiclePropsJSON.find((v) =>
car[0].toString().includes(v.type)
);
acc.push({
useType: vehicleTypeKey,
type: car[0] as string,
constructionType: car[1] as string,
loadable: car[2] as boolean,
supportersOnly: car[3] as boolean,
maxSpeed: Number(car[4] as string),
imageSrc: car[5] as string,
cargoList:
carPropsData?.cargo.split(";").map((cargo) => ({
id: cargo.split(":")[0],
totalMass: Number(cargo.split(":")[1]),
})) || [],
mass: carPropsData?.mass || 0,
length: carPropsData?.length || 0,
});
});
return acc;
},
[] as ICarWagon[]
);
},
}
});
+280
View File
@@ -0,0 +1,280 @@
import { ICargo, ICarWagon, ILocomotive, IStock, IStore, IVehicleData } from "./types";
import { reactive } from "@vue/reactivity";
import vehicleDataJSON from "@/data/vehicleData.json";
import vehiclePropsJSON from "@/data/vehicleProps.json";
import { EVehicleUseType } from "./enums/EVehicleUseType";
import { computed } from "vue";
export const Store: IStore = reactive({
chosenCar: null as ICarWagon | null,
chosenLoco: null as ILocomotive | null,
chosenCargo: null as ICargo | null,
showSupporter: false,
imageLoading: false,
chosenLocoPower: "loco-e",
chosenCarUseType: "car-passenger",
stockList: [] as IStock[],
cargoOptions: [] as any[][],
})
export const locoDataList = computed(() => Object.keys(vehicleDataJSON).reduce(
(acc, vehicleTypeKey) => {
if (!vehicleTypeKey.startsWith("loco")) return acc;
const locoVehiclesData = (vehicleDataJSON as IVehicleData)[
vehicleTypeKey
];
locoVehiclesData.forEach((loco) => {
if (loco[4] && !Store.showSupporter) return;
const locoType = loco[0] as string;
let length = 0,
mass = 0;
// Elektrowozy
if (vehicleTypeKey.startsWith("loco-e")) {
// 32m dla ET41, reszta 16
length = locoType.startsWith("ET") ? 32 : 16;
// 80t dla wszystkich EU06, EP08
mass = 80;
// 83t dla: EU07 o nr większych niż 300 & dla wszystkich EP07 oprócz nr 135,242,1002,1048
const locoNumber = Number(locoType.split("-")[1]);
if (
(locoType.startsWith("EU") && locoNumber > 300) ||
(locoType.startsWith("EP") &&
![242, 135, 1002, 1048].includes(locoNumber))
) {
mass = 83;
}
}
// Spalinowozy
if (vehicleTypeKey.startsWith("loco-s")) {
length = 14;
mass = 74;
}
// EZT
if (vehicleTypeKey.startsWith("loco-ezt")) {
// EN57
length = 65;
mass = 126;
// EN71
if (locoType.startsWith("EN71")) {
length = 86;
mass = 182;
}
// 2xEN57
if (locoType.startsWith("2EN57")) {
length = 130;
mass = 253;
}
}
// SZT
if (vehicleTypeKey.startsWith("loco-szt")) {
length = 14;
mass = 23;
}
acc.push({
power: vehicleTypeKey,
type: loco[0] as string,
constructionType: loco[1] as string,
cabinType: loco[2] as string,
maxSpeed: Number(loco[3] as string),
supportersOnly: loco[4] as boolean,
imageSrc: loco[5] as string,
length,
mass,
});
});
return acc;
},
[] as ILocomotive[]
));
export const carDataList = computed(() => Object.keys(vehicleDataJSON).reduce(
(acc, vehicleTypeKey) => {
if (!vehicleTypeKey.startsWith("car")) return acc;
const carVehiclesData = (vehicleDataJSON as IVehicleData)[
vehicleTypeKey
];
carVehiclesData.forEach((car) => {
if (car[3] && !Store.showSupporter) return;
const carPropsData = vehiclePropsJSON.find((v) =>
car[0].toString().includes(v.type)
);
acc.push({
useType: vehicleTypeKey,
type: car[0] as string,
constructionType: car[1] as string,
loadable: car[2] as boolean,
supportersOnly: car[3] as boolean,
maxSpeed: Number(car[4] as string),
imageSrc: car[5] as string,
cargoList:
carPropsData?.cargo.split(";").map((cargo) => ({
id: cargo.split(":")[0],
totalMass: Number(cargo.split(":")[1]),
})) || [],
mass: carPropsData?.mass || 0,
length: carPropsData?.length || 0,
});
});
return acc;
},
[] as ICarWagon[]
));
export const totalMass = computed(() => {
return Store.stockList.reduce(
(acc, stock) =>
acc +
(stock.cargo ? stock.cargo.totalMass : stock.mass) * stock.count,
0
)
});
export const totalLength = computed(() => {
return Store.stockList.reduce(
(acc, stock) => acc + stock.length * stock.count,
0
)
});
export const maxStockSpeed = computed(() => {
return Store.stockList.reduce(
(acc, stock) =>
stock.maxSpeed < acc || acc == 0 ? stock.maxSpeed : acc,
0
)
});
export const isTrainPassenger = computed(() => {
if (Store.stockList.length == 0) return false;
if (Store.stockList.every(stock => stock.isLoco)) return false;
return Store.stockList
.filter((stock) => !stock.isLoco)
.every((stock) => stock.useType === EVehicleUseType.CAR_PASSENGER);
})
export const maxAllowedSpeed = computed(() => {
if (Store.stockList.length < 1) return -1;
if (!Store.stockList[0].isLoco) return -1;
const headingLoco = Store.stockList[0];
if (headingLoco.type.startsWith("EU07")) {
if (isTrainPassenger.value && totalMass.value <= 650) return 125;
if (!isTrainPassenger.value && totalMass.value <= 2000) return 70;
return -1;
}
if (headingLoco.type.startsWith("EP07")) {
if (isTrainPassenger.value && totalMass.value <= 650) return 125;
if (!isTrainPassenger.value) return -1;
return -1;
}
if (headingLoco.type.startsWith("EP08")) {
if (isTrainPassenger.value && totalMass.value <= 650) return 140;
if (!isTrainPassenger.value) return -1;
return -1;
}
if (headingLoco.type.startsWith("ET41")) {
if (isTrainPassenger.value && totalMass.value <= 700) return 125;
if (!isTrainPassenger.value && totalMass.value <= 4000) return 70;
return -1;
}
if (headingLoco.type.startsWith("SM42")) {
if (totalMass.value <= 95) return 90;
if (totalMass.value <= 200) return 80;
if (totalMass.value <= 300) return 70;
if (totalMass.value <= 450) return 60;
if (totalMass.value <= 750) return 50;
if (totalMass.value <= 1130) return 40;
if (totalMass.value <= 1720) return 30;
if (totalMass.value <= 2400) return 20;
return -1;
}
return Store.stockList.reduce(
(acc, stock) =>
stock.maxSpeed < acc || acc == 0 ? stock.maxSpeed : acc,
0
);
})
export const warnings = {
trainTooLong: computed(() => {
if (isTrainPassenger.value && totalLength.value > 350) return true;
if (!isTrainPassenger.value && totalLength.value > 650) return true;
return false;
}),
locoNotSuitable: computed(() => {
if (!isTrainPassenger.value && Store.stockList.length > 1 && Store.stockList.find(stock => stock.isLoco && stock.type.startsWith("EP"))) return true;
return false;
}),
trainTooHeavy: computed(() => {
if (Store.stockList.length == 0 || !Store.stockList[0].isLoco) return false;
const headingLoco = Store.stockList[0];
if (isTrainPassenger.value && (headingLoco.type.startsWith("EU") || headingLoco.type.startsWith("EP")) && totalMass.value > 650) return true;
if (isTrainPassenger.value && headingLoco.type.startsWith("ET") && totalMass.value > 700) return true;
if (!isTrainPassenger.value && headingLoco.type.startsWith("EU") && totalMass.value > 2000) return true;
if (!isTrainPassenger.value && headingLoco.type.startsWith("ET") && totalMass.value > 4000) return true;
if (headingLoco.type.startsWith("SM") && totalMass.value > 2400) return true;
return false;
})
}
// export const trainTooLong = computed(() => {
// if (isTrainPassenger.value && totalLength.value > 350) return true;
// if (!isTrainPassenger.value && totalLength.value > 650) return true;
// return false;
// })
// export const locoNotSuitable = computed(() => {
// if (!isTrainPassenger.value && Store.stockList.length > 1 && Store.stockList.find(stock => stock.isLoco && stock.type.startsWith("EP"))) return true;
// return false;
// })
+24
View File
@@ -0,0 +1,24 @@
import { EVehicleUseType } from "@/enums/EVehicleUseType";
import { ICarWagon, ILocomotive, IStock } from "@/types";
export const verifyTrainSpec = (stockList: IStock[], vehicleMass: number, vehicleUseType: string) => {
const hasHeadLoco = stockList.length > 0
&& (stockList[0].useType == EVehicleUseType.LOCO_ELECTRICAL
|| stockList[0].useType == EVehicleUseType.LOCO_DIESEL);
if (!hasHeadLoco) return;
const headLoco = stockList[0];
const carList = stockList.filter(stock => !stock.isLoco);
console.log(carList, vehicleUseType);
const isTrainPassenger = carList.length != 0
? carList.every(stock => stock.useType == EVehicleUseType.CAR_PASSENGER)
&& vehicleUseType == EVehicleUseType.CAR_PASSENGER
: false;
console.log("Skład pasażerski: " + isTrainPassenger);
console.log("Skład towarowy: " + !isTrainPassenger);
}