In the constructor of the model class, I need to allocate the memory of this array of booleans (boolean[ ][ ] is_hidden;). I also need to set them to true, but have no idea how this happens, a nested loop will have to be used like the one in the paint method at he bottom, in order to set each element.
class MineFinderModel {
public static int MINE_SQUARE = 10;
public static int EMPTY_SQUARE = 0;
int num_of_cols;
int num_of_rows;
int[][] the_minefield;
boolean[][] is_hidden;
public MineFinderModel(int n_cols, int n_rows) {
num_of_rows = n_rows;
num_of_cols = n_cols;
the_minefield = new int[num_of_cols][num_of_rows];
is_hidden = new boolean[][];
}
Paint method example:
for (int i = 0;i<numCols;i++)
{
for(int j = 0;j<numRows;j++)
{
Rectangle r = getRect(i,j);
g.setColor(Color.black);
g2.draw(r);
if(i==0&&j==0) {
g2.drawOval(x,y,w,h);
g2.fillOval(x,y,w,h);
}
if(i==0&&j==(numRows-1))
g2.fillOval(x,y,w,h);
if(i==(numCols-1)&&j==0)
g2.fillOval(x,y,w,h);
if(i==(numCols-1)&&j==(numRows-1))
g2.fillOval(x,y,w,h);
You need to define the array with the sizes e.g.
is_hidden = new boolean[cols][rows]();
and iterate through, setting each cell to true (booleans, and boolean arrays, default to false).
Note that Arrays.fill() exists, but will only get you halfway, since it won't fill multidimensional arrays. You can use this, but you'd have to iterate through the rows, and use Arrays.fill on each row. Perhaps not worthwhile in this example, but worth being aware of regardless.
Try this:
int num_of_cols = 2;
int num_of_rows = 3;
boolean[][] is_hidden;
is_hidden = new boolean [num_of_cols][num_of_rows];
for (int i = 0; i < num_of_cols; i++) {
for (int j = 0; j < num_of_rows; j++) {
is_hidden[i][j] = true;
}
}
You can see it is now correctly initialized:
for (boolean[] col : is_hidden) {
for (boolean elem : col) {
System.out.println(elem);
}
}
when you define a boolean array the value of all the elements are false by default.
I would suggest instead of looping through all the elements, implement your conditions in way that you can use the default false value.
Eg.
boolean[][] isEnabled = new boolean[10][10];
// code to set all elements to true
if(isEnabled[i][j]){
//some code
}
this can be easily replaced by
boolean[][] isDisabled = new boolean[10][10];
if(! isDisabled[i][j]){
//some code
}
You can save processing time this way and code looks neat :).
Simply write a nested loop.
for (int i = 0;i<n_rows;i++){
for(int j = 0;j<n_cols;j++){
is_hidden[n_rows][n_cols] = true;
}
}
I have a simple solution for you: instead of using your array is_hidden and fill each element of it with true, use the name isVisible and don't fill it at all since every element of it is already initialized to false ;)
Related
I am not sure if it's rly possible to check but I have an issue rn where I have an array
let's say: int[] unmarkedSum = new int[100];
Now I put something in this array when a certain condition is true so not in every single iteration. But I know for a fact that at some point the whole array will be filled with any positive values that are not 0 because of how my algorithm works.
My question here is: Is there a way of checking WHEN it's fully filled?
Like I started like this:
for(int i = 0; i < unmarkedSum.length; i++) {
if(unmarkedSum[i] == 0 {
break;
}
else {
// idk tbh
}
}
In Java by default an array of ints is filled with zeros. You can use this to check if the array is fully filled. For example you can create a method which checks for 0 and returns true if there are no 0:
public static bool isArrayFilled(int[] array) {
for(int i = array.length; i >= 0; i--){
if(array[i] == 0) {
return false;
}
}
return true;
}
If array is big enough and filled out of order, you can use advanced algorithms to find at least one 0 value in the array.
I would simply maintain a variable size that keep tracks of how many values have been written to the array.
Example:
int size = 0;
int[] array = new int[100];
Random r = new Random();
while(size < array.length){
int index = r.nextInt(100);
int val = r.nextInt(1000)+500;
if (array[index] == 0){
array[index] = val;
size++;
}
}
System.out.println(Arrays.toString(array));
Per my previous comment, you can share this array with another thread so that one thread can fill the values and another can check the array at the same time. When the second thread finds that there are no default values (or 0s) then it can notify the first thread (or the main thread). Here is how you can do that
import java.util.Arrays;
import java.util.Random;
public class CheckArray {
public static void main(String[] args) throws InterruptedException {
var arr = new int[50];
Thread arrayChecker = new Thread(() -> {
var isZeroPresent = false;
while (true) {
for (int index = 0; index < arr.length; index++) {
isZeroPresent = false;
if (arr[index] == 0) {
isZeroPresent = true;
break;
}
}
if (isZeroPresent == false) {
// if the for loop completed then control will come here
System.out.println("Array has been filled");
System.out.println(Arrays.toString(arr));
System.exit(0);
}
}
});
arrayChecker.start();
// fill random values in the array
// while another thread has been started
Random random = new Random();
while(true) {
Thread.sleep(500);
int index = random.nextInt(arr.length);
arr[index] = random.nextInt(100);
System.out.println(Arrays.toString(arr));
}
}
}
I made a Matrix class in JAVA that consists of a 2D int array with row and column variables. The constructor of the class generates a Matrix of dimensions n x m and I also implemented two methods that print the values of the Matrix and its transpose (getMatrixValues and getTransposedValues).
However, I would like to make a function that takes as input a matrix and returns its transpose, but since this class is not an array I cannot iterate over it using AT[j][i] = A[i][j], if I understand the exception correctly that IntelliJ is returning me ("java: array required, but Matrix found").
Obviously, I could simply use an int[][] class to begin with instead of defining a new class, but since I am new to JAVA and object-oriented programming in general I wondered whether there is not another possibility without discarding my Matrix class?
Here is my code:
import java.util.Random;
import java.util.Arrays;
public class Matrix {
private int n; // rows
private int m; // cols
private int[][] A; // matrix
public static void main(String[] args){
Matrix A = new Matrix(4,4);
A.getMatrixValues();
System.out.println("\n");
A.getTransposedValues();
Matrix AT = transposeMatrix(A);
}
// constructor (randomly generates matrix)
public Matrix(int rows, int cols){
n = rows;
m = cols;
A = new int[rows][cols];
Random r = new Random();
// r.setSeed(1);
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols ; j++)
{
A[i][j] = r.nextInt(10);
}
}
}
// print matrix
public void getMatrixValues(){
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
System.out.print(A[i][j]+"\t");
}
System.out.print("\n");
}
}
// print transposed matrix
public void getTransposedValues(){
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
System.out.print(A[j][i]+"\t");
}
System.out.print("\n");
}
}
public static Matrix transposeMatrix(Matrix A){
Matrix AT = new Matrix(A.get_n(), A.get_m());
for(int i = 0; i < A.get_n(); i++)
{
for(int j = 0; j < A.get_m(); j++)
{
AT[j][i] = A[i][j];
}
}
return AT;
}
// getters
public int get_n(){
return n;
}
public int get_m(){
return m;
}
}
Preface
What I have noticed only afterwards was, that when creating the transposed matrix, you actually want to create one with m-rows and n-columns.
That means, you have mixed up m and n in transposeMatrix() when instantiating the new object.
That also means that your code -as it is- only works for square matrices. Just create the object like this: new Matrix(matrix.get_m(), matrix.get_n()).
Note: I re-named your variables; see below in section "Solution".
However, since this is not part of you question, I have not fixed it in the code-snippets below.
Scopes
When in every other method, you are in the lexical scope of the object you are in. This allows you to access its fields (like int[][] A).
But when inside transposeMatrix(Matrix A), you are inside the static scope, meaning, not in the scope of an object.
What adds to the confusion is, that your instance-variable is called A, much like the parameter Matrix A of transposeMatrix(). While you were able to access the 2D-array via A, you now access a Matrix-object via A. That is both because we are not in an object anymore, and because the new local variable overrides the access to the similarly named instance-/static-variable (you would have to use this.A or Matrix.A respectively).
Access modifier
When trying to fix your code, you will stumble upon the restriction of the access modifier you used: private.
private int[][] A will make A (your array) only accessible when referenced from inside your object. But when calling transposeMatrix(), we are in a static-context, meaning, not inside your object anymore.
To fix this, can change the access modifier to allow us to access that field from outside the object. To enable this, you can change the modifier to any other option, with the easiest being to just remove it. However, I suggest you to read more about Access Modifier in the official documentation.
Solution
Let's say we removed private from int[][] A. Will the code work?
No. That's because of the confusion I talked about when explaining scopes. To clear up the confusion, let's rename some variables: (Changed int[][] A to int[][] array, Matrix A to Matrix matrix, Matrix AT to Matrix matrixTransposed)
int[][] array; // <-- Notice the removed access modifier!
// ...
public static Matrix transposeMatrix(Matrix matrix){
Matrix matrixTransposed = new Matrix(matrix.get_n(), matrix.get_m());
for (int i = 0; i < matrix.get_n(); i++) {
for(int j = 0; j < matrix.get_m(); j++) {
matrixTransposed[j][i] = matrix[i][j]; // Won't work!
}
}
}
The code above is still faulty. That is -as we can clearly see now- because we are trying to access a Matrix-object as if it was an array. However, we need to access its instance variable. So, instead of accessing the array the wrong way, we add a .array after every Matrix-object where we try to access its array.
public static Matrix transposeMatrix(Matrix matrix){
Matrix matrixTransposed = new Matrix(matrix.get_n(), matrix.get_m());
for (int i = 0; i < matrix.get_n(); i++) {
for(int j = 0; j < matrix.get_m(); j++) {
matrixTransposed.array[j][i] = matrix.array[i][j]; // NOW we are accessing their arrays respectively
}
}
}
Another solution
With changing the access modifier of the array (like we did above), we enable one to not only override the values of the array, but also to override the array itself.
To restrict one from doing so, we can use "Getters and Setters". They are like a middle-man, allowing us to access the array only indirectly, but with that much control over it as we seem necessary.
We can define them simply creating two new methods (hence its name):
public int get(int i, int j) {
return array[i][j];
}
public void set(int i, int j, int value) {
array[i][j] = value;
}
As you see, we simply forward the request to the "middle-man", which handles it accordingly.
Note: We might encounter a Runtime Exception since we are not checking if the fields at the specified indices actually exist. You might want to add some if-statements before accessing them.
By using the getter and setter, we can modify the code to this:
private int[][] array; // We still want to restrict access to 'array'...
// ...
// ...but still allow accessing them, be it indirectly
public int get(int i, int j) {
return array[i][j];
}
public void set(int i, int j, int value) {
array[i][j] = value;
}
// Now using getter and setter
public static Matrix transposeMatrix(Matrix matrix) {
Matrix matrixTransposed = new Matrix(matrix.get_n(), matrix.get_m);
for (int i = 0; i < matrix.get_n(); i++) {
for (int j = 0; j < matrix.get_m; j++) {
matrixTransposed.set(j, i, matrix.get(i, j));
}
}
}
Sidenote
You should also take a look at naming conventions. They are not critical to make your code function, but make reading and understanding (and thus debugging) it a lot easier.
What I think is also good, is to take a look at a style-guide to see how you can make your code more readible with easy tricks, or just to have a consistent style across your code. I enjoy Google's style-guide for Java, however, there are a lot others as well.
And, you don't have to stick to an existing style-guide, you can have your own style, too! But try to be as consistent as possible. That makes it easier for others and yourself in the future when re-reading your code.
When I am creating an array of Example objects, I call something like initializeArray(); I use a simple nested for loop to traverse through the array and then assign new objects with values to each index of the array using exampleArr[i][j] = new Example(false, false, false, 0); however, calling this gives me an java.lang.ArrayIndexOutofBoundsException:0 at the line above.
I am assuming that I am instantiating the new object incorrectly, as this also happens in another method which is supposed to display all of the Example objects in the array. However, I will post the nested loop I am using in case there is something that i've done wrong that I can't see.
public void initializeArray(){
for(int i = 0; i < getRows(); i++){
for(int j = 0; j < getColumns(); j++){
tileArr[i][j] = new Tile(false, false, false, 0);
}
}
}
//Declaration of rows and columns
private int rows;
private int columns;
Tile[][] tileArr = new Tile[rows][columns];
public void setRows(int r)
{
rows = r;
}
public void setColumns(int c)
{
//various setters and getters for the array
columns = c;
}
public int getRows()
{
System.out.print(rows);
return rows;
}
public int getColumns()
{
System.out.print(columns);
return columns;
}
Thanks everyone for your help! The problem has been solved.
Declare your tileArr at the top but do not initialize.
Tile[][] tileArr;
Then initialize your array before your for loop in the initializeArray() (This is assuming your rows and columns is set. You can add logic to check this as well).
tileArr = new Tile[getRows()][getColumns()];
tileArr = new Tile[rows][columns]; //Do this instead if you don't want the print statements to be called
As #gonzo said you have got to initialize your array to allocate enough memory for all the positions you are going to be using.
Tile[][] tileArr;
public void initializeArray(){
Tile[][] tileArr = new Tile[getRows()][getColumns()];
for(int i = 0; i < getRows(); i++){
for(int j = 0; j < getColumns(); j++){
tileArr[i][j] = new Tile(false, false, false, 0);
}
}
return titleArr;
}
//...wherever you want it
this.tileArray = this.initializeArray()
But there are cases when you don't know how big this array may be. For those cases you should be using List<Tile> type like LinkedList<Tile> or ArrayList<Tile> so that you don't need to allocate space for every new position to use.
In a task I have I need to union two sets(arrays of integers), but from some reason i'm getting the wrong output...
this is the attributes of the class set:
private int []set;
private int counter;
private int max = 10;
this is the constructor I use to get numbers(i needed to use varags because i need to be able to change the number of elements in the set):
public Set (int...numbers) {
set = new int[max];
counter = 0;
for (int i = 0; i < numbers.length; i++) {
if (!this.isMember(numbers[i])) {
this.set[this.counter] = numbers[i];
this.counter++;
}
}
}
this is the union method:
public Set union (Set setToUnion) {
Set setToReturn;
if (this.equals(setToUnion)){
setToReturn = new Set(setToUnion);
return setToReturn;
}
setToReturn = new Set(this.set);
for (int i = 0; i < setToUnion.counter; i++) {
if (!setToReturn.isMember(setToUnion.set[i])) {
setToReturn.set[setToReturn.counter ] = setToUnion.set[i];
setToReturn.counter++;
}
}
return setToReturn;
}
and if you want to see how the isMember looks so here it is(just checking if some number is a member of other set):
public boolean isMember (int n) {
if (isEmpty()) {
return false;
}
for (int i = 0; i < this.counter; i++) {
if (n == this.set[i]) {
return true;
}
}
return false;
}
Now in the program I created two sets like this:
Set someSet = new Set(1,2,3,4,5);
Set anotherSet = new Set(2,6,7,8,9);
Set m = someSet.union(anotherSet);
m.show();
but the output I'm getting is (1,2,3,4,5,0,6,7,8,9) and i need the same one but without the 0 in the middle...
please help
thanks!
The problem appears to be this line in the union method:
setToReturn = new Set(this.set);
It should probably be:
setToReturn = new Set(this);
Why is that causing a problem?
At this point, this.set equals [1, 2, 3, 4, 5, 0, 0, 0, 0, 0], which is an int array. Therefore, the following constructor will be called:
public Set (int...numbers) { ... }
That means all those numbers in the array will be added, including the zeroes. Either you need to truncate the zeroes from the array by doing something like...
setToReturn = new Set( Arrays.copyOf( set, counter ) );
or have a constructor that accepts a Set. That way you can access counter to see how many numbers in the array are actually part of the Set. I guessed you already have that constructor, based on another part of the code that calls such a constructor.
I get: 'unexpected type
required: variable
found : value' on the marked lines (*)
for (int i = 0; i < boardSize; i++) {
for (int j = 0; j < boardSize; j++) {
rows[i].getSquare(j) = matrix[i][j]; // * points to the ( in (j)
columns[j].getSquare(i) = matrix[i][j]; // * points to the ( in
int[] b = getBox(i, j);
int[] boxCord = getBoxCoordinates(i + 1, j + 1);
boxes[b[0]][b[1]].getSquare(boxCord[0], boxCord[1]);
}
}
This is my Row class:
private Square[] row;
Row(int rowCount) {
this.row = new Square[rowCount];
}
public Square getSquare(int index) {
return this.row[index];
}
Please help me out by pointing out what I'm doing wrong here.
Thanks in advance.
You cannot assign something to the return value of a method. Instead, you need to add a setSquare() method to the Row class:
public Square setSquare(int index, Square value) {
this.row[index] = value;
}
and use it like this:
rows[i].setSquare(j, matrix[i][j]);
Java doesn't have pointers - references are not the same thing.
It's impossible to tell what's really going on based on the code you posted. I think you need a method to set the value of that Square in the private array your Row class owns.
public void setSquare(int index, Square newSquare) {
this.row[index] = newSquare;
}
It looks like a poor abstraction, in any case.
Java has no pointers. Objects are passed and returned by reference. In terms of C++, rows[i].getSquare(j) is an rvalue, not an lvalue, so you cannot assign to it.
Instead, you should create and use rows[i].setSquare(...).