my program is to complete Conway's game of life using multithreading. i keep getting the error Exception in thread "main" java.lang.NullPointerException
at life.main(life.java:51)
the exception is thrown at different parts of its execution, never actually completing the first threading in its entirety. any help would be appreciated.
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class life {
final static int rowBound = 9;
final static int colBound = 9;
static int numThreads;
static boolean matrix[][];
static boolean prevMatrix[][];
static boolean newMatrix[][];
static boolean stable;
public static void main(String[] args) {
matrix = new boolean[rowBound+1][colBound+1];
prevMatrix = new boolean[rowBound+1][colBound+1];
newMatrix = new boolean[rowBound+1][colBound+1];
stable = false;
Scanner in = new Scanner (System.in);
numThreads = 8;
matrix = fillMatrix(matrix);
Random r = new Random();
matrix = initializeMatrix(matrix, r);
printMatrix(matrix);
Thread[] threads = new Thread[numThreads];
while (!stable){
for (int i = 1; i < numThreads; ++i) {
Runnable prod = new update(i, newMatrix);
threads[i] = new Thread(prod);
threads[i].start();
}
for (Thread t : threads) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
stable = compare(prevMatrix, newMatrix);
printMatrix(newMatrix);
if (!stable){
prevMatrix = give(prevMatrix, matrix);
matrix = give(matrix, newMatrix);
}
}
}
// fill matrix with false
public static boolean[][] fillMatrix(boolean[][] mat) {
for (int x = 0; x < rowBound; x++) {
for (int y = 0; y < colBound; y++) {
mat[x][y] = false;
}
}
return mat;
}
// initializes the matrix
public static boolean[][] initializeMatrix(boolean[][] mat, Random r) {
for (int x = 1; x < rowBound; x++) {
for (int y = 1; y < colBound; y++)
mat[x][y] = r.nextBoolean();
}
return mat;
}
// print matrix
public static void printMatrix(boolean[][] matrix) {
System.out.println("Dead cell --> '-' Live cell --> '+'");
for (int x = 0; x <= rowBound; x++) {
for (int y = 0; y <= colBound; y++) {
if (!matrix[x][y])
System.out.print(" -");
else
System.out.print(" #");
}
System.out.println();
}
}
public static boolean compare(boolean[][] prevM, boolean[][] newM) {
for (int a = 1; a < rowBound-1; a++){
for (int b = 1; b < colBound-1; b++){
if (prevM[a][b] != newM[a][b])
return false;
}
}
return true;
}
static class update implements Runnable {
int counter;
int numRows;
int firstRow;
int lastRow;
int thread;
public update(int i, boolean[][] newMatrix) {
thread = i;
}
#Override
public void run() {
numRows = 1;
firstRow = thread * numRows;
lastRow = numRows + firstRow;
counter = 0;
for (int a = firstRow; a < lastRow; a++) {
for (int b = 1; b < colBound; b++) {
for (int c = a - 1; c <= a + 1; c++) {
for (int d = b - 1; d <= b + 1; d++) {
if (matrix[c][d] == true)
counter++;
}
}
if (matrix[a][b]) {
counter--;
if (counter < 4) {
if (counter > 1)
newMatrix[a][b] = true;
else
newMatrix[a][b] = false;
} else
newMatrix[a][b] = false;
} else {
if (counter == 3)
newMatrix[a][b] = true;
else
newMatrix[a][b] = false;
}
}
}
}
}
// gives the values from the newMatrix and puts them into matrix
public static boolean[][] give(boolean[][] matrix, boolean[][] newMatrix) {
for (int x = 0; x < rowBound; x++) {
for (int y = 0; y < colBound; y++) {
matrix[x][y] = newMatrix[x][y];
}
}
return matrix;
}
}
You are getting an NPE as you never assign a Thread at index position 0:
for (int i = 1; i < numThreads; ++i) {
so the exception is thrown when attempting to access it here:
for (Thread t : threads) {
...
t.join(); // NPE
Related
How could I optimise this code to take the String[] games values from the main method and have a separate method: public static int points(String[] games). I am super new to Java and don't really understand how to invoke methods.
public class TotalPoints {
public static void main(String[] args) {
String[] games = {"1:0","2:0","3:0","4:0","2:1","3:1","4:1","3:2","4:2","4:3"};
int sum = 0;
int matches = 10;
int x = 0;
int y = 0;
for (int i = 0; i < games.length; i++) {
String[] pieces = games[i].split(":");
x = Integer.parseInt(pieces[0]);
y = Integer.parseInt(pieces[1]);
}
for (int j = 0; j < matches; j++) {
if (x > y) {
sum = sum + 3;
} else if (x == y) {
sum = sum + 1;
}
}
System.out.println(sum);
}
}
You can write something like
public class TotalPoints {
public static void main(String[] args) {
int sum = points(args);
System.out.println(sum);
}
public static int points(String[] games) {
int sum = 0;
int matches = 10;
int x = 0;
int y = 0;
for (int i = 0; i < games.length; i++) {
String[] pieces = games[i].split(":");
x = Integer.parseInt(pieces[0]);
y = Integer.parseInt(pieces[1]);
}
for (int j = 0; j < matches; j++) {
if (x > y) {
sum = sum + 3;
} else if (x == y) {
sum = sum + 1;
}
}
return sum;
}
}
And when you run this class, pass the arguments from command line like
java TotalPoints "1:0" "2:0" "3:0" "4:0" "2:1" "3:1" "4:1" "3:2" "4:2" "4:3"
very simple:
public class TotalPoints {
public static void main(String[] args) {
String[] games = {"1:0","2:0","3:0","4:0","2:1","3:1","4:1","3:2","4:2","4:3"};
int result = points(games);
}
public static int points(String[] games) {
//dowhat ever you want and return an int value
}
}
I suggest this to you
public class TotalPoints {
public static void main(String[] args) {
String[] games = {"1:0","2:0","3:0","4:0","2:1","3:1","4:1","3:2","4:2","4:3"};
int sum = points(games);
System.out.println(sum);
}
private static int points(String[] games) {
int sum = 0;
int matches = 10;
int x = 0;
int y = 0;
for (String game : games) {
String[] pieces = game.split(":");
x = Integer.parseInt(pieces[0]);
y = Integer.parseInt(pieces[1]);
}
for (int j = 0; j < matches; j++) {
if (x > y) {
sum = sum + 3;
}
else if (x == y) {
sum = sum + 1;
}
}
return sum;
}
}
I replace for (int i = 0; i < games.length; i++)
by
for (String game : games)
it's a simpler way to browse a list
I am quite new to Java and I have this school assignment to write Conway's Game of Life. The task I am struggling with is reading a patterns from file. So far I got this code from tutorial from my school:
#FXML
private void readFromFile(){
FileChooser fileChooser = new FileChooser();
File openFile = fileChooser.showOpenDialog(null);
if(openFile == null){
return;
}
try (BufferedReader reader = Files.newBufferedReader(openFile.toPath())){
String line;
while ((line = reader.readLine()) != null){
addMessage(line);
}
}catch (IOException ex){
showIOErrorAlert(ex);
}
}
#FXML
private void showIOErrorAlert(IOException ex){
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setContentText("IOException, filen cannot be open: " + ex);
alert.show();
}
The code opens a window where I can choose a file from disk (I've downloaded all patterns in rle format , and I wish to open them rle format, because that is the assignments requirement). But when I choose a file nothing happens, not an error, nothing. What do I need to do that this work? Do I need to write a parser here? To read a rle format. I am using mvc model and java fxml this is my Cell class:
public class Cell extends Rectangle{
public static final int CELL_SIZE = 5;
private boolean alive;
public Cell(){
super(CELL_SIZE, CELL_SIZE);
setAlive(false);
}
public void setAlive(boolean bool){
alive = bool;
if (alive){
setFill(Color.WHITE);
} else {
setFill(Color.BLACK);
}
}
public boolean isAlive(){
return alive;
}
}
Board class:
public class Board {
public static final int COLUMNS = 90;
public static final int ROWS = 210;
private Cell[][] generation;
public Board(){
generation = new Cell[COLUMNS][ROWS];
for(int x = 0; x < COLUMNS; x++){
for(int y = 0; y < ROWS; y++){
generation[x][y] = new Cell();
}
}
}
public Cell[][] getBoard(){
return generation;
}
public void fill(){
Random rand = new Random();
for(int x = 0; x < COLUMNS; x++){
for(int y = 0; y < ROWS; y++){
generation[x][y].setAlive(rand.nextBoolean());
}
}
}
public void reset(){
for(int x = 0; x < COLUMNS; x++){
for(int y = 0; y < ROWS; y++){
generation[x][y].setAlive(false);
}
}
}
public int countNeighbors(int x, int y){
int neighbors = 0;
//iteration starts with -1 in order to 'wrap' the grid around
for (int a = -1; a < 2; a++){
for (int b = -1; b < 2; b++){
int nx = x + a;
int ny = y + b;
if (nx < 0){
nx = COLUMNS - 1;
}
if (ny < 0){
ny = ROWS - 1;
}
if (nx > COLUMNS - 1){
nx = 0;
}
if (ny > ROWS - 1){
ny = 0;
}
if(generation[nx][ny].isAlive()){
neighbors += 1;
}
}
}
if(generation[x][y].isAlive())
neighbors--;
return neighbors;
}
public void renew(){
Cell[][] nextGeneration = new Cell[COLUMNS][ROWS];
for(int x = 0; x < COLUMNS; x++){
for(int y = 0; y < ROWS; y++){
nextGeneration[x][y] = new Cell();
nextGeneration[x][y].setAlive(generation[x][y].isAlive());
}
}
int neighborsCount = 0;
for(int x = 0; x < COLUMNS; x++){
for(int y = 0; y < ROWS; y++){
neighborsCount = countNeighbors(x, y);
if(generation[x][y].isAlive()){
if(neighborsCount < 2 || neighborsCount > 3)
nextGeneration[x][y].setAlive(false);
}
else{
if(neighborsCount == 3)
nextGeneration[x][y].setAlive(true);
}
}
}
for(int x = 0; x < COLUMNS; x++){
for(int y = 0; y < ROWS; y++){
generation[x][y].setAlive(nextGeneration[x][y].isAlive());
}
}
}
How to write a method that reads a rle format file and adds a pattern to my board?
we're supposed to multiply every element in the matrix by a number, in this case "k". not sure what i'm doing wrong but it wont work. HELP! i have edited and added the whole project so far.
public class Matrix {
private int r;//rows
private int c;//columns
private int[][] neo; //2D array
public static void main(String[] args) {
Matrix m1 = new Matrix(3,4);
Matrix m2 = new Matrix(3,4);
System.out.println(m2);
try {
Matrix m3 = m1.multiply(m2);
} catch (Exception e) {
e.printStackTrace();
}
m2.scaleMult(k);
}//main
public Matrix(int row, int column) {
r = row;
c = column;
neo = new int[r][c];
for(int i = 0; i < neo.length; i++) {
for (int j = 0; j < neo[i].length; j++) {
neo[i][j] = (int) (1 + Math.random() * 100);
}//forLoop
}//forLoop
System.out.println(Arrays.toString(neo));
}//Matrix
public Matrix copyMatrix(Matrix m) {
Matrix copy = new Matrix(m.r, m.c);
for (int i = 0; i < r; i++) {
System.arraycopy(this.neo[i], 0, copy.neo[i], 0, this.neo[i].length);
}//forLoop
return copy;
}//copyMatrix
public void scaleMult(int k){
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++)
this.neo[i][j] * k;
}//scaleMult
public boolean equals(Matrix m2) {
if (this.r != m2.r || this.c != m2.c) {
return false;
}
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (this.neo[i][j] != m2.neo[i][j]) {
return false;
}
}
}
return true;
}//equalsMethod
public Matrix multiply(Matrix m2) throws Exception {
if (this.c != m2.r) {
throw new RuntimeException();
}//if
Matrix m3 = new Matrix(this.r, m2.c);
for (int i = 0; i < this.r; i++) {
for (int j = 0; j < m2.c; j++) {
m3.neo[i][j] = 0;
for (int k = 0; k < this.c; k++) {
m3.neo[i][j] += this.neo[i][k] * m2.neo[k][j];
}//forK
}//forJ
}//forI
return m3;
}//multiplyMethod
}//class
Change your scaleMult method to this and it should work:
public void scaleMult(int k) {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
this.neo[i][j] *= k;
// you forgot to assign the value, basically we multiply neo[i][j] by k and make neo[i][j] receive that value
// making this.neo[i][j] = this.neo[i][j] *k; would work as well
}
}
}//scaleMult
Also, based on the example you provided on your main method, your code will launch an exception on the multiply method, because as you specified, you can only multiply two matrixes if one's columns amount is equal to the other's row amount. Other than that, I would advise on creating a new class just for your main method.
If your question is multiply a matrix by a number, then here is a very simple example.
public static void main(String []args){
int[][] a = {{1,2,3},{4,5,6}};
int[][] b=new int[2][3];
int i,j,k=2;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
b[i][j]=a[i][j]*k;
for(i=0;i<2;i++)
for(j=0;j<3;j++)
System.out.println(b[i][j]);
}
There must be some array variable on left which should be assigned the multiplied value.
Do this helped? If not, please post your complete code.
I am trying to build a simple pacman game, and I just got started.
Currently my constructor looks like this:
static String[][] board;
static int pacmanBornHeight;
static int pacmanBornWidth;
public PacmanKata(int height, int width) {
board = new String[height][width];
pacmanBornHeight = (int) Math.floor(height / 2);
pacmanBornWidth = (int) Math.floor(width / 2);
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth; j++) {
board[i][j] = "*";
}
}
board[pacmanBornHeight][pacmanBornWidth] = "V";
}
This constructor set up the board and the pacman will be located at the middle, I used "V" as the symbol.
I try to create two methods currenlty, move up and down.
Here is the setup:
I first called the tickUp method:
public void tickUp(int steps) {
int counter = 1;
int timer = 0;
for (int loop = 0; loop < steps; loop++) {
board[pacmanBornHeight - counter][pacmanBornWidth] = "V";
for (int innerTimer = 0; innerTimer < counter; innerTimer++) {
board[pacmanBornHeight - innerTimer][pacmanBornWidth] = " ";
}
counter++;
timer++;
}
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth; j++) {
System.out.print(board[i][j]);
}
System.out.println();
}
System.out.println("-------------------------");
} //end going UP
And I print out this to console(I initialized a 10 by 10 board):
Pacman moved up three steps, as expected, and eat three dots. I slightly modified and created a move down method:
public void tickDown(int steps) {
int counter = 1;
int timer = 0;
for (int loop = 0; loop < steps; loop++) {
board[pacmanBornHeight + counter][pacmanBornWidth] = "V";
for (int innerTimer = 0; innerTimer < counter; innerTimer++) {
board[pacmanBornHeight + innerTimer][pacmanBornWidth] = " ";
}
counter++;
timer++;
}
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth; j++) {
System.out.print(board[i][j]);
}
System.out.println();
}
System.out.println("-------------------------");
}//end tickDown
Now I called tickDown and asked it to move down 3 steps, but I got this result:
The trouble I am having is, I do not know how to locate the Pacman last location. The move down method simply created a new Pacman and moved down 3 steps, that is not what I want. How can I fix this?
Change your tickUp and tickDown methods to save the new position of your Pacman:
public void tickDown(int steps) {
int counter = 1;
int timer = 0;
for (int loop = 0; loop < steps; loop++) {
for (int innerTimer = 0; innerTimer < counter; innerTimer++) {
board[pacmanBornHeight + innerTimer][pacmanBornWidth] = " ";
}
pacmanBornHeight += counter;
//Allow for wraparounds:
if (pacmanBornHeight > board.length) {
pacmanBornHeight = 0;
}
board[pacmanBornHeight][pacmanBornWidth] = "V";
timer++;
}
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth; j++) {
System.out.print(board[i][j]);
}
System.out.println();
}
System.out.println("-------------------------");
}//end tickDown
I moved the loop to write spaces in the board to the beginning of the outer loop; that way you get the spaces based on the starting position of Pacman. Once you've written the spaces to the array, you update Pacman's position and write it in the array.
Edit:
Here's an example showing how you'd use a one-dimensional array as your board:
public class PacmanKata {
static String[] board;
static int pacmanPosition;
static int boardHeight;
static int boardWidth;
public static void main(String[] args) {
PacmanKata kata = new PacmanKata(10,10);
kata.tickUp(7);
kata.tickRight(9);
}
public PacmanKata(int height, int width) {
boardHeight = height;
boardWidth = width;
board = new String[height*width];
int offset = (width + 1) % 2;
pacmanPosition = (int) Math.floor((height + offset)*width/2);
for (int i = 0; i < board.length; i++) {
board[i] = "*";
}
board[pacmanPosition] = "V";
}
private void printBoard() {
for (int i = 0; i < board.length; i++) {
System.out.print(board[i]);
if ((i+1) % boardWidth == 0) {
System.out.println();
}
}
System.out.println("-------------------------");
}
public void tickUp(int steps) {
int counter = -1 * boardHeight;
for (int loop = 0; loop < steps; loop++) {
//Current position = ' '
board[pacmanPosition] = " ";
//Pacman's position changes:
pacmanPosition += counter;
//Allow for wraparounds:
if (pacmanPosition < 0) {
pacmanPosition += board.length;
}
//Update the board with Pacman's new position:
board[pacmanPosition] = "V";
}
printBoard();
}//end tickUp
public void tickRight(int steps) {
int counter = 1;
for (int loop = 0; loop < steps; loop++) {
//Current position = ' '
board[pacmanPosition] = " ";
//Pacman's position changes:
pacmanPosition += counter;
if (pacmanPosition % boardWidth == 0) {
pacmanPosition -= boardWidth;
}
//Update the board with Pacman's new position:
board[pacmanPosition] = "V";
}
printBoard();
}//end tickUp
}
Instead of having pacmanBornWidth and pacmanBornHeight fields, you should have a field with pacman current position (all fields shouldn't be static):
String[][] board;
java.awt.Point pacmenPos;
public PacmanKata(int height, int width) {
board = new String[height][width];
pacmanPos = new Point((int) width/2, (int) height/2);
for (int i = 0; i < boardHeight; i++) {
for (int j = 0; j < boardWidth; j++) {
board[i][j] = "*";
}
}
board[pacmanPos.x][pacmanPos.y] = "V";
}
Now replace all occurrences of pacmanBornWidth and pacmanBornHeight with pacmanPos.x and pacmanPos.y.
And in your tickUp and tickDown methods, just update pacman position:
public void tickUp(int steps) {
...
pacmanPos.translate(0, steps);
...
}
public void tickDown(int steps) {
...
pacmanPos.translate(0, -steps);
...
}
This will also work the same if you add tickLeft and tickRight methods:
public void tickLeft(int steps) {
...
pacmanPos.translate(-steps, 0);
...
}
public void tickRight(int steps) {
...
pacmanPos.translate(steps, 0);
...
}
public class Sudoku {
public static void main(String[] args) {
// Row and column Latin but with invalid subsquares
String config1 = "1234567892345678913456789124567891235678912346" + "78912345789123456891234567912345678";
String[][] puzzle1 = makeSudoku(config1);
if (isValidSudoku(puzzle1)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle1));
System.out.println("--------------------------------------------------");
// Row Latin but column not Latin and with invalid subsquares
String config2 = "12345678912345678912345678912345678912345678" + "9123456789123456789123456789123456789";
String[][] puzzle2 = makeSudoku(config2);
if (isValidSudoku(puzzle2)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle2));
System.out.println("--------------------------------------------------");
// A valid sudoku
String config3 = "25813764914698532779324685147286319558149273663" + "9571482315728964824619573967354218";
String[][] puzzle3 = makeSudoku(config3);
if (isValidSudoku(puzzle3)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle3));
System.out.println("--------------------------------------------------");
}
public static String[][] makeSudoku(String s) {
int SIZE = 9;
int k = 0;
String[][] x = new String[SIZE][SIZE];
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
x[i][j] = s.substring(k, k + 1);
k++;
}
}
return x;
}
public static String getPrintableSudoku(String[][] x) {
int SIZE = 9;
String temp = "";
for (int i = 0; i < SIZE; i++) {
if ((i == 3) || (i == 6)) {
temp = temp + "=================\n";
}
for (int j = 0; j < SIZE; j++) {
if ((j == 3) || (j == 6)) {
temp = temp + " || ";
}
temp = temp + x[i][j];
}
temp = temp + "\n";
}
return temp;
}
//sudoku validation
public static boolean isValidSudoku(String[][] x) {
return rowsAreLatin(x) && colsAreLatin(x) && goodSubsquares(x);
}
public static boolean rowsAreLatin(String[][] x) {
// fill in your code here
boolean result = true; // Assume rows are latin
for (int i = 0; i < 9; i++) {
result = result && rowIsLatin(x, i); // Make sure each row is latin
}
return result;
}
public static boolean rowIsLatin(String[][] x, int i) {
boolean[] found = new boolean[9];
for (int j = 0; j < 9; j++) {
found[Integer.parseInt(x[i][j])] = true;
}
for (int j = 0; j < 9; j++) {
if (!found[j]) {
return false;
}
}
return true;
}
public static boolean colsAreLatin(String[][] x) {
// fill in your code here
boolean result = true; // Assume cols are latin
for (int j = 0; j < 9; j++) {
result = result && colIsLatin(x, j); // Make sure each row is latin
}
return result;
}
public static boolean colIsLatin(String[][] x, int j) {
// fill in your code here
boolean[] found = new boolean[9];
for (int i = 0; i < 9; i++) {
found[Integer.parseInt(x[i][j])] = true;
}
for (int i = 0; i < 9; i++) {
if (!found[i]) {
return false;
}
}
return true;
}
public static boolean goodSubsquares(String[][] x) {
return true;
}
public static boolean goodSubsquare(String[][] x, int i, int j) {
boolean[] found = new boolean[9];
// We have a 3 x 3 arrangement of subsquares
// Multiplying each subscript by 3 converts to the original array subscripts
for (int p = i * 3, rowEnd = p + 3; p < rowEnd; p++) {
for (int q = j * 3, colEnd = q + 3; q < colEnd; q++) {
found[Integer.parseInt(x[p][q])] = true;
}
}
for (int p = 0; p < 9; p++) {
if (!found[p]) {
return false;
}
}
return true;
}
}
This the error I am getting. Help!
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
at Sudoku.rowIsLatin(Sudoku.java:104)
at Sudoku.rowsAreLatin(Sudoku.java:93)
at Sudoku.isValidSudoku(Sudoku.java:85)
at Sudoku.main(Sudoku.java:8)
Java Result: 1
The problem is with the line:
Integer.parseInt(x[i][j])
Sudoku numbers range from [1, 9], but indices for an array (of length 9) range from [0, 8]. So, when the (i, j) element is a 9, the index is 9 and therefore the IndexOutOfBoundsException is being thrown.
You'll have to change it to
found[Integer.parseInt(x[i][j]) - 1] = true;
Note that you also make the same mistake in the column's respective method.