Saving branching possibilities easily (Java) - java

Since my last question got locked for beeing inprecise, one more try:
Lets say I start at
branch[0]
branch[0] only has an int value of 30.
Now I have two choices. Left or right.
Both have a random chance to multiply/be divided by up to 5.
So left could be 6,8,10,15,30,30,60,90,120,150. Same for right.
This choice happens for up to 30 times for every branch. so 2^30 times.
(disregard the chance of having an insanely large number, it is just an example that is easiest to understand)
Now I want to be able to know which ENDRESULT has the highest value.
AND once I know that, I also need to know the exact path it followed (l,r,l,l,l,r,l...) so I can tell myself at branch[0] which way to go.
HOW can I do this efficiently?
Because every method I thought of is either super complex or would take years to calculate and be super messy. And if possible, this way needs to work with more than just two choices.
edit
Example:
I start at a point. That point has gold = 0 as a value.
I have two options. Left and right.
Left has gold = 15; Right has gold = 25.
If I go left from the left again (LeftLeft) gold = 25;
If I go right from the left, (LeftRight) gold = 35;
If I go left from the right, (RightLeft) gold = 15;
If I go right from the right again (RightRight) gold = 45;
I need to compare the values of LL, LR, RL, RR to each other and once I know that RR has the highest gold, I need to know how I get there from my original starting position.

Related

Displaying Numbers in Certain Shapes

I just thought of this problem 15 minutes ago and even though it appears insanely easy I'm having a serious problem coming up with an answer.
Basically what I would like to do is based on a number (n) given by the user, I would like to draw a square shape.
Example: let's say the user gives the number 2, the result should be:
12
43
Now, suppose the user gives the number 3, the result should be:
123
894
765
etc..
Please don't give me the solution to this problem, I just want a clue or two to get me going.
I thought about doing it with a simple java class but I'm still struggling to get past the first condition:
public class DrawSquareWithNumbers {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter your number: ");
int number = scanner.nextInt();
for (int i = 0; i <= number; i++) {
if (i<number)
System.out.print(i);
if (i>=number) {
System.out.println("\n"+i);
}
}
}
}
Any tip? Thanks in advance.
So I think I just put way too much time in this but it's a fun challenge so I thought let's give it a go.
I implented a code version for this solution and it works quite well although it's probably not the cleanest as I approached the whole problem backwards.
Here is my solution to try out online (note it's severely unoptimized and by no ways good Java code. It's a quick and dirty implementation to be honest):
https://ideone.com/97JB7Y
So the idea is quite simple: We first calculate the correct value for each position in a matrix and then we print that matrix out.
Let's go over it in a bit more detail:
We start of by creating the Matrix for our values to print:
With a given size n this is
int[][] values = new int[n][n];
Now we want to calculate the correct value at each point. I chose to tackle it the "wrong way" around by not starting at the first point but at the center of the spiral.
Basically imagine this matrix with n = 3:
[1][2][3]
[8][9][4]
[7][6][5]
Instead of at 1 I just start at 9. Reasoning for this is that it's actually easier to calculate the position spiraling out from a point over spiraling in to a point.
So starting at this center point we spiral out from there in a circular fashion. For the matrix
[1][2]
[4][3]
this means we visit 4 -> 3 -> 2 -> 1. And then just save the correct value in the matrix.
Only problem with my approach is that for a matrix with uneven size (3, 5, 7, etc.) I still visit the points in spiraling order, for 3x3 the order of visiting is e.g. 9 -> 4 -> 3 -> 2 -> 1 -> 8 -> 7 -> 6 -> 5, as visualized in this perfect picture I totally drew in Paint:
This leads to the result matrix being inversed as such:
[5][6][7]
[4][9][8]
[3][2][1]
This small problem is easily fixed though by simply printing the matrix out inversed once more should n%2 != 0.
Hope I could help with maybe a different approach to the problem.
I think you want to make nxn matrix with user entered number. So you can check the input and then you can use loop as for(i=1; i<=n; i++) for rows and similarly for column(for j=0;j<=n;j++) and then you can print your desired shape. Since you have asked to give you idea only so I am not posting any code here. If in case you get stuck somewhere you can refer : https://www.google.com/amp/s/www.geeksforgeeks.org/print-a-given-matrix-in-spiral-form/amp/
Ok, let's give this a try. First let's assume you'll have to store the matrix before printing it and that there's no magic formula that allows you to print what you need in a single iteration.
Now, you've the NxN matrix, for example for 3 it'd be 3x3, 9 positions. Instead of solving it with a series of ifs in an ugly way, you could use direction vectors for a cleaner solution. Also assume for now that you've another NxN matrix filled with booleans, all set to false, that will represent the already printed positions in the NxN matrix that you will print in the end. When you write a number in the final NxN matrix, you put the same position's boolean to true in the boolean matrix.
So for example, you want to print the positions of the first row, 1 2 3. You are displacing to the right to print. This'd be the direction (1,0), aka the starting direction vector. You advance through the NxN matrix using this coordinates. When you go outside the matrix (in the example, your x position is 3) you decrease your x position by one and you "spin" your direction vector (this should be done in a separate function). (1,0) would spin to (0,-1). You keep using this vector to iterate your matrix, spinning as necesary. After the first whole circle, you will get to an already printed position before going outside the matrix. So after every print you've to check not only if you go outside the matrix, but also if that position has already a number on it. For this, you use the boolean matrix.
This is how I'd solve it, there are probably many other ways (and better ones). For starters you could use null, or a mark, in the final matrix and save yourself the booleans one.
Create the result matrix beforehand, and declare a variable for the current number, starting value = 1, the current co-ordinates, starting with (0,0), the stepping direction starting with "to the right"
Start loop
Calculate the co-ordinates of next step, and check it
If it is off the matrix, then change direction, and re calculate, re-check
If free, then put the number in the matrix, increment it, and loop
If it is not free, then end loop, print out result matrix

Java: How to check if a generated level is possible?

I've created a text based game which automatically generates a map with 10x10 rooms, a few of the rooms are blocked by various debris and I couldn't work out the most efficient way to check if a player can still reach a key and get to the exit without them being cut off from the map.
Currently there's a low chance needed rooms are cut off from the rest of the map, making the level impossible, I thought about checking each adjacent square to the start position, and then repeat and repeat until all of the squares that are accessible are set to 'accessible' in a variable and then if the three objects aren't reachable just regen'ing the map again until they are.
This may be slow if it regens a few times though.
Does anyone have any thoughts on the repetitive part to keep it fast, or a better way of achieving this?
Here's an image of a generated map: #'s are blocked rooms.
http://postimg.org/image/8oo88jxgb/
You can use the Dijkstra's algorithm, or some other pathfinding algorithm, to check if there is a way from the room entrance to each object and then discard the invalid rooms. This would probably be a bit slow though, specially if the rooms get bigger or you add more objects.
A better option would be to guarantee by construction that each part of the room can be reached. This can be achieved using Binary Space Partioning (BSP). It can be used to create random dungeons while assuring that all the rooms are connected. You can find more information in this tutorial.
There is a lot of material about procedurally generated dungeons around. You can check another interesting tutorial here.
The real problem is that programmers have spent far too much time
worrying about efficiency in the wrong places and at the wrong times;
premature optimization is the root of all evil (or at least most of
it) in programming.
Donald Knuth (1974 Turing Award Lecture, Communications of the ACM 17 (12), (December 1974), pp. 667–673)
Taking Knuth's advice, I recommend implementing the simplest solution that comes to mind (as outlined in the question, for example) and only looking for a more efficient algorithm if that approach turns out to be a bottleneck in the program. If he was right for computers with the performance they had in 1974, he's much more right now ...
You could represent your board as a graph holding a coordinate value as the key and a set of coordinates as the values representing each coordinates neighbors..example Map<Coordinate, HashSet<Coordinate> = new Hashmap<Coordinate, HashSet<Coordinate>();.
Then populate the graph with each coordinate value as a key with their respective neighbors as their values.
Whenever a blocked off room appears, simply remove that coordinate from each of the coordinates neighbors that surround it.
So if you have coordinate (5,5) as a blocked room, you would removed (5,5) from (4,5)s neighbor set, (5,4)s neighbor set, (6,5)s neighbor set, and (5,6)s neighbor set. This would basically not allow you to move through this path any more.
To populate the graph you could use two loops:
for(int r = 0; r <= 10; r++){
for(int c = 0; c <= 10; c++){
HashSet<Coordinate> neighbors = new HashSet<Coordinate>();
if(r > 0){
neighbors.add(new Coordinate(r - 1, c));
}
if(r < 8){
neighbors.add(new Coordinate(r + 1, c));
}
if(c > 0){
neighbors.add(new Coordinate(r, c - 1));
}
if(c < 8){
neighbors.add(new Coordinate(r, c + 1));
}
graph.put((new Coordinate(r,c)), neighbors);
}
}
I hope this is what you were asking for.
Make an array A with a row for each room and a column for each room.
Put a 1 in each i, j (row,column) position if the two rooms are connected.
This matrix( A ) is the numeric representation of the graph that is your game, the nodes of the graph are rooms and the edges are doors.
Now take a vector with a length corresponding to the number of rooms you have and fill it with zeros except for a one in the position corresponding to the room you start in. This vector( P ) is the number of ways you can get to a given room after 0 transitions. To check if it is possible to get to a given room in ( n )transitions simply multiply P A^n and look for a non zero value in the position in the vector that represents the given room.
this is a generalization of maths described well here https://en.wikipedia.org/wiki/Markov_chain

Fix collision detection penetration

I am implementing collision detection in my game, and am having a bit of trouble understanding how to calculate the vector to fix my shape overlap upon collision.
Say for example, I have two squares. squareA and squareB. For both of them, I know their xCo, yCo, width and height. squareA is moving however, so he has a velocity magnitude, and a velocity angle. Let's pretend I update the game once a second. I have illustrated the situation below.
Now, I need a formula to get the vector to fix the overlap. If I apply this vector onto the red square (squareA), they should not be overlapping anymore. This is what I am looking to achieve.
Can anyone help me figure out the formula to calculate the vector?
Bonus points if constructed in Java.
Bonus bonus points if you type out the answer instead of linking to a collision detection tutorial.
Thanks guys!
Also, how do I calculate the new velocity magnitude and angle? I would like sqaureA to continue moving along the x axis (sliding along the top of the blue square)
I had an function that looked something like this:
Position calculateValidPosition(Position start, Position end)
Position middlePoint = (start + end) /2
if (middlePoint == start || middlePoint == end)
return start
if( isColliding(middlePont) )
return calculateValidPosition(start, middlePoint)
else
return calculate(middlePoint, end)
I just made this code on the fly, so there would be a lot of room for improvements... starting by not making it recursive.
This function would be called when a collision is detected, passing as a parameter the last valid position of the object, and the current invalid position.
On each iteration, the first parameter is always valid (no collition), and the second one is invalid (there is collition).
But I think this can give you an idea of a possible solution, so you can adapt it to your needs.
Your question as stated requires an answer that is your entire application. But a simple answer is easy enough to provide.
You need to partition your space with quad-trees
You seem to indicate that only one object will be displaced when a collision is detected. (For the case of multiple interpenetrating objects, simply correct each pair of objects in the set until none are overlapping.)
Neither an elastic nor an inelastic collision is the desired behavior. You want a simple projection of the horizontal velocity (of square A), so Vx(t-1) = Vx(t+1), Vy(t-1) is irrelevant and Vy(t+1)=0. Here t is the time of collision.
The repositioning of Square A is simple.
Define Cn as the vector from the centroid of A to the vertex n (where the labeling of the vertices is arbitrary).
Define A(t-1) as the former direction of A.
Define Dn as the dot product of A(t-1) and the vector Cn
Define Rn as the width of A measured along Cn (and extending past the centroid in the opposite direction).
Define Sn as the dilation of B by a radius of Rn.
Let j be the vertex of B with highest y-value.
Let k be the vertex that is most nearly the front corner of A [in the intuitive sense, where the value of Dn indicates that Ck is most nearly parallel to A(t-1)].
Let K be the antipodal edge or vertex of A, relative to k.
Finally, translate A so that k and j are coincident and K is coincident with Sk.

How to Traverse A Square from Greatest Distance (Java)

I'm working on a program where I need to traverse a square from greatest distance to shortest distance, when starting from the center and given a maximum range that the object can travel.
The traversal would look something like this, each step is labeled starting from 0 to 35 (sorry for crappy diagram). Max distance would be 3 from center:
I was thinking it could work in two for loops, but I don't think that will work anymore without a ton of if statements. I want it to be semi-efficient if possible.
I don't need any code, just some ideas on how to get it to work (although feel free to post whatever).
Thanks for your help guys.
The simplest approach I can think of would involve 5 loops - one for each direction (all separate loops), and then one for the distance from the outside (which would be the outer-most loop).
The outer-most loop's value would allow us to determine where each loop should start and end.
As a rough draft, I imagine it would look something like this:
for i = 0 to n
for x = i to (n-i-1)
// process matrix[x][i]
for y = i to (n-i-1)
// process matrix[n-i][y]
for x = (n-i) downto i
// process matrix[x][n-i]
for y = (n-i) downto i
// process matrix[i][y]
I'll leave it to you to write the actual code.

Parbolic Equation using 3 points

Alright so I need to make a parabola that stretches across the length of my World. (W)
I am creating this in a world where the top left corner is (0,0)
my 3 points are from left to right, (x,y)
(0,H)
(W/2,0) << vertex
(W,H)
This would be from the bottom left corner of the world, to the vertex in the top center of the world, to the bottom right corner of the world.
I am sure I made this so much more complicated then it needed to be, but I fried my brain attempting to figure it out.
Also the way this would work is I would want a graphic to travel the parabola over a given amount of time.
so I would make a function to get the Y, and I would send it the X which would range from 0 to W, depending on the time elapsed.
so i would call the function,
GetPathY((WorldWidth*Percentage));
private int getPathY(double X) {
int y = (int) ScreenHeight-((4 * ScreenHeight* X)/(WorldWidth^2))
return(y);
}
would this work i think?
So: y=(((-4*ScreenHeight)/(WorldWidth^2))(x-(WorldWidth/2)^2)) or: y = H-((4Hx)/(W^2));
What's the equation for a parabola?
y(x) = c0 + c1*x + c2*x^2
You have three points:
y(0) = c0 = H
And another:
y(W/2) = H + c1*(W/2) + c2*(W/2)^2 = 0
You can solve this for either c1 or c2. Let's do it for c2:
c2 = -4H/W^2 - 2c1/W
Then there's the last equation:
y(W) = H + c1*(W) + c2*(W^2) = H
Subtract H from both sides gives:
c1*W + c2*W^2 = = 0
Simplify this one to get c1:
c1 = -c2*W
Substitute the coefficient that you solved for in the second equation into this one to get the third and you're done.
It's just algebra.
I actually made a second way to do it.
1st way I got by rearranging y=a(x-h)^2+k, to solve for 'a'
y=(WindowHeight/((WindowWidth/2)^2)*(x-(WindowWidth/2))^2
2nd way, just make two percentiles, one for up, one for horizontal. As time goes scale the X-axis percentile from 0-100% and Y-axis from 0-100% halfway into the time and then back down from 100-0% all you had to do is for the Y-axis add in a modifier so that it starts fast and slows down as it reached 100%. This will provide the curve.
Of course, the equation is easier :)
I would appreciate if you did not delete this post, because My answer was fundamentally different then the other guys, and both my solutions are valid and also different. I used nothing of his answer to obtain my own, and both these solutions may help someone else who is attempting to solve something similar in the future. Also in the reason that the first answer did not help to solve the problem in the way which it was described.

Categories