So I am trying to add a cellType into a 2D array. The input from the file looks like a 6x6 file where it can be any combination of the enum type in my enum class below. For some reason when I try to troubleshoot the program, only WALL is getting added into my 2D array. I'm thinking there might be an error in my where I am trying to iterate through the 2D array, but I can't see it.
Here is where I am trying to add it within my 2D array
MazeCell.CellType[][] cell;
int rows = 6;
int cols = 6;
MazeCell.CellType cell2Add;
while(inputFile.hasNext())
{
String mazeStart = inputFile.nextLine().trim();
String [] mazeRowsAndCols = mazeStart.split(" ");
//System.out.println(mazeStart);
//System.out.println(mazeRowsAndCols[2]);
MazeCell.CellType cell2Add;
for(int r = 1; r < rows+1; r++)
{
System.out.print(r-1);
for(int c = 1; c<cols+1; c++)
{
if(mazeRowsAndCols[r-1].equals("W"))
{
cell2Add = MazeCell.CellType.WALL;
}
else if(mazeRowsAndCols[r-1].equals("M"))
{
cell2Add = MazeCell.CellType.START;
}
else if (mazeRowsAndCols[r-1].equals("C"))
{
cell2Add = MazeCell.CellType.END;
}
else if (mazeRowsAndCols[r-1].equals("O"))
{
cell2Add = MazeCell.CellType.OPEN;
}
else if (mazeRowsAndCols[r-1].equals(" "))
{
cell2Add = MazeCell.CellType.CURRENT_PATH;
}
else if (mazeRowsAndCols[r-1].equals("S"))
{
cell2Add = MazeCell.CellType.END_FOUND;
}
else if (mazeRowsAndCols[r-1].equals("X"))
{
cell2Add = MazeCell.CellType.REJECTED;
}
System.out.print(c);
cell[r-1][c-1] = cell2Add;
}
System.out.println();
}
}
}
inputFile.close()
Here is my enum class.
public class MazeCell
{
public static enum CellType
{
WALL("W"), START("M"), END("C"), OPEN("O"), CURRENT_PATH(" "), END_FOUND("S"), REJECTED("X");
private final String display;
private String type;
CellType(String display)
{
this.display = display;
}
public String getDisplay() { return display;}
public void setType(String type){this.type = type;}
};
What the input file looks like:
W W W W W W
W W M W W W
W W O O O W
W O W O O W
W W C O O W
W W W W W W W
W W W W W W
within cel[][] all I seem to be getting is Wall,
(mazeRowsAndCols[r-1].equals("S"))
you are using OUTER index to iterate over INNER elements (input line length). Try
(mazeRowsAndCols[c-1].equals("S"))
Moreover I would rather use switch for that (yes it is possible with string).
Besides I don't like the fact that you have outer for as this should be limited by input lines so while should be more then enough.
So in fact it should be something like that:
int row=0;
while(input.hasNext()){
String line=input.nextLine();
String parts[]=input.split(" ");
for(int c=0;c<parts.length;c++){
element=parts[c];
switch(element){
case W: enumToAdd=WALL; break;
case ......
///////////do the magic with `switch` here
}
maze[r][c]=enumToAdd;
}
row++;
}
public static CellType[][] read(Scanner scan) {
final int totalRows = 6;
final int totalColumns = 6;
CellType[][] maze = new CellType[totalRows][totalColumns];
for (int row = 0; row < totalRows; row++) {
String line = scan.nextLine();
for (int col = 0; col < totalColumns; col++)
maze[row][col] = CellType.parseId(line.charAt(col));
}
return maze;
}
public enum CellType {
WALL('W'),
START('M'),
END('C'),
OPEN('O'),
CURRENT_PATH(' '),
END_FOUND('S'),
REJECTED('X');
private final char id;
CellType(char id) {
this.id = id;
}
public static CellType parseId(char id) {
for (CellType type : values())
if (type.id == id)
return type;
throw new EnumConstantNotPresentException(CellType.class, String.valueOf(id));
}
}
I would suggest a few changes to make this a little easier to reason about.
First, let's fix up cell type a little to make it easier to use:
We should add a static fromDisplay(String s) method.
We should probably remove setType, because any call to setType will set that variable for that enum value everwhere, as there is only ever one instance of an enum value.
The resultant code is
public class MazeCell
{
public static enum CellType
{
WALL("W"),
START("M"),
END("C"),
OPEN("O"),
CURRENT_PATH(" "),
END_FOUND("S"),
REJECTED("X");
static {
final Map<String, CellType> fDisplay = new HashMap<>();
for(final CellType c : CellType.values()) {
fDisplay.put(c.display, c);
}
fromDisplay = fDisplay;
}
private static final Map<String, CellType> fromDisplay;
private final String display;
CellType(String display)
{
this.display = display;
}
public String getDisplay() { return display; }
public static CellType fromDisplay(final String display) {
return fromDisplay.getOrDefault(display, REJECTED);
}
}
}
Now, let's fix up the code. The problem is, as pointed out, that you only parse the first line every time. Let's fix that and clean up the code a little, too.
// Read our input in a try-with-resources
try(final File file = ...) {
final Scanner input = new Scanner(file);
// initialize the array
final MazeCell.CellType[][] cells = new MazeCell.CellType[6][6];
// assuming there are 6 rows
for(int r=0; r<6; r++) {
if(!input.hasNext()) throw new RuntimeException("Input file does not match our expectations! Only " + (r) + " lines!");
// assuming the columns are separated by spaces
final String[] cols = input.nextLine().trim().split(" ");
if(cols.length != 6) throw new RuntimeException("Input file does not match our expectations! Row " + (r + 1) + " had " + cols.length + " columns!");
for(int c=0; c<6; c++) {
cells[r][c] = MazeCell.CellType.fromDisplay(cols[c]);
}
}
// print it out or whatever
Arrays.stream(cells).map(Arrays::toString).forEach(System.out::println);
}
That should do it. Hope this helps!
Related
I have space matrix like
|....
..|..
.....
||...
where . is empty space and | is non empty space.
and i have 3 shape like
TTT E.E ..L
..E L.L
EEE
. also empty. Now i want to fit these shape in space matrix using java code.
expected out space look like
|.ELE
.L|LE
..EEE
||TTT
may be other possibility of fit
Input File code "problem1.txt"
SPACE
|.......
..|||..|
..|.|...
........
SHAPE T
TTTT
SHAPE e
..e
eee
SHAPE t
.t.
ttt
SHAPE r
rr
rr
SHAPE i
i..
iii
SHAPE s
.ss
ss.
Here my code to read file in array
File f = new File("problem1.txt");
FileReader fr = new FileReader(f);
int pos = 0;
Scanner s = new Scanner(fr);
// space class
SpaceClass space = new SpaceClass();
List<Shapeclass> shapeClasses = new ArrayList<Shapeclass>();
Shapeclass shapeClass = null;
boolean spaceStated = false;
while(s.hasNext()) {
//read trim line
String line = s.nextLine().trim();
if("".equals(line)){
continue;
}
//CHECK For Space
if("SPACE".equals(line.trim().toUpperCase())) {
pos = -1;
spaceStated=true;
continue;
}
//check for space
if(line.trim().toUpperCase().startsWith("SHAPE")) {
pos = -1;
spaceStated=false;
shapeClass = new Shapeclass();
shapeClasses.add(shapeClass);
continue;
}
pos++;
//adding for space
if(spaceStated) {
space.addRow(pos, line);
}else{
//adding for shape
shapeClass.addRow(pos, line);
}
}
SpaceClass Look like
public class SpaceClass{
private int height=0;
private int width=0;
private char[][] s = new char[50][50];
public SpaceClass() {}
public void addRow(int rowNo, String row) throws Exception {
if(this.width > 0 && this.width != row.length()) {
throw new Exception("Invalid Input for SPACE at row : " + rowNo + " and row :- " + row);
} else {
char[] ch = row.toCharArray();
for(int i=0,j=ch.length;i<j;i++) {
s[rowNo][i] = ch[i];
}
this.width = ch.length;
this.height += 1;
}
}
}
And ShapeClass Look like
public class Shapeclass{
private int height;
private int width;
private char[][] s = new char[50][50];
int rotate=0;
public void addRow(int rowNo, String row) throws Exception {
if(this.width > 0 && this.width != row.length()) {
throw new Exception("Invalid Input for SPACE at row : " + rowNo + " and row :- " + row);
} else {
char[] ch = row.toCharArray();
for(int i=0,j=ch.length;i<j;i++) {
s[rowNo][i] = ch[i];
}
this.width = ch.length;
this.height += 1;
}
}
}
Now i want new Space class with Fit all Shape
I'm new to Java and I'm having trouble with this bit of code:
import java.util.Scanner;
public class BattleshipLogic {
private final int rows;
private final int cols;
private final boolean[][] hits;
private final boolean[][] ships;
public BattleshipLogic(int numRows, int numCols) {
this.rows = numRows;
this.cols = numCols;
this.hits = new boolean[rows][cols];
this.ships = new boolean[rows][cols];
}
public void startGame() {
placeShips();
boolean gameOver = false;
// draw field for the first time
drawUI();
while (!gameOver) {
Target target = askForTarget();
processTarget(target);
drawUI();
}
}
private Target askForTarget() {
Target t = new Target();
Scanner input = new Scanner(System.in);
System.out.print("Please enter your target:");
t = input.nextInt();
return t;
}
/*
* This is just an example. You have to draw the ships by yourself.
* If you don't like the way the UI is drawn, make your own stuff!
*/
private void drawUI() {
// draw the ui, see blatt01/oberfläche.txt for an example
System.out.println("Schiffeversenken");
System.out.println("================");
System.out.println();
// columns
System.out.print(" ");
for (int col = 0; col < this.cols; col++) {
System.out.print(col + " ");
}
System.out.println();
System.out.print(" _");
for (int col = 0; col < this.cols; col++) {
System.out.print("__");
}
System.out.println();
for (int row = 0; row < this.rows; row++) {
System.out.print(Character.toChars(3 + row));
System.out.print(" |");
System.out.println();
}
}
private void placeShips() {
// do useful stuff to place the ships here
// see Blatt01 for rules
}
private void processTarget(Target target) {
}
/**
* This class only holds the position
* of a target.
*/
private class Target {
public int row;
public int col;
}
}
Everytime I try to compile this error comes up:
error: incompatible types: int cannot be converted to BattleshipLogic.Target
I know that the types are different, but what kind of a type is Target? How can I get the user input to be assigned to t?
Thanks so much in advance!
I think you want to do this.
private Target askForTarget() {
Target t = new Target();
Scanner input = new Scanner(System.in);
System.out.print("Please enter your target:");
t.row = input.nextInt();
t.col = input.nextInt();
return t;
}
to assign the int value to
t of type Target
you need a
getter and setter method
on your t
e.g.
public class Target
{
private int myValue;
public void setMyValue(int myValue)
{
this.myValue=myValue;
}
public int getMyValue()
{
return myValue;
}
}
then in your askForTarget() method
t.setMyValue(input.nextInt());
return t;
if you ever want to use the int in t in other calling method you can use the t method
t.getMyValue();
Basically each room has a size of 10 by 10, the "W" represents the Walls, and the blank spaces -" " represent the Floor, and the numbers are Doors.I figured the best way to create the room is to create a method that receives a file and reads it and put its "information" into a String[10][10], and then create another method(or just do it in my Main) that receives the String[10][10] created and creates the room(adds the images to the room), but i am having some difficulties reading the file so if you guys could help me with that part i would be thankful.
Here is the type of text files from which i want to create my room:
WWWW0WWWWW
W W
W W
W W
W W
W WW
W WW
W WW
W W1
WWWWWWWWWW
Here are the Door, Wall and Floor classes:
public class Door implements ImageTile {
private Position position;
public Door(Position position) {
this.position = position;
}
#Override
public String getName() {
return "Door";
}
#Override
public Position getPosition() {
return position;
}
}
public class Floor implements ImageTile {
private Position position;
public Floor(Position position) {
this.position = position;
}
#Override
public String getName() {
return "Floor";
}
#Override
public Position getPosition() {
return position;
}
}
public class Wall implements ImageTile {
private Position position;
public Wall(Position position) {
this.position = position;
}
#Override
public String getName() {
return "Wall";
}
#Override
public Position getPosition() {
return position;
}
}
And this is my method for adding images to my frame:
public void newImages(final List<ImageTile> newImages) {
if (newImages == null)
return;
if (newImages.size() == 0)
return;
for (ImageTile i : newImages) {
if (!imageDB.containsKey(i.getName())) {
throw new IllegalArgumentException("No such image in DB " + i.getName());
}
}
images.addAll(newImages);
frame.repaint();
}
If you guys could help me i would appreciate it very much, thanks guys.Her is what i have now:
public class Room {
private String[][]room;
public Room(){
room = new String[10][10]; }
public static Room fromFile(File file){
if(file.exists()){
Scanner sc = null;
Room room = new Room();
try {
sc = new Scanner(file);
while(sc.hasNextLine()){
if(sc.nextLine().startsWith("#"))
sc.nextLine();
else{
String[] s0 = sc.nextLine().split("");
//Here is where my trouble is, i dont know how to add the content of this String s0 to the String s
if(s0.length==10){
for(int x = 0; x < 10; x++){
for(int y = 0; y < 10; y++){
String[x][y] s= String[x] s0;
}
}
} catch (FileNotFoundException e) {
System.out.println("Ficheiro "+file.getAbsolutePath()+
" não existe. "); }
finally{
if(sc!=null)sc.close();
}
}
else
System.out.println("Ficheiro "+file.getAbsolutePath()+
" não existe. ");
return null;
}
Each call to sc.nextLine() is reading another line from your file. You need to save the line into a temporary variable, and then refer to that temporary.
Maintain a counter of lines you've processed, so you can fill in the appropriate line in your s[][] matrix.
You only need to allocate storage for the 10 rows, since splitting the line you read in will result in an array of strings (the columns in one row) being allocated for you.
int row = 0;
String[][] s = new String[10][];
while(sc.hasNextLine() && i < 10) {
String line = sc.nextLine();
if( !line.startsWith("#")) {
String[] s0 = sc.line.split("");
s[row] = s0;
row++;
}
}
BTW, Use String[][] is overkill; since each string will only hold one character. Perhaps you could consider using char[][]. And line.toCharArray() would split the line into a char[] for you.
EDIT: (Due to edit of your question's code)
Instead of:
if(s0.length==10){
for(int x = 0; x < 10; x++){
for(int y = 0; y < 10; y++){
String[x][y] s= String[x] s0;
}
}
}
you want:
if(s0.length==10){
for(int y = 0; y < 10; y++){
s[row][y] = s0[y];
}
row++;
}
With row being the row counter in my above code.
I'm working on an assignment that takes a data file with a number matrix and determines if it is a magic square. If it is then it also needs to report the sum of the rows and columns. With the output:
The matrix is a magic square.
The sum of all the rows and columns is 34.
I'm not sure how to go about this with one method, I feel like its asking me to return 2 values. The closest I have came is by adding a System.out.println with the sum at the end of my method when it returns true.
But the issue with that is that my output is backwords:
The sum of all the rows and columns is 34.
The matrix is a magic square.
How do I get the sum when I've only been asked to create one method? Below is my code, the instructor gave the bottom 3 methods so I'm only concerned with the first 2.
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class chp8magic
{
public static void main(String args[])
{
int matrix[][] = initMatrix();
printData(matrix);
if (isMagic(matrix)) {
System.out.println("The matrix is a magic square.");
}
else {
System.out.println("Not a magic square");
}
}
public static boolean isMagic(int[][] mat)
{
int n = mat.length;
int nSquare = n*n;
int M = (n*n*(n*n+1)/2)/n;
int sumRow = 0, sumColoumns = 0, sumPriDiag = 0, sumSecDiag = 0;
boolean[] flag = new boolean[n*n];
for(int row = 0; row < n; row++){
sumRow = 0;
sumColoumns = 0;
for(int col = 0; col < n; col++)
{
if( mat[row][col] < 1 || mat[row][col] > nSquare )
return false;
if(flag[mat[row][col]-1] == true)
return false;
flag[mat[row][col]-1] = true;
sumRow += mat[row][col];
sumColoumns += mat[col][row];
}
sumPriDiag += mat[row][row];
sumSecDiag += mat[row][n-row-1];
if(sumRow!=M || sumColoumns!=M)
return false;
}
if(sumPriDiag!=M || sumSecDiag!=M)
return false;
else
return true;
}
public static int[][] initMatrix()
{
int matrix[][];
Scanner filein = null;
try {
filein = new Scanner(new File("matrix.txt"));
int numRows = Integer.parseInt(filein.nextLine());
matrix = new int[numRows][];
parseData(matrix, filein);
filein.close();
return matrix;
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
if(filein != null)
filein.close();
return null;
}
}
public static void parseData(int matrix[][], Scanner in)
{
for(int r = 0; r < matrix.length; r++)
{
String splitLine[] = in.nextLine().split(" ");
matrix[r] = new int[splitLine.length];
for(int c = 0; c < matrix[r].length; c++){
matrix[r][c] = Integer.parseInt(splitLine[c]);
}
}
}
public static void printData(int matrix[][])
{
for(int r = 0; r < matrix.length; r++){
for(int c = 0; c < matrix[r].length; c++){
System.out.print(matrix[r][c] + " ");
}
System.out.println();
}
}
}
Probably you just need to do:
System.out.println("is magic: " + isMagic);
System.out.ptintln("sum: " + sum);
However this is not really returning the values, just printing them. To return two values there are several options. You could return an object:
public class MagicSquareProperties {
private boolean magic;
private int sum;
public MagicSquareProperties(boolean magic, int sum) {
this.magic = magic;
this.sum = sum;
}
public boolean isMagic() {
return magic;
}
public int getSum() {
return sum;
}
}
// now to return both values: return new MagicSquareProperties(true, 34);
But in my opinion the best solution would be the following:
Create a class MagicSquare.
Add property declarations (e.g. private int sum).
Add a constructor, for example MagicSquare(File file), this constructor reads the file and populates the properties.
Add getters and setters if needed (e.g. getSum())
Execute the main method in another class and call new MagicSquare(...) to create a magic square object. Afterwards you can call the getters on the object whenever you need the value.
Building a rectangular with character input and specified column and rows. whitespace in the middle.
using standard input for string s, int r, int c
private static void printstuff(String s, int r, int c) {
colums(s, c);
rows(s, c, r);
colums(s, c);
}
// straight columns
private static void colums(String cs, int cc) {
for (int i = 1; i <= cc; i++) {
System.out.print(cs);
}
}
this creates desired whitespace or "" to concat string with ie making
x""""""""x
private static String whitespace(int wc) {
String ws = " ";
for (int i = 1; i <= wc - 3; i++) {
ws += " ";
}
return ws;
}
whitespace to built a rectangular.
// downwards building
private static void rows(String rs, int rc, int rr) {
String ws = whitespace(rc);
for (int i = 1; i <= rr - 1; i++) {
System.out.println(rs + ws + rs);
// put strings together
}
}
}
whitespace and character rows to built a rectangular. needless to say it failed.
sample output:
XXXX X
X X
xxxx
desired output:
xxxx
x x
xxxx
one quick solution below.. Cheers
public class Main {
public static void main(String[] args) {
String s = "X";
int totalColumns = 4;
int totalRow = 3;
colums(s, totalColumns);
rows(s, totalColumns, totalRow);
colums(s, totalColumns);
}
private static void colums(String cs, int cc) {
for (int i = 0; i < cc; i++) {
System.out.print(cs);
}
}
private static String whitespace(int tc) {
String ws = " ";
for (int i = 1; i < tc - 2; i++) {
ws += " ";
}
return ws;
}
private static void rows(String rs, int tc, int tr) {
System.out.println();
for (int i = 0; i < tr - 2 ; i++) {
System.out.println(rs + whitespace(tc) + rs);
}
}
}
Im not sure if this what you want but throw a System.out.println(""); after the for loop in colums