better distribution with fibbonachi
This commit is contained in:
parent
1216e76381
commit
f04496bf24
@ -1,5 +1,5 @@
|
|||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { View, Text, StyleSheet } from "react-native";
|
import { View, Text } from "react-native";
|
||||||
import { ColorValue } from "react-native";
|
import { ColorValue } from "react-native";
|
||||||
import i18n from "@/i18n/i18n";
|
import i18n from "@/i18n/i18n";
|
||||||
import styles from "@/styles/styles";
|
import styles from "@/styles/styles";
|
||||||
@ -22,7 +22,7 @@ const ChipDistributionSummary = ({
|
|||||||
selectedCurrency = "$",
|
selectedCurrency = "$",
|
||||||
}: ChipDistributionSummaryProps) => {
|
}: ChipDistributionSummaryProps) => {
|
||||||
const validDenominations: validDenomination[] = [
|
const validDenominations: validDenomination[] = [
|
||||||
0.05, 0.1, 0.25, 0.5, 1, 2, 2.5, 5, 10, 20, 50, 100,
|
0.05, 0.1, 0.25, 1, 5, 10, 20, 50, 100,
|
||||||
];
|
];
|
||||||
const [denominations, setDenominations] = useState<validDenomination[]>([]);
|
const [denominations, setDenominations] = useState<validDenomination[]>([]);
|
||||||
const [distributions, setDistributions] = useState<number[]>([]);
|
const [distributions, setDistributions] = useState<number[]>([]);
|
||||||
@ -38,26 +38,38 @@ const ChipDistributionSummary = ({
|
|||||||
| 5
|
| 5
|
||||||
| 10
|
| 10
|
||||||
| 20
|
| 20
|
||||||
|
| 25
|
||||||
| 50
|
| 50
|
||||||
| 100;
|
| 100;
|
||||||
|
|
||||||
const findFloorDenomination = (target: number): validDenomination => {
|
const findFloorDenomination = (target: number): validDenomination => {
|
||||||
let current: validDenomination = validDenominations[0];
|
let current: validDenomination = validDenominations[0];
|
||||||
validDenominations.forEach((value, index) => {
|
validDenominations.forEach((value, _) => {
|
||||||
if (value < target) current = value;
|
if (value < target) current = value;
|
||||||
});
|
});
|
||||||
return current;
|
return current;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Bound for the value of the highest chip
|
// Bound for the value of the highest chip
|
||||||
// This is somewhat arbitray, but 1/3 to 1/4 is reasonable depending on the number of colors.
|
// This is somewhat arbitray and imperfect, but 1/3 to 1/5 is reasonable depending on the number of colors.
|
||||||
const maxDenomination = useMemo(() => {
|
const maxDenomination: validDenomination = useMemo(() => {
|
||||||
if (totalChipsCount.length > 3) {
|
let max: validDenomination;
|
||||||
return findFloorDenomination(buyInAmount / 3);
|
switch (totalChipsCount.length) {
|
||||||
} else {
|
case 5:
|
||||||
return findFloorDenomination(buyInAmount / 4);
|
case 4:
|
||||||
|
max = findFloorDenomination(buyInAmount / 3);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
max = findFloorDenomination(buyInAmount / 4);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 1:
|
||||||
|
default:
|
||||||
|
max = findFloorDenomination(buyInAmount / 5);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}, [totalChipsCount]);
|
return max;
|
||||||
|
}, [totalChipsCount, buyInAmount]);
|
||||||
|
|
||||||
const potValue = useMemo(
|
const potValue = useMemo(
|
||||||
() => buyInAmount * playerCount,
|
() => buyInAmount * playerCount,
|
||||||
@ -67,7 +79,7 @@ const ChipDistributionSummary = ({
|
|||||||
// The total value of all chips distributed to a single player. Ideally should be equal to buyInAmount
|
// The total value of all chips distributed to a single player. Ideally should be equal to buyInAmount
|
||||||
const totalValue = useMemo(() => {
|
const totalValue = useMemo(() => {
|
||||||
let value = 0;
|
let value = 0;
|
||||||
for (let i = 0; i < totalChipsCount.length; i++) {
|
for (let i = 0; i < distributions.length; i++) {
|
||||||
value += distributions[i] * denominations[i];
|
value += distributions[i] * denominations[i];
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
@ -81,7 +93,7 @@ const ChipDistributionSummary = ({
|
|||||||
|
|
||||||
// Redenominate the chips in case of failure to properly distribute.
|
// Redenominate the chips in case of failure to properly distribute.
|
||||||
// Move the shuffle index to the next lowest denomination, and keep all else same
|
// Move the shuffle index to the next lowest denomination, and keep all else same
|
||||||
const redenominate = useCallback(
|
const _redenominate = useCallback(
|
||||||
(
|
(
|
||||||
invalidDenomination: validDenomination[],
|
invalidDenomination: validDenomination[],
|
||||||
shuffleIndex: number
|
shuffleIndex: number
|
||||||
@ -113,56 +125,53 @@ const ChipDistributionSummary = ({
|
|||||||
// Dynamically set denominations and distributions from changing inputs
|
// Dynamically set denominations and distributions from changing inputs
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let testDenomination: validDenomination[] = [];
|
let testDenomination: validDenomination[] = [];
|
||||||
const numColors = totalChipsCount.length;
|
const totalNumColors = totalChipsCount.length;
|
||||||
const testDistribution: number[] = [];
|
|
||||||
for (let i = 0; i < numColors; ++i) {
|
|
||||||
testDistribution.push(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start with max denominations, then push on the next adjacent lower denomination
|
// Start with max denominations, then push on the next adjacent lower denomination
|
||||||
testDenomination.push(maxDenomination);
|
testDenomination.push(maxDenomination);
|
||||||
let currentDenominationIndex: number =
|
let currentDenominationIndex: number =
|
||||||
validDenominations.indexOf(maxDenomination);
|
validDenominations.indexOf(maxDenomination);
|
||||||
for (let i = numColors - 2; i >= 0; i = i - 1) {
|
for (
|
||||||
|
let i = totalNumColors - 2;
|
||||||
|
i >= 0 && currentDenominationIndex > 0;
|
||||||
|
i = i - 1
|
||||||
|
) {
|
||||||
currentDenominationIndex -= 1;
|
currentDenominationIndex -= 1;
|
||||||
const currentDemoniation = validDenominations[currentDenominationIndex];
|
const currentDemoniation = validDenominations[currentDenominationIndex];
|
||||||
testDenomination.push(currentDemoniation);
|
testDenomination.push(currentDemoniation);
|
||||||
}
|
}
|
||||||
testDenomination.reverse();
|
testDenomination.reverse();
|
||||||
|
let numColors = testDenomination.length;
|
||||||
|
|
||||||
|
const testDistribution: number[] = [];
|
||||||
|
for (let i = 0; i < numColors; ++i) {
|
||||||
|
testDistribution.push(0);
|
||||||
|
}
|
||||||
|
|
||||||
// Distribute the chips using the test denomination
|
// Distribute the chips using the test denomination
|
||||||
// If distribution fails to equal the buy-in, redenominate and re-try
|
// If distribution fails to equal the buy-in, redenominate and re-try
|
||||||
// Algorithm could be improved with more complexity and optimization
|
// Algorithm could be improved with more complexity and optimization
|
||||||
let remainingValue = buyInAmount;
|
let remainingValue = buyInAmount;
|
||||||
let fail = true;
|
let stop = false;
|
||||||
let failCount = 0;
|
while (remainingValue > 0 && !stop) {
|
||||||
while (fail && failCount < 1) {
|
let distributed = false;
|
||||||
let stop = false;
|
for (let i = numColors - 1; i >= 0; i = i - 1) {
|
||||||
while (remainingValue > 0 && !stop) {
|
if (testDistribution[i] < maxPossibleDistribution[i]) {
|
||||||
let distributed = false;
|
for (
|
||||||
for (let i = numColors - 1; i >= 0; i = i - 1) {
|
let j = reverseFib[i];
|
||||||
if (testDistribution[i] < maxPossibleDistribution[i]) {
|
j > 0 && remainingValue >= testDenomination[i];
|
||||||
if (remainingValue >= testDenomination[i]) {
|
j = j - 1
|
||||||
testDistribution[i] = testDistribution[i] + 1;
|
) {
|
||||||
remainingValue = remainingValue - testDenomination[i];
|
testDistribution[i] = testDistribution[i] + 1;
|
||||||
distributed = true;
|
remainingValue = remainingValue - testDenomination[i];
|
||||||
}
|
distributed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (distributed == false) {
|
|
||||||
stop = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (remainingValue !== 0) {
|
if (distributed == false) {
|
||||||
const redenominateIndex = failCount % numColors;
|
stop = true;
|
||||||
testDenomination = redenominate(testDenomination, redenominateIndex);
|
|
||||||
failCount += 1;
|
|
||||||
fail = true;
|
|
||||||
} else {
|
|
||||||
fail = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setDenominations(testDenomination);
|
setDenominations(testDenomination);
|
||||||
setDistributions(testDistribution);
|
setDistributions(testDistribution);
|
||||||
}, [totalChipsCount, maxDenomination, buyInAmount, playerCount]);
|
}, [totalChipsCount, maxDenomination, buyInAmount, playerCount]);
|
||||||
@ -170,7 +179,7 @@ const ChipDistributionSummary = ({
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
{totalChipsCount.map((_, index) => (
|
{denominations.map((denomination, index) => (
|
||||||
<View style={{ flexDirection: "row" }} key={index}>
|
<View style={{ flexDirection: "row" }} key={index}>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
@ -180,7 +189,7 @@ const ChipDistributionSummary = ({
|
|||||||
...(colors[index] === "white" && styles.shadow),
|
...(colors[index] === "white" && styles.shadow),
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{`${distributions[index]} ${i18n.t("chips")}: ${selectedCurrency}${denominations[index]} ${i18n.t("each")}`}
|
{`${distributions[index]} ${i18n.t("chips")}: ${selectedCurrency}${denomination} ${i18n.t("each")}`}
|
||||||
</Text>
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
|
Loading…
Reference in New Issue
Block a user