Implementing pacman game issue when moving it up and down - java

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);
...
}

Related

How can I check if every single int in a randomly generated array is even and make it create another random array if it's not?

So I'm trying to create a program that creates a randomly generated array with numbers between 0 and 10.
Every time a number inside the 4x4 array is odd I want it to generate a brand new array and print every array discarded aswell until it creates a 4x4 array with only even numbers.
The problem right now is that I can't understand how to fix the last for and make it work properly with the boolean b that is supposed to restart the creation of the array.
import java.util.Scanner;
public class EvenArrayGenerator {
public static void main(String a[]) {
Boolean b;
do {
b = true;
int[][] Array = new int[4][4];
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++)
Array[i][j] = (int) (Math.random() * 11);
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
System.out.print(Array[i][j] + " ");
}
System.out.println();
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (Array[i][j] % 2 != 0)
b = false;
}
}
} while (b);
}
}
public class ArrayGen {
private int[][] array = new int[4][4];
private int iterations = 1; // you always start with one iteration
public static void main (String[] args) {
ArrayGen ag = new ArrayGen();
ag.reScramble();
while(!ag.isAllEven()) {
ag.reScramble();
ag.iterations++;
}
// this is just a nice visualisation
for (int i = 0; i < 4; i++) {
System.out.print("[");
for (int j = 0; j < 4; j++) {
System.out.print(ag.array[i][j] +((j != 3)? ", " : ""));
}
System.out.print("]\n");
}
System.out.println(ag.iterations + " iterations needed to get all-even array.");
}
private void reScramble () {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
array[i][j] = (int)(Math.random() * 11);
}
}
}
private boolean isAllEven () {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (array[i][j] % 2 == 1) {
return false;
}
}
}
return true;
}
}
I think this is a good solution. Refactoring your code into structured methods is never a bad idea. I hope this helps!
You are looping until you get an array that's all even. You should initialize b to be false, and update it to true in the (nested) for loop. Note that once's you've set it to false, there's no reason checking the other members of the array, and you can break out of the for loop.
Note, also, that using stream could make this check a tad more elegant:
b = Arrays.stream(arr).flatMapToInt(Arrays::stream).anyMatch(x -> x % 2 != 0)
What about generating random numbers up to 5 and double it? Then you don't have two check if they are even.
Instead of your last for loop:
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
if(Array[i][j] % 2!=0){
b=false;
break;
}
}
if(!b){
break;
}
}
if(!b){
break;
}
Alternatively, you could do an oddity check when you are generating the elements. Something like:
int element;
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
do{
element = (int)(Math.random()*11);
}while(element % 2 !=0)
Array[i][j] = element;
}
}
That way you don't have to check the values, they will always be even.
This should work:
import java.util.Scanner;
public class EvenArrayGenerator{
public static void main(String a[]){
boolean anyOdd;
int array = 0;
do{
System.out.println ("Array " + ++array + ":");
anyOdd=false;
int[][] Array = new int[4][4];
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
Array[i][j] = (int)(Math.random()*11);
}
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
System.out.print(Array[i][j] + " ");
}
System.out.println();
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
anyOdd |= Array[i][j] % 2!=0;
}
}
} while(anyOdd);
}
}
As you can see, I just modified the condition from b to anyOdd, so if there is any odd number, it will iterate again.
Also, you can check it when you generate the random numbers, so you avoid a second loop:
import java.util.Scanner;
public class EvenArrayGenerator{
public static void main(String a[]){
boolean anyOdd;
int array = 0;
do{
System.out.println ("Array " + ++array + ":");
anyOdd=false;
int[][] Array = new int[4][4];
for(int i=0;i<4;i++) {
for(int j=0;j<4;j++) {
Array[i][j] = (int)(Math.random()*11);
anyOdd |= array[i][j] % 2 != 0;
}
}
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
System.out.print(Array[i][j] + " ");
}
System.out.println();
}
} while(anyOdd);
}
}
public class EvenArrayGenerator {
public static void main(String a[]) {
int[][] arr = createAllEvenArray(4);
printArray(arr);
}
private static int[][] createAllEvenArray(int size) {
while (true) {
int[][] arr = createArray(size);
printArray(arr);
if (isAllEven(arr))
return arr;
}
}
private static int[][] createArray(int size) {
int[][] arr = new int[size][size];
for (int i = 0; i < arr.length; i++)
for (int j = 0; j < arr.length; j++)
arr[i][j] = (int)(Math.random() * 11);
return arr;
}
private static void printArray(int[][] arr) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (j > 0)
System.out.print("\t");
System.out.format("%2d", arr[i][j]);
}
System.out.println();
}
System.out.println();
}
private static boolean isAllEven(int[][] arr) {
for (int i = 0; i < arr.length; i++)
for (int j = 0; j < arr.length; j++)
if (arr[i][j] % 2 != 0)
return false;
return true;
}
}

different output in conways game of life

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];
}
}
}
}

optimize for loop in java

I am trying to print a square using for loop.
can the below code be improvised to print the square only using for loop instead of swing
public class TestProgram {
public static void main(String[] args) {
TestProgram test = new TestProgram();
test.draw(15, 4);
}
public void draw(int x, int y) {
// System.out.println(".");
System.out.println();
int i = 0;
int j = 0;
for (i = 0; i < x; i++) {
System.out.print(".");
// continue;
}
for (j = x; j > y; j--) {
System.out.println(".");
System.out.print("\t\t");
System.out.println(".");
}
for (int k = 0; k <= x; k++) {
System.out.print(".");
}
}
}
How about:
public class TestProgram {
public static void main(String[] args) {
TestProgram test = new TestProgram();
test.draw(15, 4);
}
public void draw(int x, int y) {
System.out.println(generateLine(x, '.'));
for (int i = 1; i< y-1; i++) {
System.out.println("." + generateLine(x-2, ' ') + ".");
}
System.out.println(generateLine(x, '.'));
}
private String generateLine(int x, char character) {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < x; i++) {
stringBuilder.append(character);
}
return stringBuilder.toString();
}
}
I am not sure i understood currectly but you're trying to print squares without swing? But you're using system.out.print. Its a bit confusing but if its for learning programming homework from school here you go to make a square with for loops:
for (int i = 0; i < width; i++) {
System.out.print("*");
}
System.out.println();
for (int i = 0; i < height - 2; i++) {
System.out.print("*");
for (int j = 0; j < width - 2; j++) {
System.out.print(" ");
}
System.out.println("*");
}
for (int i = 0; i < width; i++) {
System.out.print("*");
}
System.out.println();
}
But if you want to make rectangles (Because you mentioned swing) you should check java.awt.Rectangle2D and Rectangle:
https://docs.oracle.com/javase/7/docs/api/java/awt/Rectangle.html
You can do it in this way:
void rectangleDraw(int x, int y) {
String line1 = new String(new byte[x]).replaceAll("", ".");
String line2 = "." + new String(new byte[x - 2]).replaceAll("", " ") + ".";
System.out.println(line1);
for (int i = x; i > y; i--) {
System.out.println(line2);
}
System.out.println(line1);
}

Sorting multidimensional array without sort method?

I was tasked with creating a 2D array (10-by-10), filling it with random numbers (from 10 to 99), and other tasks. I am, however, having difficulty sorting each row of this array in ascending order without using the array sort() method.
My sorting method does not sort. Instead, it prints out values diagonally, from the top leftmost corner to the bottom right corner. What should I do to sort the numbers?
Here is my code:
public class Program3
{
public static void main(String args[])
{
int[][] arrayOne = new int[10][10];
int[][] arrayTwo = new int[10][10];
arrayTwo = fillArray(arrayOne);
System.out.println("");
looper(arrayTwo);
System.out.println("");
sorter(arrayTwo);
}
public static int randomRange(int min, int max)
{
// Where (int)(Math.random() * ((upperbound - lowerbound) + 1) + lowerbound);
return (int)(Math.random()* ((max - min) + 1) + min);
}
public static int[][] fillArray(int x[][])
{
for (int row = 0; row < x.length; row++)
{
for (int column = 0; column < x[row].length; column++)
{
x[row][column] = randomRange(10,99);
System.out.print(x[row][column] + "\t");
}
System.out.println();
}
return x;
}
public static void looper(int y[][])
{
for (int row = 0; row < y.length; row++)
{
for (int column = 0; column < y[row].length; column++)
{
if (y[row][column]%2 == 0)
{
y[row][column] = 2 * y[row][column];
if (y[row][column]%10 == 0)
{
y[row][column] = y[row][column]/10;
}
}
else if (y[row][column] == 59)
{
y[row][column] = 99;
}
System.out.print(y[row][column] + "\t");
}
System.out.println();
}
//return y;
}
public static void sorter(int[][] z)
{
int temp = 0;
int tempTwo = 0;
int lowest;
int bravo = 0;
int bravoBefore = -1;
for (int alpha = 0; alpha < z.length; alpha++)
{
//System.out.println(alpha + "a");
lowest = z[alpha][bravoBefore + 1];
bravoBefore++;
for (bravo = alpha + 1; bravo < z[alpha].length; bravo++)
{
//System.out.println(alpha + "b");
temp = bravo;
if((z[alpha][bravo]) < lowest)
{
temp = bravo;
lowest = z[alpha][bravo];
//System.out.println(lowest + " " + temp);
//System.out.println(alpha + "c" + temp);
tempTwo = z[alpha][bravo];
z[alpha][bravo] = z[alpha][temp];
z[alpha][temp] = tempTwo;
//System.out.println(alpha + "d" + temp);
}
}
System.out.print(z[alpha][bravoBefore] + "\t");
}
/*
for (int alpha = 0; alpha < z.length; alpha++)
{
for (int bravo = 0; bravo < z.length - 1; bravo++)
{
if(Integer.valueOf(z[alpha][bravo]) < Integer.valueOf(z[alpha - 1][bravo]))
{
int[][] temp = z[alpha - 1][bravo];
z[alpha-1][bravo] = z[alpha][bravo];
z[alpha][bravo] = temp;
}
}
}
*/
}
}
for(int k = 0; k < arr.length; k++)
{
for(int p = 0; p < arr[k].length; p++)
{
least = arr[k][p];
for(int i = k; i < arr.length; i++)
{
if(i == k)
z = p + 1;
else
z = 0;
for(;z < arr[i].length; z++)
{
if(arr[i][z] <= small)
{
least = array[i][z];
row = i;
col = z;
}
}
}
arr[row][col] = arr[k][p];
arr[k][p] = least;
System.out.print(arr[k][p] + " ");
}
System.out.println();
}
Hope this code helps . Happy coding
let x is our unsorted array;
int t1=0;
int i1=0;
int j1=0;
int n=0;
boolean f1=false;
for(int i=0;i<x.length;i++){
for(int j=0;j<x[i].length;j++){
t1=x[i][j];
for(int m=i;m<x.length;m++){
if(m==i)n=j+1;
else n=0;
for(;n<x[m].length;n++){
if(x[m][n]<=t1){
t1=x[m][n];
i1=m;
j1=n;
f1=true;
}
}
}
if(f1){
x[i1][j1]=x[i][j];
x[i][j]=t1;
f1=false;
}
}
}
//now x is sorted; "-";

nullpointerexception with multithreading

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

Categories