Newbie programmer here, using Java 8. I'm trying to build a PacMan game and am working on the method that builds the grid. My opening comments for the program tell you everything you need to know. I'm stuck on trying to connect the random # generator's variable to printing an equal # of cookies ("O"), and fill the rest of the array with dots (".").
/**
* This program is meant to get dimensions for a 2D array from the player.
* A grid is then displayed to player's specs filled with dots and cookies.
* The cookies must compose 20% of the total grid and be randomly
* distributed. The user will then be offered a menu of options to either
* turn left or right, or move, or exit the game. The player's choice moves
* "PacMan" around grid to eat cookies. The grid must be displayed throughout
* the game showing changes as player continues moves. If a cookie is eaten,
* a statement is printed that indicates a cookie was eaten and adds 1 to
* your score. At the end of the game, it tracks the number of moves it took
* to eat all the cookies.
*/
import java.util.Scanner;
public class PacManGame
{
public static void main(String[] args)
{
int X, Y; //Variables for number of grid rows X, and columns Y
Scanner input = new Scanner( System.in );
System.out.println();
System.out.print( "Enter the number of rows you would like in your game grid: " );
X = input.nextInt();
System.out.println();
System.out.print( "Enter the number of columns you would like in your game grid: " );
Y = input.nextInt();
System.out.println();
buildGrid(X, Y); // Calls buildGrid method
} // Closes main method
public static void buildGrid(int X, int Y) // Method for actually building the grid
{
int gameGrid [][] = new int [X][Y]; // Array built from user's input for dimensions
int totalGridSize = X * Y; // Gets the total grid size
double cookieTotal = totalGridSize * (.2); // Calculates the 20% of cookies that will be on grid
int theCookies = (int)(cookieTotal*Math.random())+1; //Assigns the randomly generated number
int i, j, k = 0; // Initialize loop counters
for (i = 0; i < X; i++)
{
for (j = 0; j < Y; j++)
{
gameGrid[X][Y] = k;
k++;
System.out.print("." + ("O" * theCookies)); // I know I can't do this, but how to fix?
}
}
} // Closes buildGrid method
} // Closes PacManGame class
It's better to exchange the array coordinates, so that first goes Y, then X. You may keep in your array 1 for cookie and 0 for the rest. To put cookieTotal of cookies you may use the following code:
new Random().ints(0, totalGridSize).distinct().limit(cookieTotal)
.forEach(pos -> gameGrid[pos/X][pos%X] = 1);
Here we generate random numbers from 0 to totalGridSize-1 and get cookieTotal distinct from it. After that we translate these numbers to the coordinates and set the corresponding array element.
To print the gaming field, you need to translate 0 to '.' and 1 to "O":
for (int[] row : gameGrid)
System.out.println(IntStream.of(row).mapToObj(val -> val == 1 ? "O" : ".")
.collect(Collectors.joining()));
Here's the complete body of your buildGrid:
int gameGrid[][] = new int[Y][X];
int totalGridSize = X * Y;
int cookieTotal = totalGridSize / 5;
new Random().ints(0, totalGridSize).distinct().limit(cookieTotal)
.forEach(pos -> gameGrid[pos / X][pos % X] = 1);
for (int[] row : gameGrid)
System.out.println(IntStream.of(row).mapToObj(val -> val == 1 ? "O" : ".")
.collect(Collectors.joining()));
Related
I'm making a tic tac toe game and I have randomily assign player 1 one to either "X" or "O" and same with player 2. I have no clue how to start the code
It should make player one either X or O and make player 2 whatever is left over from player 1
You can generate a random number between for example 0 and 1 by using a random object or the Math.Random() function.
Based on the random number you can select via if and else, which letter "X"/"O" the first player will get.
The second player can then be assigned what is left.
Have look on Math.Random:
Math.random() explanation
public class RandomTicTacToeSymbols {
public static void main(String args[]) {
String[] symbols = {"X" , "O"};
int randomIndex = (int) Math.round( Math.random());
String playerOneSymbol = symbols[randomIndex];
String playerTwoSymbol = symbols[(randomIndex+1) % 2];
System.out.println(String.format("Player 1 -> %s - Player 2 -> %s", playerOneSymbol, playerTwoSymbol) );
}
}
PROBLEM
I am working on a code where I am simulating a dog walking in a city - trying to escape the city. The dog makes random choices of which way to go to at each intersection with equal probability.If stuck at a dead end the dog will come directly back to the middle of a big city and start all over again. The dog will do this again and again until it gets out of the city or until it gets tired after T number of trials. But by the time the the dog starts again from the middle(N/2,N/2) on each try, it will have forgotten all the intersections it had visited in the previous attempt.
IDEA
The idea is to mimic a code given in our textbook and come up with the solution. We were given input N, T - where N is the number of north-south and east-west streets in the city and T is the number of times the dog will try to get out of the city before it gives up. We have to draw it out, using StdDraw. We have been given how to make random movements - generate a number between 0 and 4 - up: 0 right: 1 down: 2 left: 3
My Approach
import java.util.Random;
public class RandomWalk {
private static final Random RNG = new Random (Long.getLong ("seed",
System.nanoTime()));
public static void main(String[] args) {
int N = Integer.parseInt(args[0]); // lattice size
int T = Integer.parseInt(args[1]); // number of trials
int deadEnds = 0; // trials resulting in a dead end
StdDraw.setCanvasSize();
StdDraw.setXscale(0,N);
StdDraw.setYscale(0,N);
// simulate T self-avoiding walks
for (int t = 0; t < T; t++) {
StdDraw.clear();
StdDraw.setPenRadius(0.002);
StdDraw.setPenColor(StdDraw.LIGHT_GRAY);
for(int i=0;i<N;i++){
StdDraw.line(i, 0, i, N);
StdDraw.line(0, i, N, i);
}
StdDraw.setPenColor(StdDraw.RED);
StdDraw.setPenRadius(0.01);
boolean[][] a = new boolean[N][N]; // intersections visited
int x = N/2, y = N/2; // current position
// repeatedly take a random step, unless you've already escaped
while (x > 0 && x < N-1 && y > 0 && y < N-1) {
int t_x = x;
int t_y=y;
// dead-end, so break out of loop
if (a[x-1][y] && a[x+1][y] && a[x][y-1] && a[x][y+1]) {
deadEnds++;
break;
}
// mark (x, y) as visited
a[x][y] = true;
// take a random step to unvisited neighbor
int r = RNG.nextInt(4);
if (r ==3) {
//move left
if (!a[x-1][y])
t_x--;
}
else if (r == 1 ) {
//move right
if (!a[x+1][y])
t_x++;
}
else if (r == 2) {
//move down
if (!a[x][y-1])
t_y--;
}
else if (r == 0) {
//move up
if (!a[x][y+1])
t_y++;
}
StdDraw.line(t_x, t_y, x, y);
x = t_x;
y = t_y;
}
System.out.println("T: "+t);
}
System.out.println(100*deadEnds/T + "% dead ends");
}
}
ISSUE
Given N - 15, T - 10, -Dseed=5463786 we should get an output like - http://postimg.org/image/s5iekbkpf/
I am getting - see http://postimg.org/image/nxipit0pp/
I don't know where I am going wrong. I know this is very specific in nature, but I am really confused so as to what I am doing wrong. I tried all 24 permutations of 0,1,2,3 but none of them gave the output desired. So, I conclude that the issue in in my code.
check your StdDraw.java with:
http://introcs.cs.princeton.edu/java/stdlib/StdDraw.java.html
your code should be fine, I got the expected result
I'm a student in a Java Programming class. My problem deals with an interpretation of the Monte Carlo Simulation. I'm supposed to find the probability that three quarters or three pennies will be picked out of a purse that has 3 quarters and 3 pennies. Once a coin is picked it is not replaced. The probability should be 0.1XXXXXXX. I keep getting 0 or 1 for my answer. This is what i have so far.
public class CoinPurse {
public static void main(String[] args) {
System.out.print("Probability of Drawing 3 coins of the Same Type - ");
System.out.println(coinPurseSimulation(100));
}
/**
Runs numTrials trials of a Monte Carlo simulation of drawing
3 coins out of a purse containing 3 pennies and 3 quarters.
Coins are not replaced once drawn.
#param numTrials - the number of times the method will attempt to draw 3 coins
#returns a double - the fraction of times 3 coins of the same type were drawn.
*/
public static double coinPurseSimulation(int numTrials) {
final int P = 1;
final int Q = 2;
int [] purse = {Q, Q, Q, P, P, P};
int [] drawCoins = new int[3];
for (int draw = 0; draw < 3; draw ++) {
int index = (int)(Math.random() * purse.length);
drawCoins[draw] = purse[index];
int [] newPurse = new int[purse.length-1];
int j = 0;
for (int i =0; i < purse.length; i++) {
if (i == index) {
continue;
}
newPurse[j] = purse[i];
j++;
}
purse = newPurse;
}
double number = 0.0;
double result = 0.0;
for (int i = 0; i < numTrials; i++) {
result++;
for (int j = 0; j < numTrials;j++) {
if(drawCoins[0] == drawCoins [1] && drawCoins[1] == drawCoins[2]) {
number++;
}
}
}
return number/result;
}
}
The reason you only ever get 0 or 1 is that you only draw (or pick) coins from the purse once, but you then test that draw numTrials * numTrials times. You have two loops (with indices i and j) iterating numTrials time - your logic is a little messed up there.
You can put the first loop (for drawing coins) within a second loop (for running trials) and your code will work. I've put a minimal refactor below (using your code as closely as possible), with two comments afterwards that might help you some more.
public class CoinPurse
{
public static void main(String[] args)
{
System.out.print("Probability of Drawing 3 coins of the Same Type - ");
System.out.println(coinPurseSimulation(100));
}
/**
* Runs numTrials trials of a Monte Carlo simulation of drawing 3 coins out
* of a purse containing 3 pennies and 3 quarters. Coins are not replaced
* once drawn.
*
* #param numTrials
* - the number of times the method will attempt to draw 3 coins
* #returns a double - the fraction of times 3 coins of the same type were
* drawn.
*/
public static double coinPurseSimulation(int numTrials)
{
final int P = 1;
final int Q = 2;
double number = 0.0;
double result = 0.0;
// Changed your loop index to t to avoid conflict with i in your draw
// loop
for (int t = 0; t < numTrials; t++)
{
result++;
// Moved your draw without replacement code here
int[] purse =
{ Q, Q, Q, P, P, P };
int[] drawCoins = new int[3];
for (int draw = 0; draw < 3; draw++)
{
int index = (int) (Math.random() * purse.length);
drawCoins[draw] = purse[index];
int[] newPurse = new int[purse.length - 1];
int j = 0;
for (int i = 0; i < purse.length; i++)
{
if (i == index)
{
continue;
}
newPurse[j] = purse[i];
j++;
}
purse = newPurse;
}
// Deleted the loop with index j - you don't need to test the same
// combination numTrials times...
if (drawCoins[0] == drawCoins[1] && drawCoins[1] == drawCoins[2])
{
number++;
}
}
return number / result;
}
}
Picking coins code
I have some comments on your routing for drawing coins:
It works correctly
It is rather cumbersome
It would have been easier for you to spot the problem if you had broken this bit of code into a separate method.
I'm going to address 3 and then 2.
Break the drawing code out into a method
private static int[] pickCoins(int[] purse, int numPicks)
{
//A little error check
if (numPicks > purse.length)
{
System.err.println("Can't pick " + numPicks +
" coins from a purse with only " + purse.length + " coins!");
}
int[] samples = new int[numPicks];
// Your sampling code here
return samples;
}
You can now simply call from within your second loop i.e.
drawCoins = pickCoins(purse, 3);
Sampling algorithm
#pjs's answer recommends using Collections.shuffle() and then taking the first 3 coins in your collection (e.g. an ArrayList). This is a good suggestion, but I'm guessing you haven't been introduced to Collections yet, and may not be 'allowed' to use them. If you are - do use them. If not (as I assume), you might want to think about better ways to randomly draw n items from an r length array without replacement.
One (well accepted) way is the Fisher-Yates shuffle and its derivatives. In effect it involves picking randomly from the unpicked subset of an array.
In Java - an working example could be as follows - it works by moving picked coins to the "end" of the purse and picking only from the first maxInd unpicked coins.
private static int[] pickCoins(int[] purse, int numCoins)
{
int[] samples = new int[numCoins];
int maxInd = purse.length - 1;
for (int i = 0; i < numCoins; i++)
{
int index = (int) (Math.random() * maxInd);
int draw = purse[index];
samples[i] = draw;
// swap the already drawn sample with the one at maxInd and decrement maxInd
purse[index] = purse[maxInd];
purse[maxInd] = draw;
maxInd -= 1;
}
return samples;
}
Expected results
You say your expected result is 0.1XXXXXXX. As you're learning Monte Carlo simulation - you might need to think about that a little more. The expected result depends on how many trials you do.
First, in this simple example, you can consider the analytic (or in some sense exact) result. Consider the procedure:
You draw your first coin - it doesn't matter which one it is
Whichever coin it was, there are 2 left in the bag that are the same - the probability of picking one of those is 2 / 5
If you picked one of the matching coins in step 2, there is now 1 matching coin left in the bag. The probability of picking that is 1 / 4
So, the probability of getting 3 matching coins (of either denomination) is 2 / 5 * 1 / 4 == 2 / 20 == 0.1
Your Monte Carlo programme is trying to estimate that probability. You would expect it to converge on 0.1 given sufficient estimates (i.e. with numTrials high enough). It won't always give a value equal to, or even starting with, 0.1. With sufficient number of trials, it's likely to give something starting 0.09 or 0.1. However, if numTrials == 1, it will give either 0 or 1, because it will draw once and the draw will either match or not. If numTrials == 2, the results can only be 0, 0.5 or 1 and so on.
One of the lessons of doing Monte Carlo simulation to estimate probabilities is to have a sufficiently high sample count to get a good estimate. That in turn depends on the accuracy you want - you can use your code to investigate this once it's working.
You need to move the loop where you generate draws down into the numTrials loop. The way you've written it you're making a single draw, and then checking that one result numTrials times.
I haven't checked the logic for your draw carefully, but that's because I'd recommend a different (and much simpler) approach. Use Collections.shuffle() on your set of quarters and pennies, and check the first three elements after each shuffle.
If done correctly, the answer should be 2 * (3/6) * (2/5) * (1/4), which is 0.1.
I am creating a program that shall work like this; First the program reads
the total volume of a transport (e.g. truck) in cubic meters from the keyboard. Next the program calculates how many bags that can be stored in the truck and
displays this information.
I always want to use as many big bags as possible, meaning that I want to use as many of the biggest bags as possible, then when they can not fit anymore of the biggest bags I want to store as many of the middle size bags as possible and when they can not store anymore middle sized bags they use the smallest size bags to fill up whatever space is left.
This is how I am trying to solve this, but the greatest problem remains in the looping or logic part, I don't know how do I loop the things so that I prints out what I want.
package volumecalc;
import java.util.*;
public class BagObject {
Scanner input = new Scanner(System.in);
//volume in cubic meter
int sBag = 10 * 10 * 30; //Size of the smallest bag
int mBag = 50 * 100 * 40; //Size of the middle bag
int bBag = 100 * 200 * 50; //Size of the biggest bag
int transVol;
public void bag() {
System.out.println("Enter the current volume of your transport: ");
transVol = input.nextInt();
if (transVol > bBag) {
//Probaly here or more places, I need help
} else if (transVol < sBag) {
//Probaly here or more places, I need help
}
}
}
Main class:
package volumecalc;
import java.util.*;
public class VolumeCalc {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println(" THIS PROGRAM WILL CALCULATE THE SPACE (IN cubic centimeter) IN TRANSPORT:\n\n");
BagObject bo = new BagObject();
bo.bag();
}
}
This is how I would do it:
int numbBag, nummBag, numsBag;
int remainder;
numbBag = transvol / bBag;
remainder = transvol % bBag;
nummBag = remainder / mBag;
remainder %= mBag;
numsBag = remainder / sBag;
Assuming the transport has no specific shape.
If you want a loop that is reusable for any number of bags you can do this:
const int NUM_BAGS = 3;
//put all your bag sizes here
int[] bags = {bBag, mBag, sBag, /*other bags*/};//Array of bags from largest to smallest
int[] numBags = new int[NUM_BAGS];//Number of each bag in the transport
int remainder = transVol;
for(int varA; varA < NUM_BAGS; varA++)
{
numBags[varA] = remainder / bags[varA];
remainder %= bags[varA];
}
The number of bBags is in numBags[0], mBags in numBags[1] etc., in order from largest to smallest.
so I'm currently working on an assignment that I just can't seem to finish. Well I have everything finished but would like the extra credit. I've been looking around the web and can't really seem to find exactly what I'm looking for.
public class PascalTester
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
System.out.println("Welcome to the Pascal's Triangle program!");
System.out.println("Please enter the size of the triangle you want");
int size = kb.nextInt();
int[][] myArray = new int[size][size];
myArray = fillArray(myArray);
//myArray = calculateArray(myArray);
printArray(myArray); //prints the array
}
private static int[][] fillArray(int[][] array)
{
array[0][1] = 1;
for (int i = 1; i < array.length; i++)
{
for (int j = 1; j < array[i].length; j++)
{
array[i][j] = array[i-1][j-1] + array[i-1][j];
}
}
return array;
}
private static void printArray(int[][] array)
{
for (int i = 0; i < array.length; i++)
{
for (int j = 0; j < array[i].length; j++)
{
if(array[i][j] != 0)
System.out.print(array[i][j] + " ");
}
System.out.println();
}
}
}
The only issue that I'm having now is to properly format the output to look like an actual triangle. Any suggestions would be very helpful at this point in time. Thanks in advance
One approach to this, is, assuming you have all numbers formatted to the same width, is to treat the problem as that of centering the lines.
Java Coding left as exercise to reader but essentially:
for lineText : triange lines
leadingSpacesCount = (80/2) - lineText.length();
print " " x leadingSpacesCount + lineText
Try to use the technique at http://www.kodejava.org/examples/16.html to make an array with array.length - i - 1 spaces (need to add the number spaces between numbers.. and 2 number of 2 digit numbers if any..).
Print this array at the start of the outer for loop.
The challenge here is that you want to start printing at the top of the triangle, but you don't know where to center each row until you get to the last (and widest) row of the triangle. The trick is to not print anything until you know how wide the last row is. One way to do this is to generate all the rows as String (or StringBuilder) objects and compute the maximum width. Then, from the top, center each line by first printing an appropriate number of spaces. The correct number of spaces will be
(maxLineLength - currentLine.length()) / 2
Alternatively, you can simply assume a maximum line length and center all lines in that width. If the longer lines exceed the maximum width, then the triangle will be distorted below a certain row. (Just be sure to not try printing a negative number of spaces!)
If anyone is looking for the actual code to do this take a look at my implementation in Java, it's similar to what Craig Taylor mentioned (numbers formatted to the same width) plus it uses an algorithm to compute the elements without memory (or factorials).
The code has comments explaining each step (calculation and printing):
/**
* This method will print the first # levels of the Pascal's triangle. It
* uses the method described in:
*
* https://en.wikipedia.org/wiki/Pascal%27s_triangle#Calculating_a_row_or_diagonal_by_itself
*
* It basically computes the Combinations of the current row and col
* multiplied by the previous one (which will always be 1 at the beginning
* of each pascal triangle row). It will print each tree element to the output
* stream, aligning the numbers with spaces to form a perfect triangle.
*
* #param num
* # of levels to print
*/
public static void printPascalTriangle(int num) {
// Create a pad (# of spaces) to display between numbers to keep things
// in order. This should be bigger than the # of digits of the highest
// expected number and it should be an odd number (to have the same
// number of spaces to the left and to the right between numbers)
int pad = 7;
// Calculate the # of spaces to the left of each number plus itself
// (this is the width of the steps of the triangle)
int stepsWidth = pad / 2 + 1;
// Now calculate the maximum # of spaces from the left side of the
// screen to the first triangle's level (we will have num-1 steps in the
// triangle)
int spaces = (num - 1) * stepsWidth;
for (int n = 0; n < num; n++) {
// Print the left spaces of the current level, deduct the size of a
// number in each row
if (spaces > 0) {
System.out.printf("%" + spaces + "s", "");
spaces -= stepsWidth;
}
// This will represent the previous combination C(n k-1)
int prevCombination = 1;
for (int k = 1; k <= n + 1; k++) {
System.out.print(prevCombination);
// Calculate how many digits this number has and deduct that to
// the pad between numbers to keep everything aligned
int digits = (int) Math.log10(prevCombination);
if (digits < pad) {
System.out.printf("%" + (pad - digits) + "s", "");
}
// Formula from Wikipedia (we can remove that "+1" if we start
// the row loop at n=1)
prevCombination = prevCombination * (n + 1 - k) / k;
}
// Row separator
System.out.println();
}
}
Hope it helps someone!