I made a Board and I set the board's layout to null. So I position my token's by moving them pixel by pixel. But when turning the corners I am having a trouble. After first 10 position token can make the turn and continue for the next 10 position. But it is impossible for my token to make the 2. turn.
Can anyone advice me a better code for this problem. I think I make things get more complicated than it is.
if(g.getPosx() <= 650 && g.getPosx() >= 50 && g.getPosy()==650) {
if(g.getPosx()-unitChange*d.getDice() <= 50) {
temp = unitChange*d.getDice() - (g.getPosx() - 50);
g.setPosx(50);
g.setPosy(g.getPosy()-temp);
}
else {
g.setPosx(g.getPosx()-unitChange*d.getDice());
temp = 0;
}
}
else if(g.getPosy() <= 650 && g.getPosy() >= 50 && g.getPosx()==650) {
if(g.getPosy()-unitChange*d.getDice() <= 50) {
temp = unitChange*d.getDice() - (g.getPosy() - 50);
g.setPosy(50);
g.setPosx(g.getPosx()-temp);
}
else {
g.setPosy(g.getPosy()-unitChange*d.getDice());
temp = 0;
}
}
else if(g.getPosx() <= 650 && g.getPosx() >= 50 && g.getPosy()==50) {
if(g.getPosx()-unitChange*d.getDice() <= 50) {
temp = unitChange*d.getDice() - (g.getPosx() - 50);
g.setPosx(50);
g.setPosy(g.getPosy()-temp);
}
else {
g.setPosx(g.getPosx()-unitChange*d.getDice());
temp = 0;
}
}
else if(g.getPosy() <= 650 && g.getPosy() >= 50 && g.getPosx()==50) {
if(g.getPosy()-unitChange*d.getDice() <= 50) {
temp = unitChange*d.getDice() - (g.getPosy() - 50);
g.setPosy(50);
g.setPosx(g.getPosx()-temp);
}
else {
g.setPosy(g.getPosy()-unitChange*d.getDice());
temp = 0;
}
}
Instead of using the current X and Y positions to track which location the piece is stopped on, try tracking which property the piece has landed on instead. so property 1 would be the first stop on the board after GO all the way up to boardwalk at position 39. Then you can have a function like
movePlayerToLocation(Player player, int location){
// calculate your x and y based on the property locatoin
if(locatoin < 11){
// on first edge
} else if (location < 21) {
// on second edge
} else if (location < 31)
// on third edge
} else {
// on fourth edge of the board
}
// do your g.setPos-ing
}
Related
I'm more of an intermediate android dev and I want to learn how to write more clean and effective code, and I've come to this problem on my app that requires to check a bunch of statements like if a variable is less than something or more for each individual rating.
private void rateStock(double peRatio) {
//For Dividend Stocks
if(currentDiv != 0 && fiveYearDiv != 0){
double dividendDiff = currentDiv - fiveYearDiv;
if (peRatio <= 20 && peRatio > 0 && dividendDiff >= 0.01 && payoutRatio <= 0.65) {
int stockRatingDividend = 5;
addItems(stockRatingDividend);
} else if (peRatio > 20 && peRatio <= 25 && dividendDiff >= 0.005 && payoutRatio <= 0.75) {
int stockRatingDividend = 4;
addItems(stockRatingDividend);
} else if (peRatio > 25 && peRatio <= 30 && dividendDiff >= 0.001 && payoutRatio <= 0.85) {
int stockRatingDividend = 3;
addItems(stockRatingDividend);
} else if (peRatio > 30 && peRatio <= 35 && payoutRatio <= 0.95) {
int stockRatingDividend = 3;
addItems(stockRatingDividend);
} else if( peRatio > 35 && peRatio <= 40 && currentDiv > fiveYearDiv && payoutRatio >= 100) {
int stockRatingDividend = 2;
addItems(stockRatingDividend);
} else if( peRatio > 40 || peRatio < 0 && fiveYearDiv > currentDiv && payoutRatio >= 100) {
int stockRatingDividend = 1;
addItems(stockRatingDividend);
} else {
int stockRatingDividend = 0;
addItems(stockRatingDividend);
}
}
}
As you can see by the code above it's very messy and cluttered and doesn't even work correctly, because there are too many conditions it has to check and it usually doesn't fit into any else if statement and just returns 0
I know it might be a lot but can someone at least guide me to a post or something on how I could write more effective and clean code rather than a cluttered mess of else if statements for this block of code?
the possible values of your parameters are not fully represented by the choices in youre if/else branches. So the best way would be to implement a class which decides by itself, if it is responsible for the computation of your single resulting value stockRatingDividend. a sketch of this (with no getters, constructor and no handling, if one border for the min/max is not set) would be:
public class SRDResolver {
public class SRDRolver {
private int peRatioMin;
private int peRatioMax;
private double dividendDiffMin;
private double dividendDiffMax;
private double payoutRatioMin;
private double payoutRatioMax;
private double stockRatingDividend;
public boolean hasSolution(int peRatio,double dividendDiv,double payoutRatio){
return peRatio > peRatioMin && peRatio <= peRatioMax && dividendDiv > dividendDiffMin && dividendDiv <= dividendDiffMax && payoutRatio > payoutRatioMin && payoutRatio <= payoutRatioMax;
}
}
}
then you put the intances in a list. You then get the correct instance from streaming that list with filter(i-> i.hasSolution(...).findFirst(), which gives you an Optional as a result. If it is present, you take it's stockRatingDividend,otherwise you use your fallback value of 0.
That way you can easyily add new instances, if you need,without cluttering if/else. You might add some checks, when you put the instances into the list to ensure, that the number spaces span of the instances do not overlap.
For any future wanderers, that have the same question, I have come up with a solution myself!
What I did was split it into different classes and in the first class ValueLists.java
I created all the ranges and made a getter for the list.
public List<Range> getPeRatioRanges() {
Range range20 = new Range(0, 20);
Range range25 = new Range(21, 25);
Range range30 = new Range(26, 30);
Range range35 = new Range(31, 35);
Range range40 = new Range(36, 40);
List<Range> list = new LinkedList<>(Arrays.asList(range40, range35, range30, range25, range20)); // add in reverse order cuz index = rating
return list;
}
And in the other class CheckRatingOfStock.java I created a simple loop for iterating through the ranges and get the rating.
List<Range> peRatioRanges = getPeRatioRanges();
for (int i = 0; i < peRatioRanges.size(); i++) {
Range range = peRatioRanges.get(i);
int intPERatio = (int) rawPEratio;
if (range.contains(intPERatio)) {
rating = i + 1;
}
}
Here the index of the range is the rating + 1, so if its 0-20 its the rating of 5, because the list is reversed.
This way with 2 blocks of code I avoid a lot of back and forth and the clutter of mass else if statements, and also make it much more easily maintainable and cleaner, atleast in my opinion.
This could be implemented as a method:
static int getIndexOfRange(int intPERatio, List<Range> ranges)
{
for (int i=0; i< ranges.size(); i++)
if (ranges.get(i).contains(intPERatio))
return i+1; //if found, return immediatelly
return -1; //if it reaches this line, means the item was not found
} //return -1 as representation of this
The below two could be combined as it does the same thing.
else if (peRatio > 25 && peRatio <= 30 && dividendDiff >= 0.001 && payoutRatio <= 0.85) {
int stockRatingDividend = 3;
addItems(stockRatingDividend);
} else if (peRatio > 30 && peRatio <= 35 && payoutRatio <= 0.95) {
int stockRatingDividend = 3;
addItems(stockRatingDividend);
}
Also, I would recommend refactoring the if-else block to a new method which returns stockRatingDividend. This would keep the dividend computation logic separate from the other logic, which would actually make the code more understandable.
if(currentDiv != 0 && fiveYearDiv != 0){
double dividendDiff = currentDiv - fiveYearDiv;
addItems(getStockRatingDividend(/*arguments*/));
}
What is the problem? I am using this code to movement for two players. But it is not working. Player1 is more quick than player2. How can I fix?
for (byte i = 0; i < 20; i++) {maxDistance = 10 * Gdx.graphics.getDeltaTi
me();
if (Gdx.input.isTouched(i) && Gdx.input.getY()<= 400) {
player1TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
camera.unproject(player1TouchPosition);
}
player1Tmp.set(player1TouchPosition.x, player1TouchPosition.y).sub(player1Rectangle.x, player1Rectangle.y);
if (player1Tmp.len() <= maxDistance) {
player1Rectangle.x = player1TouchPosition.x;
player1Rectangle.y = player1TouchPosition.y;
} else {
player1Tmp.nor().scl(maxDistance);
player1Rectangle.x += player1Tmp.x;
player1Rectangle.y += player1Tmp.y;
}
if (Gdx.input.isTouched(i) && Gdx.input.getY() >= 401) {
player2TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
camera.unproject(player2TouchPosition);
}
player2Tmp.set(player2TouchPosition.x, player2TouchPosition.y).sub(player2Rectangle.x, player2Rectangle.y);
if (player2Tmp.len() <= maxDistance) {
player2Rectangle.x = player2TouchPosition.x;
player2Rectangle.y = player2TouchPosition.y;
} else {
player2Tmp.nor().scl(maxDistance);
player2Rectangle.x += player2Tmp.x;
player2Rectangle.y += player2Tmp.y;
}
}
Two errors jump out at me:
You used getY() instead of getY(i) in a couple of places, so the criteria are mixed up for any pointer besides the most recent one.
You wrapped it all in a loop that runs 20 times, so you are moving each player 20 times a frame instead of one time each, at most. The movement should be applied outside the loop.
This problem is more complicated than it initially looks, because you have to deal with rejecting extra fingers on either side of the screen. Suppose pointer 1 is a finger on the top half of the screen. If pointer 2 is a finger on the top half, you want to reject it, but if it's on the bottom half, you want to use it to move player 2. If pointers 1 and 2 are both on the top, you want to accept pointer 3 only if it's on the bottom but you want to always reject it if pointers 1 and 2 are on opposite sides.
Furthermore, if only one finger is down, but it slides across the boundary to the other side, you want to be sure you don't let it start controlling the opposite player.
Here's one possible strategy. Track the first pointer down on each side and reset it whenever the tracked pointer is released. Only update target positions for the two currently tracked pointers.
private int player1Pointer = -1, player2Pointer = -1;
// render():
//stop tracking released fingers
if (player1Pointer >=0 && !Gdx.input.isTouched(player1Pointer))
player1Pointer = -1;
if (player2Pointer >=0 && !Gdx.input.isTouched(player2Pointer))
player2Pointer = -1;
//check for new pointers and update target positions
for (int i = 0; i<20; i++){
if (!Gdx.input.isTouched(i))
continue;
if (Gdx.input.getY(i) <= 400){ //bottom, player 1
if (player2Pointer == i)
continue; //player 2 slid finger across boundary, ignore it
if (player1Pointer < 0)
player1Pointer = i; //first finger down on this side of screen, track it
if (player1Pointer == i){ //this is the tracked finger, update target
player1TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
camera.unproject(player1TouchPosition);
}
} else { //top, player 2
if (player1Pointer == i)
continue;
if (player2Pointer < 0)
player2Pointer = i;
if (player2Pointer == i){
player2TouchPosition.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
camera.unproject(player2TouchPosition);
}
}
}
//update movement toward targets
maxDistance = 10 * Gdx.graphics.getDeltaTime();
temp.set(player1TouchPosition.x, player1TouchPosition.y).sub(player1Rectangle.x, player1Rectangle.y);
if (temp.len() <= maxDistance) {
player1Rectangle.x = player1TouchPosition.x;
player1Rectangle.y = player1TouchPosition.y;
} else {
temp.nor().scl(maxDistance);
player1Rectangle.x += temp.x;
player1Rectangle.y += temp.y;
}
temp.set(player2TouchPosition.x, player2TouchPosition.y).sub(player2Rectangle.x, player2Rectangle.y);
if (temp.len() <= maxDistance) {
player2Rectangle.x = player2TouchPosition.x;
player2Rectangle.y = player2TouchPosition.y;
} else {
temp.nor().scl(maxDistance);
player2Rectangle.x += temp.x;
player2Rectangle.y += temp.y;
}
public Action getMove(CritterInfo info) {
count++;
Direction d = info.getDirection();
if (count < 100) {
if (info.getFront() == Neighbor.OTHER) {
return Action.INFECT;
} else {
return Action.RIGHT;
}
}
if (count >= 100) {
if (info.getFront() == Neighbor.OTHER) {
return Action.INFECT;
} else if (count / 100.0 < 2.0 && count / 100.0 >= 1.0 && !(d == Direction.EAST)) {
return Action.LEFT;
} else if (count / 100.0 < 3.0 && count / 100.0 >= 2.0 && !(d == Direction.WEST)) {
return Action.RIGHT;
} else {
return Action.HOP;
}
}
return Action.INFECT;
}
Right now I have this code that is part of my critter and i'm having problems are the if (count >= 100) part of the code. I can't get my go east and go west code to repeat itself because when I divide count by 100.0, it only works up until 299 then it just stays going west running into the wall. I've tried to set an else if statement after my go west code stating
} else if (count == 299) {
count = 0;
}
but this didn't solve my problem either. Any ideas? I just want my critter to sweep east and west over and over again.
Just use variables instead of your numbers, and change them each time their numbers are reached.Then you can create a method that changes the direction each time the number reaches 100+(100*n).
So, if you reach 200, it will check that the condition I set above is true and will therefore change directions for the next 100 numbers.
Was this what you were looking for , or did I misunderstand what you wanted?
You can use some kind of "cyclic" function like modulo (%) instead of the absolute value of count. E.g.
public Action getMove(CritterInfo info) {
count++;
Direction d = info.getDirection();
if (count < 100) {
if (info.getFront() == Neighbor.OTHER) {
return Action.INFECT;
} else {
return Action.RIGHT;
}
}
else {
int choiceOfAction = (count - 100)%200;
if (0 <= choiceOfDir && choiceOfDir < 100 && !(d == Direction.EAST)) {
return Action.LEFT;
} else if (100 <= choiceOfDir && choiceOfDir < 200 && !(d == Direction.WEST)) {
return Action.RIGHT;
} else {
return Action.HOP;
}
}
}
The line int choiceOfAction = (count - 100)%200; will yield a value of choiceOfAction with:
if count is in [100, 200[ : choiceOfAction is in [0, 100[
if count is in [200, 300[ : choiceOfAction is in [100, 200[
if count is in [300, 400[ : choiceOfAction is in [0, 100[
etc.
Note that I removed the last return in your method that was never reached, and also, that in the case above you will HOP only when you reach the limit and change direction.
I'm trying to solve a problem which uses a 2D array, the problem of a rat in a maze.
While checking the conditions trying to compile, it finds an Array index out of bounds exception... how can I check the values so it doesn't go out of the array bounds?
static void solveMaze(){
int nSteps = 0; // Number of steps.
int x = 0; int y = 0; // Starting point.
boolean mazeCompleted = false;
while (!mazeCompleted){
if(x == maze.mazeMatrix.length && y == maze.mazeMatrix.length)
mazeCompleted = true;
else if(maze.mazeMatrix[x+1][y] == 0){ // Move right.
maze.mazeMatrix[x+1][y] = 2;
x++; nSteps++;
}
else if(maze.mazeMatrix[x-1][y] == 0){ // Move left.
maze.mazeMatrix[x-1][y] = 2;
x--; nSteps++;
}
else if(maze.mazeMatrix[x][y+1] == 0){ // Move down.
maze.mazeMatrix[x][y+1] = 2;
y++; nSteps++;
}
else if(maze.mazeMatrix[x][y-1] == 0){ // Move up.
maze.mazeMatrix[x][y-1] = 2;
y--; nSteps++;
}
}
maze.printMatrix();
System.out.println("Maze COMPLETE! - With a total of " + nSteps + " steps.");
}
Tried before with two "for" loops to prevent the out of bounds but I just can't go diagonal in this problem.
You have a pretty crucial bug in your program. You will never reach the end of the maze!
if(x == maze.mazeMatrix.length && y == maze.mazeMatrix.length)
references indices that are out of bounds! It should be
if(x == maze.mazeMatrix.length - 1 && y == maze.mazeMatrix.length - 1)
You also need to check to see whether you can & should move before you try to move there. I.E. :
while (!mazeCompleted){
boolean moveRight = (x + 1 < mazeMatrix.length && maze.mazeMatrix[x+1][y] == 0 ? true : false);
boolean moveLeft = (x - 1 >= 0 && maze.mazeMatrix[x-1][y] == 0 ? true : false);
boolean moveUp = (y + 1 < mazeMatrix[x].length && maze.mazeMatrix[x][y+1] == 0 ? true : false);
boolean moveDown = (y - 1 >= 0 && maze.mazeMatrix[x][y-1] == 0 ? true : false);
And:
else if(moveRight) { // Move right.
maze.mazeMatrix[x+1][y] = 2;
x++; nSteps++;
}
etc. Although it does seem like this is something that should be solved recursively, as if there are any loops in the maze you will end up getting stuck and infinite looping.
I have a cube and I am moving it between 3 points (float positions) only on the x axis. So the cube will start at 0.00 I press the right key and it moves right on the x axis to 2.0f. I then press the left key and it moves back to 0.0f. I then press the left key again and it moves to -2.0f. Pressing the right key should now return it to 0.0f but instead it goes beyond 0. and the size of the error depends on the speed I move at.
This also has the same result if i start with the left key.
if(MoveLeftFlag == true)
{
if(PositionFlag == 0)
{
if(Cube1.PositionX > MinCubeMovement)
{
Cube1.MoveLocalX(-CubeMoveSpeed * FrameTime );
}
else if(Cube1.PositionX < MinCubeMovement)
{
PositionFlag = -1;
MoveLeftFlag = false;
}
}
if(PositionFlag == 1)
{
if(Cube1.PositionX > Middle)
{
Cube1.MoveLocalX(-CubeMoveSpeed * FrameTime );
}
else if(Cube1.PositionX < Middle)
{
MoveLeftFlag = false;
PositionFlag = 0;
}
}
}
if(MoveRightFlag == true)
{
if(PositionFlag == 0)
{
if(Cube1.PositionX < MaxCubeMovement)
{
Cube1.MoveLocalX(CubeMoveSpeed * FrameTime );
}
else if(Cube1.PositionX > MaxCubeMovement)
{
MoveRightFlag = false;
PositionFlag = 1;
}
}
if(PositionFlag == -1)
{
if(Cube1.PositionX < Middle)
{
Cube1.MoveLocalX(CubeMoveSpeed * FrameTime );
}
else if(Cube1.PositionX > Middle)
{
MoveRightFlag = false;
PositionFlag = 0;
}
}
}
FrameTime is float frametime = getTimeInMillSeconds()/1000;
and the speed is set to `0.000001f; which moves it at a nice smooth speed for me.
As i said if i make the speed greater then when the cube is returning to 0.0f for the second time the offset error becomes greater.
Can anyone point me in the right direction.
Ok Well i have fixed the problem,surprised i didnt pick up on this but basically i was using < and > when i should have been using >= and <=.