more work in progress on algorithm
This commit is contained in:
parent
f2710588ea
commit
1a027e1feb
@ -4,6 +4,15 @@ import PlayerSelector from "@/components/PlayerSelector";
|
|||||||
import BuyInSelector from "@/components/BuyInSelector";
|
import BuyInSelector from "@/components/BuyInSelector";
|
||||||
import ChipsSelector from "@/components/ChipsSelector";
|
import ChipsSelector from "@/components/ChipsSelector";
|
||||||
import ChipDistributionSummary from "@/components/ChipDistributionSummary";
|
import ChipDistributionSummary from "@/components/ChipDistributionSummary";
|
||||||
|
|
||||||
|
export enum COLORS {
|
||||||
|
"white",
|
||||||
|
"red",
|
||||||
|
"green",
|
||||||
|
"blue",
|
||||||
|
"black",
|
||||||
|
}
|
||||||
|
|
||||||
const IndexScreen = () => {
|
const IndexScreen = () => {
|
||||||
const [playerCount, setPlayerCount] = useState(2);
|
const [playerCount, setPlayerCount] = useState(2);
|
||||||
const [buyInAmount, setBuyInAmount] = useState<number>(20);
|
const [buyInAmount, setBuyInAmount] = useState<number>(20);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React, { useEffect, useMemo, useState } from "react";
|
import React, { useEffect, useMemo, useState } from "react";
|
||||||
import { View, Text, StyleSheet } from "react-native";
|
import { View, Text, StyleSheet } from "react-native";
|
||||||
import { ColorValue } from "react-native";
|
import { ColorValue } from "react-native";
|
||||||
|
// import { COLORS } from "@/app";
|
||||||
|
|
||||||
interface ChipDistributionSummaryProps {
|
interface ChipDistributionSummaryProps {
|
||||||
playerCount: number;
|
playerCount: number;
|
||||||
@ -15,12 +16,25 @@ const ChipDistributionSummary = ({
|
|||||||
totalChipsCount,
|
totalChipsCount,
|
||||||
colors = ["white", "red", "green", "blue", "black"],
|
colors = ["white", "red", "green", "blue", "black"],
|
||||||
}: ChipDistributionSummaryProps) => {
|
}: ChipDistributionSummaryProps) => {
|
||||||
// const [chipCountPerPlayer, setChipCountPerPlayer] = useState<
|
const validDenominations: validDenomination[] = [
|
||||||
// Record<string, { count: number; value: number }>
|
|
||||||
// >({});
|
|
||||||
const validDenominations = [
|
|
||||||
0.05, 0.1, 0.25, 0.5, 1, 2, 2.5, 5, 10, 20, 50, 100,
|
0.05, 0.1, 0.25, 0.5, 1, 2, 2.5, 5, 10, 20, 50, 100,
|
||||||
];
|
];
|
||||||
|
const [denominations, setDenominations] = useState<validDenomination[]>([]);
|
||||||
|
const [distributions, setDistributions] = useState<number[]>([]);
|
||||||
|
|
||||||
|
type validDenomination =
|
||||||
|
| 0.05
|
||||||
|
| 0.1
|
||||||
|
| 0.25
|
||||||
|
| 0.5
|
||||||
|
| 1
|
||||||
|
| 2
|
||||||
|
| 2.5
|
||||||
|
| 5
|
||||||
|
| 10
|
||||||
|
| 20
|
||||||
|
| 50
|
||||||
|
| 100;
|
||||||
|
|
||||||
// Re-organize the inputs in a map for convience
|
// Re-organize the inputs in a map for convience
|
||||||
const chipMap: Map<ColorValue, number> = useMemo(() => {
|
const chipMap: Map<ColorValue, number> = useMemo(() => {
|
||||||
@ -32,124 +46,131 @@ const ChipDistributionSummary = ({
|
|||||||
}, [playerCount, buyInAmount, totalChipsCount]);
|
}, [playerCount, buyInAmount, totalChipsCount]);
|
||||||
|
|
||||||
// Helper function to return the closest (but lower) valid denomination to the target
|
// Helper function to return the closest (but lower) valid denomination to the target
|
||||||
const findFloorDenomination = (target: number) => {
|
const findFloorDenomination = (target: number): validDenomination => {
|
||||||
let current: number = validDenominations[0];
|
let current: validDenomination = validDenominations[0];
|
||||||
validDenominations.forEach((value, index) => {
|
validDenominations.forEach((value, index) => {
|
||||||
if (value < target) current = value;
|
if (value < target) current = value;
|
||||||
});
|
});
|
||||||
return current;
|
return current;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Bound for the value of the highest chip
|
||||||
const maxDenomination = useMemo(() => {
|
const maxDenomination = useMemo(() => {
|
||||||
if (chipMap.size > 3) {
|
if (chipMap.size > 3) {
|
||||||
return findFloorDenomination(buyInAmount / 2);
|
return findFloorDenomination(buyInAmount / 3);
|
||||||
} else {
|
} else {
|
||||||
return findFloorDenomination(buyInAmount / 4);
|
return findFloorDenomination(buyInAmount / 4);
|
||||||
}
|
}
|
||||||
}, [chipMap]);
|
}, [chipMap]);
|
||||||
|
|
||||||
|
// Total value of the pot
|
||||||
|
const totalValue = useMemo(
|
||||||
|
() => buyInAmount * playerCount,
|
||||||
|
[buyInAmount, playerCount]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Maximum quantity of each chip which may be distributed to a single player before running out
|
||||||
|
const maxPossibleDistribution = useMemo(
|
||||||
|
() => totalChipsCount.map((v) => Math.floor(v / playerCount)),
|
||||||
|
[totalChipsCount, playerCount]
|
||||||
|
);
|
||||||
|
|
||||||
|
function denominate(min: number, max: number, count: number = 4): number[] {
|
||||||
|
if (max - min + 1 < count) {
|
||||||
|
throw new Error(
|
||||||
|
"Range is too small to generate the required number of unique values."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const numbers = new Set<number>();
|
||||||
|
|
||||||
|
while (numbers.size < count) {
|
||||||
|
const randomNum = Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
numbers.add(randomNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
// const denominations
|
||||||
|
|
||||||
|
return Array.from(numbers);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const testDistribution: Map<ColorValue, number> = new Map();
|
// const testDistribution: Map<ColorValue, number> = new Map();
|
||||||
|
const testDenomination: validDenomination[] = [];
|
||||||
|
|
||||||
const numColors = chipMap.size;
|
const numColors = chipMap.size;
|
||||||
testDistribution.set(colors[numColors - 1], maxDenomination);
|
const testDistribution: number[] = [];
|
||||||
const maxDenominationIndex: number =
|
for (let i = 0; i < numColors; ++i) {
|
||||||
|
testDistribution.push(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
let numColorsRemaining = numColors;
|
||||||
|
// testDistribution.set(colors[numColors - 1], maxDenomination);
|
||||||
|
testDenomination.push(maxDenomination);
|
||||||
|
numColorsRemaining -= 1;
|
||||||
|
let currentDenominationIndex: number =
|
||||||
validDenominations.indexOf(maxDenomination);
|
validDenominations.indexOf(maxDenomination);
|
||||||
|
while (numColorsRemaining > 0) {
|
||||||
|
numColorsRemaining -= 1;
|
||||||
|
currentDenominationIndex -= 1;
|
||||||
|
const currentDemoniation = validDenominations[currentDenominationIndex];
|
||||||
|
testDenomination.push(currentDemoniation);
|
||||||
|
}
|
||||||
|
testDenomination.reverse();
|
||||||
|
|
||||||
|
console.log("BUY IN: ", buyInAmount);
|
||||||
|
console.log("PLAYER COUNT ", playerCount);
|
||||||
|
|
||||||
|
// DISTRIBUTE
|
||||||
|
let remainingValue = buyInAmount;
|
||||||
|
const remainingChips = [...maxPossibleDistribution];
|
||||||
|
console.log("\ntest Denomination", testDenomination);
|
||||||
console.log("test distribution ", testDistribution);
|
console.log("test distribution ", testDistribution);
|
||||||
}, [chipMap, maxDenomination]);
|
console.log("remainingChips", remainingChips);
|
||||||
|
console.log("remaining value ", remainingValue);
|
||||||
|
|
||||||
// useEffect(() => {
|
//First distribute one of each chip to each player
|
||||||
// if (
|
for (let i = numColors - 1; i >= 0; i--) {
|
||||||
// buyInAmount !== null &&
|
testDistribution[i] = testDistribution[i] + 1;
|
||||||
// playerCount > 0 &&
|
remainingChips[i] = remainingChips[i] - 1;
|
||||||
// totalChipsCount.every((chips) => chips > 0)
|
remainingValue = remainingValue - testDenomination[i];
|
||||||
// ) {
|
}
|
||||||
// const availableColors = Math.min(colors.length, 5);
|
console.log("\ntest Denomination", testDenomination);
|
||||||
// let selectedChips: number[] = [];
|
console.log("test distribution ", testDistribution);
|
||||||
// let maxDenomination = buyInAmount / 2;
|
console.log("remainingChips", remainingChips);
|
||||||
|
console.log("remaining value ", remainingValue);
|
||||||
|
|
||||||
// // Select the denominations for available colors (up to 5 colors)
|
//Then, greedy approach to distribute remaining chips
|
||||||
// for (let i = validDenominations.length - 1; i >= 0; i--) {
|
|
||||||
// if (
|
|
||||||
// validDenominations[i] <= maxDenomination &&
|
|
||||||
// selectedChips.length < availableColors
|
|
||||||
// ) {
|
|
||||||
// selectedChips.unshift(validDenominations[i]);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Ensure the selected chips are sorted from low to high denomination
|
|
||||||
// selectedChips = selectedChips.sort((a, b) => a - b);
|
|
||||||
|
|
||||||
// let distribution = new Array(selectedChips.length).fill(0);
|
|
||||||
// let remainingValue = buyInAmount;
|
|
||||||
// let remainingChips = [...totalChipsCount.slice(0, selectedChips.length)];
|
|
||||||
|
|
||||||
// // First pass: Distribute at least one chip of each selected denomination per player
|
|
||||||
// for (let i = 0; i < selectedChips.length; i++) {
|
|
||||||
// const chipValue = selectedChips[i];
|
|
||||||
// if (remainingValue >= chipValue && remainingChips[i] >= playerCount) {
|
|
||||||
// distribution[i] = 1;
|
|
||||||
// remainingValue -= chipValue;
|
|
||||||
// remainingChips[i] -= playerCount;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Second pass: Distribute remaining buy-in amount fairly across chip colors
|
|
||||||
// while (remainingValue > 0) {
|
// while (remainingValue > 0) {
|
||||||
// let allocatedInRound = false;
|
// for (let i = numColors - 1; i >= 0; i--) {
|
||||||
|
// if (remainingChips[i] > 0 && remainingValue > testDenomination[i]) {
|
||||||
// for (let i = 0; i < selectedChips.length; i++) {
|
// testDistribution[i] = testDistribution[i] + 1;
|
||||||
// if (remainingValue <= 0) break;
|
// remainingChips[i] = remainingChips[i] - 1;
|
||||||
// const chipValue = selectedChips[i];
|
// remainingValue = remainingValue - testDenomination[i];
|
||||||
|
// }
|
||||||
// if (remainingChips[i] >= playerCount && remainingValue >= chipValue) {
|
// remainingValue = 0;
|
||||||
// distribution[i] += 1;
|
|
||||||
// remainingValue -= chipValue;
|
|
||||||
// remainingChips[i] -= playerCount;
|
|
||||||
// allocatedInRound = true;
|
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
console.log("\ntest Denomination", testDenomination);
|
||||||
// if (!allocatedInRound) break; // Prevent infinite loops
|
console.log("test distribution ", testDistribution);
|
||||||
// }
|
console.log("remainingChips", remainingChips);
|
||||||
|
console.log("remaining value ", remainingValue);
|
||||||
// // Create a mapping from chip color names to chip counts and denominations
|
setDenominations(testDenomination);
|
||||||
// let chipMap: Record<string, { count: number; value: number }> = {};
|
setDistributions(testDistribution);
|
||||||
// for (let i = 0; i < selectedChips.length; i++) {
|
}, [chipMap, maxDenomination, buyInAmount, playerCount]);
|
||||||
// if (distribution[i] > 0) {
|
|
||||||
// // Map denomination and color to chip count
|
|
||||||
// chipMap[colors[i]] = {
|
|
||||||
// count: distribution[i],
|
|
||||||
// value: selectedChips[i],
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// setChipCountPerPlayer(chipMap);
|
|
||||||
// } else {
|
|
||||||
// setChipCountPerPlayer({});
|
|
||||||
// }
|
|
||||||
// }, [buyInAmount, playerCount, totalChipsCount, colors]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.title}>Chip Distribution Summary:</Text>
|
<Text style={styles.title}>Chip Distribution Summary:</Text>
|
||||||
{/**Object.keys(chipCountPerPlayer).length > 0 ? (
|
{colors.map((color, index) => (
|
||||||
<View style={styles.chipContainer}>
|
<View style={styles.chipContainer} key={index}>
|
||||||
{Object.entries(chipCountPerPlayer).map(
|
<Text style={styles.chipText}>
|
||||||
([color, { count, value }]) => (
|
{String(color).charAt(0).toUpperCase() + String(color).slice(1)}{" "}
|
||||||
<Text style={styles.chipText} key={color}>
|
chips: {distributions[index]} ( ${denominations[index]} each)
|
||||||
{color.charAt(0).toUpperCase() + color.slice(1)} chips: {count}{" "}
|
|
||||||
( ${value} each)
|
|
||||||
</Text>
|
</Text>
|
||||||
)
|
|
||||||
)}
|
|
||||||
</View>
|
</View>
|
||||||
) : (
|
))}
|
||||||
<Text style={styles.noDataText}>
|
|
||||||
No valid distribution calculated yet.
|
|
||||||
</Text>
|
|
||||||
)**/}
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user