Classes and 2 Dimension Arrays - java

The code I am working with is below. I feel like this should be simple, but I'm having an incredibly hard time focusing this week and need some help.
I'm not able to properly set the values for pt.x or pt.y in the nested for loops. IDEA is telling me that the symbol can't be resolved. The class is identified from another java file in the package that only identifies that class. it is as follows:
public class pointClass {
class point{
int x;
int y;
int z;
}
}
(Adding text to demonstrate these are 2 separate files)
This is for a class assignment, but I'm not sharing the whole assignment, just what I need help with. I'm trying to learn, not have things done for me.
public class main {
public static void main (String args[]){
ArrayList<pointClass.point> pointlist = new ArrayList<>();
//Creating map
int row = 40;
int col = 40;
int [][] bigarray = new int [row] [col];
//iterating through map
for (int i = 0; i < row; i++;){
for (int j=0; j< col; j++){
pointClass pt = new pointClass.point;
pt.x = row;
pt.y = col;
pt.z = ;//RNG HERE//
}
}
How do I need to more properly identify these class attributes? For context,this code cretes a 40x40 array and will assign a random value to each number. Another code stanza will be added to print the 2D array.

There doesn't seem to be a need for a Nested class here. Consider just using the following:
public class Point {
int x;
int y;
int z;
}
Now let's take a look at your syntax errors. Most are fairly simple, but deserve discussion nonetheless.
public class Main {
public static void main(String args[]){
ArrayList<Point> pointlist = new ArrayList<>(); //Now that we aren't using a nested class, Just <Point>
//Creating map
int row = 40;
int col = 40;
int [][] bigarray = new int [row] [col];
//iterating through map
for (int i = 0; i < row; i++){ //No semicolon after i++
for (int j=0; j< col; j++){
Point pt = new Point(); //Calling a constructor is a method, hence ()
pt.x = j; //You probably mean j and k here, not row and col (which don't change)
pt.y = k;
pt.z = 0;//RNG HERE// //Not sure what you mean here, but you can set pt.z to whatever you want
//You created pointlist, but never add to it. Did you mean to?
pointlist.add(pt);
}
}
}
}
I've just tested the above and it compiles and runs correctly. That said, you can do a lot better stylistically. Here are some tips.
Class names start with a capital letter. Point, not point. PointClass, not pointClass.
Non-final / mutable fields should be private. Thus your Point class, while correct, is fairly bad practice (the reasons for which are very well documented elsewhere). Consider using the following alternative:
public class Point {
private int x;
private int y;
private int z;
public Point(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getX() { return x; }
public int getY() { return y; }
public int getZ() { return z; }
}

Related

Breaking up a class with many methods for readability

My grid super class has become large with many public methods and I'm trying to figure out how I can break it up to become more manageable. Methods fall into a few categories, methods below are for getting index info:
class grid{
int tot, cols, rows;
float gw, gh, w, h,gx,gy,gcx,gcy;
ArrayList<cell> cells = new ArrayList<cell>();
grid(float width, float height, int cols, int rows){
this.gx = 0;
this.gy = 0;
this.gw = width;
this.gh = height;
this.cols = cols;
this.rows = rows;
w = gw/float(cols);
h = gh/float(rows);
}
// how to move these methods somewhere else?
int rc(int row, int col){ // get index at row# col#
int val = 0;
for(int i = 0; i < cells.size(); i++){
if(cells.get(i).row == row && cells.get(i).col == col){
val = i;
}
}
return val;
}
int col(int inst){
if(altFlow == 1){
return floor(inst/rows);
} else {
return inst%cols;
}
}
int[] listRow(int indexIn){
int stIndex = cols*indexIn;
int[] arrayOut = new int[cols];
for(int i = 0; i < cols; i++) arrayOut[i] = i+stIndex;
return arrayOut;
}
}
My thought was to use composition, but I would still need a method for each function in the main class? Is this the best way?
class grid{
gridInfo gi;
...
//still need one of these for each method?
int col(int inst){
return gi.col(inst);
}
}
class gridInfo(){
grid parent;
...
int col(int inst){
if(altFlow == 1){
return floor(inst/parent.rows);
} else {
return inst%parent.cols;
}
}
}
You can start with an abstract class defining some methods and then enhance it (derive from it) by adding more methods.
This tutorial explains abstract classes: https://www.javatpoint.com/abstract-class-in-java
But I would not do that unless you have different classes derived from the same abstract base. I see no problem having large source code files. Every IDE provides lots of features to navigate quickly, regardless if the class has 100 or 3000 lines.

How do I call a public integer from another public integer in another class? [duplicate]

This question already has answers here:
Cannot make a static reference to the non-static method
(8 answers)
Closed 3 years ago.
I'm working on an assignment for class, and it's working on classes to make us call items from other classes as often as possible. I'm trying to call public int side(int number) from another public int, but it won't let me.
I can't rearrange the code to edit public int side at all because it was included in part of the assignment
package lab6_carl6188;
class Polygon
{
private int[] sideLengths;
public Polygon(int sides, int ... lengths)
{
int index = 0;
sideLengths = new int[sides];
for (int length: lengths)
{
sideLengths[index] = length;
index += 1;
}
}
public int side(int number)
{
return sideLengths[number];
}
public int perimeter()
{
int total = 0;
for (int index = 0; index < sideLengths.length; index += 1)
{
total += side(index);
}
return total;
}
}
class Rectangle{
private int[] sideLengths;
public Rectangle(int length1, int length2) {
sideLengths[0] = length1;
sideLengths[1] = length2;
}
public int area() {
int total = 1;
for(int x = 0; x < sideLengths.length; x++) {
total = total * Polygon.side(x);
}
}
}
}
This whole block is the code. I'm not allowed to edit class Polygon in any way.
public int side(int number)
{
return sideLengths[number];
}
is what I want to call, and I'm calling it this way:
public int area() {
int total = 1;
for(int x = 0; x < sideLengths.length; x++) {
total = total * Polygon.side(x);
}
}
My error is "Cannot make a static reference to the non-static method side(int) from the type Polygon"
Polygon.side is not a static method. That means you can't call it on the class object but instead you need to create an instance of the class.
Polygon polygon = new Polygon();
polygon.side(x);

MineSweeper game array

I have the same problem as some guy who asked this.
I want to code some basic stuff for a little minesweeper game.
Now I have the problem that my code
public class Minesweeper1 {
public static int[][] makeRandomBoard(int s, int z, int n){
int feld[][] = new int [s][z];
for(int i = 0; i < s; i++){
for(int j = 0; j < z; j++){
feld[i][j] = 0;
}
}
for(int i = 0; i < n; i++){
selectRandomPosition(s, z);
feld[randomHeight][randomWidth] = 1;
}
}
so it starts the selectRandomPosition code:
public static int[] selectRandomPosition(int maxWidth, int maxHeight) {
int randomHeight = StdRandom.uniform(0, maxHeight);
int randomWidth = StdRandom.uniform(0, maxWidth);
return new int[]{randomHeight, randomWidth};
}
Here I am not allowed to change anything, but it returns a new array. Now my question is how can I use the new array in makeRandomBoard?, since I do not know any name of the array. When I use feld[randomHeight][randomWidth] = 1; it says that it does not know these variables.
And he did get the answer:
Call the method, and assign its return value to a variable. Now you have a name for the array:
// Make a call
int[] randomArray = selectRandomPosition(maxW, maxH);
// Access the width
int randomW = randomArray[0];
// Access the height
int randomH = randomArray[1];
but what do I have to write now?
I tried it with:
feld[randomW][randomH] = 1;
but it seems like it doesn't work. I also need a return statement.
Can anyone help me?
I believe this is the solution you are looking for:
Solution
public class Minesweeper1 {
// Note:
// s == Height
// z == Width
public static int[][] makeRandomBoard(int s, int z, int n) {
// Note: Misspelling of "field"?
int feld[][] = new int [s][z];
// Initialize the game board with no mines (value of 0)
for(int i = 0; i < s; i++) {
for(int j = 0; j < z; j++) {
feld[i][j] = 0;
}
}
// Iterate through n times to place "mines" (value of 1)
for(int i = 0; i < n; i++){
// selectRandomPosition returns an array of length 2
// the first index (0) = randomHeight
// the second index (1) = randomWidth
// Notice that z and s is flipped
// because the first parameter is for width, which is z
// and the second parameter is for height, which is s
int[] position = selectRandomPosition(z, s);
int positionX = position[1];
int positionY = position[0];
// The order of positionY/positionX is key!
// If it's in the wrong order you will get an
// IndexOutOfBoundsException!
feld[positionY][positionX] = 1;
}
// Return the newly created array
return feld;
}
public static int[] selectRandomPosition(int maxWidth, int maxHeight) {
int randomHeight = StdRandom.uniform(0, maxHeight);
int randomWidth = StdRandom.uniform(0, maxWidth);
// Notice that this is returning a fixed array of two elements
// the first being the Y component, and the second being the X
// component.
return new int[]{randomHeight, randomWidth};
}
}
Problems
Passing the wrong values
You were calling selectRandomPosition wrong. Remember that s is the Height, and z is the Width. So you were passing into selectRandomPosition the Height for the first parameter, and the Width for the second parameter. Look at the method declaration:
public static int[] selectRandomPosition(int maxWidth, int maxHeight)
That meant you passed the Height into the maxWidth, and the Width into the maxHeight. My solution flips it for you. This can be confusing because s and z don't really give you hints to what they are (Height and Width) - consider renaming these variables to help you.
Accessing in the wrong order
You have in your question:
feld[randomW][randomH] = 1;
This is wrong, it should be:
feld[randomH][randomW] = 1;
This image shows a visual representaion of what a two dimensional array looks like:
So the access would be:
feld[0][0] == 1
feld[0][1] == 1
feld[0][2] == 1
feld[1][0] == 1
feld[1][1] == 2
feld[1][2] == 4
feld[2][0] == 1
feld[2][1] == 3
feld[2][2] == 9
Nit-Pick: Misspellings
Other than having weird variable names like s and z that do not help you at all in remembering what means what, your main variable that you will eventually return is misspelled. Did you mean "field"?
Variable naming is important and can help you, and other readers, to easily understand your code. Also, comments in places where you think you need them also help!

2d array holding objects of one class in another class

I would like to create a 2d array ( the way its done in the block commented out below) which holds Cell objects.However i dont want to create this array in Cell class but in a Game class. I'm not sure how to do it? If i just put that in game class then i get an error of unknown class.In c++ an include would do but in java i'm quite new...
public class Cell{
public int positionX;
public int positionY;
public int valueOfCell = 0;
/*
Cell[][] array = new Cell[12][12];
for (int i = 0; i < 12; i++)
{
for (int j = 0; j < 12; j++) {
array[i][j] = new Cell(i, j);
}
}
*/
public Cell getCell() {
}
public void setCell(Cell object,int Nvalue) {
object.valueOfCell=Nvalue;
}
}
EDIT: All classes are in one package
While assigning new instance of Cell to array, int i and int j are passed in the constructor i.e. new Cell(i, j) but there is no constructor with two parameters defined in Cell.java. Also, as mentioned above the getCell method is not returning anything when the return type is declared to be of Type Cell. Cell.java can be modified as below:
public class Cell {
public int positionX;
public int positionY;
public int valueOfCell = 0;
public Cell(int i, int j) {
this.positionX = i;
this.positionY = j;
}
public Cell getCell() {
return this;
}
public void setCell(Cell object, int Nvalue) {
object.valueOfCell = Nvalue;
}
}
In addition, I would declare positionX, positionY, and valueOfCell as private instead of public and use getter and setter instead.
import Cell into your Game class at the top of your file for Cell.java:
import Cell;
Give it the fully qualified package name if Cell outside the package Game is in.

Initializing 2d java array

I am working on an extremely basic game. However when I try to create the array i am running into errors. The error is index out of bounds. However I thought I fixed it by adding the -1 to make sure I don't go out of bounds. can someone tell me, or give me a clue as to what I did wrong?
package gameProject;
public class world {
int numEnemies, numBosses;
int [][] world = new int[10][10];
public world(){
int[][] world = createArray(10,10);
populateWorld(world);
}
private int[][] createArray(int inX, int inY){
//create the array that holds world values
int[][] world = new int[inX][inY];
//initialize the world array
for(int i = 0; i < world.length - 1; i ++){
for(int j = 0; j < world[0].length - 1; j++){
world[i][j] = 0;
}
}
return world;
}
private void populateWorld(int[][] world){
for(int i = 0; i < world.length - 1; i++){
for(int j = 0; j < world[0].length - 1; i++){
world[i][j] = 0;
}
}
}
}
In your populateWorld method, change
for(int j = 0; j < world[0].length - 1; i++)
to
for(int j = 0; j < world[0].length - 1; j++)
You keep incrementing the wrong counter, going eventually out of its bounds. (10)
(PS: you don't need the length - 1 in your loops' condition, just length would do)
The error is in
for (int j = 0; j < world[0].length - 1; i++)
you should write
for (int j = 0; j < world[0].length - 1; j++)
instead.
Note that you can reduce your code a little bit:
You create the array for member World.world twice. Also the elements of an int array are already initialized to 0 so you don't need to do this explicitly.
You should just do
private int[][] createArray(int inX, int inY) {
int[][] world = new int[inX][inY];
for (int i = 0; i < inX; i++)
for (int j = 0; j < inY; j++)
world[i][j] = 0;
return world;
}
You never actually need to check the length of the world array, because the length was already passed in as a parameter value.
And then also
private void populateWorld(int[][] world) {
for (int i = 0; i < world.length; i++)// v error 'i' should be 'j'
for (int j = 0; j < world[i].length; j++) // <- error on this line
world[i][j] = 0;
}
Your basic problem is that you're incrementing the wrong loop variable.
Why? Because you're far off from any clean code.
Lemme show you how clean coding is done:
class names start with a capital letter, method and variable name with lower case letters
you might prefix your variables with their scope ('m' for member, 'p' for parameter, nothing for local variables). Saves you the all-time-reference to 'this'. Strongly depends on your code style. I highly suggest doing it, keeps your code clean and really easy to debug.
use the final and private keywords where possible
use descriptive variable names. Here especially x and y for loop variables, as you're abstracting a 2d-plane
Some more considerations:
usually games grow more complex. Usually simple primitives (like your int-array) will not suffice for long to store all relevant information. Use classes like Cell
use enums so you can lose magic numbers => coding, reading and debugging made a lot easier
So - after a lot of talk - here's the final code:
package gameproject;
/**
* Use comments like this to describe what the classes purpose is.
* Class comment is the most important one. If you can't tell what a method/variable is doing by its name, you should also comment methods and/or variables!
* #author JayC667
*/
public class World {
/*
* STATIC part of the class - keep separated from object code
*/
// you could/should also put these static classes to their separate files and make em non-static
/**
* Denotes, what a {#linkplain Cell} is occupied with
*/
static public enum CellType {
EMPTY, //
BOSS, //
ENEMY
}
/**
* Represents a single cell within the world. Stores information about its coodrinates (redundant) and its occupator (see {#linkplain CellType})
* #author JayC667
*/
static private class Cell { // use cell to store data for you
public final int mX; // x and y are actually not useful at the moment, you could also remove them
public final int mY;
private CellType mCellType = CellType.EMPTY;
public Cell(final int pX, final int pY) {
mX = pX;
mY = pY;
}
public CellType getCellType() {
return mCellType;
}
public void setCellType(final CellType pCellType) {
mCellType = pCellType;
}
}
// when possible, make methods static, unless you unnecessarily blow up the parameter list
// this is a typical demo for a factory method
static private Cell[][] createWorld(final int pWidth, final int pHeight) {
final Cell[][] newWorld = new Cell[pWidth][pHeight];
for (int y = 0; y < pHeight - 1; y++) {
for (int x = 0; x < pWidth - 1; x++) {
newWorld[y][x] = new Cell(x, y);
}
}
return newWorld;
}
/*
* OBJECT part of the class - keep separated from static code
*/
private final Cell[][] mWorld;
private final int mWorldWidth;
private final int mWorldHeight;
private final int mNumberOfEnemies;
private final int mNumberOfBosses;
public World(final int pWidth, final int pHeight, final int pNumberOfEnemies, final int pNumberOfBosses) {
if (pWidth < 1 || pHeight < 1) throw new IllegalArgumentException("World width and height must be greater than 0!");
if (pNumberOfEnemies < 0 || pNumberOfBosses < 0) throw new IllegalArgumentException("Enemy and boss counts must not be negative!");
if (pWidth * pHeight < pNumberOfEnemies + pNumberOfBosses) throw new IllegalArgumentException("World is too small for all the bad guys!");
mWorldWidth = pWidth;
mWorldHeight = pHeight;
mNumberOfEnemies = pNumberOfEnemies;
mNumberOfBosses = pNumberOfBosses;
mWorld = createWorld(pWidth, pHeight);
populateWorld();
}
// refers to many member variables, so not static (would only blow up parameter list)
private void populateWorld() {
for (int i = 0; i < mNumberOfBosses; i++) {
final Cell c = getRandomCell(CellType.EMPTY);
mWorld[c.mY][c.mX].setCellType(CellType.BOSS);
}
for (int i = 0; i < mNumberOfEnemies; i++) {
final Cell c = getRandomCell(CellType.EMPTY);
mWorld[c.mY][c.mX].setCellType(CellType.ENEMY);
}
}
private Cell getRandomCell(final CellType pCellType) {
while (true) { // TODO not a good, but simple solution; might run infinite loops
final int randomX = (int) (mWorldWidth * Math.random());
final int randomY = (int) (mWorldHeight * Math.random());
if (mWorld[randomY][randomX].getCellType() == pCellType) return new Cell(randomX, randomY);
}
}
}

Categories

Resources