Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gambler's Ruin ASCII Plot in Java

Tags:

java

ascii

|  * |
| *  |
|  * |
| *  |
|  * |
| *  |
|  * |
|  * |
| *  |
| *  |
|  * |
| *  |
|*   |

I need to print something like the above ASCII plot for a Gambler's Ruin problem. Where the stake & goal are taken as args. The left most | represents 0 dollars, the right most | represents the goal and the * represents the cash on hand. My program is below:

  public class RuinPath {

  public static void main(String[] args) {
        // TODO - Your solution

    int stake = Integer.parseInt(args[0]);    // gambler's stating bankroll
    int goal = Integer.parseInt(args[1]);    // gambler's desired bankroll

    {
      int i = 0;
      if (i == 0) {
        System.out.print("|");
        i++;
        while (i < stake) {
          System.out.print(" ");
          i++;

          if (i == stake) {
            System.out.print("*");
            i++;

            while (i > stake && i < goal) {
              System.out.print(" ");
              i++;

              if (i == goal) {
                System.out.print("|");
                i = 0;
                System.out.println();

                {

                  if (Math.random() < 0.5) {

                    stake++;     // win $1
                  } else {
                    stake--;    // lose $1

                  }

                  if (stake == 1 || stake == goal - 1);
                  break;

                }
              }
            }
          }
        }
      }
    }
  }
}

what this program prints though is:

|    *    |
    *     |
     *    |
      *   |
       *  |
      *   |
       *  |
      *   |
       *  |
      *   |
       *  |
      *   |
       *  |
        * |
         *

Why does my program not loop so that i can get the left most | to appear to represent 0 dollars all the way through? I have it so i = 0; at the end of the loop so that when it goes back around it should re-loop until the stake is 1 or less than the goal. Instead it re-loops from the middle of the program.

like image 463
user2874403 Avatar asked Oct 30 '13 04:10

user2874403


2 Answers

Your logic is a little too complicated. Also, your indentation will make any sort of debugging extremely difficult.

Just take it one step at a time:

public class RuinPath {
    public static void main(String[] args) {
        int stake = Integer.parseInt(args[0]);  // Starting bankroll
        int goal  = Integer.parseInt(args[1]);  // Desired bankroll

        while (stake > 0 && stake < goal) {
            System.out.print("|");

            // Print out the spaces. Using a for loop and 
            //   printing a "*" if the counter variable 
            //   is equal to stake is good way to do it.

            // Flip a coin and increment/decrement the stake

            System.out.print("|\n");
        }
    }
}
like image 104
Blender Avatar answered Sep 30 '22 11:09

Blender


Here is a broken out solution that might be easier to reason about:

import java.io.PrintStream;

public class SO {
  private static int gambleWithCaution(int stake) {
    if (Math.random() < 0.5) {
      return stake+1; // win $1
    } else {
      return stake-1;    // lose $1
    }
  }

  private static void renderStanding(int stake, int goal) {
    System.out.print('|');
    for(int dollar = 1; dollar< goal; dollar++) {
      if(dollar == stake) {
        System.out.print('*');
      } else {
        System.out.print(' ');
      }
    }
    System.out.println('|');
  }

  public static void main(String ... args) {
    int stake = Integer.parseInt(args[0]);    // gambler's stating bankroll
    int goal = Integer.parseInt(args[1]);    // gambler's desired bankroll

    while(stake > 0 && stake < goal) {
      renderStanding(stake, goal);
      stake = gambleWithCaution(stake);
    }
    System.out.println((stake > goal) ? "You Won!" : "You Lost");
  }
}

With the values 3 and 5 you get this output:

|  * |
| *  |
|*   |
| *  |
|  * |
|   *|
|  * |
|   *|
You Won!

Now that this is seperated out you can have some fun with it like creating a gamble function like this:

private static int gambleWithReclessAbandon(int stake, int goal, double abandon) {
  int onTheLine = (int)(Math.random() * (int)(stake * abandon));
  if(stake < (0.5)*goal) {
    //If you are at less than 50% of your goal then just put it all on the line
    //and let it ride :)
    onTheLine = stake;
  }
  if (Math.random() < 0.5) {
    return stake+onTheLine; // win $
  } else {
    return stake-onTheLine; // lose $
  }
}

Which can be invoked like this:

//Gamble up to 80% of your current stake
stake = gambleWithReclessAbandon(stake, goal, 0.80);

With the same two values this is what I saw on my first pass (I was sooo close :)):

|  * |
|  * |
|   *|
| *  |
|   *|
You Lost
like image 43
Jason Sperske Avatar answered Sep 30 '22 11:09

Jason Sperske