fix : added logic for each button (touch)
This commit is contained in:
parent
bbeb97b7b4
commit
5a85de1742
@ -1,4 +1,4 @@
|
|||||||
// selection.service.ts
|
// ✅ Updated SelectionService with ComputeAmount logic adapted from C#
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
|
|
||||||
@ -7,24 +7,23 @@ export interface SelectionData {
|
|||||||
numbers: (number | string)[];
|
numbers: (number | string)[];
|
||||||
value: number;
|
value: number;
|
||||||
total: number;
|
total: number;
|
||||||
|
isBoxed?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
@Injectable({ providedIn: 'root' })
|
||||||
export class SelectionService {
|
export class SelectionService {
|
||||||
// Stores finalized selections
|
|
||||||
private selections = new BehaviorSubject<SelectionData[]>([]);
|
private selections = new BehaviorSubject<SelectionData[]>([]);
|
||||||
selections$ = this.selections.asObservable();
|
selections$ = this.selections.asObservable();
|
||||||
|
|
||||||
// Stores current "in-progress" row
|
|
||||||
private currentRow = new BehaviorSubject<SelectionData>({
|
private currentRow = new BehaviorSubject<SelectionData>({
|
||||||
label: '',
|
label: '',
|
||||||
numbers: [],
|
numbers: [],
|
||||||
value: 0,
|
value: 0,
|
||||||
total: 0
|
total: 0,
|
||||||
|
isBoxed: false
|
||||||
});
|
});
|
||||||
currentRow$ = this.currentRow.asObservable();
|
currentRow$ = this.currentRow.asObservable();
|
||||||
|
|
||||||
// ✅ 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 = { ...current, ...update };
|
||||||
@ -32,21 +31,25 @@ export class SelectionService {
|
|||||||
const label = updated.label;
|
const label = updated.label;
|
||||||
const value = updated.value;
|
const value = updated.value;
|
||||||
const numbers = (updated.numbers || []).filter(n => typeof n === 'number') as number[];
|
const numbers = (updated.numbers || []).filter(n => typeof n === 'number') as number[];
|
||||||
|
const isBoxed = updated.isBoxed ?? false;
|
||||||
|
|
||||||
updated.total = 0;
|
updated.total = 0;
|
||||||
|
|
||||||
if (numbers.length > 0 && value > 0 && label) {
|
if (numbers.length > 0 && value > 0 && label) {
|
||||||
switch (label) {
|
switch (label) {
|
||||||
// SINGLELEG: WIN, SHP, THP, PLC
|
// 🟢 Single Leg Pools
|
||||||
case 'WIN':
|
case 'WIN': // WNP
|
||||||
case 'SHP':
|
case 'SHP':
|
||||||
case 'THP':
|
case 'THP':
|
||||||
case 'PLC':
|
case 'PLC': // PLP
|
||||||
updated.total = numbers.length * value * 10;
|
updated.total = numbers.length * value * 10;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// EXOTIC: QUI (2 groups)
|
// 🟡 Exotic Pools (e.g., QNP, TNP, EXP)
|
||||||
case 'QUI': {
|
case 'FOR': // FRP
|
||||||
|
case 'TAN': // TNP
|
||||||
|
case 'EXA': // EXP
|
||||||
|
case 'QUI': { // QNP (QUI special case already handled in UI logic)
|
||||||
const mid = Math.floor(numbers.length / 2);
|
const mid = Math.floor(numbers.length / 2);
|
||||||
const group1 = numbers.slice(0, mid);
|
const group1 = numbers.slice(0, mid);
|
||||||
const group2 = numbers.slice(mid);
|
const group2 = numbers.slice(mid);
|
||||||
@ -56,48 +59,51 @@ export class SelectionService {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MULTILEG: TRE (3 legs), MJP (4), JKP (5)
|
// 🔵 Multileg Pools (e.g., TBP, MJP, JPP)
|
||||||
case 'TRE':
|
case 'TRE': // TBP
|
||||||
case 'MJP':
|
case 'MJP':
|
||||||
case 'JKP':
|
case 'JKP': { // JPP
|
||||||
case 'SJP': {
|
|
||||||
const legs = this.splitToLegs(numbers, this.getLegCount(label));
|
const legs = this.splitToLegs(numbers, this.getLegCount(label));
|
||||||
const comb = legs.reduce((acc, leg) => acc * (leg.length || 1), 1);
|
const comb = legs.reduce((acc, leg) => acc * (leg.length || 1), 1);
|
||||||
updated.total = comb * value * 10;
|
updated.total = comb * value * 10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXOTIC fallback (e.g., TAN, EXA, FRP, QNP, EXP, etc.)
|
// ⚪ BOX logic
|
||||||
default:
|
default: {
|
||||||
updated.total = this.calculateCombinations(numbers.length) * value * 10;
|
const combCount = isBoxed
|
||||||
|
? this.calculatePermutations(numbers.length)
|
||||||
|
: this.calculateCombinations(numbers.length);
|
||||||
|
updated.total = combCount * value * 10;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.currentRow.next(updated);
|
this.currentRow.next(updated);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Finalize the current row and push it to the finalized list
|
|
||||||
finalizeCurrentRow() {
|
finalizeCurrentRow() {
|
||||||
const completed = this.currentRow.value;
|
const completed = this.currentRow.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 finalRow: SelectionData = { ...completed };
|
const finalRow: SelectionData = { ...completed };
|
||||||
this.selections.next([...this.selections.value, finalRow]);
|
this.selections.next([...this.selections.value, finalRow]);
|
||||||
|
|
||||||
this.currentRow.next({ label: '', numbers: [], value: 0, total: 0 });
|
this.currentRow.next({ label: '', numbers: [], value: 0, total: 0, isBoxed: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Clear everything (for ERASE)
|
|
||||||
clearSelections() {
|
clearSelections() {
|
||||||
this.selections.next([]);
|
this.selections.next([]);
|
||||||
this.currentRow.next({ label: '', numbers: [], value: 0, total: 0 });
|
this.currentRow.next({ label: '', numbers: [], value: 0, total: 0, isBoxed: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
private calculateCombinations(n: number): number {
|
private calculateCombinations(n: number): number {
|
||||||
return n >= 2 ? (n * (n - 1)) / 2 : 0;
|
return n >= 2 ? (n * (n - 1)) / 2 : 0; // nC2
|
||||||
|
}
|
||||||
|
|
||||||
|
private calculatePermutations(n: number): number {
|
||||||
|
return n >= 2 ? n * (n - 1) : 0; // nP2
|
||||||
}
|
}
|
||||||
|
|
||||||
private splitToLegs(numbers: number[], legCount: number): number[][] {
|
private splitToLegs(numbers: number[], legCount: number): number[][] {
|
||||||
@ -111,10 +117,9 @@ export class SelectionService {
|
|||||||
|
|
||||||
private getLegCount(label: string): number {
|
private getLegCount(label: string): number {
|
||||||
switch (label) {
|
switch (label) {
|
||||||
case 'TRE': return 3;
|
case 'TRE': return 3; // TBP
|
||||||
case 'MJP': return 4;
|
case 'MJP': return 4;
|
||||||
case 'JKP': return 5;
|
case 'JKP': return 5; // JPP
|
||||||
case 'SJP': return 5;
|
|
||||||
default: return 3;
|
default: return 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<div class="d-flex flex-wrap justify-content-center gap-2 first">
|
<div class="d-flex flex-wrap justify-content-center gap-2 first">
|
||||||
<button class="btn btn-dark one" (click)="openCalculator()">CALC</button>
|
<button class="btn btn-dark one" (click)="openCalculator()">CALC</button>
|
||||||
<button class="btn btn-dark two" (click)="erase()">ERASE</button>
|
<button class="btn btn-dark two" (click)="erase()">ERASE</button>
|
||||||
<button class="btn btn-secondary three">BOX</button>
|
<button class="btn btn-secondary three" (click)="toggleBoxMode()">BOX</button>
|
||||||
<button class="btn btn-secondary four">FIELD</button>
|
<button class="btn btn-secondary four">FIELD</button>
|
||||||
<!-- <button class="btn btn-secondary four">Enter</button> -->
|
<!-- <button class="btn btn-secondary four">Enter</button> -->
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -28,18 +28,15 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
selectedNumbers: number[] = [];
|
selectedNumbers: number[] = [];
|
||||||
padValue: string = '';
|
padValue: string = '';
|
||||||
canPrint = false;
|
canPrint = false;
|
||||||
|
|
||||||
calculatorOpen = false;
|
calculatorOpen = false;
|
||||||
calcDisplay = '';
|
calcDisplay = '';
|
||||||
|
|
||||||
maxRowsReached: boolean = false;
|
maxRowsReached: boolean = false;
|
||||||
|
|
||||||
// ✅ Disabled labels list
|
|
||||||
disabledLabels: string[] = ['SHW', 'SJP'];
|
disabledLabels: string[] = ['SHW', 'SJP'];
|
||||||
|
|
||||||
isQUIFirstGroupComplete = false;
|
isQUIFirstGroupComplete = false;
|
||||||
QUIGroup1: number[] = [];
|
QUIGroup1: number[] = [];
|
||||||
QUIGroup2: number[] = [];
|
QUIGroup2: number[] = [];
|
||||||
|
isBoxed: boolean = false;
|
||||||
|
|
||||||
constructor(private selectionService: SelectionService) {}
|
constructor(private selectionService: SelectionService) {}
|
||||||
|
|
||||||
@ -47,7 +44,6 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
this.labelRowsFlat = this.labelRows.flat();
|
this.labelRowsFlat = this.labelRows.flat();
|
||||||
this.numbersFlat = this.numberRows.flat();
|
this.numbersFlat = this.numberRows.flat();
|
||||||
|
|
||||||
// Watch filled rows count
|
|
||||||
this.selectionService.selections$.subscribe(selections => {
|
this.selectionService.selections$.subscribe(selections => {
|
||||||
this.maxRowsReached = selections.length >= 5;
|
this.maxRowsReached = selections.length >= 5;
|
||||||
});
|
});
|
||||||
@ -71,7 +67,6 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Check if label is disabled
|
|
||||||
isLabelDisabled(label: string): boolean {
|
isLabelDisabled(label: string): boolean {
|
||||||
return this.disabledLabels.includes(label);
|
return this.disabledLabels.includes(label);
|
||||||
}
|
}
|
||||||
@ -84,6 +79,7 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
this.isQUIFirstGroupComplete = false;
|
this.isQUIFirstGroupComplete = false;
|
||||||
this.QUIGroup1 = [];
|
this.QUIGroup1 = [];
|
||||||
this.QUIGroup2 = [];
|
this.QUIGroup2 = [];
|
||||||
|
this.isBoxed = false;
|
||||||
this.selectionService.updatePartial({ label });
|
this.selectionService.updatePartial({ label });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,10 +126,14 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
this.updateCanPrint();
|
this.updateCanPrint();
|
||||||
|
|
||||||
// 👇 Update value in real-time
|
|
||||||
const value = parseFloat(this.padValue);
|
const value = parseFloat(this.padValue);
|
||||||
if (!isNaN(value)) {
|
if (!isNaN(value)) {
|
||||||
this.selectionService.updatePartial({ value });
|
this.selectionService.updatePartial({
|
||||||
|
value,
|
||||||
|
isBoxed: this.isBoxed,
|
||||||
|
label: this.selectedLabel || '',
|
||||||
|
numbers: [...this.selectedNumbers]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +152,6 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
print() {
|
print() {
|
||||||
// 👇 Finalize current row (push to list)
|
|
||||||
this.selectionService.finalizeCurrentRow();
|
this.selectionService.finalizeCurrentRow();
|
||||||
this.resetSelections();
|
this.resetSelections();
|
||||||
}
|
}
|
||||||
@ -167,6 +166,10 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
this.selectedNumbers = [];
|
this.selectedNumbers = [];
|
||||||
this.padValue = '';
|
this.padValue = '';
|
||||||
this.canPrint = false;
|
this.canPrint = false;
|
||||||
|
this.isBoxed = false;
|
||||||
|
this.isQUIFirstGroupComplete = false;
|
||||||
|
this.QUIGroup1 = [];
|
||||||
|
this.QUIGroup2 = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
openCalculator() {
|
openCalculator() {
|
||||||
@ -195,10 +198,25 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
|
|
||||||
calculate() {
|
calculate() {
|
||||||
try {
|
try {
|
||||||
// eslint-disable-next-line no-eval
|
|
||||||
this.calcDisplay = eval(this.calcDisplay).toString();
|
this.calcDisplay = eval(this.calcDisplay).toString();
|
||||||
} catch {
|
} catch {
|
||||||
this.calcDisplay = 'Error';
|
this.calcDisplay = 'Error';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleBoxMode() {
|
||||||
|
this.isBoxed = !this.isBoxed;
|
||||||
|
|
||||||
|
// 🔁 Re-calculate with current selections and value
|
||||||
|
const value = parseFloat(this.padValue) || 0;
|
||||||
|
this.selectionService.updatePartial({
|
||||||
|
isBoxed: this.isBoxed,
|
||||||
|
label: this.selectedLabel || '',
|
||||||
|
numbers: [...this.selectedNumbers],
|
||||||
|
value: value
|
||||||
|
});
|
||||||
|
|
||||||
|
// Optional: force canPrint update
|
||||||
|
this.updateCanPrint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user