Skip to content

Commit

Permalink
Merge pull request #2 from PocketRice/v1.1
Browse files Browse the repository at this point in the history
v1.1
  • Loading branch information
pocketrice authored Jan 26, 2023
2 parents 72ce624 + 1044d15 commit e2b7cde
Show file tree
Hide file tree
Showing 23 changed files with 348 additions and 26 deletions.
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# READ ME!!
To Dr. Kahle,

For the rough draft for this project, the **runner file for the console-based version of this project is... a little buried.** (sorry!)

# Gambler's Delight (GDJFX)
![casino](https://user-images.githubusercontent.com/79682953/214141005-cf24c024-4be7-4759-9161-91269e993b71.jpg)
_Lean green gambling machine running on the power of coffee beans and JavaFX._
<br><br>
_<h3>Here's where you can find the runner file:</h3>_
* src/com.gdjfx/console/ProgramConsole.java
#
> Execute program (app or CLI) at com.gdjfx/app/ProgramApplet or com.gdjfx/cli/ProgramConsole. Requires JavaFX.
Binary file modified out/production/GD-JFX/com/gdjfx/Card.class
Binary file not shown.
Binary file modified out/production/GD-JFX/com/gdjfx/CardDeck.class
Binary file not shown.
Binary file modified out/production/GD-JFX/com/gdjfx/Dice.class
Binary file not shown.
Binary file modified out/production/GD-JFX/com/gdjfx/app/GdFastScene.class
Binary file not shown.
Binary file modified out/production/GD-JFX/com/gdjfx/app/GdSlowScene$1.class
Binary file not shown.
Binary file modified out/production/GD-JFX/com/gdjfx/app/GdSlowScene.class
Binary file not shown.
Binary file modified out/production/GD-JFX/com/gdjfx/app/ProgramApplet$1.class
Binary file not shown.
Binary file modified out/production/GD-JFX/com/gdjfx/app/ProgramApplet.class
Binary file not shown.
4 changes: 4 additions & 0 deletions out/production/GD-JFX/com/gdjfx/app/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
}


/* Credit to https://stackoverflow.com/questions/48048943/javafx-8-scroll-bar-css */

.scroll-bar:horizontal .track,
.scroll-bar:vertical .track{
-fx-background-color : #FFFFFF;
Expand Down Expand Up @@ -93,6 +95,8 @@
-fx-background-radius : 2.0em;
}

/* End of credit */

#btnPause {
-fx-background-color: #958cad70 !important;
}
Expand Down
Binary file modified out/production/GD-JFX/com/gdjfx/cli/GdFastConsole.class
Binary file not shown.
Binary file modified out/production/GD-JFX/com/gdjfx/cli/GdSlowConsole.class
Binary file not shown.
Binary file modified out/production/GD-JFX/com/gdjfx/cli/ProgramConsole.class
Binary file not shown.
5 changes: 5 additions & 0 deletions src/com/gdjfx/Card.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ public Card(Suit cs, int cv) {
cardRank = Rank.values()[cv-1];
}

// Randomly select a choice out of a given pool either equally or individually weighted.
// @param choices - generic array of objects
// @param weights - array of weights of equal length to choices corresponding to each index
// @param autoEqualize - should weights be overwritten with an array of equalized weights?
// @return randomly selected object from objects
public static <T> T weightedRandom(T[] choices, double[] weights, boolean autoEqualize)
{
double rng = Math.random();
Expand Down
22 changes: 16 additions & 6 deletions src/com/gdjfx/CardDeck.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,20 @@ public CardDeck() {
cardCount = cards.length;
deckColor = generateRandomColor();
}
// "There's millions of people living on this planet that haven't even tried crappy ice cream"

public CardDeck(Card[] cards, Color color) {
this.cards = cards;
workingCards = cards;
cardCount = cards.length;
deckColor = color;
}

public Card[] generateSuit(Card.Suit suit) { // Generates a suit of cards. This is useful if you want to generate a custom suit more systematically

// Generates a suit of cards. This is useful if you want to generate a custom suit more systematically (e.g. easier to trim off all 3s from deck).
// No jokers are included.
// @param suit - card suit type to generate
// @return full 13-card suit
public Card[] generateSuit(Card.Suit suit) {
Card[] newSuit = new Card[13];
for (int i = 0; i < newSuit.length; i++) {
newSuit[i] = new Card(suit, i+1);
Expand All @@ -36,6 +41,9 @@ public Card[] generateSuit(Card.Suit suit) { // Generates a suit of cards. This
return newSuit;
}

// Generates a full, 52-card valid deck of cards. No jokers are included.
// @param N/A
// @return full 52-card deck
public Card[] generateValidDeck() {
List<Card> newDeck = new ArrayList<>();
newDeck.addAll(Arrays.asList(generateSuit(Card.Suit.CLUB)));
Expand All @@ -46,16 +54,18 @@ public Card[] generateValidDeck() {
return newDeck.toArray(new Card[]{});
}

// Generates a random rgb color. deckColor is not used so this method has no use.
// @param N/A
// @return randomly generated rgb color
public Color generateRandomColor() {
return new Color((int)(Math.random() * 255), (int)(Math.random() * 255), (int)(Math.random() * 255));
}

// Resets working cards deck (see above for info).
// @param N/A
// @return N/A
public void resetWorkingCards() { // Resets working cards
workingCards = cards;
}

public void shuffleDeck(int iterations) {

}

}
13 changes: 13 additions & 0 deletions src/com/gdjfx/Dice.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,20 @@ public Dice(int[] sv) {
selectedValue = -1; // 2nd assertion guarantees no negatives; this allows for safely checking if selectedValue was not set yet.
}

// Generate a theoretical dice roll value. This was intended to be paired with getPhysicalSelectedValue, where based on
// the highest side of the dice (determined by finding the highest point) a side was selected (which would not be perfectly equal randomness).
// @param N/A
// @return theoretical dice roll value
public int getTheoreticalSelectedValue() { // Based on hard, cold equal probabilities.
return weightedRandom(ArrayUtils.toObject(sideValues), new double[sideValues.length], true);
}


// Randomly select a choice out of a given pool either equally or individually weighted.
// @param choices - generic array of objects
// @param weights - array of weights of equal length to choices corresponding to each index
// @param autoEqualize - should weights be overwritten with an array of equalized weights?
// @return randomly selected object from objects
public static <T> T weightedRandom(T[] choices, double[] weights, boolean autoEqualize)
{
double rng = Math.random();
Expand All @@ -47,6 +57,9 @@ public static <T> T weightedRandom(T[] choices, double[] weights, boolean autoEq
return null;
}

// Tracks and rolls the dice.
// @param N/A
// @return N/A
public void roll() {
selectedValue = getTheoreticalSelectedValue();
}
Expand Down
93 changes: 91 additions & 2 deletions src/com/gdjfx/app/GdFastScene.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class GdFastScene extends GdFastConsole {
Set<Node> roundAssets = new HashSet<>();
boolean isPaused = false, isRunningAgain = true;

// Credit to https://stackoverflow.com/questions/46369046/how-to-wait-for-user-input-on-javafx-application-thread-without-using-showandwai
private final Object PAUSE_KEY = new Object();

private void pause() {
Expand All @@ -58,6 +59,7 @@ private void resume() {
Platform.exitNestedEventLoop(PAUSE_KEY, null);
}

// End of credit

private int thousandsValue, hundredsValue, tensValue, onesValue;
private int currentRound, totalWins, totalLosses, doubleWins, quadWins, initLosses, doubleLosses, quadLosses;
Expand All @@ -84,7 +86,9 @@ public GdFastScene() {
}



// Load color presets into designated map.
// @param N/A
// @return N/A
public void loadColorPresets() {
GD_PRESETS.put("GD_BLUE", GD_BLUE);
GD_PRESETS.put("GD_DEW", GD_DEW);
Expand All @@ -97,6 +101,10 @@ public void loadColorPresets() {
GD_PRESETS.put("GD_YELLOW", GD_YELLOW);
}

// Toggles the obfuscation panel (dark overlay for pause screen, startup, etc). Necessary as it is difficult to both animate opacity and hide object's visibility without many lines.
// @param obfPanel - obfuscation panel
// @param isVisible - whether to show or hide the panel
// @return N/A
public void toggleObfPanel(Rectangle obfPanel, boolean isVisible) {
Animated<Double> obfAnimator = new Animated<>(obfPanel, PropertyWrapper.of(obfPanel.opacityProperty())).custom(settings -> settings.withDuration(Duration.seconds(4)));
root.getChildren().add(obfAnimator);
Expand All @@ -119,6 +127,10 @@ public void toggleObfPanel(Rectangle obfPanel, boolean isVisible) {
}
}


// Initialize the root pane.
// @param N/A
// @return N/A
public void initializeRoot() throws FileNotFoundException, InterruptedException {
loadColorPresets();

Expand Down Expand Up @@ -408,6 +420,10 @@ public void initializeRoot() throws FileNotFoundException, InterruptedException
root.getChildren().add(btnStart);
}


// Specific animation for prompt info bar's two "attention-directing" arrows; downward-pointing gesture. Inspired by Ace Attorney.
// @param promptBarArrow - target arrow
// @return N/A
public static void playPromptBarArrowAnim(FontIcon promptBarArrow) {
Timeline promptBarArrowAnim = new Timeline(
new KeyFrame(Duration.ZERO, e -> promptBarArrow.setLayoutY(313.2)),
Expand All @@ -422,6 +438,10 @@ public static void playPromptBarArrowAnim(FontIcon promptBarArrow) {
promptBarArrowAnim.play();
}

// Update UI textflow with given strings (JFX UI equivalent of System.out.print).
// @param textflow - target textflow
// @param addendums - strings to append (separated as each string only supports one color b/c they are parsed as Text objects)
// @return N/A
public void updateOutputText (TextFlow textflow, String... addendums) {
// An addendum string can be parsed to have colors. This is done by typing {CONST_NAME} or {any hex color} prior to any text.
for (String addendum : addendums) {
Expand All @@ -444,6 +464,11 @@ public void updateOutputText (TextFlow textflow, String... addendums) {
}
}


// Compare a string against several patterns and return true only if all patterns match (strict matching).
// @param string
// @param patterns - regex patterns to test
// @return whether or not string matched ALL patterns
public static boolean bulkContains(String string, Pattern... patterns) { // <+> APM - too lazy to write one for just one pattern, so here ya go
for (Pattern pattern : patterns) {
Matcher matcher = pattern.matcher(string);
Expand All @@ -456,6 +481,13 @@ public static boolean bulkContains(String string, Pattern... patterns) { // <+>
return true; // All patterns were matched.
}


// JFX / Gambler's Delight-specific monetaryParse method that uses color presets in place of ansi colors (which don't work in GUI).
// @param num
// @param includeDecimal
// @param includeExplicitSign
// @param includeCOlor
// @return monetary-parsed string
public static String gdMonetaryParse(double num, boolean includeDecimal, boolean includeExplicitSign, boolean includeColor) { // BUG: for some reason this doesn't work 100% (see 'expected value' on occassions)
String[] monetaryColors = (includeColor) ? new String[]{"{GD_DEW}", "{GD_BLUE}", "{GD_CRIMSON}"} : new String[]{"","",""};

Expand All @@ -476,6 +508,12 @@ public static String gdMonetaryParse(double num, boolean includeDecimal, boolean
}
}



// JFX / Gambler's Delight-specific fancyDelay method using Ikonli icons in place of chars and \b (which was a little too funky for GUI)
// @param output - target textflow
// @param loadMessage
// @return N/A
public void gdFancyDelay(TextFlow output, String loadMessage) { // assumes that method is ONLY used for actions needing user input (e.g. roll dice) and then stop.
int recursionCount = 0;
Text message = new Text(loadMessage + " ");
Expand Down Expand Up @@ -518,6 +556,13 @@ public void gdFancyDelay(TextFlow output, String loadMessage) { // assumes that
else updateOutputText(output, "\n");*/
}


// Create and display a visual representation of a generated dice roll. Final positions are slightly randomized and rotation/position has attached transitions.
// @param diceA
// @param diceB
// @param root - root pane
// @param roundAssets - any assets (only visualized dice and cards) used within one single round. This grouping is used later.
// @return N/A
public void visualizeDice(Dice diceA, Dice diceB, Pane root, Set<Node> roundAssets) throws FileNotFoundException {
diceA.roll();
diceB.roll();
Expand Down Expand Up @@ -566,11 +611,21 @@ public void visualizeDice(Dice diceA, Dice diceB, Pane root, Set<Node> roundAsse
visualizeDiceAnim.play();
}


// Generate a random number anchored on a base value with customizable skews to either side.
// @param base - base value
// @param lowerOffset - lowest possible # (higher = more skew leftward)
// @param upperOffset - highest possible # (higher = more skew rightward)
// @return random number based on set specs
public static double proximityRandom(double base, double lowerOffset, double upperOffset) { // <+> APM
return Math.random()*(lowerOffset + upperOffset) + base - lowerOffset;
}


// The card equivalent of visualizeDice.
// @param card
// @param root
// @param roundAssets
// @return N/A
public void visualizeCard(Card card, Pane root, Set<Node> roundAssets) throws FileNotFoundException {

Image cardCover = ((int)(Math.random()*2) == 0) ? retrieveImage("src/com/gdjfx/app/assets/redCardCover.png") : retrieveImage("src/com/gdjfx/app/assets/blueCardCover.png");
Expand Down Expand Up @@ -598,6 +653,10 @@ public void visualizeCard(Card card, Pane root, Set<Node> roundAssets) throws Fi
visualizeCardAnim.play();
}


// Rolls first round of cycle. Overwritten to include steps for visualization.
// @param N/A
// @return N/A
@Override
public boolean rollInitRound() {
// Roll 2x dice; move on if either is prime.
Expand All @@ -612,6 +671,10 @@ public boolean rollInitRound() {
return (isPrime(diceA.selectedValue) || isPrime(diceB.selectedValue));
}


// Rolls second round of cycle. Overwritten to include steps for visualization.
// @param N/A
// @return N/A
@Override
public boolean rollDoubleRound() {
// Pick a card; move on if diamond, spade, or JQK of heart
Expand All @@ -622,6 +685,10 @@ public boolean rollDoubleRound() {
return (card.cardSuit.equals(Card.Suit.DIAMOND) || card.cardSuit.equals(Card.Suit.SPADE) || (card.cardSuit.equals(Card.Suit.HEART) && card.cardRank.ordinal() > 9));
}


// Rolls third round of cycle. Overwritten to include steps for visualization.
// @param N/A
// @return N/A
@Override
public boolean rollQuadRound() {
// Roll 2x dice; win if both numbers are equal
Expand All @@ -636,6 +703,10 @@ public boolean rollQuadRound() {
return (diceA.selectedValue == diceB.selectedValue);
}


// Non-generic prompting method to ask the user for # of trials
// @param message - message to display
// @return # of trials to run per cycle
public long trialPrompt (String message) {
updateOutputText(outputText, message);
ynPrompt.setVisible(false);
Expand All @@ -647,6 +718,11 @@ public long trialPrompt (String message) {
return thousandsValue * 1000 + hundredsValue * 100 + tensValue * 10 + onesValue;
}



// Non-generic prompting method to ask the user if they want to run another cycle
// @param N/A
// @return whether or not to run another cycle
public boolean ynPrompt () {
updateOutputText(outputText, "{GD_PURPLE}* Cycle complete. Would you like to continue rolling trials?\n\n\n\n\n\n\n\n\n\n\n");
ynPrompt.setVisible(true);
Expand All @@ -658,6 +734,10 @@ public boolean ynPrompt () {
return isRunningAgain;
}


// Rolls a full cycle. Not many changes from console version apart from JFX-compatibility changes and some magic to allow JFX to wait for user input (otherwise it would compile the pane fully).
// @param N/A
// @return N/A
public void rollCycle() throws InterruptedException, FileNotFoundException {
int rerunCount = 0;
long initialBal = balance;
Expand Down Expand Up @@ -768,6 +848,10 @@ else if (i < 5){
}
}


// JFX-specific delay (equivalent to Thread.sleep(ms)) by using some clever trickery.
// @param ms - milliseconds to wait
// @return N/A
public void fxDelay(long ms) {
Timeline fxDelayAnim = new Timeline(
new KeyFrame(Duration.millis(ms), e -> resume())
Expand All @@ -776,6 +860,11 @@ public void fxDelay(long ms) {
pause();
}


// Adds a bulk amount of items to a collection without needing to package into a collection first.
// @param collection - any collection of objects of type E
// @param items - objects of type E
// @return N/A
@SafeVarargs
public static <T extends Collection<E>, E> void bulkAdd(T collection, E... items) { // <+> APM -- this may seem redundant (see List.addAll) but this might be useful when adding a bunch of individual items.
collection.addAll(Arrays.asList(items));
Expand Down
Loading

0 comments on commit e2b7cde

Please sign in to comment.