I am currently working on designing abstract classes for a possible chess game.
I needed help regarding how to move different pieces(for example queen, knight)
public class MyPiece extends Piece {
#Override
public boolean canMove(int x, int y) {
return (this.x != x && Math.abs(this.y - y) == 1);
}
}
The above code displays a sample for some piece that can just move up and down. It is not a valid chess move. So if i were to move a queen how would i go about?To simply things we are just assuming that we already have a board of matrix (x,y) 8 by 8.
Especially for chess queen it is not so simple. You have to:
determine that the move straight, i.e. horizontal, vertical, or diagonal.
That there are no other pieces on the way.
So,
To determine that move is horizontal check this.x == x && this.y != y
To determine that move is vertical check this.y == y && this.x != x
To determine diagonal check Math.abs(this.x - x) == Math.abs(this.y - y)
Now chose the direction, iterate over the way and check that your matrix does not contain elements in cells that are going to be passed by queen during this move.
You need to think in terms of "Given piece P on location (x,y) on the board which coordinates can the piece move to?". I.e. for a rook on (1,1) you can move to (1,2)..(1,8) and (2,1)..(8,1).
Unfortunately there are additional restrictions, for example:
Most pieces cannot pass other pieces. Hence, you need to know the coordinates of pieces on the board.
Kings cannot move into a check. Hence, you need to know the locations of where the opponents pieces can move to.
Kings can castle if they have not moved (it is not enough to be in the original position). Hence you need to know the history of the game.
Modelling a chess game is an interesting exercise, but perhaps you should try checkers first to get accustomed to working with an abstract representation of a physical game, and then have a second go at chess?
Quick though:
Introduce an interface called "Moveable". Your figure classes (you call them "pieces") will be defined like this. Extract your canMove() method into this interface and add move() method returning some unchecked exception if it fails.
public class MyPiece extends Piece implements Moveable{
//your code goes here
}
Create enum called MovementPossibilities. Here you should store all possible movements. Each movement possibility consists of possible directions (binary status, just on/off, true/false, can move in that direction/cannot). For every direction, introduce three integers -> minStep, maxStep, stride. Obviously, they tell you how much your figure can move in given direction.
This attemp is good in one thing - it first lets you test if your figure can move in that direction. If no, no other tests are needed.
Related
So what I'm trying to make is a function where I input the location of a moving circle and its target location, the location of a stationary circle and both of their radiuses, and I want to return the point at which they intersected if they did and the target location if they didn't.
The starting position of both circles, their radiuses and the end position of the moving circle are all known.
In this example I want to in a single frame move circle A from point Start to point End, if A collides with B I want to return the point where they touch closest to Start. In between Start and End there is a vector that can be calculated through End-Start which I'll call V and use in my attempt at solving this.
I will to refer the point Start as S and the position of B as P, the radius of A as Ra and the radius of B as Rb as seen in this image: variables.
So this is how far I've got:
When the two circles are just about touching the distance between them should be their radiuses combined like in this image: radiuses combined.
Therefore Ra+Rb = length of P-C which becomes (Ra+Rb)² = (P.x-C.x)² + (P.y-C.y)² according to Pythagoras (I squared both sides to remove the square root)
C can be described as the point S plus the vector V scaled by some constant t, C = S + tV so for example the point half way between Start and End could be described as S + 0.5V.
So the equation would then become (Ra+Rb)² = (P.x-(S.x+tV.x))² + (P.y-(S.y+tV.y))²
I have not gotten further than that since I cant isolate t which I need to find C
Any help is greatly appreciated! Sorry if I made any mistakes, its my first time posting.
(If anyone has code in Java for this that would be amazing)
You would probably have received a better answer for your question over at math.stackexchange.com, since this really seems to be a question about the maths related to your program.
But anyhow, this problem can be solved in a few steps:
1. Projection of a point onto a line:
Let Q be a projected point on V. Is the distance P-Q larger than the sum of Ra and Rb? If so, there is no collision, else proceed:
2. Pythagoras:
You now know the distance P-Q, and as you noted yourself, the circles will intersect at a distance Ra+Rb - if they collide. So, now if we find the distance Q-C, we can find where C is, since we already know where Q is from the projection onto V.
So, what is the distance Q-C: Sqrt((B-Q)^2 - (B-C)^2)
3. Find C by translating Q by distance Q-C
Now, you just need to make sure that you translate Q in the right direction: toward S.
As for the coding part of your problem, there was never a question asked, so there's nothing to respond to...
[Edit: fixed #3 Translate->Find]
I need some help regarding an assignment that I've received through school. I've been stuck on a specific part of the assignment, detecting whether a rectangle is overlapping another. I tried to create an If-statement for the cases when the two rectangles aren't overlapping, but the teacher said that it would be easier doing the opposite and gave me a picture of seven scenarios that I should create If-statements for. I'm not looking for an complete answer, just maybe a solution to one of the cases so I get an idea of how I should think, or maybe just a tip. Thanks!
here is the picture,
The program language is Java. The rectangles have the dimensions: dx(width), dy(height). They each have coordinates: x, y. Which are located on the top left of each rectangle.
Try to solve it for one dimension first, then the other and combine the results.
Line A would overlap line B if start of A is before end of B while at the same time end of A is after start of B.
So if these two criterions match for the horizontal coordinates, perform the same check for the vertical coordinates. Only when you have overlap both horizontally and vertically the rectangles have a common area.
In code:
boolean isOverlap(java.awt.Rectangle A, java.awt.Rectangle B) {
if ((A.x <= B.x+B.width) && (A.x+A.width >= B.x)) {
// overlap horizontally, now check vertical
if ((A.y <= B.y+B.height) && (A.y+A.height >= B.y)) {
// overlap also vertically
return true;
}
}
return false;
}
I have a 3x3 array of integers (0 or 1): int[][] matrix. The goal is to get through the maze (matrix) of 0's and 1's by assuming the 0's are walls. I'm not sure how to go about checking the neighbors.
For example, starting at [0][0] and checking above it, I need to do something like:
if (currentPosition.getColumn()-1 != null && !checkIfWall[getRow()][getColumn()-1]) {
//do stuff
}
Where checkIfWall is a boolean 2D array of walls or not wall. The problem is that checkIfWall returns ArrayOutOfBounds if any of the values are -1. Additionally, I have to write three other if statements to check below, left, and right, which seems tedious. Is there a better way to do this?
The way I would do it is assume that any location outside the array is a wall - so then you can create a function to do a collision test and check the bounds inside that.
boolean isWall(int x, int y) {
if (x<0||x>3)
return true;
if (y<0||y>3)
return true;
return data[x][y]==0;
}
Now you can just call isWall for any co-ordinates you like and it will never error, and so you don't need to worry about where you are in all your other algorithms - anything outside the maze is always treated as a wall.
First of all, I think you're confusing the directions ... you think about "up" as "-1", but usually what happens in a 2d array is that the top left corner is 0,0. and as "y" grows, it's going "down".
In any case, regarding your question, I would solve this by having a method that simply gets the current location and a direction (up,down, right, left, either strings, or better enums). You should have in your file a global variable for the size, so you can verify you are in a "valid" state, and if you're trying to check a value "outside" the array, it should return false (treat as a wall, since you can't go that way).
This will have the benefits of making your code readable as well. for example: if (isValid(this, up)) go up... and so on...
So first of all I'm in a 100 level CS college class that uses Java. Our assignment is to make a tower defense game and I am having trouble with the pathing. I found from searching that A* seems to be the best for this. Though my pathing get's stuck when I put a U around the path. I'll show some beginner psuedo code since I haven't taken a data structures class yet and my code looks pretty messy(working on that).
Assume that I will not be using diagonals.
while(Castle not reached){
new OpenList
if(up, down, left, right == passable && isn't previous node){
//Adds in alternating order to create a more diagonal like path
Openlist.add(passable nodes)
}
BestPath.add(FindLeasDistancetoEnd(OpenList));
CheckCastleReached(BestPath[Last Index]);
{
private node FindLeastDistancetoEnd(node n){
return first node with Calculated smallest (X + Y to EndPoint)
}
I've stripped A* down(too much, my problem most likely). So I'm adding parents to my nodes and calculating the correct parent though I don't believe this will solve my problem. Here's a visual of my issue.
X = impassable(Towers)
O = OpenList
b = ClosedList(BestPath)
C = Castle(EndPoint)
S = Start
OOOOXX
SbbbBX C
OOOOXX
Now the capitol B is where my issue is. When the towers are placed in that configuration and my Nav Path is recalculated it gets stuck. Nothing is put into the OpenList since the previous node is ignored and the rest are impassable.
Writing it out now I suppose I could make B impassable and backtrack... Lol. Though I'm starting to do a lot of what my professor calls "hacking the code" where I keep adding patches to fix issues, because I don't want to erase my "baby" and start over. Although I am open to redoing it, looking at how messy and unorganized some of my code is bothers me, can't wait to take data structures.
Any advice would be appreciated.
Yes, data structures would help you a lot on this sort of problem. I'll try to explain how A* works and give some better Pseudocode afterwards.
A* is a Best-First search algorithm. This means that it's supposed to guess which options are best, and try to explore those first. This requires you to keep track of a list of options, typically called the "Front" (as in front-line). It doesn't keep track of a path found so far, like in your current algorithm. The algorithm works in two phases...
Phase 1
Basically, you start from the starting position S, and all the neighbouring positions (north, west, south and east) will be in the Front. The algorithm then finds the most promising of the options in the Front (let's call it P), and expands on that. The position P is removed from the Front, but all of its neighbours are added in stead. Well, not all of its neighbours; only the neighbours that are actual options to go. We can't go walking into a tower, and we wouldn't want to go back to a place we've seen before. From the new Front, the most promising option is chosen, and so on. When the most promising option is the goal C, the algorithm stops and enters phase 2.
Normally, the most promising option would be the one that is closest to the goal, as the crow flies (ignoring obstacles). So normally, it would always explore the one that is closest to the goal first. This causes the algorithm to walk towards the goal in a sort-of straight line. However, if that line is blocked by some obstacle, the positions of the obstacle should not be added to the Front. They are not viable options. So in the next round then, some other position in the Front would be selected as the best option, and the search continues from there. That is how it gets out of dead ends like the one in your example. Take a look at this illustration to get what I mean: https://upload.wikimedia.org/wikipedia/commons/5/5d/Astar_progress_animation.gif The Front is the hollow blue dots, and they mark dots where they've already been in a shade from red to green, and impassable places with thick blue dots.
In phase 2, we will need some extra information to help us find the shortest path back when we found the goal. For this, we store in every position the position we came from. If the algorithm works, the position we came from necessarily is closer to S than any other neighbour. Take a look at the pseudocode below if you don't get what I mean.
Phase 2
When the castle C is found, the next step is to find your way back to the start, gathering what was the best path. In phase 1, we stored the position we came from in every position that we explored. We know that this position must always be closer to S (not ignoring obstacles). The task in phase 2 is thus very simple: Follow the way back to the position we came from, every time, and keep track of these positions in a list. At the end, you'll have a list that forms the shortest path from C to S. Then you simply need to reverse this list and you have your answer.
I'll give some pseudocode to explain it. There are plenty of real code examples (in Java too) on the internet. This pseudocode assumes you use a 2D array to represent the grid. An alternative would be to have Node objects, which is simpler to understand in Pseudocode but harder to program and I suspect you'd use a 2D array anyway.
//Phase 1
origins = new array[gridLength][gridWidth]; //Keeps track of 'where we came from'.
front = new Set(); //Empty set. You could use an array for this.
front.add(all neighbours of S);
while(true) { //This keeps on looping forever, unless it hits the "break" statement below.
best = findBestOption(front);
front.remove(best);
for(neighbour in (best's neighbours)) {
if(neighbour is not a tower and origins[neighbour x][neighbour y] == null) { //Not a tower, and not a position that we explored before.
front.add(neighbour);
origins[neighbour x][neighbour y] = best;
}
}
if(best == S) {
break; //Stops the loop. Ends phase 1.
}
}
//Phase 2
bestPath = new List(); //You should probably use Java's ArrayList class for this if you're allowed to do that. Otherwise select an array size that you know is large enough.
currentPosition = C; //Start at the endpoint.
bestPath.add(C);
while(currentPosition != S) { //Until we're back at the start.
currentPosition = origins[currentPosition.x][currentPosition.y];
bestPath.add(currentPosition);
}
bestPath.reverse();
And for the findBestOption method in that pseudocode:
findBestOption(front) {
bestPosition = null;
distanceOfBestPosition = Float.MAX_VALUE; //Some very high number to start with.
for(position in front) {
distance = Math.sqrt(position.x * position.x - C.x * C.x + position.y * position.y - C.y * C.y); //Euclidean distance (Pythagoras Theorem). This does the diagonal thing for you.
if(distance < distanceOfBestPosition) {
distanceOfBestPosition = distance;
bestPosition = position;
}
}
}
I hope this helps. Feel free to ask on!
Implement the A* algorithm properly. See: http://en.wikipedia.org/wiki/A%2A_search_algorithm
On every iteration, you need to:
sort the open nodes into heuristic order,
pick the best;
-- check if you have reached the goal, and potentially terminate if so;
mark it as 'closed' now, since it will be fully explored from.
explore all neighbors from it (by adding to the open nodes map/ or list, if not already closed).
Based on the ASCII diagram you posted, it's not absolutely clear that the height of the board is more than 3 & that there actually is a path around -- but let's assume there is.
The proper A* algorithm doesn't "get stuck" -- when the open list is empty, no path exists & it terminates returning a no path null.
I suspect you may not be closing the open nodes (this should be done as you start processing them), or may not be processing all open nodes on every iteration.
Use a Map<GridPosition, AStarNode> will help performance in checking for all those neighboring positions, whether they are in the open or closed sets/lists.
I need to examine each pixel inside an oval with Java.
For drawing, I am currently using:
drawOval(x,y,r*2,R*2).
However, since I need to get each pixel inside the Oval, I would like to create a loop that iterates inside it (assuming I have x,y,r and R). Is there any built in functionality for this purpose?
Thanks,
Joel
Java's Ellipse2D implements the Shape interface, so you can use one of the latter's contains() methods as required. It's also possible to render the Shape into a BufferedImage and traverse its WritableRaster.
simple canonical implicit equation for Oval is (with center 0; 0)
So yo can iterate throw all possible coordinates and check it using this equation.
I don't think there's any built in functionality for this.
Let's go through this step by step.
Assuming that your ellipse's center is at (0,0), one radius is a, other is b, the canonical equation is
x^2/a^2+y^2/b^2=1
Multiplying both sides with a^2 and b^2, you get
x^2*b^2+y^2*a^2=a^2*b^2
Now, you must do a double for loop. a and b must be positive. Pseudocode:
for x = -a; x <= a; ++x:
for y = -b; y <= b; ++y:
if(x^2*b^2+y^2*a^2 <= a^2*b^2)
// you're in your ellipse, do as you please
Of course, this will work only if center is at (0,0), so if you want this algorithm to work, shift your points appropriately using translation. If you leave the center somewhere else, this algorithm will get messier.
Note: didn't test this. If somebody sees a mistake, please point it out.