Java - Beckers robots package. Parameter stepwise refinement - java

i am using the import becker.robots file for this assignment!
I must create a class DistributeBot (extended RobotSE) which will put down a number of 'things' in the shape of 2 squares.
When the main method is then created, a single call to a method (which i must create myself using stepwise refinement and also contains a parameter) called this.putThings();
The method i am to create should have a single variable parameter to define the size of the squares! ie a parameter of (4) will make a 4x4 square of 'Things'.
The robot should set out the Things one line at a time from left to right! (once one line is displayed, it should move back to the LHS before displaying the next line)
I think i will be able to complete the scenario without problem whenever i am certain on how to create the method with the parameter i have specified.
Assumptions.
1. Starting position of the robot will always be the same. ie starting at 1, 1.
2. There will always be enough 'things' in the robots backpack to display the two squares.
Anyone have an idea how I would go about setting up this method initially with the variable parameter?

If you have your method starting
Public void MakeSquare(int size)
{
for(int i = 0; i < size; i++)
{
for(int x = 0; x < size; x++)
{
//drop thing
//move right
}
for(int y = 0; y < size; y++)
{
//move left
}
//move up
}
}
Whilst reading the question you should try and break it down into its simplest parts.
start with Build a square that is the most abstract form of the scenario and so makes your method, then break it down
//I want to move up until I hit size limit
for each number in "the size you want"
//I want to move right and drop a thing, until I hit size limit
for each number in "the size you want"
drop a thing
move one right
endloop
//I want to move back to the LHS until I hit size limit
for each number in "the size you want"
move one left
endloop
//then make the move up
move up
endlood
If you make this method and call it twice you will make the 2 squares as required)

Related

How do you make sure the 2 balls are removed after the collision?

I am a beginner and I am making a space shooter game in Netbeans. I want if the spacecraft's bullet hits the enemy's bullet that the 2 bullets are removed. I have created an Arraylist of bullets and bulletsEnemy. Then I created a method hitByBullet that should ensure that I can search for the bullets that collided. Then in the method bulletsHit (), the bullets should be removed.
My enemies shoot in a loop and don't move. My problem is that the bullets go through each other. The radius of the bullets is 5.
These is the 2 methods that I have written
'''
public int hitByBullet(){
for(int i=0; i<bullets.size(); i++){
for(int j= 0;j< bulletsEnemy.size(); j++){
if( bullets.get(i).getY() - bulletsEnemy.get(j).getY()<= 5)
if(bullets.get(i).getX() -bulletsEnemy.get(j).getX()<= 5){
return i;
}
}
}
return -1;
}
'''
public boolean bulletsHit(){
if (hitByBullet()!= -1){
bullets.remove(this); //with 'this' I refer too 'i'
bulletsEnemy.remove(this);
return true;
}
return false;
}
'''
[This is how it looks like] (https://i.stack.imgur.com/4XsCR.png)
I will try to answer in a way to let you find your way to implement what you want. There are several frameworks out there which will help you with this and as you are new to programming there are a lot of things you could change/do better. But I will ignore these things.
I think your are trying to check if one 5x5 bullet intersects with another 5x5 bullet.
To make it easy let us asume your bullets are squares:
In your hitByBullet you should check your square centers (i asume that are x,y of your bullets) distance in both dimensions:
Sth. like this should check the collision:
if(Math.abs(bullets.get(i).getY() - bulletsEnemy.get(j).getY()) < 5 &&
Math.abs(bullets.get(i).getX() - bulletsEnemy.get(j).getX()) < 5) {
return i;
}
Depending of the size of your bullets you need to change the distance check ( <=5). If your bullets have a size of 5 px it should be < 10. If your bullets are 10x10 you should check against < 20 ...
Regarding a more realistic scenario, that your bullets are circles (e.g. resulting of a 5x5 square px or a radius r=5):
You need to check if the distance between your two bullet centers is smaller than the bullet radius * 2.
That will bring you to use the theorem of pythagoras:
https://en.wikipedia.org/wiki/Pythagorean_theorem
The distance between your bullet centers is c. a is the distance in dimensional x and b the distance in dimensional y. You don't need to take care about negative dimensional values cause you need pow them by 2 which will always give you a positive value.
To check for collision you should calculate the distance c as follows:
c = SquareRootOf(a^2+b^2)
Math.sqrt(Math.pow(bullets.get(i).getX() - bulletsEnemy.get(j).getX()),2) + Math.pow(bullets.get(i).getY() - bulletsEnemy.get(j).getY(),2)) < 10
I think you should read basics about collision detection and geometry. Just two possible points of information:
An easy to start example with code:
https://zetcode.com/javagames/collision/
Circle intersection:
https://www.geeksforgeeks.org/check-two-given-circles-touch-intersect/
Regarding the removal of the bullets I asume you have some kind of game loop in which you frequently draw the bullets and calculate the collision (call the bulletsHit method):
I will make an assumption to make things easier: The movement speed of your bullets is not faster than one pixel per loop. Otherwise I think you need to take care of your loop circle time and calculate the positions of all elements and also take care about bullets that won't intersect in one loop circle because they could have passed by from one loop circle to the next loop circle. I'm not familiar with game dev, so maybe there are more things to cover.
Regarding this you should change things:
The method hitByBullet() will only return one collision per call.
You could store your collidedBullets in two sets and after removing them from your bullets and bulletsEnemy list clear these temporary sets.
I don't understand what you are doing with "this" and your result of
hitByBullet.
I would do it like this
public void hitByBullet(){
for(int i=0; i<bullets.size(); i++){
for(int j= 0;j< bulletsEnemy.size(); j++){
if( Math.sqrt(Math.pow(bullets.get(i).getX() - bulletsEnemy.get(j).getX()),2) + Math.pow(bullets.get(i).getY() - bulletsEnemy.get(j).getY(),2)) < 10){
bulletsToDelete.add(bullets.get(i));
bulletsEnemyToDelete.add(bulletsEnemy.get(j));
}
}
}
}
public boolean bulletsHit(){
hitByBullet();
bulletsToDelete.forEach(bullet -> bullets.remove(bullet);
bulletsEnemyToDelete.forEach(bullet -> bulletsEnemy.remove(bullet);
boolean bulletsHit = !bulletsToDelete.isEmpty();
bulletsToDelete.clear();
bulletsEnemyToDelete.clear();
return bulletsHit;
}
As I mentioned before there are a lots of things you should improve:
general structure of your code
naming of your method (e.g. bulletsHit sounds like only checking if bullets are hit but you are also removing them)
double checking of bullets
Greetings

Using HashMaps in creating a game of 15 puzzle?

I am creating a simple game of 15 puzzle (Please see here: https://en.wikipedia.org/wiki/15_puzzle). I have an array of 4 by 4 buttons and want to know the best way to handle a user clicking on a button and moving around the numbers.
I have started off by creating a JavaFX gridpane to display the buttons as well as a HashMap (suggested by multiple people) to store a mapping between the displayed number (1-15) and the button at that location.
I populate the map with class objects "Btn"
public class Btn {
private int ID;
private int x;
private int y;
public Button button;
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 4; j++) {
Btn btn = new Btn(count, j, i, new Button("" + count));
map.put(count, btn);
btn.button.setMinSize(100, 100);
btn.button.setOnAction(e -> {
if (isMoveLegal(btn) == true) {
move(btn);
}
});
count++;
grid.add(btn.button, j, i);
}
}
So far it has worked quite well. In the isMoveLegal() method I check if the empty field is above, left, right, or below the clicked button. Which gets quite complicated because of the HashMaps nature of not preserving any order. But my real problem lies in the move() method. Since there is no order, I can't just switch 2 map nodes or can I?
if (MoveDir.equals("Right")) {
map.get((btn.getYs()+1)*4 - (4-btn.getXs())).button.setText("" + map.get(btn.getID()).getID());
map.get(btn.getID()).button.setText("" + map.get((btn.getYs()+1)*4 - (4-btn.getXs())).getID());
int tempID = map.get(btn.getID()).getID();
map.get(btn.getID()).setID(16);
map.get((btn.getYs()+1)*4 - (4-btn.getXs())).setID(tempID);
// System.out.println(map.get(btn.getID()).getID());
// System.out.println(map.get((btn.getYs()+1)* 4 - (4-btn.getXs())).getID());
map.get(btn.getID()).setYs(map.get(btn.getID()).getYs()+1);
map.get((btn.getYs()+1)* 4 - (4-btn.getXs())).setYs(map.get((btn.getYs()+1)* 4 - (4-btn.getXs())).getYs()-1);
This is what I have come up with so far, which extremely complicated and tedious. To quickly sum it up, I first switch the labels of the buttons, then I change the ID variables of the 2 buttons, and then I change the cord variables (x & y) to indicate their new location in map/grid.
I'm pretty sure I have gone way too far with this and there is a simpler solution to all of this but I am just unsure what that would be. Should I ditch the HashMap entirely and just use an object array of Btns?
Thanks for the help.
The problem you're facing is that your UI and your data structure are too tightly coupled. You need to separate them, give them their own responsibilities, and use communication (method calls) between them to make things happen.
For example, the UI should only be responsible for displaying the numbers and allowing the user to click a number to perform a move. Using a gridpane of buttons seems reasonable for this. Each button only needs to know it's x,y coordinate.
The data model should be a 2-dimensional array that contains the number at that location. For example:
+-+-+-+
|4|1|8|
+-+-+-+
|2|3|7|
+-+-+-+
| |5|6|
+-+-+-+
(You can figure out how to represent the empty space. Maybe a null, or the number '0' or '-1')
The data model can be wrapped in a data object that handles questions about and manipulations to the data model. For example, one method it might contain is getTheNumberAtLocation(x,y) which the buttons will call, and will return the number at that location. The buttons will use this to determine what number they should show.
Another method it might contain is isThereASpaceNextToLocation(x,y). This would return whether or not a space exists next to the location given by the x,y. The button will call this method to determine whether or not it can be clicked.
Finally, you could have a moveLocationToEmptySpace(x,y) which will manipulate the data to put the number at the current location into the empty space. After that, all the buttons should call getTheNumberAtLocation(x,y) to update the number they are showing.
By arranging your code like this you've nicely separated the concern of the UI (show text, handle button clicks) from the concern of maintaining the game state (checking if a move is valid, performing a move, determining the state of the board). Now when you write code it will be easier to write because each method will be responsible for a small, manageable piece of logic.
To summarise:
Gridpane (4x4)
-> Button
-> label [calls GameData.getTheNumberAtLocation]
-> click [calls GameData.isThereASpaceNextToLocation, moveLocationToEmptySpace]
GameData
-> Array (4x4) (private)
-> Integer (1-15)
-> getTheNumberAtLocation(x,y)
-> isThereASpaceNextToLocation(x,y)
-> moveLocationToEmptySpace(x,y)

Finding nearest point excluding last point LibGDX Java

I am trying to find a way to get a bunch of points to connect via the ShapeRenderer`s method of line(Vector2 first, Vector2 second). So I will explain then show image and code to help.
There is a List of type Vector2 and I need to find the next closest vertice and then exclude the first point. Here is an image of what I mean. I labeled the iterations of the loop in the image.
1st iteration.) it finds the closest point.
2nd iteration.) it sees that the first point is closer but still chooses the third point. This is the core problem, I need to make sure the second point finds the third point even though the first point is the closer one.
Here is the code I have tried to do this.
private void cleanVertices(Array<Vector2> verts){
newVerts = new Array<Vector2>();
Vector2 tmpKey, tmpClose = null;
tmpKey = verts.get(0);
for(int i = 0; i < verts.size; i++){
for(int k = 0; k < (verts.size - 1); k++){
if(k == i)
continue;
//Distance formula
double dist = MathFactory.distance(verts.get(i), verts.get(k));
if(MathFactory.distance(verts.get(i), verts.get(k + 1)) < dist){
tmpClose = verts.get(k + 1);
}else
tmpClose = verts.get(i);
}
tmpKey = tmpClose;
newVerts.add(tmpClose);
}
}'
This does not accomplish what I need, instead, it seems to connect points closest on x-axis. I desperately need help with this. Thanks!
Make a deep copy of the input parameter verts (i.e. a new Array containing the same list of references in verts). Then iterate over that, but remove each point after you choose it as the next "nearest" neighbor.
I'm not familiar with the Array class, but an ArrayList would have the correct behavior when you remove an element. At each point only unvisited points would remain in the list.
since your problem is to find the closest vertex to the second vertex,which is the third in your case, without considering the first one. Make the second for loop starts from the position of the first for loop in every iteration ( k = i). Meaning that the second for loop will not consider the first vertex as point to calculate the distance from.

Attempting to exchange two sections of an image

I am trying to swap the values of two sections of an image in a specific fashion: I want to move one block of pixes to the right 225 pixels, and take the block that was there and move it to the left 225 at the same time. However, it looks like the only transformation that takes hold is the first one:
public void exchange() {
int[][] stablePic = picArray.clone();
for (int i = 80; i < 230; i++)
{
for (int j = 50; j < 250; j++)
{
picArray[i][j] = stablePic[i][j+225];
picArray[i][j+225] = stablePic[i][j];
}
}
}
"picArray" is initialized earlier in the code - this compiles and runs, but only makes the first exchange - the second portion of the image still has the appearance of the first portion. Is there any way to have both transformations take place at once?
Are you sure the second fragment is the only one working? It seems to me that is the first one which is working.
To copy one array to other array don't just assign it. Use 2 for-loops for this, and when you see it works, investigate about how to replace the inner for-loop with Arrays.copyOf.
Here you have:
int[][] stablePic = picArray;
Which makes both variables point to the same memory, then when you modify your picArray you are modifying your stablePic also.
You are trying to swap two sections of an image for understanding purpose just take it as how can you swap two variables i.e
int a=10;
int b=20;
int temp ;//take a temp variable for swapping
temp =a;
a=b;
b=temp;
like this you have to take a temporary array.For swapping .in your code second one is working because it is overriding with the previous one.

Making a player move on 2D array game grid

I am creating a game using a 10x10 2D array. The player starts at the top left hand corner indicated as "P" and the objective is to get the player to avoid obstacles to get to the treasure indicated as "T" located in the lower right corner.
How would I go about making the player move about the grid using commands Up/Down/Left/Right?
Would I use a for loop to count through the elements in the array to designate the move?
Here is what I have so far:
import java.util.Scanner;
import java.util.Random;
public class Adventure {
public static void main(String[] args) {
char grid[][]= new char[10][10];
Scanner move = new Scanner(System.in);
System.out.println("Here is the current game board:");
System.out.println("-------------------------------");
for(int i=0; i<grid.length; i++) {
for(int j=0; j<grid.length; j++) {
double random = Math.random();
if(random <=.05) {
grid[i][j]='*';
}
else if(random > .06 && random <= .15) {
grid[i][j]='X';
}
else {
grid[i][j]='.';
}
grid[0][0]='P';
grid[9][9]='T';
System.out.print(grid[i][j]);
}
System.out.println("");
}
System.out.print("Enter your move (U/D/L/R)>");
}
}
you should keep track of the current position of the player and just update those variables.
initial values would be (0,0) as you said.
int px = 0;
int py = 0;
when a move is made, update the variables accordingly:
grid[px][py] = <empty cell>;
switch (move) {
case 'u': py += 1; break;
case 'r': px += 1; break;
...
}
grid[px][py] = 'P';
of course you shouldn't just updated the values "blindly", you should insert some validation logic to follow the rules of the game:
if (grid[px][py] != <obstacle> )
// update player coordinates...
Looks like you're using row-major ordering, judging from the way your board prints out. Based on that, here's what you'll need to do:
First, you need to store the player's position somewhere. Right now it's hardcoded to 0,0.
Second, you need to read in the player's move. That will have to happen in a loop, where you get a move, check if the move is allowed, perform the move, and display the results.
Third, you need to be able to calculate the new position based on the move. Up means row -= 1. Right means column += 1. Etc.
Given the new coordinates, you need to make sure the move is valid. At the very least, you have to stop them from walking off the board, but you may also prevent them from entering a square with an obstacle, etc.
Once you know that the move is valid, you have to update the variables you're storing the current coordinates in.
At the end of the loop, you'll need to redraw the board.
That's the basic gist of it. Right now you are doing everything in main(), and that's okay, but if it were me I would start to split things out into separate methods, like InitializeBoard(), GetNextMove(), CheckIfMoveIsValid(int r, int c), and so on. That way, main() becomes a high-level view of your game loop, and the guts of the different operations are compartmentalized and more easy to deal with. This will require storing off things like your game board into class variables rather than local variables, which should actually make things like obstacle detection easier than it would be currently.
All of the above answers are great. Here are a few suggestions I would make:
Instead of a char two-dimensional array, I would make a custom object, such as Space, and define a two-dimensional array of Spaces (eg, Space[][]). There are a few reasons for this:
You can define a space in a variety of ways (rather than just 1 character). For example, Space[i][j].hasTreasure() can return a boolean to let you know whether or not you found the treasure.
If you want to add functionality later, its as easy as adding an attribute to your Space class. Again, you are not limited to one character here.
More to your question of movement, I would also recommend a few things. Similar to redneckjedi's suggestion of a CheckIfMoveIsValid() method, I would pass the grid and move direction as parameters and return a boolean. To ensure that you do not end up with ArrayIndexOutOfBounds issues, I would also suggest adding a row/column of walls on each side. I would widen the grid out to 12x12 and put a strip of obstacle-type blocks around the outside. This will ensure that you cannot step outside of the grid as hitting a wall will always return 'false' on a valid move.

Categories