package oo15loipe; /** * Loipe class * * @author Camil Staps, s4498062 // Thijs Heijligenberg, s4451414 */ public class Loipe implements InfoLoipe { /** * Class constants for direction (for readability) */ private final static int DIRECTION_EAST = 0, DIRECTION_SOUTH = 1, DIRECTION_WEST = 2, DIRECTION_NORTH = 3; /** * The height and width of the loipe */ private int height = 0, width = 0; /** * Start point * The path in coordinates * The current position * The map as 2D array of Fragments */ private Punt start; private Punt[] path; private int path_pointer = 0; private Fragment[][] loipe; /** * Construct the loipe based on a path * * @param pad */ public Loipe (String pad) { setLoipe(pad); } /** * Refresh everything based on a new path * * @param pad */ public final void setLoipe(String pad) { setWidthAndHeight(pad); fillLoipe(pad); path_pointer = 0; } /** * Set the width and height of the loipe based on a path * * @param pad */ private void setWidthAndHeight(String pad) { int direction = DIRECTION_NORTH; int maxX = 0, maxY = 0, minX = 0, minY = 0; Punt current_point = new Punt(0,0); for (int i = 0; i < pad.length(); i++) { if (current_point.getX() < minX) minX = current_point.getX(); if (current_point.getX() > maxX) maxX = current_point.getX(); if (current_point.getY() < minY) minY = current_point.getY(); if (current_point.getY() > maxY) maxY = current_point.getY(); switch (pad.charAt(i)) { case 'r': switch (direction) { case DIRECTION_EAST: direction = DIRECTION_SOUTH; break; case DIRECTION_SOUTH: direction = DIRECTION_WEST; break; case DIRECTION_WEST: direction = DIRECTION_NORTH; break; case DIRECTION_NORTH: direction = DIRECTION_EAST; break; } break; case 'l': switch (direction) { case DIRECTION_EAST: direction = DIRECTION_NORTH; break; case DIRECTION_SOUTH: direction = DIRECTION_EAST; break; case DIRECTION_WEST: direction = DIRECTION_SOUTH; break; case DIRECTION_NORTH: direction = DIRECTION_WEST; break; } } switch (direction) { case DIRECTION_EAST: current_point = new Punt(current_point.getX() + 1, current_point.getY()); break; case DIRECTION_SOUTH: current_point = new Punt(current_point.getX(), current_point.getY() + 1); break; case DIRECTION_WEST: current_point = new Punt(current_point.getX() - 1, current_point.getY()); break; case DIRECTION_NORTH: current_point = new Punt(current_point.getX(), current_point.getY() - 1); break; } } height = maxY - minY + 1; width = maxX - minX + 1; start = new Punt(-minX, -minY); } /** * Fill the loipe with fragments based on a path. * Assumes the width, height and start attributes to be correct. * * @param pad */ private void fillLoipe(String pad) { loipe = new Fragment[width + 1][height + 1]; path = new Punt[pad.length()]; Punt current_point = start; int direction = DIRECTION_NORTH; for (int i = 0; i < pad.length(); i++) { path[i] = current_point; if (loipe[current_point.getX()][current_point.getY()] != null) { loipe[current_point.getX()][current_point.getY()] = Fragment.KR; } else { switch (pad.charAt(i)) { case 'r': switch (direction) { case DIRECTION_EAST: loipe[current_point.getX()][current_point.getY()] = Fragment.ZW; break; case DIRECTION_SOUTH: loipe[current_point.getX()][current_point.getY()] = Fragment.NW; break; case DIRECTION_WEST: loipe[current_point.getX()][current_point.getY()] = Fragment.NO; break; case DIRECTION_NORTH: loipe[current_point.getX()][current_point.getY()] = Fragment.ZO; break; } break; case 'l': switch (direction) { case DIRECTION_EAST: loipe[current_point.getX()][current_point.getY()] = Fragment.NW; break; case DIRECTION_SOUTH: loipe[current_point.getX()][current_point.getY()] = Fragment.NO; break; case DIRECTION_WEST: loipe[current_point.getX()][current_point.getY()] = Fragment.ZO; break; case DIRECTION_NORTH: loipe[current_point.getX()][current_point.getY()] = Fragment.ZW; break; } break; case 's': switch (direction) { case DIRECTION_EAST: case DIRECTION_WEST: loipe[current_point.getX()][current_point.getY()] = Fragment.OW; break; case DIRECTION_SOUTH: case DIRECTION_NORTH: loipe[current_point.getX()][current_point.getY()] = Fragment.NZ; } } } switch (pad.charAt(i)) { case 'r': switch (direction) { case DIRECTION_EAST: direction = DIRECTION_SOUTH; break; case DIRECTION_SOUTH: direction = DIRECTION_WEST; break; case DIRECTION_WEST: direction = DIRECTION_NORTH; break; case DIRECTION_NORTH: direction = DIRECTION_EAST; break; } break; case 'l': switch (direction) { case DIRECTION_EAST: direction = DIRECTION_NORTH; break; case DIRECTION_SOUTH: direction = DIRECTION_EAST; break; case DIRECTION_WEST: direction = DIRECTION_SOUTH; break; case DIRECTION_NORTH: direction = DIRECTION_WEST; break; } } switch (direction) { case DIRECTION_EAST: current_point = new Punt(current_point.getX() + 1, current_point.getY()); break; case DIRECTION_SOUTH: current_point = new Punt(current_point.getX(), current_point.getY() + 1); break; case DIRECTION_WEST: current_point = new Punt(current_point.getX() - 1, current_point.getY()); break; case DIRECTION_NORTH: current_point = new Punt(current_point.getX(), current_point.getY() - 1); break; } } } @Override public int getHeight() { return height; } @Override public int getWidth() { return width; } @Override public String toString() { StringBuilder sb = new StringBuilder(); for (Punt p : path) { sb.append(p).append(" -> "); } return sb.toString(); } @Override public Fragment getFragment(int x, int y) { return loipe[x][y]; } @Override public Punt start() { return start; } /** * We chose to have the man go back to the start when he has finished the loipe. */ @Override public Punt stap() { if (path_pointer >= path.length) { path_pointer = 0; } Punt result = path[path_pointer]; path_pointer++; return result; } }