fix : TAN , QUI , FOR logic is good (not with box )
This commit is contained in:
parent
244604702a
commit
06bb867dc5
@ -1,4 +1,4 @@
|
|||||||
// ✅ Updated SelectionService with ComputeAmount logic adapted from C#
|
// ✅ Final SelectionService.ts with special TAN (three-group) logic
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { BehaviorSubject } from 'rxjs';
|
import { BehaviorSubject } from 'rxjs';
|
||||||
|
|
||||||
@ -37,32 +37,53 @@ export class SelectionService {
|
|||||||
|
|
||||||
if (numbers.length > 0 && value > 0 && label) {
|
if (numbers.length > 0 && value > 0 && label) {
|
||||||
switch (label) {
|
switch (label) {
|
||||||
// 🟢 Single Leg Pools
|
case 'WIN':
|
||||||
case 'WIN': // WNP
|
|
||||||
case 'SHP':
|
case 'SHP':
|
||||||
case 'THP':
|
case 'THP':
|
||||||
case 'PLC': // PLP
|
case 'PLC':
|
||||||
updated.total = numbers.length * value * 10;
|
updated.total = numbers.length * value * 10;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 🟡 Exotic Pools (e.g., QNP, TNP, EXP)
|
case 'FOR':
|
||||||
case 'FOR': // FRP
|
case 'QUI': {
|
||||||
case 'TAN': // TNP
|
const dashIndex = updated.numbers.indexOf('-');
|
||||||
case 'EXA': // EXP
|
const group1 = updated.numbers.slice(0, dashIndex).filter(n => typeof n === 'number') as number[];
|
||||||
case 'QUI': { // QNP (QUI special case already handled in UI logic)
|
const group2 = updated.numbers.slice(dashIndex + 1).filter(n => typeof n === 'number') as number[];
|
||||||
const mid = Math.floor(numbers.length / 2);
|
|
||||||
const group1 = numbers.slice(0, mid);
|
let combinations = group1.length * group2.length;
|
||||||
const group2 = numbers.slice(mid);
|
if (isBoxed) {
|
||||||
const combinations = group1.length * group2.length;
|
combinations = this.calculatePermutations(group1.length + group2.length);
|
||||||
|
}
|
||||||
|
|
||||||
updated.total = combinations * value * 10;
|
updated.total = combinations * value * 10;
|
||||||
updated.numbers = [...group1, '-', ...group2];
|
updated.numbers = [...group1, '-', ...group2];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 🔵 Multileg Pools (e.g., TBP, MJP, JPP)
|
case 'TAN': {
|
||||||
case 'TRE': // TBP
|
const dashIndices = updated.numbers
|
||||||
|
.map((n, idx) => (n === '-' ? idx : -1))
|
||||||
|
.filter(idx => idx !== -1);
|
||||||
|
|
||||||
|
if (dashIndices.length < 2) break; // not ready yet
|
||||||
|
|
||||||
|
const group1 = updated.numbers.slice(0, dashIndices[0]).filter(n => typeof n === 'number') as number[];
|
||||||
|
const group2 = updated.numbers.slice(dashIndices[0] + 1, dashIndices[1]).filter(n => typeof n === 'number') as number[];
|
||||||
|
const group3 = updated.numbers.slice(dashIndices[1] + 1).filter(n => typeof n === 'number') as number[];
|
||||||
|
|
||||||
|
let combinations = group1.length * group2.length * group3.length;
|
||||||
|
if (isBoxed) {
|
||||||
|
combinations = this.calculatePermutations(group1.length + group2.length + group3.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
updated.total = combinations * value * 10;
|
||||||
|
updated.numbers = [...group1, '-', ...group2, '-', ...group3];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'TRE':
|
||||||
case 'MJP':
|
case 'MJP':
|
||||||
case 'JKP': { // JPP
|
case 'JKP': {
|
||||||
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;
|
||||||
@ -86,10 +107,7 @@ export class SelectionService {
|
|||||||
finalizeCurrentRow() {
|
finalizeCurrentRow() {
|
||||||
const completed = this.currentRow.value;
|
const completed = this.currentRow.value;
|
||||||
if (!completed.label || completed.numbers.length === 0 || completed.value <= 0) return;
|
if (!completed.label || completed.numbers.length === 0 || completed.value <= 0) return;
|
||||||
|
this.selections.next([...this.selections.value, { ...completed }]);
|
||||||
const finalRow: SelectionData = { ...completed };
|
|
||||||
this.selections.next([...this.selections.value, finalRow]);
|
|
||||||
|
|
||||||
this.currentRow.next({ label: '', numbers: [], value: 0, total: 0, isBoxed: false });
|
this.currentRow.next({ label: '', numbers: [], value: 0, total: 0, isBoxed: false });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,10 +135,10 @@ export class SelectionService {
|
|||||||
|
|
||||||
private getLegCount(label: string): number {
|
private getLegCount(label: string): number {
|
||||||
switch (label) {
|
switch (label) {
|
||||||
case 'TRE': return 3; // TBP
|
case 'TRE': return 3;
|
||||||
case 'MJP': return 4;
|
case 'MJP': return 4;
|
||||||
case 'JKP': return 5; // JPP
|
case 'JKP': return 5;
|
||||||
default: return 3;
|
default: return 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -19,7 +19,7 @@
|
|||||||
<button
|
<button
|
||||||
*ngIf="showShashEnter"
|
*ngIf="showShashEnter"
|
||||||
class="btn btn-dark"
|
class="btn btn-dark"
|
||||||
[disabled]="selectedLabel === 'QUI' && isQUIFirstGroupComplete"
|
[disabled]="twoGroupLabels.includes(selectedLabel || '') && isFirstGroupComplete"
|
||||||
(click)="padEnter()"
|
(click)="padEnter()"
|
||||||
>
|
>
|
||||||
shash ENTER
|
shash ENTER
|
||||||
|
|||||||
@ -11,12 +11,11 @@ import { SelectionService } from '../selection.service/selection.service';
|
|||||||
})
|
})
|
||||||
export class TouchPadMenuComponent implements OnInit {
|
export class TouchPadMenuComponent implements OnInit {
|
||||||
@Input() ticketingActive: boolean = false;
|
@Input() ticketingActive: boolean = false;
|
||||||
|
public twoGroupLabels = ['FOR', 'QUI'];
|
||||||
|
|
||||||
labels: string[] = [
|
labels: string[] = [
|
||||||
'WIN', 'SHP', 'THP',
|
'WIN', 'SHP', 'THP', 'PLC', 'SHW', 'FOR',
|
||||||
'PLC', 'SHW', 'FOR',
|
'QUI', 'TAN', 'EXA', 'WSP', 'TRE', 'MJP',
|
||||||
'QUI', 'TAN', 'EXA',
|
|
||||||
'WSP', 'TRE', 'MJP',
|
|
||||||
'JKP', 'SJP', '.'
|
'JKP', 'SJP', '.'
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -33,12 +32,19 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
maxRowsReached: boolean = false;
|
maxRowsReached: boolean = false;
|
||||||
|
|
||||||
disabledLabels: string[] = ['SHW', 'SJP'];
|
disabledLabels: string[] = ['SHW', 'SJP'];
|
||||||
isQUIFirstGroupComplete = false;
|
|
||||||
QUIGroup1: number[] = [];
|
// TAN logic
|
||||||
QUIGroup2: number[] = [];
|
tanGroupStage = 0;
|
||||||
|
tanGroups: number[][] = [[], [], []];
|
||||||
|
|
||||||
|
// FOR/QUI logic
|
||||||
|
isFirstGroupComplete = false;
|
||||||
|
firstGroup: number[] = [];
|
||||||
|
secondGroup: number[] = [];
|
||||||
|
|
||||||
isBoxed: boolean = false;
|
isBoxed: boolean = false;
|
||||||
|
|
||||||
// 🔘 FIELD modal related
|
// FIELD modal
|
||||||
fieldModalOpen = false;
|
fieldModalOpen = false;
|
||||||
fieldInput: string = '';
|
fieldInput: string = '';
|
||||||
fieldFEntered = false;
|
fieldFEntered = false;
|
||||||
@ -48,7 +54,6 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.labelRowsFlat = this.labelRows.flat();
|
this.labelRowsFlat = this.labelRows.flat();
|
||||||
this.numbersFlat = this.numberRows.flat();
|
this.numbersFlat = this.numberRows.flat();
|
||||||
|
|
||||||
this.selectionService.selections$.subscribe(selections => {
|
this.selectionService.selections$.subscribe(selections => {
|
||||||
this.maxRowsReached = selections.length >= 5;
|
this.maxRowsReached = selections.length >= 5;
|
||||||
});
|
});
|
||||||
@ -67,8 +72,17 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get showShashEnter(): boolean {
|
get showShashEnter(): boolean {
|
||||||
const enabledLabels = ['FOR', 'QUI', 'TAN', 'EXA', 'WSP', 'TRE', 'MJP', 'JKP', 'SJP', '.'];
|
const specialLabels = ['FOR', 'QUI', 'TAN', 'EXA', 'WSP', 'TRE', 'MJP', 'JKP', 'SJP', '.'];
|
||||||
return enabledLabels.includes(this.selectedLabel || '');
|
return specialLabels.includes(this.selectedLabel || '');
|
||||||
|
}
|
||||||
|
|
||||||
|
get isShashEnterDisabled(): boolean {
|
||||||
|
if (this.selectedLabel === 'TAN') {
|
||||||
|
return this.tanGroupStage >= 2 || this.tanGroups[this.tanGroupStage].length === 0;
|
||||||
|
} else if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
|
||||||
|
return this.isFirstGroupComplete || this.firstGroup.length === 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private chunk<T>(array: T[], size: number): T[][] {
|
private chunk<T>(array: T[], size: number): T[][] {
|
||||||
@ -86,55 +100,92 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
this.selectedNumbers = [];
|
this.selectedNumbers = [];
|
||||||
this.padValue = '';
|
this.padValue = '';
|
||||||
this.canPrint = false;
|
this.canPrint = false;
|
||||||
this.isQUIFirstGroupComplete = false;
|
|
||||||
this.QUIGroup1 = [];
|
|
||||||
this.QUIGroup2 = [];
|
|
||||||
this.isBoxed = false;
|
this.isBoxed = false;
|
||||||
|
|
||||||
|
// Reset TAN state
|
||||||
|
this.tanGroupStage = 0;
|
||||||
|
this.tanGroups = [[], [], []];
|
||||||
|
|
||||||
|
// Reset FOR/QUI state
|
||||||
|
this.isFirstGroupComplete = false;
|
||||||
|
this.firstGroup = [];
|
||||||
|
this.secondGroup = [];
|
||||||
|
|
||||||
this.selectionService.updatePartial({ label });
|
this.selectionService.updatePartial({ label });
|
||||||
}
|
}
|
||||||
|
|
||||||
selectNumber(number: number) {
|
selectNumber(number: number) {
|
||||||
if (!this.selectedLabel) return;
|
if (!this.selectedLabel) return;
|
||||||
|
|
||||||
if (this.selectedLabel === 'QUI') {
|
if (this.selectedLabel === 'TAN') {
|
||||||
if (this.isQUIFirstGroupComplete) {
|
if (!this.tanGroups[this.tanGroupStage].includes(number)) {
|
||||||
if (!this.QUIGroup2.includes(number)) {
|
this.tanGroups[this.tanGroupStage].push(number);
|
||||||
this.QUIGroup2.push(number);
|
const combined: (number | string)[] = [...this.tanGroups[0]];
|
||||||
this.selectedNumbers = [...this.QUIGroup1, '-', ...this.QUIGroup2];
|
if (this.tanGroupStage > 0) combined.push('-', ...this.tanGroups[1]);
|
||||||
}
|
if (this.tanGroupStage > 1) combined.push('-', ...this.tanGroups[2]);
|
||||||
} else {
|
this.selectedNumbers = combined;
|
||||||
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.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.padValue = '';
|
if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
|
||||||
this.canPrint = false;
|
if (!this.isFirstGroupComplete) {
|
||||||
|
if (!this.firstGroup.includes(number)) {
|
||||||
|
this.firstGroup.push(number);
|
||||||
|
this.selectedNumbers = [...this.firstGroup];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!this.secondGroup.includes(number)) {
|
||||||
|
this.secondGroup.push(number);
|
||||||
|
this.selectedNumbers = [...this.firstGroup, '-', ...this.secondGroup];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.selectedNumbers.includes(number)) {
|
||||||
|
this.selectedNumbers.push(number);
|
||||||
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isNumberDisabled(number: number): boolean {
|
isNumberDisabled(number: number): boolean {
|
||||||
if (this.selectedLabel === 'QUI') {
|
if (this.twoGroupLabels.includes(this.selectedLabel || '') || this.selectedLabel === 'TAN') return false;
|
||||||
return false; // ✅ Allow reuse in second group
|
|
||||||
}
|
|
||||||
return this.selectedNumbers.includes(number);
|
return this.selectedNumbers.includes(number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
padEnter() {
|
||||||
|
if (this.selectedLabel === 'TAN') {
|
||||||
|
if (this.tanGroupStage < 2) {
|
||||||
|
this.tanGroupStage++;
|
||||||
|
const combined: (number | string)[] = [...this.tanGroups[0]];
|
||||||
|
if (this.tanGroupStage > 0) combined.push('-', ...this.tanGroups[1]);
|
||||||
|
if (this.tanGroupStage > 1) combined.push('-', ...this.tanGroups[2]);
|
||||||
|
this.selectedNumbers = combined;
|
||||||
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.twoGroupLabels.includes(this.selectedLabel || '')) {
|
||||||
|
if (!this.isFirstGroupComplete && this.firstGroup.length > 0) {
|
||||||
|
this.isFirstGroupComplete = true;
|
||||||
|
this.secondGroup = [];
|
||||||
|
this.selectedNumbers = [...this.firstGroup, '-'];
|
||||||
|
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (this.canPrint) {
|
||||||
|
this.print();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enterPadVal(key: string) {
|
enterPadVal(key: string) {
|
||||||
if (!this.numericPadEnabled) return;
|
if (!this.numericPadEnabled) return;
|
||||||
if (/[0-9]/.test(key)) {
|
if (/[0-9]/.test(key)) this.padValue += key;
|
||||||
this.padValue += key;
|
else if (key === 'X') this.padValue += 'X';
|
||||||
} else if (key === 'X') {
|
|
||||||
this.padValue += 'X';
|
|
||||||
}
|
|
||||||
|
|
||||||
this.updateCanPrint();
|
this.updateCanPrint();
|
||||||
|
|
||||||
@ -153,24 +204,6 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
this.canPrint = this.padValue.trim().length > 0 && /^[0-9]+$/.test(this.padValue);
|
this.canPrint = this.padValue.trim().length > 0 && /^[0-9]+$/.test(this.padValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
padEnter() {
|
|
||||||
if (this.selectedLabel === 'QUI') {
|
|
||||||
if (!this.isQUIFirstGroupComplete && this.QUIGroup1.length > 0) {
|
|
||||||
this.isQUIFirstGroupComplete = true;
|
|
||||||
|
|
||||||
// ✅ Add dash to represent separator
|
|
||||||
this.selectedNumbers = [...this.QUIGroup1, '-'];
|
|
||||||
this.QUIGroup2 = [];
|
|
||||||
|
|
||||||
// Update to prepare for second group
|
|
||||||
this.selectionService.updatePartial({ numbers: [...this.selectedNumbers] });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (this.canPrint) {
|
|
||||||
this.print();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
print() {
|
print() {
|
||||||
this.selectionService.finalizeCurrentRow();
|
this.selectionService.finalizeCurrentRow();
|
||||||
this.resetSelections();
|
this.resetSelections();
|
||||||
@ -187,14 +220,35 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
this.padValue = '';
|
this.padValue = '';
|
||||||
this.canPrint = false;
|
this.canPrint = false;
|
||||||
this.isBoxed = false;
|
this.isBoxed = false;
|
||||||
this.isQUIFirstGroupComplete = false;
|
|
||||||
this.QUIGroup1 = [];
|
// Reset FOR/QUI
|
||||||
this.QUIGroup2 = [];
|
this.isFirstGroupComplete = false;
|
||||||
|
this.firstGroup = [];
|
||||||
|
this.secondGroup = [];
|
||||||
|
|
||||||
|
// Reset TAN
|
||||||
|
this.tanGroupStage = 0;
|
||||||
|
this.tanGroups = [[], [], []];
|
||||||
|
|
||||||
|
// Reset field modal
|
||||||
|
this.fieldModalOpen = false;
|
||||||
this.fieldInput = '';
|
this.fieldInput = '';
|
||||||
this.fieldFEntered = false;
|
this.fieldFEntered = false;
|
||||||
this.fieldModalOpen = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleBoxMode() {
|
||||||
|
this.isBoxed = !this.isBoxed;
|
||||||
|
const value = parseFloat(this.padValue) || 0;
|
||||||
|
this.selectionService.updatePartial({
|
||||||
|
isBoxed: this.isBoxed,
|
||||||
|
label: this.selectedLabel || '',
|
||||||
|
numbers: [...this.selectedNumbers],
|
||||||
|
value
|
||||||
|
});
|
||||||
|
this.updateCanPrint();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculator methods
|
||||||
openCalculator() {
|
openCalculator() {
|
||||||
this.calculatorOpen = true;
|
this.calculatorOpen = true;
|
||||||
this.calcDisplay = '';
|
this.calcDisplay = '';
|
||||||
@ -214,9 +268,7 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
backspace() {
|
backspace() {
|
||||||
this.calcDisplay = this.calcDisplay === 'Error'
|
this.calcDisplay = this.calcDisplay === 'Error' ? '' : this.calcDisplay.slice(0, -1);
|
||||||
? ''
|
|
||||||
: this.calcDisplay.slice(0, -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculate() {
|
calculate() {
|
||||||
@ -227,30 +279,10 @@ export class TouchPadMenuComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleBoxMode() {
|
// FIELD modal methods
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 🔘 FIELD Modal Logic
|
|
||||||
canUseField(): boolean {
|
canUseField(): boolean {
|
||||||
const allowedLabels = ['WIN', 'SHP', 'THP', 'PLC', 'SHW'];
|
const allowedLabels = ['WIN', 'SHP', 'THP', 'PLC', 'SHW'];
|
||||||
return (
|
return this.selectedLabel !== null && allowedLabels.includes(this.selectedLabel) && this.selectedNumbers.length === 0;
|
||||||
this.selectedLabel !== null &&
|
|
||||||
allowedLabels.includes(this.selectedLabel) &&
|
|
||||||
this.selectedNumbers.length === 0
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
openFieldModal() {
|
openFieldModal() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user