feat : touchpad math logic
This commit is contained in:
parent
e135911c5e
commit
bbeb97b7b4
@ -1,9 +1,10 @@
|
|||||||
|
// selection.service.ts
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
// selection.service.ts
|
|
||||||
export interface SelectionData {
|
export interface SelectionData {
|
||||||
label: string;
|
label: string;
|
||||||
numbers: number[];
|
numbers: (number | string)[];
|
||||||
value: number;
|
value: number;
|
||||||
total: number;
|
total: number;
|
||||||
}
|
}
|
||||||
@ -25,30 +26,56 @@ export class SelectionService {
|
|||||||
|
|
||||||
// ✅ Update only part of the current row (label / numbers / value)
|
// ✅ Update only part of the current row (label / numbers / value)
|
||||||
updatePartial(update: Partial<SelectionData>) {
|
updatePartial(update: Partial<SelectionData>) {
|
||||||
const current = this.currentRow.value;
|
const current = this.currentRow.value;
|
||||||
|
const updated: SelectionData = { ...current, ...update };
|
||||||
|
|
||||||
const updated: SelectionData = {
|
const label = updated.label;
|
||||||
...current,
|
const value = updated.value;
|
||||||
...update
|
const numbers = (updated.numbers || []).filter(n => typeof n === 'number') as number[];
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const multiplyByTenLabels = ['WIN', 'SHP', 'THP', 'PLC'];
|
|
||||||
|
|
||||||
if (updated.numbers.length > 0 && updated.value > 0) {
|
|
||||||
if (multiplyByTenLabels.includes(updated.label)) {
|
|
||||||
updated.total = updated.numbers.length * updated.value * 10;
|
|
||||||
} else {
|
|
||||||
// For other labels, define your logic e.g. no multiply by 10 or another multiplier
|
|
||||||
updated.total = updated.numbers.length * updated.value;
|
|
||||||
// Or whatever logic you need here
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updated.total = 0;
|
updated.total = 0;
|
||||||
}
|
|
||||||
|
|
||||||
this.currentRow.next(updated);
|
if (numbers.length > 0 && value > 0 && label) {
|
||||||
}
|
switch (label) {
|
||||||
|
// SINGLELEG: WIN, SHP, THP, PLC
|
||||||
|
case 'WIN':
|
||||||
|
case 'SHP':
|
||||||
|
case 'THP':
|
||||||
|
case 'PLC':
|
||||||
|
updated.total = numbers.length * value * 10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// EXOTIC: QUI (2 groups)
|
||||||
|
case 'QUI': {
|
||||||
|
const mid = Math.floor(numbers.length / 2);
|
||||||
|
const group1 = numbers.slice(0, mid);
|
||||||
|
const group2 = numbers.slice(mid);
|
||||||
|
const combinations = group1.length * group2.length;
|
||||||
|
updated.total = combinations * value * 10;
|
||||||
|
updated.numbers = [...group1, '-', ...group2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MULTILEG: TRE (3 legs), MJP (4), JKP (5)
|
||||||
|
case 'TRE':
|
||||||
|
case 'MJP':
|
||||||
|
case 'JKP':
|
||||||
|
case 'SJP': {
|
||||||
|
const legs = this.splitToLegs(numbers, this.getLegCount(label));
|
||||||
|
const comb = legs.reduce((acc, leg) => acc * (leg.length || 1), 1);
|
||||||
|
updated.total = comb * value * 10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXOTIC fallback (e.g., TAN, EXA, FRP, QNP, EXP, etc.)
|
||||||
|
default:
|
||||||
|
updated.total = this.calculateCombinations(numbers.length) * value * 10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentRow.next(updated);
|
||||||
|
}
|
||||||
|
|
||||||
// ✅ Finalize the current row and push it to the finalized list
|
// ✅ Finalize the current row and push it to the finalized list
|
||||||
finalizeCurrentRow() {
|
finalizeCurrentRow() {
|
||||||
@ -57,29 +84,38 @@ export class SelectionService {
|
|||||||
// Validation: must have label, numbers, and valid value
|
// Validation: must have label, numbers, and valid value
|
||||||
if (!completed.label || completed.numbers.length === 0 || completed.value <= 0) return;
|
if (!completed.label || completed.numbers.length === 0 || completed.value <= 0) return;
|
||||||
|
|
||||||
const total = completed.numbers.length * completed.value * 10;
|
const finalRow: SelectionData = { ...completed };
|
||||||
const finalRow: SelectionData = { ...completed, total };
|
this.selections.next([...this.selections.value, finalRow]);
|
||||||
|
|
||||||
const updatedSelections = [...this.selections.value, finalRow];
|
this.currentRow.next({ label: '', numbers: [], value: 0, total: 0 });
|
||||||
this.selections.next(updatedSelections);
|
|
||||||
|
|
||||||
// Reset current row
|
|
||||||
this.currentRow.next({
|
|
||||||
label: '',
|
|
||||||
numbers: [],
|
|
||||||
value: 0,
|
|
||||||
total: 0
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Clear everything (for ERASE)
|
// ✅ Clear everything (for ERASE)
|
||||||
clearSelections() {
|
clearSelections() {
|
||||||
this.selections.next([]);
|
this.selections.next([]);
|
||||||
this.currentRow.next({
|
this.currentRow.next({ label: '', numbers: [], value: 0, total: 0 });
|
||||||
label: '',
|
}
|
||||||
numbers: [],
|
|
||||||
value: 0,
|
private calculateCombinations(n: number): number {
|
||||||
total: 0
|
return n >= 2 ? (n * (n - 1)) / 2 : 0;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
private splitToLegs(numbers: number[], legCount: number): number[][] {
|
||||||
|
const result: number[][] = [];
|
||||||
|
const perLeg = Math.floor(numbers.length / legCount);
|
||||||
|
for (let i = 0; i < legCount; i++) {
|
||||||
|
result.push(numbers.slice(i * perLeg, (i + 1) * perLeg));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private getLegCount(label: string): number {
|
||||||
|
switch (label) {
|
||||||
|
case 'TRE': return 3;
|
||||||
|
case 'MJP': return 4;
|
||||||
|
case 'JKP': return 5;
|
||||||
|
case 'SJP': return 5;
|
||||||
|
default: return 3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,7 +14,14 @@
|
|||||||
|
|
||||||
<!-- Right Group: COPY, CLEAR, PR -->
|
<!-- Right Group: COPY, CLEAR, PR -->
|
||||||
<div class="d-flex flex-wrap justify-content-center gap-2 second">
|
<div class="d-flex flex-wrap justify-content-center gap-2 second">
|
||||||
<button class="btn btn-dark">Enter</button>
|
<button
|
||||||
|
class="btn btn-dark"
|
||||||
|
[disabled]="selectedLabel === 'QUI' && isQUIFirstGroupComplete"
|
||||||
|
(click)="padEnter()"
|
||||||
|
>
|
||||||
|
Enter
|
||||||
|
</button>
|
||||||
|
|
||||||
<button class="btn btn-dark">COPY</button>
|
<button class="btn btn-dark">COPY</button>
|
||||||
<button class="btn btn-dark">CLEAR</button>
|
<button class="btn btn-dark">CLEAR</button>
|
||||||
<button class="btn btn-dark">PR</button>
|
<button class="btn btn-dark">PR</button>
|
||||||
|
|||||||
@ -37,6 +37,10 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
// ✅ Disabled labels list
|
// ✅ Disabled labels list
|
||||||
disabledLabels: string[] = ['SHW', 'SJP'];
|
disabledLabels: string[] = ['SHW', 'SJP'];
|
||||||
|
|
||||||
|
isQUIFirstGroupComplete = false;
|
||||||
|
QUIGroup1: number[] = [];
|
||||||
|
QUIGroup2: number[] = [];
|
||||||
|
|
||||||
constructor(private selectionService: SelectionService) {}
|
constructor(private selectionService: SelectionService) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
@ -77,24 +81,43 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
this.selectedNumbers = [];
|
this.selectedNumbers = [];
|
||||||
this.padValue = '';
|
this.padValue = '';
|
||||||
this.canPrint = false;
|
this.canPrint = false;
|
||||||
|
this.isQUIFirstGroupComplete = false;
|
||||||
// 👇 Update label immediately in table
|
this.QUIGroup1 = [];
|
||||||
|
this.QUIGroup2 = [];
|
||||||
this.selectionService.updatePartial({ label });
|
this.selectionService.updatePartial({ label });
|
||||||
}
|
}
|
||||||
|
|
||||||
selectNumber(number: number) {
|
selectNumber(number: number) {
|
||||||
if (!this.selectedLabel) return;
|
if (!this.selectedLabel) return;
|
||||||
if (!this.selectedNumbers.includes(number)) {
|
|
||||||
this.selectedNumbers.push(number);
|
|
||||||
this.padValue = '';
|
|
||||||
this.canPrint = false;
|
|
||||||
|
|
||||||
// 👇 Update numbers immediately in table
|
if (this.selectedLabel === 'QUI') {
|
||||||
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
if (this.isQUIFirstGroupComplete) {
|
||||||
|
if (!this.QUIGroup2.includes(number)) {
|
||||||
|
this.QUIGroup2.push(number);
|
||||||
|
this.selectedNumbers = [...this.QUIGroup1, ...this.QUIGroup2];
|
||||||
|
this.selectionService.updatePartial({ numbers: this.selectedNumbers });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!this.QUIGroup1.includes(number)) {
|
||||||
|
this.QUIGroup1.push(number);
|
||||||
|
this.selectedNumbers = [...this.QUIGroup1];
|
||||||
|
this.selectionService.updatePartial({ numbers: this.selectedNumbers });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!this.selectedNumbers.includes(number)) {
|
||||||
|
this.selectedNumbers.push(number);
|
||||||
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
this.padValue = '';
|
||||||
|
this.canPrint = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
isNumberDisabled(number: number) {
|
isNumberDisabled(number: number) {
|
||||||
|
if (this.selectedLabel === 'QUI') {
|
||||||
|
return this.QUIGroup1.includes(number) || this.QUIGroup2.includes(number);
|
||||||
|
}
|
||||||
return this.selectedNumbers.includes(number);
|
return this.selectedNumbers.includes(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +142,11 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
padEnter() {
|
padEnter() {
|
||||||
if (this.canPrint) {
|
if (this.selectedLabel === 'QUI') {
|
||||||
|
if (!this.isQUIFirstGroupComplete && this.QUIGroup1.length > 0) {
|
||||||
|
this.isQUIFirstGroupComplete = true;
|
||||||
|
}
|
||||||
|
} else if (this.canPrint) {
|
||||||
this.print();
|
this.print();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user