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?
Related
I have to create a Java program for Conway's Game Of Life in procedural manner and I'm only one step away from finishing - all I have left to do is figure out how to make the output change itself(something like a GIF). Instead, my program outputs all the results one by one. I'm figuring it should be some kind of a loop, but I'm not sure. Here's the code:
import java.util.Random;
import java.util.Scanner;
class gameOfLife {
public static void main(String[] args) {
//User input
Scanner in = new Scanner(System.in);
System.out.println("How many rows?");
int rows = in.nextInt();
System.out.println("How many columns?");
int cols = in.nextInt();
//Declaring variables and grids
int[][] grid = new int[rows][cols];
int[][] nextGrid = new int[rows][cols];
int[][] temp = new int [rows][cols];
//Initializing first generation
initiateGrid(grid);
printGameBoard(grid);
//Looping through 10 generations
for (int x = 0; x < 20; x++) {
applyTheRules(grid, rows, cols, nextGrid);
temp = nextGrid;
nextGrid = grid;
grid = temp;
printGameBoard(grid);
}
}
//Initiating first generation grid randomly
static void initiateGrid(int[][] grid) {
Random r = new Random();
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
grid[i][j] = r.nextInt(2);
}
}
}
//Printing out the game board
static void printGameBoard(int[][] grid) {
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[i].length; j++) {
if (grid[i][j] == 0)
System.out.print(" . ");
else
System.out.print(" ■ ");
}
System.out.println();
}
System.out.println();
}
//Applying the rules of the game
static void applyTheRules(int [][] grid, int rows, int cols, int [][] nextGrid) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int count = 0;
if(i-1>=0 && i+1<grid.length && j-1>=0 && j+1<grid[i].length) {
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
count += grid[i + x][j + y];
}
}
count -= grid[i][j];
} else{
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) {
count += 0;
}
}
}
//Alive cell becomes dead, if there are more than
//3 or less than 2 neighbouring cells
if((grid[i][j]==1)&&(count<2)||(count>3))
nextGrid[i][j]=0;
//Dead cell becomes alive if there are exactly 3 neighbouring cells
else if((grid[i][j]==0)&&(count==3))
nextGrid[i][j]=1;
//State stays the same
else
nextGrid[i][j]=grid[i][j];
}
}
}
}
i am trying to make a game like a candy crush or bejeweled, but i had a problem with find a same items in row.
i have this
public void mapfinder() {
int typ = -1;
int pocet = 0;
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
if (plocha[x][y].getgem() == typ) {
pocet++;
} else if (pocet > 2) {
while (pocet > 0) {
pocet--;
plocha[x][y - pocet] = new Actor(x, y, nogem);
}
} else {
typ = plocha[x][y].getgem();
}
}
}
}
acctualy, its slow and i often get outOfArrayExeption
any ideas?
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);
...
}
So this program needs to do a few things with the image. I started writing method called replicate and what it needs to do is to take in num1 and num2, and then duplicate the image left-right num1 times, and then replicate the picture num2 times top to bottom. So like the same a small image would act as desktop wallpaper, it's repeat itself. I am not allowed to use image buffer. thank you
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
public class ImageTool {
// THIS METHOD MAY BE CALLED, BUT MUST NOT BE MODIFIED!
//
public static int[][] readGrayscaleImage(String filename) {
int [][] result = null;
try {
File imageFile = new File(filename);
BufferedImage image = ImageIO.read(imageFile);
int height = image.getHeight();
int width = image.getWidth();
result = new int[height][width];
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int rgb = image.getRGB(x, y);
result[y][x] = rgb & 0xff;
}
}
}
catch (IOException ioe) {
System.err.println("Problems reading file named " + filename);
System.exit(1);
}
return result;
}
// THIS METHOD MAY BE CALLED, BUT MUST NOT BE MODIFIED!
//
public static void writeGrayscaleImage(String filename, int[][] array) {
int width = array[0].length;
int height = array.length;
try {
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
int rgb = array[y][x];
rgb |= rgb << 8;
rgb |= rgb << 16;
image.setRGB(x, y, rgb);
}
}
File imageFile = new File(filename);
ImageIO.write(image, "jpg", imageFile);
}
catch (IOException ioe) {
System.err.println("Problems writing file named " + filename);
System.exit(1);
}
}
public static void main (String [] args) {
if (args.length < 1) {
System.out.println("Invalid program execution");
System.out.println("Please provide command");
System.exit(-1);
}
if (args[0].equals("--dump")){
String fileName = args[1];
int [][] image = readGrayscaleImage(fileName);
print2dArray(image);
} else if (args[0].equals("--reflectV")){
String fileName = args[1];
int [][] image = readGrayscaleImage(fileName);
int [][] reflected = reflectV(image);
String outputFilename = args[2];
writeGrayscaleImage(outputFilename, reflected);
} else if (args[0].equals("--reflectH")){
String fileName = args[1];
int [][] image = readGrayscaleImage(fileName);
int [][] reflected = reflectH(image);
String outputFilename = args[2];
writeGrayscaleImage(outputFilename, reflected);
} else if (args[0].equals("--ascii")){
String fileName=args[1];
int [][] image = readGrayscaleImage(fileName);
ascii(image);
} else if (args[0].equals("--replicate")) {
String fileName = args[2];
int [][] image = readGrayscaleImage(fileName);
double factor = args[0];
String outputFilename = args[3];
writeGrayscaleImage(outputFilename, reflected);
}
}
public static void replicate(double num1, double num2, int[][]arr) {
double length = num1 * arr.length;
double height = num2 * arr[0].length;
int[][]newArr = new int[length][height];
for(int i = 0; i <= newArr.length; i++){
for(int j = 0; j <= arr.length; j++){
newArr[i][j]=arr[i][j];
}
}
}
public static void ascii (int[][]arr) {
int rows = arr.length;
int cols = arr[0].length;
for(int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++){
if(arr[i][j] >= 0 && arr[i][j] <= 25){
System.out.print("M");
} else if(arr[i][j]>=26 && arr[i][j] <=50){
System.out.print("$");
} else if(arr[i][j]>=51 && arr[i][j] <= 76){
System.out.print("0");
} else if(arr[i][j]>=77 && arr[i][j] <=102){
System.out.print("|");
} else if(arr[i][j]>=103 && arr[i][j]<=127){
System.out.print("*");
} else if (arr[i][j]>=128 && arr[i][j]<=152){
System.out.print(":");
} else if (arr[i][j]>=153 && arr[i][j]<=178){
System.out.print("=");
} else if (arr[i][j]>=179 && arr[i][j]<=204){
System.out.print("\'");
} else if (arr[i][j]>=205 && arr[i][j]<=230){
System.out.print(".");
} else if (arr[i][j]>=231 && arr[i][j]<=255){
System.out.print(" ");
}
}
System.out.println();
}
}
public static void print2dArray(int[][] arr) {
for (int i = 0; i <arr.length; i++){
//System.out.println(Arrays.toString(arr[i]));
for (int j = 0; j< arr[i].length; j++){
System.out.format("%3d, " , arr[i][j]);
}
System.out.println();
}
}
public static int [][] reflectV (int [][] arr) {
int rows = arr.length;
int cols = arr[0].length;
int [][] reflected = new int[rows][cols];
for (int i = 0; i < rows; i++){
for(int j = 0; j < cols; j++) {
reflected [i][j] = arr[i][cols-j-1];
}
}
//go through arr and reverse values in each row
return reflected;
}
public static int [][] reflectH (int [][] arr) {
int rows = arr.length;
int cols = arr[0].length;
int [][] reflected = new int[rows][cols];
for (int i = 0; i < cols; i++){
for(int j = 0; j < rows; j++) {
reflected [j][i] = arr[cols-j-1][i];
}
}
//go through arr and reverse values in each row
return reflected;
}
}
This should be the solution:
public static int[][] replicate(double num1, double num2, int[][]arr) {
double length = num1 * arr.length;
double height = num2 * arr[0].length;
int[][]newArr = new int[(int) length][(int) height];
for(int i = 0; i < newArr.length; i++){
for(int j = 0; j < newArr[i].length; j++){
newArr[i][j]=arr[i % arr.length][j % arr[0].length];
}
}
return newArr;
}
Test input:
1 2 3
4 5 6
7 8 9
The method calculates the output array as follows (num1=1.8d and num2=1.8d):
1 2 3 1 2
4 5 6 4 5
7 8 9 7 8
1 2 3 1 2
4 5 6 4 5
Please note that I have changed the signature of the method. It now returns the resulting array.
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