How to navigate a Barbie in a grid system? [closed] - java

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I'm trying to solve an interesting problem for navigating a Barbie doll inside a grid system. Initially, Barbie is in [0,0] position, means in the intersection of the X and Y axis. Barbie has 3 operations on movement with 'F' for forward, 'R' for right turn (90 degree) and 'L' for left turn (90 degree). Say, if I pass the direction String of "FF", the position should be [0,2]. I solve the problem and the current state of code is as following,
public static void barbiePosition(String str ){
if( str == null || str.length() == 0)
return;
int [] initial = {0,0};
boolean xPos = false, xNeg = false, yPos = true, yNeg = false;
char[] ch = str.toCharArray();
for( char c: ch){
// the initial postion of the robot is towards the positive Y axis
if(c == 'L'){
if(xPos){
xPos = false;
yPos = true;
}
else if ( xNeg){
xNeg = false;
yNeg = true;
}
else if(yPos){
xNeg = true;
yPos = false;
}
else if (yNeg){
yNeg = false;
xPos = true;
}
}
else if ( c == 'R'){
if(xPos){
xPos = false;
yNeg = true;
}
else if ( xNeg){
yPos = true;
xNeg = false;
}
else if(yPos){
yPos = false;
xPos = true;
}
else if (yNeg){
yNeg = false;
xNeg = true;
}
}
else if (c == 'F'){
if(xNeg){
initial[0] -= 1;
}
else if (xPos){
initial[0] += 1;
}
else if (yNeg){
initial[1] -=1;
}
else if( yPos){
initial[1] += 1;
}
}
}
System.out.println(Arrays.toString(initial));
}
The thing is I just don't the solution as it's feels ugly. Is there any better way
to design the algorithm ?

What constitutes 'forward' in your application is a function of the previous move.
Forward simply means you repeat your last move.
If forward is your first move you need to pick a convention that says something like "Barbie is initially moving to the right".

Related

the draw() method in my code isn't working properly [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 days ago.
Improve this question
I am making a uno game for a school project. The code displayed below if giving me some issues, and i dont know why.
The code below is suppose to check if the cpu has any cards that match the players card in the middle. If there is a card that matches, the cpu places it down. If there isnt a card that matches, the code checks to see if the cpu has a wild card, if so it places it down, if not then it draws.
For some reason the draw() method is giving me issues, rather than the cpu drawing just 1 card, sometimes it draws 2, 5, 10,etc.
To be clear, i am pretty sure the issue isnt my draw method, i have tested it out.
I assume the issue stems from a problem with my loops in the gamePlayed subclass.
Here is the code
private void game_played(Canvas canvas, MouseEvent event) {
//Setting the horizontal position of the mouse to x
double x = event.getX();
//Setting the Vertical position of the mouse to x
double y = event.getY();
//Setting the defualt card in the Middle
boolean played = false;
for (int i = 0 ; i < human.getHand().size(); i++) {
if (x > 20+75*(i%10) && x < 20+75*(i%10) + 75
&& y > 400+110*(i/10) && y <400+110*(i/10)+110) {
//C becomes the card we clicked
myCard c = human.getHand().get(i);
//C is placed in the middle of the scene
humanMiddle = c;
//We remove the card clicked from our hand
human.getHand().remove(i);
//Breaking the loop
//My code - checking for color match
//If the card in the middle for the human is red
if (humanMiddle.color == myCard.RED) {
//loop through the cpu hand, and see if you find a red card
for (int r = 0; r < cpu.getHand().size(); r++ ) {
//if you find a red card
if (cpu.getHand().get(r).color == myCard.RED) {
//the cpu middle now becomes that card
cpuMiddle = cpu.getHand().get(r);
//we remove the card from the hand
cpu.getHand().remove(r);
//else if, we have a wild card
} else if (cpu.getHand().get(r).value == -1){
//the cpu middle now becomes the wild card
cpuMiddle = cpu.getHand().get(r);
//we remove the wild card from the hand
cpu.getHand().remove(r);
} else {
cpu.draw();
}
}
}
if (humanMiddle.color == myCard.BLUE) {
for (int b = 0; b < cpu.getHand().size(); b++ ) {
if (cpu.getHand().get(b).color == myCard.BLUE) {
cpuMiddle = cpu.getHand().get(b);
cpu.getHand().remove(b);
} else if (cpu.getHand().get(b).value == -1){
cpuMiddle = cpu.getHand().get(b);
cpu.getHand().remove(b);
} else {
cpu.draw();
}
}
}
if (humanMiddle.color == myCard.YELLOW) {
for (int ye = 0; ye < cpu.getHand().size(); ye++ ) {
if (cpu.getHand().get(ye).color == myCard.YELLOW) {
cpuMiddle = cpu.getHand().get(ye);
cpu.getHand().remove(ye);
} else if (cpu.getHand().get(ye).value == -1){
cpuMiddle = cpu.getHand().get(ye);
cpu.getHand().remove(ye);
} else {
cpu.draw();
}
}
}
if (humanMiddle.color == myCard.GREEN) {
for (int g = 0; g < cpu.getHand().size(); g++ ) {
if (cpu.getHand().get(g).color == myCard.GREEN) {
cpuMiddle = cpu.getHand().get(g);
cpu.getHand().remove(g);
} else if (cpu.getHand().get(g).value == -1){
cpuMiddle = cpu.getHand().get(g);
cpu.getHand().remove(g);
} else {
cpu.draw();
}
}
}
played = true;
break;
}
}
here is the draw method
public void draw() {
int value = (int)(Math.random()*13);
int color = (int)(Math.random()*5);
while (value == 11) value = (int)(Math.random()*13);
if (color == myCard.BLACK) {
value = -1;
}
myCard card = new myCard();
card.value = value;
card.color = color;
hand.add(card);
}
I would appreciet any help
I have tried, adding breaks, to stop the loops at Certain points, but it just makes it worst.

When the player hits the food make it disapear

I am new to programing, so bare with me lol. Our teacher has given us a game in which we need to add some elements to it. It's a game where we have a player, some enemies and some food made out of rectangles. If the player hits the food i want the food to spawn somewhere else in the window. Heres is the code where im trying to make it happen:
private void updateFood(){
for(int i = 0; i < food.length; ++i)
{
//Should we follow or move randomly?
//2 out of 3 we will follow..
if(rnd.nextInt(3) < 2)
{
//We follow
int dx = player.getX() - food[i].getX();
int dy = player.getY() - food[i].getY();
if(abs(dx) > abs(dy))
{
if(dx > 0)
{
//Player is to the right - opiste
food[i].moveLeft();
}
else
{
//Player is to the left - opiste
food[i].moveRight();
}
}
else if(dy > 0)
{
//Player is down; - opiste
food[i].moveUp();
}
else
{//Player is up; - opiste
food[i].moveDown();
}
}
else
{
//We move randomly
int move = rnd.nextInt(4);
if(move == 0)
{
//Move right
food[i].moveRight();
}
else if(move == 1)
{
//Move left
food[i].moveLeft();
}
else if(move == 2)
{
//Move up
food[i].moveUp();
}
else if(move == 3)
{
//Move down
food[i].moveDown();
}
}
if(food[i].getX() == player.getX() && food[i].getY() == player.getY()){
food[i].getX() = random(0,width);
food[i].getY() = random(0,height);
}
}
}
the last 10 lines (or so) is where im having the problem.
if(food[i].getX() == player.getX() && food[i].getY() == player.getY()){
food[i].getX() = random(0,width);
food[i].getY() = random(0,height);
With limited info on what methods your food[index] objects have, I'm going to guess .getX() is read-only, meaning you can't set a value to it. Either find a .setX(number) method, or use the existing .moveLeft/Right/Up/Down(number) with a bit of maths.

Room placement in a maze using Prim's algorithm

I am attempting to place rooms on an ASCII screen, and then use Prim's algorithm to "fill" the space between rooms with maze, but without actually breaking into the rooms. I have been tinkering for a few hours, and I can't figure out a way to stop my algorithm from breaking into my rooms.
Can anyone help me? I'm pretty lost. I'm practicing map generation techniques, and this is my 5th one I'm on. No, I don't want to do it another way, I simply want to do it this way - but right.
Below is both a photo of my current output with rooms, my current output without rooms, and a link to the relevant source code (AKA the Prim's algorithm section). Thanks again if you can actually help me!
Note: All the opposite method does is figure out which cell the "parent" cell is, and determine direction based off of that. So if parent cell's x value is 7, and the child's x value is 6, then it know that's the new child.
start = new Point(x,y, null);
map[start.x][start.y] = Tile.STAIRS_DOWN;
for(int nx = -1; nx <= 1; nx++){
for(int ny = -1; ny <= 1; ny++){
if((nx == 0 && ny == 0) || (nx != 0 && ny != 0)){
continue;
}
try{
if(map[start.x + nx][start.y + ny] == Tile.FLOOR){
continue;
}
frontier.add(new Point(start.x+nx, start.y + ny, start));
}
catch(Exception e){
continue;
}
}
}
Point last = null;
while(!frontier.isEmpty()){
Point cu = frontier.remove(RandomGen.rand(0, frontier.size() - 1));
Point op = cu.opposite();
try{
if((map[cu.x][cu.y] == Tile.WALL) && (map[op.x][op.y] == Tile.WALL)){
for (int bx = -1; bx <= 1; bx++)
for (int by = -1; by <= 1; by++) {
boolean failed = false;
if (bx == 0 && by == 0 || bx != 0 && by != 0)
continue;
try {
if(map[op.x + bx][op.y + by] == Tile.FLOOR){
break;
}
last = op;
if(!failed){
map[cu.x][cu.y] = Tile.FLOOR;
map[op.x][op.y] = Tile.FLOOR;
frontier.add(new Point(op.x + bx, op.y + by, op));
}
}
catch(Exception e){
continue;
}
}
}
}
catch(Exception e){}
}
Without Rooms
With Rooms
Solved: I needed to check my forward facing corners for open spaces. So if I'm going "east" then I need to check Northeast and Southeast tiles as well, or else I will potentially burrow into the rooms.

Maze pathfinding, Array 2-D [duplicate]

This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 6 years ago.
I am trying to use stacks to find my way through a maze.
Before I worry about stacks, I am trying to get it so that it comes to a dead-end first.
However, when I run my code I am getting java.lang.ArrayIndexOutofBoundsException: -1. Which does not make sense since I am constantly updating the rows and columns.
Here is part of my code that I am stuck on:
Maze myMaze = new Maze (rows, columns);
MazeDisplay myDisplay = new MazeDisplay (myMaze);
myMaze.buildMaze(10);
myMaze.setSolveAnimationDelay(75);
boolean [][] mazeArray = new boolean [rows][columns];
for (int row=0; row<mazeArray.length; row++)
for (int col=0; col<mazeArray[row].length; col++)
mazeArray[row][col] = false;
mazeArray [myMaze.getCurrentRow()][myMaze.getCurrentCol()] = true;
for (int i = 0; i < 9999999 ; i++) //Temporary for now
{
int arrayRows = myMaze.getCurrentRow();
int arrayCols = myMaze.getCurrentCol();
if (myMaze.isOpen(Maze.Direction.RIGHT) && mazeArray [arrayRows][1 + arrayCols] == false)
{
myMaze.move(Maze.Direction.RIGHT);
//mazeStack.push(Maze.Direction.RIGHT);
mazeArray[arrayRows][arrayCols] = true;
}
else if (myMaze.isOpen(Maze.Direction.UP) && mazeArray [1 + arrayRows][arrayCols] == false)
{
myMaze.move(Maze.Direction.UP);
//mazeStack.push(Maze.Direction.UP);
mazeArray[arrayRows][arrayCols] = true;
}
else if (myMaze.isOpen(Maze.Direction.LEFT) && mazeArray [arrayRows][arrayCols - 1] == false) // <---Getting an error here.
{
myMaze.move(Maze.Direction.LEFT);
//mazeStack.push(Maze.Direction.LEFT);
mazeArray[arrayRows][arrayCols] = true;
}
else if (myMaze.isOpen(Maze.Direction.DOWN) && mazeArray [arrayRows - 1][arrayCols] == false) // <---Getting an error here.
{
myMaze.move(Maze.Direction.DOWN);
//mazeStack.push(Maze.Direction.DOWN);
mazeArray[arrayRows][arrayCols] = true;
}
Is there a way to get around this? What I want is to access the ArrayList's position down or left of the current position.
Here are some of the methods of the Maze class:
//-------- isOpen - returns true if there is no wall in the direction that is passed in
public boolean isOpen(Direction direction)
{
boolean result = false;
if (direction == Direction.UP && mazeArray[currentArrayRow-1][currentArrayCol]==0)
result = true;
else if (direction == Direction.DOWN && mazeArray[currentArrayRow+1][currentArrayCol]==0)
result = true;
else if (direction == Direction.LEFT && mazeArray[currentArrayRow][currentArrayCol-1]==0)
result = true;
else if (direction == Direction.RIGHT && mazeArray[currentArrayRow][currentArrayCol+1]==0)
result = true;
return result;
}
//-------- getCurrentRow - returns the current (real) row
public int getCurrentRow()
{
return currentArrayRow/2;
}
//-------- getCurrentCol - returns the current (real) col
public int getCurrentCol()
{
return currentArrayCol/2;
}
// -------- move - receives a Direction and moves there if OK. Calls the other
// arrayMove to do this
public boolean move(Direction direction)
{
boolean success = false;
if (direction == Direction.UP)
success = arrayMove(currentArrayRow-2, currentArrayCol);
else if (direction == Direction.DOWN)
success = arrayMove(currentArrayRow+2, currentArrayCol);
else if (direction == Direction.LEFT)
success = arrayMove(currentArrayRow, currentArrayCol-2);
else if (direction == Direction.RIGHT)
success = arrayMove(currentArrayRow, currentArrayCol+2);
return success;
}
//This is Maze's enumerated data type: moves can be UP, DOWN, LEFT, RIGHT
public enum Direction
{
UP, DOWN, LEFT, RIGHT
}
//-------- getMazeArray - returns the mazeArray
public int[][] getMazeArray()
{
return mazeArray;
}
Before checking the left cell, you should check that you are not on the left edge. Otherwise mazeArray [arrayRows][arrayCols - 1] will throw an exception, since arrayCols - 1 = -1.
If I understand your code correctly, your algorithm isn't perfect. It gets stuck at dead ends. I think the shortest path algorithm is the easiest one to implement.

Can anyone lend a fresh pair of eyes for debugging?

The purpose of this assignment was to create a Field and Robot class and objects of those classes.
The single field object is limited to a square of points from (0, 0) to (50, 50), and contains 3 pieces of gold and 3 bombs.
Three robot objects search the field (one after another) for gold from left to right (0, 0) to (0, 50) and descend through the field (1, 0) to 1, 50) and so on.
The robots are destroyed by bombs that are places by input from the user. Once the gold is collected it cannot be picked up by another robot, and one a bomb explodes it does not do so again.
This is my attempt at solving the problem so far, I am continuing to work on it, but would appreciate a second pair of eyes on it to catch something im missing. The program compiles, but the bombs and gold arent being "found" correctly and the output states that the following robots die on the same bomb as the one before it. Also, there are several pieces of code removed by comments, I did this to test different parts of the program. I think this section is where I'm having trouble. The methods field.alreadyFound() and field.alreadyBombed() return a boolean with the value true. My if statements should be saying if the gold/bomb has already been found, ignore it.
while(x <= 50 && y <= 50 && alive2 == true) {
foundGold1 = robot2.look(field.locateGold1());
foundGold2 = robot2.look(field.locateGold2());
foundGold3 = robot2.look(field.locateGold3());
foundBomb1 = robot2.look(field.locateBomb1());
foundBomb2 = robot2.look(field.locateBomb2());
foundBomb3 = robot2.look(field.locateBomb3());
/*gotBomb1 = field.alreadyBombed1();
gotBomb2 = field.alreadyBombed2();
gotBomb3 = field.alreadyBombed3();
gotGold1 = field.alreadyFound1();
gotGold2 = field.alreadyFound2();
gotGold3 = field.alreadyFound3();*/
if (foundGold1 == true){
if (field.alreadyFound1() == true){}
else {robot2.addGold();
field.foundGold1();}
}
if (foundGold2 == true) {
if (field.alreadyFound2() == true){}
else {robot2.addGold();
field.foundGold2();}
}
if (foundGold3 == true) {
if (field.alreadyFound3() == true){}
else {robot2.addGold();
field.foundGold3();}
}
if (foundBomb1 == true) {
if (field.alreadyBombed1() == true){}
else alive2 = false;
}
if (foundBomb2 == true) {
if (field.alreadyBombed2() == true){}
else alive2 = false;
}
if (foundBomb3 == true) {
if (field.alreadyBombed3() == true){}
else alive2 = false;
}
y = y + 1;
robot2.setLocation(x, y);
//System.out.println(y);
if (y == 50)
{x = x + 1;
y = 0;}
}
I don't see where you set that a bomb has exploded, so from what I see here, you're missing that part.
Below is the code reformatted and slightly restructured: I found the code fairly difficult to work with as-is. It may be easier to work with this shorter, more canonical, and IMO more communicative version.
while (x <= 50 && y <= 50 && alive2 == true) {
foundGold1 = robot2.look(field.locateGold1());
foundGold2 = robot2.look(field.locateGold2());
foundGold3 = robot2.look(field.locateGold3());
foundBomb1 = robot2.look(field.locateBomb1());
foundBomb2 = robot2.look(field.locateBomb2());
foundBomb3 = robot2.look(field.locateBomb3());
/*gotBomb1 = field.alreadyBombed1();
gotBomb2 = field.alreadyBombed2();
gotBomb3 = field.alreadyBombed3();
gotGold1 = field.alreadyFound1();
gotGold2 = field.alreadyFound2();
gotGold3 = field.alreadyFound3();*/
if (foundGold1 && !field.alreadyFound1()) {
robot2.addGold();
field.foundGold1();
}
if (foundGold2 && !field.alreadyFound2()) {
robot2.addGold();
field.foundGold2();
}
if (foundGold3 && !field.alreadyFound3()) {
robot2.addGold();
field.foundGold3();
}
if (foundBomb1 && !field.alreadyBombed1()) {
alive2 = false;
}
if (foundBomb2 && !field.alreadyBombed2()) {
alive2 = false;
}
if (foundBomb3 && !field.alreadyBombed3()) {
alive2 = false;
}
y = y + 1;
robot2.setLocation(x, y);
if (y == 50) {
x = x + 1;
y = 0;
}
}
You may also be hampered by the amount of code it takes to do this work: I assume you have essentially identical code for robot1 and robot2, the only difference being which robot you're currently processing.
Rather than repeat the code, consider passing a currentRobot in to a single method. There are a variety of ways to go about dealing with issues like this, but that fits in well with what you've already done. You're likely want to add an isAlive method/property to the robot class.

Categories

Resources