Creating complex probabilities within Java - java

I'm trying to create a baseball simulation game within java. I'm utilizing instances of 'pitches' as the the iteration for my system. Within this, I have several different possibilities for the outcome. Hit, miss(strike), foul ball(no effect). I created an array of players from another class that read in specific attributes of my players that I design. The only attributes I'm trying to utilize currently are the power of the hitters and their consistency. I'm using random numbers to generate a certain and depending on where that value lies, determines whether it is a ball or a strike. The 'ball' logic is simple and works effectively; however, I'm only receiving counts of balls for the hitters. I'm stuck on how to implement the logic of probability of a strike(a missed swing) or a hit in regards to the pitch being a strike. The constructor I'm using for the player goes as follows
Player a = new Player(false, false, true, 10, 20, 0.75, true, null);
you can ignore the false's and true's and null, just pay attention to the numbers
the first number(10) indicates the speed, not relevant.
The second number(20) indicates the power.
The third indicates the consistency of the hitter.
I apologize if this may be confusing or too elementary, I've only been programming for a little over a month. All help would be greatly appreciated. Currently the only thing printing for me looks a little like
Press 'p' to initiate pitches
p
Ball count is: (0,0)
Ball count is: (0,0)
Ball count is: (0,0)
Ball count is: (0,0)
Ball!
Ball count is: (1,0)
Ball count is: (1,0)
Ball!
Ball count is: (2,0)
Ball count is: (2,0)
Ball count is: (2,0)
Ball!
Ball count is: (3,0)
I don't understand why the program is only recognizing balls and not describing what is printing as nothing, which I assume to be the foul ball(however its not printing my statement)
Please help, and thank you so much!
import java.util.Scanner;
public class Game {
public static void main(String[] args) {
System.out.println("Press 'p' to initiate pitches");
Scanner kb = new Scanner(System.in);
String s = kb.nextLine();
if(s.equalsIgnoreCase("p"))
{
int ball = 0;
int strike = 0;
//10 instances of pitches
for(int i = 0; i < 10; i++)
{
double number = Math.random();
if(number > 0.5)
{
ball++;
if(ball == 4)
{
System.out.println("Ball four, take your base");
break;
}
System.out.print("Ball!");
}
else if(strike() == true)
{
{
if(isMiss() == true)
{
System.out.print(" Strike!");
strike++;
}
else if(isFoul() == true)
{
System.out.println("Foul ball!");
}
}
if(strike == 3)
{
System.out.print(" Player struck out!");
break;
}
}
else
{
if(isHit() == true)
{
System.out.println("The ball was hit!");
System.out.println(isHit());
break;
}
}
System.out.println(" Ball count is: " + "(" + ball + "," + strike + ")");
}
}
}
public static boolean strike()
{
if(isMiss() == true)
{
return true;
}
else if(isFoul() == true)
{
return false;
}
else if(isHit() == true)
{
return true;
}
return false;
}
public static boolean isHit()
{
double probability = Math.random();
Player a = new Player(false, false, true, 10, 20, 0.75, true, null);
if(a.power > 5)
{
if(a.consistency > 0.5)
{
if(probability > 3 && probability < 6)
{
return false;
}
if(probability > 6 && probability < 9)
{
return false;
}
if(probability > 9 && probability < 12)
{
return true;
}
return true;
}
System.out.println("The ball was hit!");
}
return false;
}
public static boolean isMiss()
{
double probability = Math.random();
Player a = new Player(false, false, true, 10, 20, 0.75, true, null);
if(a.power > 5)
{
if(a.consistency > 0.5)
{
if(probability > 3 && probability < 6)
{
return true;
}
if(probability > 6 && probability < 9)
{
return false;
}
if(probability > 9 && probability < 12)
{
return false;
}
return false;
}
}
return false;
}
public static boolean isFoul()
{
double probability = Math.random();
Player a = new Player(false, false, true, 10, 20, 0.75, true, null);
if(a.power > 5)
{
if(a.consistency > 0.5)
{
if(probability > 3 && probability < 6)
{
return false;
}
if(probability > 6 && probability < 9)
{
return true;
}
if(probability > 9 && probability < 12)
{
return false;
}
}
}
return false;
}

I suggest you use your debugger to step through your code as there are many sections which don't make sense to me and I cannot run your code for you using with the Player class (and I cannot make it up as it doesn't make sense ;)
Sections of code which don't make sense are
double probability = Math.random();
so probability is a number between [0, 1)
if(probability > 3 && probability < 6) // always false.
if(probability > 6 && probability < 9) // always false
if(probability > 9 && probability < 12) // always false.
// prints the ball was hit but returns `false` to isHit
System.out.println("The ball was hit!");
}
return false;

For strikes:
if (Math.random() > consistency) { /* strike! */ }
You might want a constant foul ball chance (like if they hit the ball, they have a 10% chance of foul ball:
else if (Math.random() < 0.1) { ... }
And same for power, but maybe multiply it by 0.3 (since home runs are rare):
if (Math.random() < power * 0.3) { ... }
Note that for these to work, your consistency and power variables have to be decimals.
For example, 50% consistency would be 0.5. 20% consistency would be 0.2. Similarly, 1 is the maximum amount of power and 0 is really weak.
0.5 would be in between.

Related

While loop not checking both conditions?

I am fairly new to programming and have decided to take on a project where I create a game in the console. The user has the options to move up, down, left, or right from the center of an area that is a 3x3 grid. One of the x,y locations is marked a 'bad' square and the game ends when the user's x and y are equal to that of the bad square's. The bad squares location is x = 1 and y = 3.
The problem I have is that when the user enters Up or Left (hence the users y becomes 3 or the users x becomes 1) and the game ends even though one of the other axis values does not match the bad squares.
Here is my code:
public static void main (String[]args){
//scanner
Scanner userIn = new Scanner(System.in);
//string that will get users value
String movement;
//strings that are compared to users to determine direction
String up = "Up";
String down = "Down";
String left = "Left";
String right = "Right";
//starting coordinates of user
int x = 2;
int y = 2;
//coordinates of bad square
int badx = 1;
int bady = 3;
//message telling user options to move (not very specific yet)
System.out.println("Up, Down, Left, Right");
//do while loop that continues until
do {
movement = userIn.nextLine();
//checking user input and moving them accordingly
if (movement.equals(up)) {
y++;
} else if (movement.equals(down)) {
y--;
} else if (movement.equals(left)) {
x--;
} else if (movement.equals(right)) {
x++;
} else {
System.out.println("Unacceptable value");
}
//checking if user is out of bounds, if user tries to leave area, x or y is increased or decreased accordingly
if (x < 0 || y < 0 || x > 3 || y > 3) {
System.out.println("Out of bounds");
if (x < 0) {
x++;
} else if (y < 0) {
y++;
} else if (x > 3) {
x--;
} else if (y > 3) {
y--;
}
}
//message showing user x and y coordinates
System.out.println("x =" + x + " y =" + y);
} while (y != bady && x != badx); //what checks to see if user has come across the bad square
//ending message (game ends)
System.out.println("Bad Square. Game over.");
}
Your while(y != bady && x != badx) test tests y isn't bad AND x isn't bad therefore it only takes one of these to be false for your loop to cease.
An easy fix might be to swap your logic around a little.
while(!(y == bady && x == badx))
If you think about how your conditional statement is phrased while(y != bady && x != badx) you will see that when either x = 1 or y = 3, one of the sides in the AND statement evaluates to false and causes the whole condition to be false. You could handle it by instead writing:
while(y != bady || x != badx)
Just set logic OR in condition
while(y != bady || x != badx);
&& matters that both conditions should be true

If the two cars meet at any point print yes else no?

Here x1 and v1 are initial position and velocity of car1, and x2 and v2 for car2. I need to find if the two cars meet at any point. It gives me error displaying "No" always.Any suggestions?
if (v1 > v2) {
while ((x1 + (v1 * i)) > (x2 + (v2 * i))) {
if ((x1 + (v1 * i)) == (x2 + (v2 * i))) {
prime = true;
break;
}
System.out.println(""+i);
i++;
}
if (prime == true) {
s = "Yes";
} else {
s = "No";
}
}
if (v2 > v1) {
while ((x2 + (v2 * i)) > (x1 + (v1 * i))) {
if ((x1 + (v1 * i)) == (x2 + (v2 * i))) {
prime = true;
break;
}
System.out.println(""+i);
i++;
}
if (prime == true) {
s = "Yes";
} else {
s = "No";
}
}
if (v1 == v2) {
if (x1 == x2) {
s = "Yes";
} else s = "No";
}
System.out.println(""+s);
}
}
This is a mathematical question not so much a programming one. Basically you don't need any loops and stuff to answer it. I assume (since there are no other implications) that both cars go in the same X direction with speed V where both X and V are positive numbers.
So basically your logic can be -> If the faster car is behind the slower one they will eventually meet. Otherwise they won't. And in this case you won't need any loops. The last check in the example below is if they are already in the same spot.
if((x1<x2 && v1>v2) || (x1>x2 && v1<v2) || (x1==x2)) {
System.out.println("Yes");
} else {
System.out.println("No");
}
If V can be negative (for example to show going backwards which is a bit strange way because velosity cannot be negative) then it is still the same. You might go for a loop only if you want to know the point on the vector X where they met. But with some calculations you can still calculate it without loops. For example :
int vDiff=Math.abs(v1-v2);
int xDiff=Math.abs(x1-x2);
System.out.println("Meeting point: "+(((double)xDiff)/((double)vDiff)*v1+x1));
I think you're complicating the problem, with your iterations you're essentially finding the time step at which the cars meet, if they do meet.
There are actually only five possibilities for these two cars, when considered in one direction:
1) Car 1 is ahead of car 2, and moving faster than or the same speed as car 2 => Cars never meet
2) Car 1 is behind car 2, and moving faster than car 2 => Cars meet
3) Car 1 is ahead of car 2, and moving slower than car 2 => Cars meet
4) Car 1 is behind car 2, and moving slower than or the same speed as car 2 => Cars never meet
5) Cars have already met.
In code this might look like the following:
boolean carsMeet(x1,v1,x2,v2){
boolean output = false;
if(x1 > x2){
// Conditions 1 and 3. Car 1 is ahead of car 2
if (v2 > v1){
// Condition 3
output = true;
}
} else if (x1 < x2){
// Conditions 2 and 4. Car 2 is ahead of car 1
if (v1 > v2){
// Condition 2
output = true;
}
} else {
// Condition 5. Car 1 has already met car 2
output = true;
}
return output;
}
I haven't run this code to check it for syntax errors, but in general this is how I advise tackling the problem, rather than your current approach.
s = "No";
if (x1 == x2) {
s = "Yes";
} else if (v1 == v2) {
s = "No";
} else if ((x2-x1)/(v1-v2) > 0) {
s = "Yes";
}

Calculating how far a robot will move in Java

I'm working on a project for school that requires me to move a robot. How far the robot will move each second (variable t) is calculated by the function below.
The first function is easy. The 2nd and 3rd on the other are where I'm stuck. How would I write F(t-1)? Below is what I have so far.
if (t == 0) {
distance = 2;
} else if (t > 0 && <=6 || t > 12) {
// No clue on how to write the 2nd distance equation.
} else if (t >= 7 && <=12) {
// No clue on how to write the 3rd distance equation.
}
Recursion really isn't necessary to solve this.
Note that in each of the non-zero time cases, F(t) = F(t-1) + something.
So you can simply do:
double f = 2; /* Initial value at t=0 */
for (int t = 1; t <= maxT; ++t) { // maxT is the maximum value of t.
if (t <= 6 || t > 12) {
f += /* something for case 2 */;
} else {
f += /* something for case 3 */;
}
}
System.out.println(f);
You can do this with recursion, but you will get a StackOverflowError if maxT becomes modestly large; by contrast, using a loop will work for arbitrarily large maxT (modulo floating point errors).
As pointed out by #Andreas, you can do this without looping over all values of t:
double f = 2 * (maxT + 1);
for (int t = 7; t <= maxT && t <= 12; ++t) {
f += log(t) - 2;
}
and you can eliminate that loop too by precomputing the values.
This is a problem which involves the use of recursion. By and large, pay close attention to the notation Ft-1, since that refers to an evaluation of the specific function at t-1.
I won't write out all of the code, but I'll give you some of the basics:
When t = 0, return 2. This is your base case.
When t is between 0 and 6 inclusive or greater than 12, return an evaluation of the function at t-1 and add 2.
When t is between 7 and 12 both inclusive, return an evaluation of the function at t-1 and add log2(t).
Here's something to get you at least started in the right direction.
public double evaluateDistance(int t) {
if(t == 0) {
return 2;
} else if(t > 0 && t <= 6) || (t > 12) {
// Think about this - it would involve another call to evaluateDistance, but what is t again?
} else if(t >= 7 && t <= 12) {
// Another evaluation involving the function.
// For free, the change of base operation you'll need to get base-2 evaluation for the log:
return ??? + Math.log(t)/Math.log(2);
}
}
Think I figured it out. Sorry if I wasn't clear on what I needed, just needed to figure out how to write the equations in the function. Think I figured it out though.
public double move()
{
int t = 0;
if(t == 0) // After the first second, robot moves 2
{
distance = 2;
}
else if(t > 0 && t <= 6 || t > 12) // From seconds 0 to 6 and after 12, robot moves distance equation
{
distance = (2*t)+2;
}
else if(t >= 7 && t <= 12) // From seconds 7 to 12, robot moves distances equation
{
distance = (2*t)+(Math.log(t)/Math.log(2));
}
position = position + distance;
return position;
}
}

How to check if an interval contains power of two

I'm working on Java. I'd like some help with the following. So, given a specific interval (int low, int high), how can we check if it contains any number that is power of two? My method to check if a number is a power of two is:
private static boolean isPowerOfTwo(int n){
if( n == 0 || n == 1){
return false;
} else if( (n & -n) == n ){
return true;
}
else{
return false;
}
}
The method I've done to check if there is any number that is power of two in the interval is:
private static boolean ContainsPowerOfTwo(int low, int high){
boolean f = false ;
if (isPowerOfTwo(low) || isPowerOfTwo(high)){
return true;
}
for (int i = low; low <= high; i++){
if ( (low & -low ) == low && low!=0 && low!=1 ) {
f = true;
break;
}
}
if ( f == true ){
return true;
}else{
return false;
}
}
Apparently, I'm doing something wrong. If I set the interval to be: (0, 1), I do not get any message on my main program:
int high = readInt(" Please insert the number: ");
rgen = new RandomGenerator();
int random = (int) rgen.nextInt(0, high);
while (valid){
if(high<0) {
println( " The highest value must be positive. ");
high = readInt(" Please insert the highest value: ");
}else if(ContainsPowerOfTwo(0, high)==false){
println(" There are no power of two numbers in this interval.");
println("-1");
valid = false;
break;
}else{
valid=false;
}
}
while(flag2){
if(isPowerOfTwo(random) == false) {
rgen = new RandomGenerator();
random = (int) rgen.nextInt(0, high);
}else{
println(" The random generated number that is power of two is: " + random);
flag2=false;
}
}
Can you please help me find the issue(s)?
You can use Long functions to make this easier.
public static boolean powerOf2InRange(long low, long high) {
return Long.bitCount(low) == 1 ||
Long.bitCount(high) == 1 ||
Long.highestOneBit(low) != Long.highestOneBit(high);
}
If you only need to assess the existence of a power of two and not its value, it would be enough by using Bolzano's theorem:
private static boolean ContainsPowerOfTwo(int low, int high){
if(isPowerOfTwo(low) || isPowerOfTwo(high))
// Checking the extremes
return true;
else
// If the integer part of the logarithms are different, there must be a number within the interval where the logarithm is exact (Bolzano's theorem)
return (Math.floor(log(high, 2)) > Math.floor(log(low, 2)))
}
private static double log(int x, int base) {
return (Math.log(x) / Math.log(base));
}
It looks like the code:
for (int i = low; low <= high; i++){
if ( (low & -low ) == low && low!=0 && low!=1 ) {
f = true;
break;
}
}
Would result in an infinite loop. Your for loop will run if low <= high, since your loop doesn't change the value of low this will always be true and your loop will run forever. I suspect you meant i <= low.
There are a few other areas which could be improved, but if that infinite loop is the case then perhaps overcoming that can get you started. Are you using an IDE? You can debug your code and step through it to see if the flow is as you'd expect. This should highlight where the code deviates from what you expect.
A bit different approach not to check all the values in the given interval. Because the function power-of-2 is strictly increasing, I have taken the log2 of the interval limits and checked them.
public class Main {
public static void main(String[] args) {
containsPowerOfTwo(43, 64);
containsPowerOfTwo(31, 63);
containsPowerOfTwo(32, 63);
containsPowerOfTwo(33, 63);
containsPowerOfTwo(33, 64);
containsPowerOfTwo(55, 127);
containsPowerOfTwo(56, 128);
containsPowerOfTwo(34, 127);
}
private static boolean containsPowerOfTwo(int low, int high) {
double log2Low = log2(low);
// System.out.println("log2Low: " + log2Low);
double log2High = log2(high);
// System.out.println("log2High: " + log2High);
double floorlog2Low = Math.floor(log2Low);
// System.out.println("floorlog2Low: " + floorlog2Low);
double floorlog2High = Math.floor(log2High);
// System.out.println("floorlog2High: " + floorlog2High);
boolean retVal = log2High == floorlog2High || log2Low == floorlog2Low || floorlog2High - floorlog2Low >= 1;
System.out.println(String.format("%d - %d %B ",low ,high, retVal));
return retVal;
}
private static double log2(int value) {
return Math.log(value) / Math.log(2);
}
}
Output:
43 - 64 TRUE
31 - 63 TRUE
32 - 63 TRUE
33 - 63 FALSE
33 - 64 TRUE
55 - 127 TRUE
56 - 128 TRUE
34 - 127 TRUE

Java Conditions Confusion? (Beginner)

The aim of this program is to make a Rock Paper Scissors game. I have succeeded in making it however I can not get it to loop no matter what I try. I tried:
while (index = 0)
while (index < gamesCount)
However, while my index is 0 and my condition says while (index != 0), it seems to be the only condition that runs the program but it will not loop regardless. How can I get my game to loop?
import java.util.Scanner;
import java.util.Random;
public class RockPaperScissors {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Random randomGen = new Random();
//Variables
String player1;
int cpu;
int start = 1;
int end = 3;
int index = 0;
// 1 = Rock | 2 = Scissors | 3 = Paper
//Code
System.out.println("Welcome to Rock, Paper, Scissors!");
while (index != 0) {
System.out.print("Rock, Paper, or Scissors?: ");
player1 = in.nextLine();
cpu = randomGen.nextInt(3);
System.out.println(cpu);
if (player1.equals("Rock") && (cpu == 2)) {
System.out.println("You lose!");
} else if (player1.equals("Rock") && (cpu == 1)) {
System.out.println("You win!");
} else if (player1.equals("Rock") && (cpu == 0)) {
System.out.println("Draw!");
}
// --------------------
if (player1.equals("Scissors") && (cpu == 2)) {
System.out.println("Draw!");
} else if (player1.equals("Scissors") && (cpu == 1)) {
System.out.println("You win!");
} else if (player1.equals("Scissors") && (cpu == 0)) {
System.out.println("You lose!");
}
//---------------------
if (player1.equals("Paper") && (cpu == 2)) {
System.out.println("You lose!");
} else if (player1.equals("Paper") && (cpu == 1)) {
System.out.println("You win!");
} else if (player1.equals("Paper") && (cpu == 0)) {
System.out.println("Draw!");
}
}
}
}
You have your index variable set to 0. The condition of the while loop is saying, if index does not equal 0, execute the code in the loop. Since your index equals 0, the instructions in the loop will not be executed. Also, you will need to update the index variable in the loop so that if the condition you are looking for is met, the code will stop looping.
ie:
int gamesPlayed = 0;
int gamesRequested = 3; // or get this from the user
while (gamesPlayed < gamesRequested){
String player1Choice = in.nextLine();
if(!"".equals(player1)){
// your code
gamesPlayed++;
} else {
System.out.print("Rock, Paper, or Scissors?: ");
}
}
Two mistakes:
while (index != 0);
this is the entire loop. it ends either at the end of the { } block (which you don't have), or at the first ; which is immediately after the statement.
Correct this, though, and it still won't loop:
int index = 0;
// 1 = Rock | 2 = Scissors | 3 = Paper
//Code
System.out.println("Welcome to Rock, Paper, Scissors!");
while (index != 0);
index = 0, so (index != 0) will never return true.
Your index variable is set to a value of 0.
Your while loop says
while (index != 0);
Which means, while the index isn't 0, run my code. The problem is your code will never run then because your index value is always 0.
Try changing it to another value (say 5 for example), and it should work now.
:)

Categories

Resources