Solving 2D Maze in Java - java

I've been trying to make a program that will solve a 2D integer maze. I keep getting a stackOverFlowError. I incorporated cases to set preferences in movement i.e North, South, East, West. I cannot find the issue in my recursive method.
import java.util.*;
import java.awt.*;
public class Runner
{
private static int[][] maze = MazeReader.getMaze("C:\\Users\\owner\\Desktop\\myMaze.txt");
private static int[][] solution = new int[maze.length][maze[0].length];
private static Point[] prefs = new Point[4];
private static int goalX, goalY, startX, startY;
/*
* if (x,y outside maze) return false
if (x,y is goal) return true
if (x,y not open) return false
mark x,y as part of solution path
if (FIND-PATH(North of x,y) == true) return true
if (FIND-PATH(East of x,y) == true) return true
if (FIND-PATH(South of x,y) == true) return true
if (FIND-PATH(West of x,y) == true) return true
unmark x,y as part of solution path
return false
*/
private static boolean FIND_PATH(int x, int y)
{
if(x<0||x>=maze.length||y<0||y>=maze[0].length){return false;}
if(x==goalX&&y==goalY){return true;}
if(maze[x][y]==1){return false;}
solution[x][y] = 2;
if(FIND_PATH(x+(int)prefs[0].getX(),y+(int)prefs[0].getY())){return true;}
else if(FIND_PATH(x+(int)prefs[1].getX(),y+(int)prefs[1].getY())){return true;}
else if(FIND_PATH(x+(int)prefs[2].getX(),y+(int)prefs[2].getY())){return true;}
else if(FIND_PATH(x+(int)prefs[3].getX(),y+(int)prefs[3].getY())){return true;}
else {solution[x][y] = 0;}
return false;
}
/*
* Locate the start position (call it startx, starty).
Call FIND-PATH(startx, starty).
*/
private static void solve(int sx, int sy, int gx, int gy, char p1, char p2, char p3, char p4)
{
establishPrefs(p1,p2,p3,p4);
startX = sx;
startY = sy;
goalX = gx;
goalY = gy;
if(FIND_PATH(startX,startY))
{
solution[startX][startY] = 3;
solution[goalX][goalY] = 4;
}
else{System.out.println("No Solution Found");}
FIND_PATH(startX,startY);
}
private static void establishPrefs(char p1, char p2, char p3, char p4)
{
switch(p1)
{
case 'N': prefs[0] = new Point(0,1);break;
case 'S': prefs[0] = new Point(0,-1);break;
case 'E': prefs[0] = new Point(1,0);break;
case 'W': prefs[0] = new Point(-1,0);break;
}
switch(p2)
{
case 'N': prefs[1] = new Point(0,1);break;
case 'S': prefs[1] = new Point(0,-1);break;
case 'E': prefs[1] = new Point(1,0);break;
case 'W': prefs[1] = new Point(-1,0);break;
}
switch(p3)
{
case 'N': prefs[2] = new Point(0,1);break;
case 'S': prefs[2] = new Point(0,-1);break;
case 'E': prefs[2] = new Point(1,0);break;
case 'W': prefs[2] = new Point(-1,0);break;
}
switch(p4)
{
case 'N': prefs[3] = new Point(0,1);break;
case 'S': prefs[3] = new Point(0,-1);break;
case 'E': prefs[3] = new Point(1,0);break;
case 'W': prefs[3] = new Point(-1,0);break;
}
}
private static Point[] getPrefs(){return prefs;}
public static void main(String[] args)
{
MazeReader.display(maze);
solve(0,0,0,2,'S','E','N','W');
MazeReader.display(solution);
}
}

Although you are marking solution[x][y] as part of your solution path, you are not checking if you are returning to a previous point on your solution. In essence, you end up going in circles.
You must not follow paths that lead you into a position that is currently part of your tentative solution.
if(maze[x][y]==1){return false;}
if(solution[x][y] == 2) {return false;} // <-- Add
solution[x][y] = 2;

Related

Array of Characters not updated properly java

I am trying to make pong in a terminal on windows in java.
I have an array of characters (called board) and the paddle positions are updated by the following code
public void movePaddles()
{
int inp = 0;
try
{
inp = System.in.read();
}
catch(Exception e)
{
return;
}
int olr = rtop;
int oll = ltop;
switch(inp)
{
case 'w':
ltop -=1;
break;
case 's':
ltop += 1;
break;
case 'i':
rtop -= 1;
break;
case 'k':
rtop += 1;
break;
}
updatePaddle('L',oll);
updatePaddle('R',olr);
}
public void updatePaddle(char side,int oldtop)
{
int edge = 0;
int top = 0;
// Leave 1 char of space
if (side == 'L')
{
edge = 1;
top = ltop;
}
else if (side == 'R')
{
edge = y-2;
top = rtop;
}
for (int i = oldtop;i < paddleSize+1;i++)
{
board[i][edge] = ' ';
}
for (int i = top;i < paddleSize+2;i++)
{
board[i][edge] = paddleChar;
}
}
What ends up happening is that the paddles disappear when moving down, making the game unplayable. What am I doing wrong?
(full code on github at https://github.com/Tookmund/Text-Pong)
I did try debugging my program before I posted my question but not properly it appears.
Basically I needed to add the value of the current location (top/oldtop) so that the loop would not exit prematurely because i was initially bigger that the paddleSize.

DeckOfCards and HighLow Class incompatible types

I get an incompatible types error when running my code. It is when "playerGuess = d1.deal();"
Thank you in advanced. This main has two other classes that go along with it. The DeckOfCards and Cards Classes.
Card Class
public class Card
{
public final static int ACE = 1;
public final static int TWO = 2;
public final static int THREE = 3;
public final static int FOUR = 4;
public final static int FIVE = 5;
public final static int SIX = 6;
public final static int SEVEN = 7;
public final static int EIGHT = 8;
public final static int NINE = 9;
public final static int TEN = 10;
public final static int JACK = 11;
public final static int QUEEN = 12;
public final static int KING = 13;
public final static int CLUBS = 1;
public final static int DIAMONDS = 2;
public final static int HEARTS = 3;
public final static int SPADES = 4;
private final static int NUM_FACES = 13;
private final static int NUM_SUITS = 4;
private int face, suit;
private String faceName, suitName;
//-----------------------------------------------------------------
// Creates a random card.
//-----------------------------------------------------------------
public Card()
{
face = (int) (Math.random() * NUM_FACES) + 1;
setFaceName();
suit = (int) (Math.random() * NUM_SUITS) + 1;
setSuitName();
}
//-----------------------------------------------------------------
// Creates a card of the specified suit and face value.
//-----------------------------------------------------------------
public Card(int faceValue, int suitValue)
{
face = faceValue;
setFaceName();
suit = suitValue;
setSuitName();
}
//-----------------------------------------------------------------
// Sets the string representation of the face using its stored
// numeric value.
//-----------------------------------------------------------------
private void setFaceName()
{
switch (face)
{
case ACE:
faceName = "Ace";
break;
case TWO:
faceName = "Two";
break;
case THREE:
faceName = "Three";
break;
case FOUR:
faceName = "Four";
break;
case FIVE:
faceName = "Five";
break;
case SIX:
faceName = "Six";
break;
case SEVEN:
faceName = "Seven";
break;
case EIGHT:
faceName = "Eight";
break;
case NINE:
faceName = "Nine";
break;
case TEN:
faceName = "Ten";
break;
case JACK:
faceName = "Jack";
break;
case QUEEN:
faceName = "Queen";
break;
case KING:
faceName = "King";
break;
}
}
//-----------------------------------------------------------------
// Sets the string representation of the suit using its stored
// numeric value.
//-----------------------------------------------------------------
private void setSuitName()
{
switch (suit)
{
case CLUBS:
suitName = "Clubs";
break;
case DIAMONDS:
suitName = "Diamonds";
break;
case HEARTS:
suitName = "Hearts";
break;
case SPADES:
suitName = "Spades";
break;
}
}
//-----------------------------------------------------------------
// Determines if this card is higher than the passed card. The
// second parameter determines if aces should be considered high
// (beats a King) or low (lowest of all cards). Uses the suit
// if both cards have the same face.
//-----------------------------------------------------------------
public boolean isHigherThan(Card card2, boolean aceHigh)
{
boolean result = false;
if (face == card2.getFace())
{
if (suit > card2.getSuit())
result = true;
}
else
{
if (aceHigh && face == ACE)
result = true;
else
if (face > card2.getFace())
result = true;
}
return result;
}
//-----------------------------------------------------------------
// Determines if this card is higher than the passed card,
// assuming that aces should be considered high.
//-----------------------------------------------------------------
public boolean isHigherThan(Card card2)
{
return isHigherThan(card2, true);
}
//-----------------------------------------------------------------
// Returns the face (numeric value) of this card.
//-----------------------------------------------------------------
public int getFace()
{
return face;
}
//-----------------------------------------------------------------
// Returns the suit (numeric value) of this card.
//-----------------------------------------------------------------
public int getSuit()
{
return suit;
}
//-----------------------------------------------------------------
// Returns the face (string value) of this card.
//-----------------------------------------------------------------
public String getFaceName()
{
return faceName;
}
//-----------------------------------------------------------------
// Returns the suit (string value) of this card.
//-----------------------------------------------------------------
public String getSuitName()
{
return suitName;
}
//-----------------------------------------------------------------
// Returns the string representation of this card, including
// both face and suit.
//-----------------------------------------------------------------
public String toString()
{
return faceName + " of " + suitName;
}
}
Deck of Cards Class
public class DeckOfCards
{
private Card[] myCardDeck;
private int nowCard;
public DeckOfCards( ) {
myCardDeck = new Card[ 52 ];
int i = 0;
for ( int suit = Card.SPADES; suit <= Card.DIAMONDS; suit++ )
for ( int pos = 1; pos <= 13; pos++ )
myCardDeck[i++] = new Card(suit, pos);
nowCard = 0;
}
public void shuffle(int n)
{
int i, j, k;
for ( k = 0; k < n; k++ )
{
i = (int) ( 52 * Math.random() );
j = (int) ( 52 * Math.random() );
Card tmp = myCardDeck[i];
myCardDeck[i] = myCardDeck[j];
myCardDeck[j] = tmp;;
}
nowCard = 0;
}
public Card deal()
{
if ( nowCard < 52 )
{
return ( myCardDeck[ nowCard++ ] );
}
else
{
System.out.println("No Cards BRUH");
return ( null );
}
}
public String toString()
{
String s = "";
int Q = 0;
for ( int i = 0; i < 4; i++ )
{
for ( int j = 1; j <= 13; j++ )
s += (myCardDeck[Q++] + " ");
s += "\n";
}
return ( s );
}
public int deckSize()
{
for(int z =0; z < myCardDeck.length && z < 52; z++);
return myCardDeck.length;
}
}
The main driver class (HighLow)
import java.util.*;
public class HighLow
{
public static void main (String [] args)
{
DeckOfCards d1 = new DeckOfCards();
Scanner scan = new Scanner(System.in);
String playerGuess;
Card firstDeal, secondDeal;
int count =0;
d1.shuffle(1);
firstDeal = d1.deal();
while(true)
{
if(d1.deckSize() == 0);
{
System.out.print("Game over! Score: " + count);
break;
}
System.out.print(firstDeal);
System.out.print("Guess if next card will be a high card, or a low card!");
System.out.print("Use H or L");
playerGuess = d1.deal();
if(secondDeal.isHigherThan(firstDeal)&&playerGuess.equals("H"))
{
System.out.print("Nice!!!!");
count++;
firstDeal=secondDeal;
}
else if(firstDeal.isHigherThan(secondDeal) && playerGuess.equals("L"))
{
System.out.println("NICE!!!!");
count++;
firstDeal = secondDeal;
}
else if (firstDeal.isHigherThan(secondDeal) && playerGuess.equals("L"))
{
System.out.print("Good Job!!!!");
count++;
firstDeal = secondDeal;
}
else
{
System.out.println("Sorry, the game is over. But your score is! " + count);
break;
}
}
}}
Thank you!
The method deal() returns a Card:
public Card deal() { ... }
The variable playerGuess is a String:
String playerGuess;
You can't assign a Card to a String:
playerGuess = d1.deal(); // incompatible types
It looks like you want playerGuess to store the user input, so it should be:
playerGuess = scan.next();

java.lang.reflect.InvocationTargetException error

I am working on a robot maze where the robot finds the target without bumping into walls. As a "backtrack" method, I need the robot to go in the opposite direction as it did when it first came across a junction. This is my code:
import uk.ac.warwick.dcs.maze.logic.IRobot;
import java.util.ArrayList;
import java.util.*;
import java.util.Iterator;
public class Explorer {
private int pollRun = 0; // Incremented after each pass.
private RobotData robotData; // Data store for junctions.
private ArrayList<Integer> nonWallDirections;
private ArrayList<Integer> passageDirections;
private ArrayList<Integer> beenbeforeDirections;
private Random random = new Random();
int [] directions = {IRobot.AHEAD, IRobot.LEFT, IRobot.RIGHT, IRobot.BEHIND};
public void controlRobot (IRobot robot) {
// On the first move of the first run of a new maze.
if ((robot.getRuns() == 0) && (pollRun ==0))
robotData = new RobotData();
pollRun++; /* Increment poll run so that the data is not reset
each time the robot moves. */
int exits = nonwallExits(robot);
int direction;
nonWallDirections = new ArrayList<Integer>();
passageDirections = new ArrayList<Integer>();
beenbeforeDirections = new ArrayList<Integer>();
// Adding each direction to the appropriate state ArrayList.
for(int item : directions) {
if(robot.look(item) != IRobot.WALL) {
nonWallDirections.add(item);
}
}
for(int item : directions) {
if(robot.look(item) == IRobot.PASSAGE) {
passageDirections.add(item);
}
}
for(int item : directions) {
if(robot.look(item) == IRobot.BEENBEFORE) {
beenbeforeDirections.add(item);
}
}
// Calling the appropriate method depending on the number of exits.
if (exits < 2) {
direction = deadEnd(robot);
} else if (exits == 2) {
direction = corridor(robot);
} else {
direction = junction(robot);
robotData.addJunction(robot);
robotData.printJunction(robot);
}
robot.face(direction);
}
/* The specification advised to have to seperate controls: Explorer and Backtrack
and a variable explorerMode to switch between them.
Instead, whenever needed I shall call this backtrack method.
If at a junction, the robot will head back the junction as to when it first approached it.
When at a deadend or corridor, it will follow the beenbefore squares until it
reaches an unexplored path. */
public int backtrack (IRobot robot) {
if (nonwallExits(robot) > 2) {
return robotData.reverseHeading(robot);
} else {
do {
return nonWallDirections.get(0);
} while (nonwallExits(robot) == 1);
}
}
// Deadend method makes the robot follow the only nonwall exit.
public int deadEnd (IRobot robot) {
return backtrack(robot);
}
/* Corridor method will make the robot follow the one and only passage.
The exception is at the start. Sometimes, the robot will start with
two passages available to it in which case it will choose one randomly.
If there is no passage, it will follow the beenbefore squares
until it reaches an unexplored path.*/
public int corridor (IRobot robot) {
if (passageExits(robot) == 1) {
return passageDirections.get(0);
} else if (passageExits(robot) == 2) {
int randomPassage = random.nextInt(passageDirections.size());
return passageDirections.get(randomPassage);
} else {
return backtrack(robot);
}
}
/* Junction method states if there is more than one passage, it will randomly select one.
This applies to crossroads as well as essentially they are the same.
If there is no passage, it will follow the beenbefore squares until it reaches an unexplored
path. */
public int junction(IRobot robot) {
if (passageExits(robot) == 1) {
return passageDirections.get(0);
} else if (passageExits(robot) > 1) {
int randomPassage = random.nextInt(passageDirections.size());
return passageDirections.get(randomPassage);
} else {
return backtrack(robot);
}
}
// Calculates number of exits.
private int nonwallExits (IRobot robot) {
int nonwallExits = 0;
for(int item : directions) {
if(robot.look(item) != IRobot.WALL) {
nonwallExits++;
}
}
return nonwallExits;
}
// Calculates number of passages.
private int passageExits (IRobot robot) {
int passageExits = 0;
for(int item : directions) {
if(robot.look(item) == IRobot.PASSAGE) {
passageExits++;
}
}
return passageExits;
}
// Calculates number of beenbefores.
private int beenbeforeExits (IRobot robot) {
int beenbeforeExits = 0;
for(int item : directions) {
if(robot.look(item) == IRobot.PASSAGE) {
beenbeforeExits++;
}
}
return beenbeforeExits;
}
// Resets Junction Counter in RobotData class.
public int reset() {
return robotData.resetJunctionCounter();
}
}
class RobotData {
/* It was advised in the specification to include the variable:
private static int maxJunctions = 10000;
However, as I am not using arrays, but ArrayLists, I do not
need this. */
private static int junctionCounter = 0;
private ArrayList<Junction> junctionList = new ArrayList<Junction>();
private Iterator<Junction> junctionIterator = junctionList.iterator();
// Resets the Junction counter.
public int resetJunctionCounter() {
return junctionCounter = 0;
}
// Adds the current junction to the list of arrays.
public void addJunction(IRobot robot) {
Junction newJunction = new Junction(robot.getLocation().x, robot.getLocation().y, robot.getHeading());
junctionList.add(newJunction);
junctionCounter++;
}
// Gets the junction counter for Junction info method in Junction class.
public int getJunctionCounter (IRobot robot) {
return junctionCounter;
}
// Prints Junction info.
public void printJunction(IRobot robot) {
String course = "";
switch (robot.getHeading()) {
case IRobot.NORTH:
course = "NORTH";
break;
case IRobot.EAST:
course = "EAST";
break;
case IRobot.SOUTH:
course = "SOUTH";
break;
case IRobot.WEST:
course = "WEST";
break;
}
System.out.println("Junction " + junctionCounter + " (x=" + robot.getLocation().x + ", y=" + robot.getLocation().y +") heading " + course);
}
/* Iterates through the junction arrayList to find the
heading of the robot when it first approached the junction. */
public int searchJunction(IRobot robot) {
Junction currentJunction = junctionIterator.next();
while (junctionIterator.hasNext()) {
if ((((currentJunction.x)==(robot.getLocation().x))) && ((currentJunction.y)==(robot.getLocation().y)))
break;
}
return currentJunction.arrived;
}
// Returns the reverse of the heading the robot had when first approaching the junction.
public int reverseHeading(IRobot robot) {
int firstHeading = searchJunction(robot);
int reverseHeading = 1; // Random integer to Iniitalise variable.
switch (firstHeading) {
case IRobot.NORTH:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.BEHIND;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.RIGHT;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.AHEAD;
else
reverseHeading = IRobot.LEFT;
break;
case IRobot.EAST:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.LEFT;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.BEHIND;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.RIGHT;
else
reverseHeading = IRobot.AHEAD;
break;
case IRobot.SOUTH:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.AHEAD;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.LEFT;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.BEHIND;
else
reverseHeading = IRobot.RIGHT;
break;
case IRobot.WEST:
if (robot.getHeading() == IRobot.NORTH)
reverseHeading = IRobot.RIGHT;
else if (robot.getHeading() == IRobot.EAST)
reverseHeading = IRobot.AHEAD;
else if (robot.getHeading() == IRobot.SOUTH)
reverseHeading = IRobot.LEFT;
else
reverseHeading = IRobot.BEHIND;
break;
}
return reverseHeading;
}
}
class Junction {
int x;
int y;
int arrived;
public Junction(int xcoord, int ycoord, int course) {
x = xcoord;
y = ycoord;
arrived = course;
}
}
Whenever it is backtracking and reaches a junction it has already visited, it freezes and this comes up.
`java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor41.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at uk.ac.warwick.dcs.maze.controllers.PolledControllerWrapper.start(PolledControllerWrapper.java:70)
at uk.ac.warwick.dcs.maze.logic.ControllerThread.run(ControllerThread.java:46)
Caused by: java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at RobotData.searchJunction(Explorer.java:242)
at RobotData.reverseHeading(Explorer.java:255)
at Explorer.backtrack(Explorer.java:74)
at Explorer.junction(Explorer.java:122)
at Explorer.controlRobot(Explorer.java:56)
... 5 more`
I don't think your searchJunction() is right or safe, the ConcurrentModificationException might be thrown due to the incorrect iterator through junctionList . The problem should be more about the iterator rather than reflection.
You might try:
private Iterator<Junction> junctionIterator = junctionList.iterator(); doesn't make much sense since the list is empty when initialize a RobotData object. Try to move it into searchJunction()
Check hasNext() first then invoke next()
public int searchJunction(IRobot robot) {
Iterator<Junction> junctionIterator = junctionList.iterator();
while (junctionIterator.hasNext()) {
Junction currentJunction = junctionIterator.next();
if ((((currentJunction.x)==(robot.getLocation().x))) && ((currentJunction.y)==(robot.getLocation().y)))
break;
}
return currentJunction.arrived;
}
It looks like that issue is in following code -
`public int searchJunction(IRobot robot) {
Junction currentJunction = junctionIterator.next();
while (junctionIterator.hasNext()) {
if ((((currentJunction.x)==(robot.getLocation().x))) && ((currentJunction.y)==(robot.getLocation().y)))
break;
}
return currentJunction.arrived;
}
You are calling junctionIterator.next() before calling junctionIterator.hasNext(). Iterator specification says that you should call next() only after calling hasNext()

how to convert a char array back into string [duplicate]

This question already has answers here:
How to convert a char array back to a string?
(14 answers)
Closed 9 years ago.
i am doing a porter stemmer.....the code gives me output in char array....but i need to convert that into string to proceed with futher work.....in the code i have given 2 words "looking" and "walks"....that is returned as look and walk(but in char array)...the output is printed in stem() function
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package file;
import java.util.Vector;
/**
*
* #author sky
*/
public class stemmer {
public static String line1;
private char[] b;
private int i, /* offset into b */
i_end, /* offset to end of stemmed word */
j, k;
private static final int INC = 50;
/* unit of size whereby b is increased */
public stemmer()
{
//b = new char[INC];
i = 0;
i_end = 0;
}
/**
* Add a character to the word being stemmed. When you are finished
* adding characters, you can call stem(void) to stem the word.
*/
public void add(char ch)
{
System.out.println("in add() function");
if (i == b.length)
{
char[] new_b = new char[i+INC];
for (int c = 0; c < i; c++)
new_b[c] = b[c];
b = new_b;
}
b[i++] = ch;
}
/** Adds wLen characters to the word being stemmed contained in a portion
* of a char[] array. This is like repeated calls of add(char ch), but
* faster.
*/
public void add(char[] w, int wLen)
{ if (i+wLen >= b.length)
{
char[] new_b = new char[i+wLen+INC];
for (int c = 0; c < i; c++)
new_b[c] = b[c];
b = new_b;
}
for (int c = 0; c < wLen; c++)
b[i++] = w[c];
}
public void addstring(String s1)
{
b=new char[s1.length()];
for(int k=0;k<s1.length();k++)
{
b[k] = s1.charAt(k);
System.out.println(b[k]);
}
i=s1.length();
}
/**
* After a word has been stemmed, it can be retrieved by toString(),
* or a reference to the internal buffer can be retrieved by getResultBuffer
* and getResultLength (which is generally more efficient.)
*/
public String toString() { return new String(b,0,i_end); }
/**
* Returns the length of the word resulting from the stemming process.
*/
public int getResultLength() { return i_end; }
/**
* Returns a reference to a character buffer containing the results of
* the stemming process. You also need to consult getResultLength()
* to determine the length of the result.
*/
public char[] getResultBuffer() { return b; }
/* cons(i) is true <=> b[i] is a consonant. */
private final boolean cons(int i)
{ switch (b[i])
{ case 'a': case 'e': case 'i': case 'o': case 'u': return false;
case 'y': return (i==0) ? true : !cons(i-1);
default: return true;
}
}
/* m() measures the number of consonant sequences between 0 and j. if c is
a consonant sequence and v a vowel sequence, and <..> indicates arbitrary
presence,
<c><v> gives 0
<c>vc<v> gives 1
<c>vcvc<v> gives 2
<c>vcvcvc<v> gives 3
....
*/
private final int m()
{ int n = 0;
int i = 0;
while(true)
{ if (i > j) return n;
if (! cons(i)) break; i++;
}
i++;
while(true)
{ while(true)
{ if (i > j) return n;
if (cons(i)) break;
i++;
}
i++;
n++;
while(true)
{ if (i > j) return n;
if (! cons(i)) break;
i++;
}
i++;
}
}
/* vowelinstem() is true <=> 0,...j contains a vowel */
private final boolean vowelinstem()
{ int i; for (i = 0; i <= j; i++) if (! cons(i)) return true;
return false;
}
/* doublec(j) is true <=> j,(j-1) contain a double consonant. */
private final boolean doublec(int j)
{ if (j < 1) return false;
if (b[j] != b[j-1]) return false;
return cons(j);
}
/* cvc(i) is true <=> i-2,i-1,i has the form consonant - vowel - consonant
and also if the second c is not w,x or y. this is used when trying to
restore an e at the end of a short word. e.g.
cav(e), lov(e), hop(e), crim(e), but
snow, box, tray.
*/
private final boolean cvc(int i)
{ if (i < 2 || !cons(i) || cons(i-1) || !cons(i-2)) return false;
{ int ch = b[i];
if (ch == 'w' || ch == 'x' || ch == 'y') return false;
}
return true;
}
private final boolean ends(String s)
{
int l = s.length();
int o = k-l+1;
if (o < 0)
return false;
for (int i = 0; i < l; i++)
if (b[o+i] != s.charAt(i))
return false;
j = k-l;
return true;
}
/* setto(s) sets (j+1),...k to the characters in the string s, readjusting
k. */
private final void setto(String s)
{ int l = s.length();
int o = j+1;
for (int i = 0; i < l; i++)
b[o+i] = s.charAt(i);
k = j+l;
}
/* r(s) is used further down. */
private final void r(String s) { if (m() > 0) setto(s); }
/* step1() gets rid of plurals and -ed or -ing. e.g.
caresses -> caress
ponies -> poni
ties -> ti
caress -> caress
cats -> cat
feed -> feed
agreed -> agree
disabled -> disable
matting -> mat
mating -> mate
meeting -> meet
milling -> mill
messing -> mess
meetings -> meet
*/
private final void step1()
{
if (b[k] == 's')
{ if (ends("sses")) k -= 2; else
if (ends("ies")) setto("i"); else
if (b[k-1] != 's') k--;
}
if (ends("eed")) { if (m() > 0) k--; } else
if ((ends("ed") || ends("ing")) && vowelinstem())
{ k = j;
if (ends("at")) setto("ate"); else
if (ends("bl")) setto("ble"); else
if (ends("iz")) setto("ize"); else
if (doublec(k))
{ k--;
{ int ch = b[k];
if (ch == 'l' || ch == 's' || ch == 'z') k++;
}
}
else if (m() == 1 && cvc(k)) setto("e");
}
}
/* step2() turns terminal y to i when there is another vowel in the stem. */
private final void step2() { if (ends("y") && vowelinstem()) b[k] = 'i'; }
/* step3() maps double suffices to single ones. so -ization ( = -ize plus
-ation) maps to -ize etc. note that the string before the suffix must give
m() > 0. */
private final void step3() { if (k == 0) return; /* For Bug 1 */ switch (b[k-1])
{
case 'a': if (ends("ational")) { r("ate"); break; }
if (ends("tional")) { r("tion"); break; }
break;
case 'c': if (ends("enci")) { r("ence"); break; }
if (ends("anci")) { r("ance"); break; }
break;
case 'e': if (ends("izer")) { r("ize"); break; }
break;
case 'l': if (ends("bli")) { r("ble"); break; }
if (ends("alli")) { r("al"); break; }
if (ends("entli")) { r("ent"); break; }
if (ends("eli")) { r("e"); break; }
if (ends("ousli")) { r("ous"); break; }
break;
case 'o': if (ends("ization")) { r("ize"); break; }
if (ends("ation")) { r("ate"); break; }
if (ends("ator")) { r("ate"); break; }
break;
case 's': if (ends("alism")) { r("al"); break; }
if (ends("iveness")) { r("ive"); break; }
if (ends("fulness")) { r("ful"); break; }
if (ends("ousness")) { r("ous"); break; }
break;
case 't': if (ends("aliti")) { r("al"); break; }
if (ends("iviti")) { r("ive"); break; }
if (ends("biliti")) { r("ble"); break; }
break;
case 'g': if (ends("logi")) { r("log"); break; }
} }
/* step4() deals with -ic-, -full, -ness etc. similar strategy to step3. */
private final void step4() { switch (b[k])
{
case 'e': if (ends("icate")) { r("ic"); break; }
if (ends("ative")) { r(""); break; }
if (ends("alize")) { r("al"); break; }
break;
case 'i': if (ends("iciti")) { r("ic"); break; }
break;
case 'l': if (ends("ical")) { r("ic"); break; }
if (ends("ful")) { r(""); break; }
break;
case 's': if (ends("ness")) { r(""); break; }
break;
} }
/* step5() takes off -ant, -ence etc., in context <c>vcvc<v>. */
private final void step5()
{ if (k == 0) return; /* for Bug 1 */ switch (b[k-1])
{ case 'a': if (ends("al")) break; return;
case 'c': if (ends("ance")) break;
if (ends("ence")) break; return;
case 'e': if (ends("er")) break; return;
case 'i': if (ends("ic")) break; return;
case 'l': if (ends("able")) break;
if (ends("ible")) break; return;
case 'n': if (ends("ant")) break;
if (ends("ement")) break;
if (ends("ment")) break;
/* element etc. not stripped before the m */
if (ends("ent")) break; return;
case 'o': if (ends("ion") && j >= 0 && (b[j] == 's' || b[j] == 't')) break;
/* j >= 0 fixes Bug 2 */
if (ends("ou")) break; return;
/* takes care of -ous */
case 's': if (ends("ism")) break; return;
case 't': if (ends("ate")) break;
if (ends("iti")) break; return;
case 'u': if (ends("ous")) break; return;
case 'v': if (ends("ive")) break; return;
case 'z': if (ends("ize")) break; return;
default: return;
}
if (m() > 1) k = j;
}
/* step6() removes a final -e if m() > 1. */
private final void step6()
{ j = k;
if (b[k] == 'e')
{ int a = m();
if (a > 1 || a == 1 && !cvc(k-1)) k--;
}
if (b[k] == 'l' && doublec(k) && m() > 1) k--;
}
/** Stem the word placed into the Stemmer buffer through calls to add().
* Returns true if the stemming process resulted in a word different
* from the input. You can retrieve the result with
* getResultLength()/getResultBuffer() or toString().
*/
public void stem()
{
// step1();
// System.out.println("hello in stem");
// step2();
// step3();
// step4();
// step5();
// step6();
//
// i_end = k+1;
// i = 0;
System.out.println(i);
k = i - 1;
if (k > 1)
{
step1();
step2();
step3();
step4();
step5();
step6();
}
for(int c=0;c<=k;c++)
System.out.println(b[c]);
i_end = k+1; i = 0;
}
public static void main(String[] args)
{
stemmer s = new stemmer();
s.addstring("looking");
s.stem();
s.addstring("walks");
s.stem();
//System.out.println("Output " +s.b);
}
}
- Use Character class method toString();
Eg:
class Test
{
public static void main (String[] args) throws java.lang.Exception
{
char c = 'a';
String s = Character.toString(c);
System.out.println(s);
}
}
- Now use this above explained method to convert all the character array items into String.
char[] data = new char[10];
String text = String.valueOf(data);
to convert a char[] to string use this way
String x=new String(char[])
example
char x[]={'a','m'};
String z=new String(x);
System.out.println(z);
output
am
char[] a = new char[10];
for(int i=0;i<10;i++)
{
a[i] = 's';
}
System.out.println(new String(a));
or
System.out.println(String.copyValueOf(a));

Changing the direction of a point

I was to create a code where I mimic the functions of a robot. Turning and moving and such. I feel as if I'm approaching this in all the wrong ways... When I was writing this I thought I understood the gist of it, if the direction in the constructor is this then if it turn the new direction is this. I tested this and of course I ended up with some real incorrect results. I'm absolutely sure that I don't actually use any of these functions for my object. Can I get a tip about how to work this kind of code?
import java.awt.Point;
public class Robot
{
private int x;
private int y;
private int d;
private int p;
public static final int NORTH = 0;
public static final int SOUTH = 1;
public static final int EAST = 2;
public static final int WEST = 3;
/**
* Constructor for objects of class Robot
* #param theX the x coordinate
* #param theY the y coordinate
* #param theDirection the direction the robot is facing
*/
public Robot(int theX, int theY, int theDirection)
{
x = theX;
y = theY;
d = theDirection;
}
public void turnLeft()
{
if(d == NORTH) {
d = WEST;
}
if(d == WEST) {
d = SOUTH;
}
if(d == SOUTH) {
d = EAST;
}
if(d == EAST) {
d = NORTH;
}
}
public String getDirection()
{
if(d == NORTH) {
return "N";
}
if(d == SOUTH) {
return "S";
}
if(d == WEST) {
return "W";
}
if(d == EAST) {
return "E";
}
return "";
}
}
Testing
Robot rob = new Robot(20, 20, Robot.SOUTH);
rob.turnLeft;
System.out.println(rob.getDirection);
this return S when I think it should actually return E.
You need else if. When you turn left you assign a new value to d which is matching the condition of the following if statements.
Your turnLeft method is not quite right.
Here's the code by using if:
public void turnLeft() {
if (d == NORTH) {
d = WEST;
} else if (d == WEST) {
d = SOUTH;
} else if (d == SOUTH) {
d = EAST;
} else if (d == EAST) {
d = NORTH;
}
}
Here's the code by using switch..case
public void turnLeft() {
switch (d) {
case NORTH: d = WEST; break;
case WEST: d = SOUTH; break;
case SOUTH: d = EAST; break;
case EAST: d = NORTH; break;
}
}
Enum
public enum Direction {
private String name;
private String indicator;
public Direction(String name, String indicator) {
this.name = name;
this.indicator= indicator;
}
// getters
NORTH("North", "N"),
EAST("East", "E"),
SOUTH("South", "S"),
WEST("West", "W");
}
Next you can easily do this:
turnLeft() {
switch (d) {
case Direction.NORTH: return Direction.WEST;
case Direction.WEST: return Direction.SOUTH;
case Direction.SOUTH: return Direction.EAST;
case Direction.EAST: return Direction.NORTH;
}
}
getDirection() {
return d.getIndicator();
}
This way you can get rid of the four static int (NORTH, WEST, EAST, SOUTH) and change int d into Direction d. I would really recommend using an enum for this. Just to be typesafe.
What's the p var that you're using?
Your current direction is stored in d
...
d = theDirection;
...
You should try with this one:
public void turnLeft()
{
if(d == NORTH) {
d = WEST;
}
if(d == WEST) {
d = SOUTH;
}
if(d == SOUTH) {
d = EAST;
}
if(d == EAST) {
d = NORTH;
}
}
EDIT:
Just to clarify.
You wrote something like
if(p == SOUTH) {
d = EAST;
}
So you're checking if p is SOUTH and not d.
You're not using p anywhere so it will never be SOUTH, that's why your turnLeft() method does absolutely nothing!
1st) you should really clean up your p and d stuff ;) i suggest to call d "direction"
2nd) you should rearrange your int constants for directions in clockwise order. so you could reduce your turnLeft() method to a single line of code. You could order them this way:
public static final int NORTH = 0;
public static final int EAST = 1;
public static final int SOUTH = 2;
public static final int WEST = 3;
3rd) for testing you should use JUnit:
#Test
public void turnLeft() {
Robot rob = new Robot(20, 20, Robot.SOUTH);
rob.turnLeft;
assertEquals("E", rob.getDirection);
rob.turnLeft;
assertEquals("N", rob.getDirection);
rob.turnLeft;
assertEquals("W", rob.getDirection);
rob.turnLeft;
assertEquals("S", rob.getDirection);
}
In case someone ever neeeded, here is a solution for turning either way:
public enum Direction {
UP,
LEFT,
DOWN,
RIGHT;
Direction turnLeft() {
int turnLeft = 1;
return getDirectionByOrdinalMovingClockwise(turnLeft);
}
Direction turnRight() {
int turnRight = -1;
return getDirectionByOrdinalMovingClockwise(turnRight);
}
Direction turnAround() {
int turnAround = 2;
return getDirectionByOrdinalMovingClockwise(turnAround);
}
private Direction getDirectionByOrdinalMovingClockwise(int moveBy) {
var thisDirectionOrdinal = ordinal();
int newDirectionOrdinal = (thisDirectionOrdinal + moveBy) % enumElementsCount();
if (newDirectionOrdinal < 0) {
newDirectionOrdinal = enumElementsCount() + newDirectionOrdinal;
}
return values()[newDirectionOrdinal];
}
private int enumElementsCount() {
return values().length;
}
}

Categories

Resources