Parchis game: number of pawns won't stop by 4 - java

For a school project we need to make the game 'Parchis', but we are a bit struggling. Normally there is a maximum of 4 pawns in the game for each color. in our case, this number does not want to stop at 4, but sometimes a player can have 6 or 7 pawns. We found out why: if two pawns of the same color land on the same square, the code counts this as 1 pawn while 2 pawns are allowed to land on the same square (according to the assignment). How can I make sure that 2 pawns are allowed on the same square (also with different color) so that the number of pawns per color on the board is 4 at most?
In this photo, you can see our class 'Pawn' where we create a new pawn.
public class Pion {
private Kleur kleur;
public Pion(Kleur kleur) {
this.kleur = kleur;
}
public Kleur getKleur() {
return this.kleur;
}
#Override
public String toString() {
return "Pion{" +
"kleur=" + kleur +
'}';
}
}
The next class is Parchis, where we have put the course of the game. It is a big method but this way I hope it is clear enough.
int beurt = 0;
int vakjesInDoel = 0;
public void speel() {
label33:
while (!this.einde()) {
beurt++;
vakjesInDoel = 0;
java.util.Iterator var2 = this.spelers.iterator();
while (true) {
while (true) {
Speler speler;
if (!var2.hasNext()) {
continue label33;
}
speler = (Speler) var2.next();
if (speler.type == Type.NORMAAL) {
this.basics.drukEenKnop();
}
this.currentSpeler = speler;
this.basics.spelerBeurt(this.currentSpeler);
ArrayList<Vakje> lijstSpelerPion = currentSpeler.getVakjesMetPion();
for (int i = 0; i < lijstSpelerPion.size(); i++) {
if (currentSpeler.getVakjesMetPion().get(i).getTypeVakje() == TypeVakje.DOEL) {
vakjesInDoel++;
//TODO kijken of de juiste methode is aangeroepen
if(currentSpeler.iterator.hasNext()){
int kies = this.currentSpeler.kies(currentSpeler.kleur, currentSpeler.getPionOpBord());
this.bord.movePion((Pion) ((Vakje) lijstSpelerPion.get(kies - 1)).getPionList().get(0), (Vakje) lijstSpelerPion.get(kies - 1), 10);
}
}
}
System.out.println("BeurtNR #" + this.beurt + " Pionnen in spel " + currentSpeler.getPionOpBord() + " pionnen in doel: " + this.bord.getLandingsbaan().get(7).getPionList().size());
new Scanner(System.in);
this.resultaatDobbel = this.dobbelsteen.gooiDobbelsteen();
for (int aantal_zes = 0; aantal_zes < 2; aantal_zes++) {
if (this.resultaatDobbel == 6) {
ArrayList<Vakje> lijstVakjesMetPion = this.iterator.verplaats(this.currentSpeler.getKleur());
if (currentSpeler.getPionOpBord() < 4) {
if (lijstVakjesMetPion.size() > 0) {
this.currentSpeler.locatieSpelerPion();
int kies = this.currentSpeler.kies(currentSpeler.kleur, currentSpeler.getPionOpBord());
this.bord.movePion((Pion) ((Vakje) lijstVakjesMetPion.get(kies - 1)).getPionList().get(0), (Vakje) lijstVakjesMetPion.get(kies - 1), this.resultaatDobbel);
if (speler.type.equals(Type.NORMAAL)) {
this.basics.drukEenKnop();
this.resultaatDobbel = this.dobbelsteen.gooiDobbelsteen();
// this.checkResult();
} else {
this.resultaatDobbel = this.dobbelsteen.gooiDobbelsteen();
//this.checkResult();
}
} else {
if (speler.type.equals(Type.NORMAAL)) {
this.basics.drukEenKnop();
this.resultaatDobbel = this.dobbelsteen.gooiDobbelsteen();
// this.checkResult();
} else {
this.resultaatDobbel = this.dobbelsteen.gooiDobbelsteen();
// this.checkResult();
}
}
} else {
this.currentSpeler.locatieSpelerPion();
int kies = this.currentSpeler.kies(currentSpeler.kleur, currentSpeler.getPionOpBord());
this.bord.movePion((Pion) ((Vakje) lijstVakjesMetPion.get(kies - 1)).getPionList().get(0), (Vakje) lijstVakjesMetPion.get(kies - 1), this.resultaatDobbel + 1);
}
}
}
if (this.resultaatDobbel == 5 && (currentSpeler.getPionOpBord() < 4)) {
/* if (currentSpeler.getPionOpBord() >= 4) {
System.out.println("DIT IS NIET OK ALS JE DIT PRINT");
}*/
this.bord.addPion(this.currentSpeler.getKleur());
System.out.println("Nieuwe Pion toegevoegd op bord");
} else {
ArrayList<Vakje> lijstVakjesMetPion = this.iterator.verplaats(this.currentSpeler.getKleur());
if (lijstVakjesMetPion.size() > 0) {
this.currentSpeler.locatieSpelerPion();
int kies = this.currentSpeler.kies(currentSpeler.kleur, currentSpeler.getPionOpBord());
this.bord.movePion((Pion) ((Vakje) lijstVakjesMetPion.get(kies - 1)).getPionList().get(0), (Vakje) lijstVakjesMetPion.get(kies - 1), this.resultaatDobbel);
}
}
If there is any question or doubts, please hit me up.
We tried for a if structure and a maximum of 4 pawns but it didn't work. We also tried a maximum of numbers in the class 'Pawn' but nothing.

Related

Minecraft Bukkit coding Type mismatch: cannot convert from element type Object to String

Here is the full code for it:
public void trackAll() {
int north = count(Direction.North) * 25;
int east = count(Direction.East) * 25;
int south = count(Direction.South) * 25;
int west = count(Direction.West) * 25;
if ((north == 0) && (east == 0) && (south == 0) && (west == 0)) {
this.player.sendMessage(ChatColor.RED + "Not a valid tracking compass.");
return;
}
for (Direction direction : Direction.values()) {
int length = count(direction) * 25;
if (length != 0) {
#SuppressWarnings("rawtypes")
Set players = new TreeSet();
for (Player player : Bukkit.getOnlinePlayers()) {
if (this.player.canSee(player)) if ((on(player, direction) & !player.equals(this.player))) {
players.add(player.getDisplayName());
}
}
FancyMessage message = new FancyMessage(direction + " (" + length + "): ").color(ChatColor.DARK_AQUA);
int i = 0;
for (String str : players) {
if (i == players.size() - 1)
message.then(str).color(ChatColor.GRAY).tooltip(ChatColor.GREEN + "Click here to track " + ChatColor.RESET + str + ChatColor.GREEN + ".").command("/track " + ChatColor.stripColor(str));
else {
message.then(str).color(ChatColor.GRAY).tooltip(ChatColor.GREEN + "Click here to track " + ChatColor.RESET + str + ChatColor.GREEN + ".").command("/track " + ChatColor.stripColor(str)).then(", ");
}
i++;
}
message.send(this.player);
}
}
}
And I also have another issue "Type mismatch: cannot convert from element type Object to Block"
public int count(Direction direction, boolean b) {
int length = 0;
#SuppressWarnings("rawtypes")
Set toDelete = new HashSet();
for (int i = 1; i < 10000; i++) {
Block next = this.middle.getRelative(BlockFace.valueOf(direction.toString().toUpperCase()), i);
if (next.getType() == Material.COBBLESTONE) {
length++;
toDelete.add(next); } else {
if (next.getType() == Material.STONE) {
length++;
toDelete.add(next);
toDelete.add(this.middle);
break;
}
length = 0;
toDelete.clear();
break;
}
}
if (b) {
for (Block block : toDelete) {
block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getTypeId());
block.setType(Material.AIR);
}
}
return length;
}
I currently don't have someone that can look over the code I personally do not see the issue but I've been working on it for hours so yeah ;/ Thanks. This code is to do with a Minecraft plugin it's tracking a players location and sending the information to the player that executed the command.
Use
Set<String> players = new TreeSet<>();
and
Set<Block> toDelete = new HashSet<>();

Why do object arrays in my ArrayList fail to retain their values?

I am creating a program in Java to simulate evolution. The way I have it set up, each generation is composed of an array of Organism objects. Each of these arrays is an element in the ArrayList orgGenerations. Each generation, of which there could be any amount before all animals die, can have any amount of Organism objects.
For some reason, in my main loop when the generations are going by, I can have this code without errors, where allOrgs is the Organism array of the current generation and generationNumber is the number generations since the first.
orgGenerations.add(allOrgs);
printOrgs(orgGenerations.get(generationNumber));
printOrgs is a method to display an Organism array, where speed and strength are Organism Field variables:
public void printOrgs(Organism[] list)
{
for (int x=0; x<list.length; x++)
{
System.out.println ("For organism number: " + x + ", speed is: " + list[x].speed + ", and strength is " + list[x].strength + ".");
}
}
Later on, after this loop, when I am trying to retrieve the data to display, I call this very similar code:
printOrgs(orgGenerations.get(0));
This, and every other array in orgGenerations, return a null pointer exception on the print line of the for loop. Why are the Organism objects loosing their values?
Alright, here is all of the code from my main Simulation class. I admit, it might be sort of a mess. The parts that matter are the start and simulator methods. The battle ones are not really applicable to this problem. I think.
import java.awt.FlowLayout;
import java.util.*;
import javax.swing.JFrame;
public class Simulator {
//variables for general keeping track
static Organism[] allOrgs;
static ArrayList<Organism[]> orgGenerations = new ArrayList <Organism[]>();
ArrayList<Integer> battleList = new ArrayList<Integer>();
int deathCount;
boolean done;
boolean runOnce;
//setup
Simulator()
{
done = false;
Scanner asker = new Scanner(System.in);
System.out.println("Input number of organisms for the simulation: ");
int numOfOrgs = asker.nextInt();
asker.close();
Organism[] orgArray = new Organism[numOfOrgs];
for (int i=0; i<numOfOrgs; i++)
{
orgArray[i] = new Organism();
}
allOrgs = orgArray;
}
//graphsOrgs
public void graphOrgs() throws InterruptedException
{
JFrame f = new JFrame("Evolution");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(1000,500);
f.setVisible(true);
Drawer bars = new Drawer();
//System.out.println(orgGenerations.size());
for (int iterator=0;iterator<(orgGenerations.size()-1); iterator++)
{
printOrgs(orgGenerations.get(0));
//The 0 can be any number, no matter what I do it wont work
//System.out.println("first");
f.repaint();
bars.data = orgGenerations.get(iterator);
f.add(bars);
//System.out.println("before");
Thread.sleep(1000);
//System.out.println("end");
}
}
//prints all Orgs and their statistics
public void printOrgs(Organism[] list)
{
System.out.println("Number Of Organisms: " + list.length);
for (int x=0; x<list.length; x++)
{
System.out.println ("For organism number: " + x + ", speed is: " + list[x].speed + ", and strength is " + list[x].strength + ".");
}
System.out.println();
}
//general loop for the organisms lives
public void start(int reproductionTime) throws InterruptedException
{
int generationNumber = 0;
orgGenerations.add(allOrgs);
printOrgs(orgGenerations.get(0));
generationNumber++;
while(true)
{
deathCount = 0;
for(int j=0; j<reproductionTime; j++)
{
battleList.clear();
for(int m=0; m<allOrgs.length; m++)
{
if (allOrgs[m].alive == true)
oneYearBattleCheck(m);
}
battle();
}
reproduction();
if (done == true)
break;
orgGenerations.add(allOrgs);
printOrgs(orgGenerations.get(generationNumber));
generationNumber++;
}
printOrgs(orgGenerations.get(2));
}
//Checks if they have to fight this year
private void oneYearBattleCheck(int m)
{
Random chaos = new Random();
int speedMod = chaos.nextInt(((int)Math.ceil(allOrgs[m].speed/5.0))+1);
int speedSign = chaos.nextInt(2);
if (speedSign == 0)
speedSign--;
speedMod *= speedSign;
int speed = speedMod + allOrgs[m].speed;
if (speed <= 0)
speed=1;
Random encounter = new Random();
boolean battle = false;
int try1 =(encounter.nextInt(speed));
int try2 =(encounter.nextInt(speed));
int try3 =(encounter.nextInt(speed));
int try4 =(encounter.nextInt(speed));
if (try1 == 0 || try2 == 0 || try3 == 0 || try4 == 0 )
{
battle = true;
}
if(battle == true)
{
battleList.add(m);
}
}
//Creates the matches and runs the battle
private void battle()
{
Random rand = new Random();
if (battleList.size()%2 == 1)
{
int luckyDuck = rand.nextInt(battleList.size());
battleList.remove(luckyDuck);
}
for(int k=0; k<(battleList.size()-1);)
{
int competitor1 = rand.nextInt(battleList.size());
battleList.remove(competitor1);
int competitor2 = rand.nextInt(battleList.size());
battleList.remove(competitor2);
//Competitor 1 strength
int strengthMod = rand.nextInt(((int)Math.ceil(allOrgs[competitor1].strength/5.0))+1);
int strengthSign = rand.nextInt(2);
if (strengthSign == 0)
strengthSign--;
strengthMod *= strengthSign;
int comp1Strength = strengthMod + allOrgs[competitor1].strength;
//Competitor 2 strength
strengthMod = rand.nextInt(((int)Math.ceil(allOrgs[competitor2].strength/5.0))+1);
strengthSign = rand.nextInt(2);
if (strengthSign == 0)
strengthSign--;
strengthMod *= strengthSign;
int comp2Strength = strengthMod + allOrgs[competitor2].strength;
//Fight!
if (comp1Strength>comp2Strength)
{
allOrgs[competitor1].life ++;
allOrgs[competitor2].life --;
}
else if (comp2Strength>comp1Strength)
{
allOrgs[competitor2].life ++;
allOrgs[competitor1].life --;
}
if (allOrgs[competitor1].life == 0)
{
allOrgs[competitor1].alive = false;
deathCount++;
}
if (allOrgs[competitor2].life == 0)
{
allOrgs[competitor2].alive = false;
deathCount ++ ;
}
}
}
//New organisms
private void reproduction()
{
//System.out.println("Number of deaths: " + deathCount + "\n");
if (deathCount>=(allOrgs.length-2))
{
done = true;
return;
}
ArrayList<Organism> tempOrgs = new ArrayList<Organism>();
Random chooser = new Random();
int count = 0;
while(true)
{
int partner1 = 0;
int partner2 = 0;
boolean partnerIsAlive = false;
boolean unluckyDuck = false;
//choose partner1
while (partnerIsAlive == false)
{
partner1 = chooser.nextInt(allOrgs.length);
if (allOrgs[partner1] != null)
{
if (allOrgs[partner1].alive == true)
{
partnerIsAlive = true;
}
}
}
count++;
//System.out.println("Count 2: " + count);
partnerIsAlive = false;
//choose partner2
while (partnerIsAlive == false)
{
if (count+deathCount == (allOrgs.length))
{
unluckyDuck=true;
break;
}
partner2 = chooser.nextInt(allOrgs.length);
if (allOrgs[partner2] != null)
{
if (allOrgs[partner2].alive == true)
{
partnerIsAlive = true;
}
}
}
if (unluckyDuck == false)
count++;
//System.out.println("count 2: " + count);
if (unluckyDuck == false)
{
int numOfChildren = (chooser.nextInt(4)+1);
for (int d=0; d<numOfChildren; d++)
{
tempOrgs.add(new Organism(allOrgs[partner1].speed, allOrgs[partner2].speed, allOrgs[partner1].strength, allOrgs[partner2].strength ));
}
allOrgs[partner1] = null;
allOrgs[partner2] = null;
}
if (count+deathCount == (allOrgs.length))
{
Arrays.fill(allOrgs, null);
allOrgs = tempOrgs.toArray(new Organism[tempOrgs.size()-1]);
break;
}
//System.out.println(count);
}
}
}
Main method:
public class Runner {
public static void main(String[] args) throws InterruptedException {
Simulator sim = new Simulator();
int lifeSpan = 20;
sim.start(lifeSpan);
sim.graphOrgs();
}
}
Organism class:
import java.util.Random;
public class Organism {
static Random traitGenerator = new Random();
int life;
int speed;
int strength;
boolean alive;
Organism()
{
speed = (traitGenerator.nextInt(49)+1);
strength = (50-speed);
life = 5;
alive = true;
}
Organism(int strength1, int strength2, int speed1, int speed2)
{
Random gen = new Random();
int speedMod = gen.nextInt(((int)Math.ceil((speed1+speed2)/10.0))+1);
int speedSign = gen.nextInt(2);
if (speedSign == 0)
speedSign--;
speedMod *= speedSign;
//System.out.println(speedMod);
int strengthMod = gen.nextInt(((int)Math.ceil((strength1+strength2)/10.0))+1);
int strengthSign = gen.nextInt(2);
if (strengthSign == 0)
strengthSign--;
strengthMod *= strengthSign;
//System.out.println(strengthMod);
strength = (((int)((strength1+strength2)/2.0))+ strengthMod);
speed = (((int)((speed1+speed2)/2.0))+ speedMod);
alive = true;
life = 5;
}
}
The problem lies in the graphOrgs class when I try to print to check if it is working in preparation for graphing the results. This is when it returns the error. When I try placing the print code in other places in the Simulator class the same thing occurs, a null pointer error. This happens even if it is just after the for loop where the element has been established.
You have code that sets to null elements in your allOrgs array.
allOrgs[partner1] = null;
allOrgs[partner2] = null;
Your orgGenerations list contains the same allOrgs instance multiple times.
Therefore, when you write allOrgs[partner1] = null, the partner1'th element becomes null in all the list elements of orgGenerations, which is why the print method fails.
You should create a copy of the array (you can use Arrays.copy) each time you add a new generation to the list (and consider also creating copies of the Organism instances, if you want each generation to record the past state of the Organisms and not their final state).

Why am i getting the error java.lang.NullPointerException in my battleship game? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 8 years ago.
I'm trying to code a battleship game and im getting a weird error when i run it: Exception in thread "main" java.lang.NullPointerException
at Caculations.findShip(Caculations.java:29)
at Board.main(Board.java:60)
Please help im stuck and i dont know how to continue! Here is my code: (Note, its in 2 class files in my eclipse work enviorment)
public class Board {
public static void main(String[] args) {
boolean continuePlay = true;
int[][] board = new int[10][10]; // creating 2d array 'board'
char[][] boardGraphical = new char[10][10]; // creating 2d array 'board
// this time the visual
for (int x = 0; x < 10; x++) { // for within for //initializing elements
// in both boards using double for
// method
for (int y = 0; y < 10; y++) {
board[x][y] = 0;
boardGraphical[x][y] = 'o';
System.out.println("Board element " + x + " " + y // printing
// initialized
// elements
// here
+ " initialized");
}
}
/*
* 1) Make user ships 1 and computer ships 2 (all numbers other than 0 =
* true)
*
* 2) Make it where if the computer gets a hit on a '1' than it sets
* that value to like a 3 or something so it knows when the ship is
* sunk. So in a if it does if([x][y] && [x][y])
* System.out.println("You sunk my ship!");
*
* 3) REMEMBER YOU CAN DO MULTIPLE IFS INSIDE IFS FOR MULTIPLE
* CONDITIONS. 4) declare ships here!
*
* 5) PUT STUFF IN A WHILE LOOP SO COMP CAN KEEP GOING
*/
board[3][3] = 1; // declaring a battleship. Very important.
board[3][4] = 1;
board[3][5] = 1;
boardGraphical[3][3] = 's';
boardGraphical[3][4] = 's';
boardGraphical[3][5] = 's';
while (continuePlay == true) { // while loop so that computer keeps
// guessing
// WITHIN THIS LOOP KEEP REPRINTING THE BOARD
double computerChoiceXd = Math.floor(Math.random() * 10); // using
// Math.random
// functions
// for
// computers
// first
// guess
// to be
// a
// random
// num
double computerChoiceYd = Math.floor(Math.random() * 10);
int computerChoiceX = (int) computerChoiceXd;
int computerChoiceY = (int) computerChoiceYd;
if (board[computerChoiceX][computerChoiceY] == 1) { // checking if
// math.random
// landed on a
// ship point
System.out.println("Computer got a hit at " + computerChoiceX
+ " " + computerChoiceY);
board[computerChoiceX][computerChoiceY] = 2; // setting the
// point as 2 or
// 'hit'
boardGraphical[computerChoiceX][computerChoiceY] = 'H';
for (int row = 0; row < 10; row++) { // printing out graphical
// board using the same
// method as when
// intializing
for (int col = 0; col < 10; col++) {
System.out.print(boardGraphical[row][col]);
}
System.out.println(" "); // spacer for printing
}
Caculations test = new Caculations(computerChoiceX, // Creating
// a new
// object of
// calculation
computerChoiceY, board);
test.findShip();
// break;
if (board[3][3] == 2) { // checking to see if ship is sunk using
// a triple if statement
if (board[3][4] == 2) {
if (board[3][5] == 2) {
System.out.println("Battleship sunk!");
continuePlay = false; // if so than it breaks out of
// loop to end the game
break;
}
}
}
} else if (board[computerChoiceX][computerChoiceY] == 0) { // otherwise
// if
// the
// area
// is a
// 0 or
// 'unmarked'
System.out.println("Computer missed at " + computerChoiceX
+ " " + computerChoiceY);
boardGraphical[computerChoiceX][computerChoiceY] = 'x'; // mark
// area
// as a
// miss
for (int row = 0; row < 10; row++) { // print out board
for (int col = 0; col < 10; col++) {
System.out.print(boardGraphical[row][col]);
}
System.out.println(" ");
}
}
}
}
}
public class Caculations {
int xValue;
int yValue;
int[][] myArray;
int[][] storage = new int[10][10];
boolean xAxisChangeP;
boolean yAxisChangeP;
boolean xAxisChangeN;
boolean yAxisChangeN;
boolean notSunk;
Caculations(int x, int y, int[][] myArray) {
xValue = x;
yValue = y;
xAxisChangeP = true;
yAxisChangeP = true;
xAxisChangeN = true;
yAxisChangeN = true;
notSunk = true;
}
void findShip() {
while (notSunk == true) {
// 1
while (xAxisChangeP == true) {
if (myArray[xValue + 1][yValue] == 1) {
myArray[xValue + 1][yValue] = 2;
if (myArray[3][3] == 2) {
if (myArray[3][4] == 2) {
if (myArray[3][5] == 2) {
System.out.println("Battleship sunk!");
notSunk = false;
}
}
}
continue;
}
else {
xAxisChangeP = false;
}
}
while (xAxisChangeN == true) {
if (myArray[xValue - 1][yValue] == 1) {
myArray[xValue - 1][yValue] = 2;
if (myArray[3][3] == 2) {
if (myArray[3][4] == 2) {
if (myArray[3][5] == 2) {
System.out.println("Battleship sunk!");
notSunk = false;
}
}
}
continue;
}
else {
xAxisChangeN = false;
}
}
// 1
while (yAxisChangeP == true) {
if (myArray[xValue][yValue + 1] == 1) {
myArray[xValue][yValue + 1] = 2;
if (myArray[3][3] == 2) {
if (myArray[3][4] == 2) {
if (myArray[3][5] == 2) {
System.out.println("Battleship sunk!");
notSunk = false;
}
}
}
continue;
}
else {
yAxisChangeP = false;
}
}
while (yAxisChangeN == true) {
if (myArray[xValue][yValue - 1] == 1) {
myArray[xValue][yValue - 1] = 2;
if (myArray[3][3] == 2) {
if (myArray[3][4] == 2) {
if (myArray[3][5] == 2) {
System.out.println("Battleship sunk!");
notSunk = false;
}
}
}
continue;
}
else {
yAxisChangeN = false;
}
}
}
}
}
Have you initialized myarray? Best is debug your code to see, which statement throws the exception. In eclipse you can add NullPointerExeption as your breakpoint and debug.
You use myArray, but you never initialize it.
public class Caculations {
int xValue;
int yValue;
int[][] myArray; // array declared but never initialized
// ....
void findShip() {
while (notSunk == true) {
// 1
while (xAxisChangeP == true) {
if (myArray[xValue + 1][yValue] == 1) // then you use it here
Solution: initialize variables before using.
More importantly, you need to learn the general concepts of how to debug a NPE (NullPointerException). You should critically read your exception's stacktrace to find the line of code at fault, the line that throws the exception, and then inspect that line carefully, find out which variable is null, and then trace back into your code to see why. You will run into these again and again, trust me.
In your constructor for Calculations, you never initialized myArray:
Caculations(int x, int y, int[][] myArray) {
xValue = x;
yValue = y;
xAxisChangeP = true;
yAxisChangeP = true;
xAxisChangeN = true;
yAxisChangeN = true;
notSunk = true;
this.myArray = myArray; //Add this line
}
This is a direct answer to your problem, but all in all, you should do some research regarding the meaning behind the exception that was thrown so you understand what it means.
Why this problem happened
In Java, all objects and primitives, if not initialized manually, are given a default value.
For default values of primitives, check this: Primitive Data Types
In case of non-primitive types - such as Object, String, Thread, etc, as well as any user-defined class (i.e. Calculations) and also arrays (i.e. myArray) - the default value is null.
With that in mind, inside your constructor, as exemplified above, you have not initialized myArray, which means that when this variable was accessed for the first time, the value returned was null.
So, what's the problem with null?
Well, by itself, it does no harm. It's there. It doesn't bother you. Until you decide to use a variable that doesn't have an object assigned to it, but somehow you forget that and treat it as if it held something like a String or an array.
That's when Java will tell you: "Hey! There's no object here. I can't work like this. Let's throw an exception!".

Random number - increase/decrease by 1

I'm working on a method, that takes steps between 3 and -3. My program will not print out the steps in a numerical order, and I can't quite figure out how to do it, and I can't find anything elsewhere.
public static final int SENTINEL = Math.abs(3);
public static void randomWalk(Random rand) {
int walk = 0;
while (walk != SENTINEL) {
walk = (rand.nextInt((3 - (-3)) + 1) - 3);
System.out.println("Position = " + walk);
}
}
If that is what you are looking for :
int walk = 0;
int randomStep = 0;
Random rand = new Random();
while (Math.abs(walk) != 3) {
randomStep = rand.nextInt(2) > 0 ? 1 : -1; // -1 or 1 with 50% probability
walk += randomStep;
System.out.print(walk + " ");
}
//sample output: -1 -2 -1 0 1 2 1 2 3
public static void randomWalk(Random rand) {
int walk = 0;
while (walk != SENTINEL) {
walk += rand.nextInt(3) - 1;
if(walk>3) walk = 3;
if(walk<-3) walk = -3;
System.out.println("Position = " + walk);
}
}
I guess you want this.
while (walk != SENTINEL) {
int walk = 0;
walk = (rand.nextInt((3 - (-3)) + 1) - 3);
System.out.println("Walk is = " + walk);
int temp = walk;
if (walk >= -3) {
System.out.println("Wlak plus = " + (temp + 1));
System.out.println("Wlak minus =" + (temp - 1));
}
}
Could this be what you are looking for?
package com.stackoverflow.random;
import java.util.Random;
public class Walking {
private final int bounds;
public Walking(int bounds) {
this.bounds = bounds;
}
private boolean isWithinBounds(int walk) {
return Math.abs(walk) < bounds;
}
public String randomWalk() {
int walk = 0;
StringBuilder sb = new StringBuilder();
while(isWithinBounds(walk)) {
sb.append(walk);
walk = getNextStep(walk);
}
return sb.toString();
}
private Random random = null;
private int getNextStep(int walk) {
if (random == null)
random = new Random();
boolean increase = random.nextBoolean();
return increase?++walk:--walk;
}
public static void main(String[] args) {
Walking app = new Walking(3);
System.out.println("walking: " + app.randomWalk());
}
}

Time delay and JInput

OK, I don't know how to word this question, but maybe my code will spell out the problem:
public class ControllerTest
{
public static void main(String [] args)
{
GamePadController rockbandDrum = new GamePadController();
DrumMachine drum = new DrumMachine();
while(true)
{
try{
rockbandDrum.poll();
if(rockbandDrum.isButtonPressed(1)) //BLUE PAD HhiHat)
{
drum.playSound("hiHat.wav");
Thread.sleep(50);
}
if(rockbandDrum.isButtonPressed(2)) //GREEN PAD (Crash)
{
//Todo: Change to Crash
drum.playSound("hiHat.wav");
Thread.sleep(50);
}
//Etc....
}
}
}
public class DrumMachine
{
InputStream soundPlayer = null;
AudioStream audio = null;
static boolean running = true;
public void playSound(String soundFile)
{
//Tak a sound file as a paramater and then
//play that sound file
try{
soundPlayer = new FileInputStream(soundFile);
audio = new AudioStream(soundPlayer);
}
catch(FileNotFoundException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
AudioPlayer.player.start(audio);
}
//Etc... Methods for multiple audio clip playing
}
Now the problem is, if I lower the delay in the
Thread.sleep(50)
then the sound plays multiple times a second, but if I keep at this level or any higher, I could miss sounds being played...
It's an odd problem, where if the delay is too low, the sound loops. But if it's too high it misses playing sounds. Is this just a problem where I would need to tweak the settings, or is there any other way to poll the controller without looping sound?
Edit: If I need to post the code for polling the controller I will...
import java.io.*;
import net.java.games.input.*;
import net.java.games.input.Component.POV;
public class GamePadController
{
public static final int NUM_BUTTONS = 13;
// public stick and hat compass positions
public static final int NUM_COMPASS_DIRS = 9;
public static final int NW = 0;
public static final int NORTH = 1;
public static final int NE = 2;
public static final int WEST = 3;
public static final int NONE = 4; // default value
public static final int EAST = 5;
public static final int SW = 6;
public static final int SOUTH = 7;
public static final int SE = 8;
private Controller controller;
private Component[] comps; // holds the components
// comps[] indices for specific components
private int xAxisIdx, yAxisIdx, zAxisIdx, rzAxisIdx;
// indices for the analog sticks axes
private int povIdx; // index for the POV hat
private int buttonsIdx[]; // indices for the buttons
private Rumbler[] rumblers;
private int rumblerIdx; // index for the rumbler being used
private boolean rumblerOn = false; // whether rumbler is on or off
public GamePadController()
{
// get the controllers
ControllerEnvironment ce =
ControllerEnvironment.getDefaultEnvironment();
Controller[] cs = ce.getControllers();
if (cs.length == 0) {
System.out.println("No controllers found");
System.exit(0);
}
else
System.out.println("Num. controllers: " + cs.length);
// get the game pad controller
controller = findGamePad(cs);
System.out.println("Game controller: " +
controller.getName() + ", " +
controller.getType());
// collect indices for the required game pad components
findCompIndices(controller);
findRumblers(controller);
} // end of GamePadController()
private Controller findGamePad(Controller[] cs)
/* Search the array of controllers until a suitable game pad
controller is found (eith of type GAMEPAD or STICK).
*/
{
Controller.Type type;
int i = 0;
while(i < cs.length) {
type = cs[i].getType();
if ((type == Controller.Type.GAMEPAD) ||
(type == Controller.Type.STICK))
break;
i++;
}
if (i == cs.length) {
System.out.println("No game pad found");
System.exit(0);
}
else
System.out.println("Game pad index: " + i);
return cs[i];
} // end of findGamePad()
private void findCompIndices(Controller controller)
/* Store the indices for the analog sticks axes
(x,y) and (z,rz), POV hat, and
button components of the controller.
*/
{
comps = controller.getComponents();
if (comps.length == 0) {
System.out.println("No Components found");
System.exit(0);
}
else
System.out.println("Num. Components: " + comps.length);
// get the indices for the axes of the analog sticks: (x,y) and (z,rz)
xAxisIdx = findCompIndex(comps, Component.Identifier.Axis.X, "x-axis");
yAxisIdx = findCompIndex(comps, Component.Identifier.Axis.Y, "y-axis");
zAxisIdx = findCompIndex(comps, Component.Identifier.Axis.Z, "z-axis");
rzAxisIdx = findCompIndex(comps, Component.Identifier.Axis.RZ, "rz-axis");
// get POV hat index
povIdx = findCompIndex(comps, Component.Identifier.Axis.POV, "POV hat");
findButtons(comps);
} // end of findCompIndices()
private int findCompIndex(Component[] comps,
Component.Identifier id, String nm)
/* Search through comps[] for id, returning the corresponding
array index, or -1 */
{
Component c;
for(int i=0; i < comps.length; i++) {
c = comps[i];
if ((c.getIdentifier() == id) && !c.isRelative()) {
System.out.println("Found " + c.getName() + "; index: " + i);
return i;
}
}
System.out.println("No " + nm + " component found");
return -1;
} // end of findCompIndex()
private void findButtons(Component[] comps)
/* Search through comps[] for NUM_BUTTONS buttons, storing
their indices in buttonsIdx[]. Ignore excessive buttons.
If there aren't enough buttons, then fill the empty spots in
buttonsIdx[] with -1's. */
{
buttonsIdx = new int[NUM_BUTTONS];
int numButtons = 0;
Component c;
for(int i=0; i < comps.length; i++) {
c = comps[i];
if (isButton(c)) { // deal with a button
if (numButtons == NUM_BUTTONS) // already enough buttons
System.out.println("Found an extra button; index: " + i + ". Ignoring it");
else {
buttonsIdx[numButtons] = i; // store button index
System.out.println("Found " + c.getName() + "; index: " + i);
numButtons++;
}
}
}
// fill empty spots in buttonsIdx[] with -1's
if (numButtons < NUM_BUTTONS) {
System.out.println("Too few buttons (" + numButtons +
"); expecting " + NUM_BUTTONS);
while (numButtons < NUM_BUTTONS) {
buttonsIdx[numButtons] = -1;
numButtons++;
}
}
} // end of findButtons()
private boolean isButton(Component c)
/* Return true if the component is a digital/absolute button, and
its identifier name ends with "Button" (i.e. the
identifier class is Component.Identifier.Button).
*/
{
if (!c.isAnalog() && !c.isRelative()) { // digital and absolute
String className = c.getIdentifier().getClass().getName();
// System.out.println(c.getName() + " identifier: " + className);
if (className.endsWith("Button"))
return true;
}
return false;
} // end of isButton()
private void findRumblers(Controller controller)
/* Find the rumblers. Use the last rumbler for making vibrations,
an arbitrary decision. */
{
// get the game pad's rumblers
rumblers = controller.getRumblers();
if (rumblers.length == 0) {
System.out.println("No Rumblers found");
rumblerIdx = -1;
}
else {
System.out.println("Rumblers found: " + rumblers.length);
rumblerIdx = rumblers.length-1; // use last rumbler
}
} // end of findRumblers()
// ----------------- polling and getting data ------------------
public void poll()
// update the component values in the controller
{
controller.poll();
}
public int getXYStickDir()
// return the (x,y) analog stick compass direction
{
if ((xAxisIdx == -1) || (yAxisIdx == -1)) {
System.out.println("(x,y) axis data unavailable");
return NONE;
}
else
return getCompassDir(xAxisIdx, yAxisIdx);
} // end of getXYStickDir()
public int getZRZStickDir()
// return the (z,rz) analog stick compass direction
{
if ((zAxisIdx == -1) || (rzAxisIdx == -1)) {
System.out.println("(z,rz) axis data unavailable");
return NONE;
}
else
return getCompassDir(zAxisIdx, rzAxisIdx);
} // end of getXYStickDir()
private int getCompassDir(int xA, int yA)
// Return the axes as a single compass value
{
float xCoord = comps[ xA ].getPollData();
float yCoord = comps[ yA ].getPollData();
// System.out.println("(x,y): (" + xCoord + "," + yCoord + ")");
int xc = Math.round(xCoord);
int yc = Math.round(yCoord);
// System.out.println("Rounded (x,y): (" + xc + "," + yc + ")");
if ((yc == -1) && (xc == -1)) // (y,x)
return NW;
else if ((yc == -1) && (xc == 0))
return NORTH;
else if ((yc == -1) && (xc == 1))
return NE;
else if ((yc == 0) && (xc == -1))
return WEST;
else if ((yc == 0) && (xc == 0))
return NONE;
else if ((yc == 0) && (xc == 1))
return EAST;
else if ((yc == 1) && (xc == -1))
return SW;
else if ((yc == 1) && (xc == 0))
return SOUTH;
else if ((yc == 1) && (xc == 1))
return SE;
else {
System.out.println("Unknown (x,y): (" + xc + "," + yc + ")");
return NONE;
}
} // end of getCompassDir()
public int getHatDir()
// Return the POV hat's direction as a compass direction
{
if (povIdx == -1) {
System.out.println("POV hat data unavailable");
return NONE;
}
else {
float povDir = comps[povIdx].getPollData();
if (povDir == POV.CENTER) // 0.0f
return NONE;
else if (povDir == POV.DOWN) // 0.75f
return SOUTH;
else if (povDir == POV.DOWN_LEFT) // 0.875f
return SW;
else if (povDir == POV.DOWN_RIGHT) // 0.625f
return SE;
else if (povDir == POV.LEFT) // 1.0f
return WEST;
else if (povDir == POV.RIGHT) // 0.5f
return EAST;
else if (povDir == POV.UP) // 0.25f
return NORTH;
else if (povDir == POV.UP_LEFT) // 0.125f
return NW;
else if (povDir == POV.UP_RIGHT) // 0.375f
return NE;
else { // assume center
System.out.println("POV hat value out of range: " + povDir);
return NONE;
}
}
} // end of getHatDir()
public boolean[] getButtons()
/* Return all the buttons in a single array. Each button value is
a boolean. */
{
boolean[] buttons = new boolean[NUM_BUTTONS];
float value;
for(int i=0; i < NUM_BUTTONS; i++) {
value = comps[ buttonsIdx[i] ].getPollData();
buttons[i] = ((value == 0.0f) ? false : true);
}
return buttons;
} // end of getButtons()
public boolean isButtonPressed(int pos)
/* Return the button value (a boolean) for button number 'pos'.
pos is in the range 1-NUM_BUTTONS to match the game pad
button labels.
*/
{
if ((pos < 1) || (pos > NUM_BUTTONS)) {
System.out.println("Button position out of range (1-" +
NUM_BUTTONS + "): " + pos);
return false;
}
if (buttonsIdx[pos-1] == -1) // no button found at that pos
return false;
float value = comps[ buttonsIdx[pos-1] ].getPollData();
// array range is 0-NUM_BUTTONS-1
return ((value == 0.0f) ? false : true);
} // end of isButtonPressed()
// ------------------- Trigger a rumbler -------------------
public void setRumbler(boolean switchOn)
// turn the rumbler on or off
{
if (rumblerIdx != -1) {
if (switchOn)
rumblers[rumblerIdx].rumble(0.8f); // almost full on for last rumbler
else // switch off
rumblers[rumblerIdx].rumble(0.0f);
rumblerOn = switchOn; // record rumbler's new status
}
} // end of setRumbler()
public boolean isRumblerOn()
{ return rumblerOn; }
} // end of GamePadController class
I think you are using the wrong design pattern here. You should use the observer pattern for this type of thing.
A polling loop not very efficient, and as you've noticed doesn't really yield the desired results.
I'm not sure what you are using inside your objects to detect if a key is pressed, but if it's a GUI architecture such as Swing or AWT it will be based on the observer pattern via the use of EventListeners, etc.
Here is a (slightly simplified) Observer-pattern
applied to your situation.
The advantage of this design is that when a button
is pressed and hold, method 'buttonChanged' will
still only be called once, instead of start
'repeating' every 50 ms.
public static final int BUTTON_01 = 0x00000001;
public static final int BUTTON_02 = 0x00000002;
public static final int BUTTON_03 = 0x00000004;
public static final int BUTTON_04 = 0x00000008; // hex 8 == dec 8
public static final int BUTTON_05 = 0x00000010; // hex 10 == dec 16
public static final int BUTTON_06 = 0x00000020; // hex 20 == dec 32
public static final int BUTTON_07 = 0x00000040; // hex 40 == dec 64
public static final int BUTTON_08 = 0x00000080; // etc.
public static final int BUTTON_09 = 0x00000100;
public static final int BUTTON_10 = 0x00000200;
public static final int BUTTON_11 = 0x00000400;
public static final int BUTTON_12 = 0x00000800;
private int previousButtons = 0;
void poll()
{
rockbandDrum.poll();
handleButtons();
}
private void handleButtons()
{
boolean[] buttons = getButtons();
int pressedButtons = getPressedButtons(buttons);
if (pressedButtons != previousButtons)
{
buttonChanged(pressedButtons); // Notify 'listener'.
previousButtons = pressedButtons;
}
}
public boolean[] getButtons()
{
// Return all the buttons in a single array. Each button-value is a boolean.
boolean[] buttons = new boolean[MAX_NUMBER_OF_BUTTONS];
float value;
for (int i = 0; i < MAX_NUMBER_OF_BUTTONS-1; i++)
{
int index = buttonsIndex[i];
if (index < 0) { continue; }
value = comps[index].getPollData();
buttons[i] = ((value == 0.0f) ? false : true);
}
return buttons;
}
private int getPressedButtons(boolean[] array)
{
// Mold all pressed buttons into a single number by OR-ing their values.
int pressedButtons = 0;
int i = 1;
for (boolean isBbuttonPressed : array)
{
if (isBbuttonPressed) { pressedButtons |= getOrValue(i); }
i++;
}
return pressedButtons;
}
private int getOrValue(int btnNumber) // Get a value to 'OR' with.
{
int btnValue = 0;
switch (btnNumber)
{
case 1 : btnValue = BUTTON_01; break;
case 2 : btnValue = BUTTON_02; break;
case 3 : btnValue = BUTTON_03; break;
case 4 : btnValue = BUTTON_04; break;
case 5 : btnValue = BUTTON_05; break;
case 6 : btnValue = BUTTON_06; break;
case 7 : btnValue = BUTTON_07; break;
case 8 : btnValue = BUTTON_08; break;
case 9 : btnValue = BUTTON_09; break;
case 10 : btnValue = BUTTON_10; break;
case 11 : btnValue = BUTTON_11; break;
case 12 : btnValue = BUTTON_12; break;
default : assert false : "Invalid button-number";
}
return btnValue;
}
public static boolean checkButton(int pressedButtons, int buttonToCheckFor)
{
return (pressedButtons & buttonToCheckFor) == buttonToCheckFor;
}
public void buttonChanged(int buttons)
{
if (checkButton(buttons, BUTTON_01)
{
drum.playSound("hiHat.wav");
}
if (checkButton(buttons, BUTTON_02)
{
drum.playSound("crash.wav");
}
}
Please post more information about the GamePadController class that you are using.
More than likely, that same library will offer an "event" API, where a "callback" that you register with a game pad object will be called as soon as the user presses a button. With this kind of setup, the "polling" loop is in the framework, not your application, and it can be much more efficient, because it uses signals from the hardware rather than a busy-wait polling loop.
Okay, I looked at the JInput API, and it is not really event-driven; you have to poll it as you are doing. Does the sound stop looping when you release the button? If so, is your goal to have the sound play just once, and not again until the button is release and pressed again? In that case, you'll need to track the previous button state each time through the loop.
Human response time is about 250 ms (for an old guy like me, anyway). If you are polling every 50 ms, I'd expect the controller to report the button depressed for several iterations of the loop. Can you try something like this:
boolean played = false;
while (true) {
String sound = null;
if (controller.isButtonPressed(1))
sound = "hiHat.wav";
if (controller.isButtonPressed(2))
sound = "crash.wav";
if (sound != null) {
if (!played) {
drum.playSound(sound);
played = true;
}
} else {
played = false;
}
Thread.sleep(50);
}

Categories