comparing and creating Point 2D arrays - java

So i am still trying to get this to work... I need it to tell me with the users position matches the position of one of the walls in the array.
I output all the coordinates into the console and everything looks right except that when they equal it doesn't work. (this has worked before... it seems if i don't create the walls in the loop it will work but once i declare too many walls it seems to quit working(not exactly sure but i set the map without the loop and it didn't work consistently i couldn't figure out a reason..
The GameObject(user).position is Point2D and `setPosition set the posiion,
public class Map {
public ArrayList<Wall> theseWalls = new ArrayList<Wall>();
private boolean isSomethingThere;
public Boolean somethingIsThere(GameObject user){
for(int i = 0; i < theseWalls.size(); i++){
GameObject a = (Wall) theseWalls.get(i);
if( user.returnPosition().equals(a.returnPosition())){
isSomethingThere= true;
} else {
isSomethingThere= false;
}
}
return isSomethingThere;
}
}
so that checks if they hit a wall
and this makes the walls
public void makeWallWE(double starty, double endy, double x ){
double length = endy - starty;
for(int i = 1; i<=(int)length;i++){
Wall Wallie= new Wall();
Wallie.setPosition(x,starty+i);
Wallie.showPosition();
theseWalls.add(Wallie);
}
}

You have:
public Boolean somethingIsThere(GameObject user){
for(int i = 0; i < theseWalls.size(); i++){
GameObject a = (Wall) theseWalls.get(i);
if( user.returnPosition().equals(a.returnPosition())){
isSomethingThere= true;
} else {
isSomethingThere= false;
}
}
return isSomethingThere;
}
Even if the user's position matches one of the walls, you continue checking through the rest of the walls and end up setting isSomethingThere to false. The only time this works is if the last wall in theseWalls is the one that matches.
You'll want to break out of that loop as soon as you find a wall that matches, to avoid resetting isSomethingThere to false when you check walls later in the list that don't match.

Related

How to use an array in an IF statement?

I have created this program where an array of bubble objects will be created in the constructor, and then the bubbles will float accross the canvas and once the bubbles touch each other they will disappear and reveal the words "POP!". My method called noneLeft() should return true if all the bubbles have been popped and then another method called redisplayAll() will be called and the bubbles will reset and redisplay again. However, I am not sure what to write for my if statement to return true once the last bubble has been popped. How do I write down if the last bubble in the array has been popped, then return true. Would I have to use bubbles.length?
public Mover(double width, double height, int numberOfBubbles) {
canvasWidth = width;
canvasHeight = height;
bubbles = new Bubble[numberOfBubbles];
for (int i = 0; i < numberOfBubbles; i ++){
bubbles[i] = new Bubble();
bubbles[i].showBubble(width, height);
}
count = 0;
}
public boolean noneLeft() {
if (bubbles[].isPopped() == true){
return true;
}
return false;
}
The code should be
public boolean noneLeft() {
for (Bubble b : bubbles) {
if (!b.isPopped()) {
return false;
}
}
return true;
}
Iterate over the bubbles and as soon as you find one that has not popped return false since at least one bubble is left.

Is there something wrong with these simple java methods (filling a boolean array, checking if said array is full)

I have to write a program that figures out if certain people can buy certain pieces of land, represented by an array. To do this, I created another boolean array that, from the start, is filled with all falses. When somebody "purchases" that piece of land, this boolean array is filled with "true" in places where the land has been purchased. Hence, if another person would want to buy land where somebody has already done so, my program should know that this land is already taken.
However, I'm encountering problems. Are these methods written OK?
private static boolean IsItFree (boolean [][] boolArray, int y, int x, int h, int w) {
if (!boolArray[y][x]) {
for (int i=0; i<h; i++) {
if (boolArray[y+i][x]) {
return false;
}
}
for (int i=0; i<w; i++) {
if (boolArray [y][x+i]) {
return false;
}
}
return true;
}
return false;
}
private static boolean[][] fillItUp (boolean[][] boolArray, int y, int x, int h, int w) {
for (int i=y; i<y+h; i++) {
for (int j=x; j<x+w; j++) { //mogoce minus 1
boolArray[i][j] = true;
}
}
return boolArray;
}
the "land" is given with y and x variables that indicate array indexes where the land will start. H indicates how many spaces the (always square) piece of land should occupy vertically (down, 1 means only the boolArray [y][x], with no horiz. movement) and W is the same for vertical movement.
This is how I reference this in the main method:
`
...
boolean isFree = isItFree (boolArray, y, x, h, w);
if (free) {
boolArray = fillItUp(boolArray, y, x, h, w);
}
Could the problem be that I'm referencing boolArray in fillItUp, because I'm using it in a static context?
No, your code is not correct.
In your IsItFree you are checking wether or not some fields to be purchased are already purchased. But your current code logic only checks first if the fields along one axis are purchased and then checks the other axis, it does not check a mix of both. Visually your code checks only two sides of the rectangle but misses the other two sides and the inner area:
######
#OOO##
#O####
#O####
######
(no guarantee those are the actual sides which are getting checked in your coordinate system).
A fix for that is easy: you basically already wrote the logic in the fillItUp. Basically do the exact same loops but change the action inside:
private static boolean isItFree (boolean [][] boolArray, int y, int x, int h, int w) {
for (int i=y; i<y+h; i++) {
for (int j=x; j<x+w; j++) {
if (boolArray[i][j]) // already purchased
return false;
}
}
return true;
}
Further notes:
please name the method isItFree (starting with a lower case letter)
no need to return the / an array in the fillItUp method

How to detect if two sprites are being touched at the same time?

I tried this:
if(spr.getBoundingRectangles.contain(x,y)){
//do this
}
but how to detect if the other sprite is touched by the second pointer?
EDIT:
for(int i = 0; i < Constants.MAX_POINTERS; i++){
if(Gdx.input.isTouched(i)){
xy.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
xy1.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
WorldRenderer.camera.unproject(xy);
WorldRenderer.camera.unproject(xy1);
if(Spr.getBoundingRectangle().contains(xy.x, xy.y) &&
Spr1.getBoundingRectangle().contains(xy.x, xy.y))
score += 1;
}
}
What happens is that xy and xy1 are always the same, when I touch the screen with the second pointer they will just both switch to the new coordinates instead of having two different x,y for both xy and xy1.
you can iterate over all pointers checking whether they are touching the screen and then check if positions overlapping sprites position
final int MAX_POINTERS = 5;
...
for(int i = 0; i < MAX_POINTERS; i++)
{
if( Gdx.input.isTouched(i) )
{
int x = Gdx.input.getX(i);
int y = Gdx.input.getY(i);
if( sprite.getBoundingRectangle().contains(x, y) ) //instead of checking one sprite iterate over sprites array
{
System.out.println("The sprite is touched!");
}
//if... - or just add more ifs
}
}
you need to define max count of pointers to iterate over it - as far as I know Libgdx supports up to 20 pointers
ABOUT EDIT:
Of course they are the same... :) You are placing the same value to vetors. My example above is far more generic that you need - if you know that you have two pointers you can just use:
if( Gdx.input.isTouched(0) && Gdx.input.isTouched(1) ) //because if two pointers are touching screen there is a chance that they are touching two sprites
{
xy.set(Gdx.input.getX(0), Gdx.input.getY(0), 0);
xy1.set(Gdx.input.getX(1), Gdx.input.getY(1), 0);
//checking if pointer 1 is touching sprite 1 and pointer 2 is touching sprite 2 OR VICE VERSA
if( (Spr.getBoundingRectangle().contains(xy.x, xy.y) && Spr1.getBoundingRectangle().contains(xy1.x, xy1.y))
||
(Spr.getBoundingRectangle().contains(xy1.x, xy1.y) && Spr1.getBoundingRectangle().contains(xy.x, xy.y))
)
{
score += 1;
}
}
or just create the function that will return true if all sprites you will pass to it are touched (which actually will can handle more than two sprites)
boolean allTouched(Array<Sprite> sprites)
{
int spritesCount = sprites.size;
int spritesTouched = 0;
for(int i = 0; i < MAX_POINTERS; i++)
{
if( Gdx.input.isTouched(i) )
{
for(Sprite sprite : sprites)
{
if( sprite.getBoundingRectangle().contains(Gdx.input.getX(i), Gdx.input.getY(i)) )
{
spritesTouched++;
sprites.removeValue(sprite, true); //to not doubling the same sprite
}
}
}
}
return spritesCount == spritesTouched ;
}

Sudoku backtracking algorithm (Java)

I've created a Sudoku solver that will solve a Sudoku as a human might- by checking possibilities + definite values in squares corresponding to the square being checked.
(Source: http://pastebin.com/KVrXUDBF)
However, I would like to create a random Sudoku generator (from a blank grid), and so have decided to use a backtracking algorithm. I understand the concept of backtracking, but am confused about one thing:
How do I know which previous node to return to (and change) once I know a certain solution is not allowed?
Should I simply return to the previous node and cycle through all possibilities? (And then if this yields no correct answers, return to the value before, etc.). This seems like a viable method, but also quite inefficient. Is this the correct way of implementing a backtracking method or is there a better way to go about it?
Thanks in advance.
More can be found about backtracking here: http://en.wikipedia.org/wiki/Backtracking
Sudoku Puzzle can be reduced to graph coloring problem which can be solved using simple backtracking like assigning colors to node (1-9) till the there is no violation that all directly connected nodes have no same color.
Constructing Graph from Sudoku : -
There is an direct edge between two grid points if they are in same
row or column or square.
Backtracking :-
Assign one color (1-9) to node
Check if there is no other directly connected node with same color
If valid color move to next node.
else change the color and recheck.
If all color exhausted backtrack to previous node.
Do recursion till all nodes are color.
Once You are done with it you can start removing numbers from the grid at random till you think the problem is unsolvable if any more numbers are removed.
A simple way to generate random Sudoku is that
1) generate a random completing Sudoku, that is, generate random Sudoku no square is blank.
2) Remove numbers from squares of 1).
3) Solve Sudoku of 2). If there are many solutions, then add a number removed at 2).
If there are still many solutions, then repeat 3).
1) sample source code:
public int[][] generateRandomCompleteSudoku() {
int[][] sudoku = new int[10];
for(int i = 1; i <= 9; i++) {
sudoku[i] = new int[10];
Arrays.fill(sudoku[i], 0);
}
generateRandomCompleteSudoku(sudoku, 1, 1);
return sudoku;
}
private boolean generateRandomCompleteSudoku(int[][] sudoku, int x, int y) {
if(x > 9) {
x = 1;
y++;
}
//sudoku of the argument is completing sudoku.
//so return true
if(y > 9) {
return true;
}
// enumerate the possible numbers of the pos(x,y).
List<Integer> possibleNumbers = new ArrayList<Integer>();
for(int i = 1; i <= 9; i++) {
boolean possible = true;
//check i is a possible number.
//check there isn't i in the raw of y .
for(int j = 1; j <= x - 1; j++) {
if(sudoku[j][y] == i) {
possible = false;
break;
}
}
//check there isn't i in the column of x(omitted).
//check there isn't i in the group of x,y(omitted).
if(possible) {
possibleNumbers.add(i);
}
}
//sudoku is wrong so return false.(There is no solution of sudoku)
if(possibleNumbers.size() <= 0) {
return false;
}
Collections.shuffle(possibleNumbers);// This gives sudoku randomness.
for(Integer possibleNumber : possibleNumbers) {
sudoku[x][y] = possibleNumber;
// a sudoku is generated, so return true
if(generateRandomCompleteSudoku(sudoku, x + 1, y)) {
return true;
}
}
// No sudoku is generated, so return false
return false;
}
For a backtracking solution, the first step is to define the state. So for this problem, I think the most straightforward way is (x,y, blank , num) with x , y is the position of the current state, blank is the number of blank position left, and num is the value you want to fill in that position (from 0 to 9 and 0 means blank).
And the return type should be boolean, which determine whether the move is valid or not (which means is there any valid solution for this move).
So, the state transition is column by column, row by row: x, y to x , (y + 1) or x , y to (x + 1), 0.
Similarly, the blank will be from a -> a - 1-> ... 0.
We have a draft solution here:
public boolean move(int x, int y, int blank, int num, int[][]sudoku){
sudoku[x][y] = num;
//checking condition and return if x,y is the last position, code omitted
if(y == sudoku[x].length){
x++;
y = 0;
}else{
y++;
}
for(int i = 1; i < 10; i++){
if(move(x,y,blank,i,sudoku){//Backtrack here
return true;
}
}
if(blank > 0){
if(move(x,y,blank - 1, 0, sudoku){//Backtrack here
return true;
}
}
return false;
}
So when ever there is a false return from the current state, it will backtrack to the last state , and the last state will continue to check for the next num until it find a correct solution (or return false).

Java game - run code sequentially in the game loop

I am creating a Java game within which the user can enter the commands of up, left, right, or down to move the character in that location for a certain amount of pixels. Within the Player class I am receiveing the commands from the user in an ArrayList of JTextFields after they have pressed the start button. I then use a for loop to go through all the inputs from the user and create x and y targets within a multi-dimensional array for the x and y amount of distance that the player needs to move. Finally I have a function called updatePosition() which is called within the main game loop. Within this function I loop through the multi-dimensional array of targets and have an if statement to check if the target has been reached or not. However when this method is executed and the user has input the commands of up and right for example, then the character moves diagonally up. I want a way which will move the character in the direction that the user has specified, executing them one after another.
Here is the code:
moveSpeed = 1;
private double moveAmt = 20;
private Double[][] targetCoordinates = null;
private ArrayList<JTextField> userInputTextFields = new ArrayList<JTextField>();
With method below I acquire the ArrayList of JTextFields within which the user has entered the commands and store it in a local ArrayList. I also instatiate an Array in the size of the amount of JTextFields that the user has entered the commands in. This array will be used to store the x and y targets for the character. I then lastly call the moveChar(); method which will set the target x and y.
public void getInputText(ArrayList<JTextField> textFields){
this.userInputTextFields = textFields;
targetCoordinates = new Double[userInputTextFields.size()][2];
moveChar();
}
This method will check if the commands that the user has enetered and set the x and y targets within the targetCoordinates array.
private void moveChar(){
for (int i = 0; i < userInputTextFields.size(); i++) {
if(userInputTextFields.get(i).getText().equals("up")){
targetCoordinates[i][0] = x;
targetCoordinates[i][1] = y - moveAmt;
} else if(userInputTextFields.get(i).getText().equals("down")){
targetCoordinates[i][0] = x;
targetCoordinates[i][1] = y + moveAmt;
} else if(userInputTextFields.get(i).getText().equals("left")){
targetCoordinates[i][0] = x - moveAmt;
targetCoordinates[i][1] = y;
} else if(userInputTextFields.get(i).getText().equals("right")){
targetCoordinates[i][0] = x + moveAmt;
targetCoordinates[i][1] = y;
}
}
}
Finally, this is the method which gets called within the main game loop. It goes through the targetCoordinates array and checks if the targets have been met. If not then incriment or decrement the character's x and y position accordingly.
public void updatePosition(){
if(targetCoordinates != null){
for (int i = 0; i < targetCoordinates.length; i++) {
if(y >= targetCoordinates[i][1]) {
moveCharacter(x, y - moveSpeed);
} else if(y < targetCoordinates[i][1]) {
moveCharacter(x, y + moveSpeed);
} else if(x > targetCoordinates[i][0]) {
moveCharacter(x - moveSpeed, y);
} else if(x <= targetCoordinates[i][0]) {
moveCharacter(x + moveSpeed, y);
}
}
}
}
At present you use all the available commands to create a single target position and use that to direct your motion (or possibly move towards all target positions simultaneously).
Instead you want a "hopper" of commands that survive beyond a specific game loop and a new command is only fetched after the current one is completed. New commands go in the top and out the bottom to be excecuted.
This would most likely look something like this
public class Player {
//holding commands as strings is a little bug prone, consider creating a custom class or enum
ArrayList<String> commandsHopper=new ArrayList<String>();
//replace with some sort of Vector2i as improvement
double[] targetCoOrdinates=new double[2];
public void addCommand(String command){
commandsHopper.add(command); //commands added at the top of arraylist
}
public void update(double timeSlice){
//Called once, every game loop
if (isAtTarget()){
getNextTarget();
}
moveTowardsTarget(timeSlice);
}
public void getNextTarget(){
if (commandsHopper.isEmpty()==false){
//commands used from bottom of the arraylist
targetCoOrdinates=determineTargetFromCommand(commandsHopper.get(0));
commandsHopper.remove(0); //inefficient with arraylist, consider other collections
}
}
}

Categories

Resources