I am currently making a paint program and am implementing the undo and redo function. So far, if I remove the code for the redo part, it works, but for some reason, if I add the redo code back in, it just throws a arrayOutOfIndex exception or NullPointer. I have tried everything, and do not know what else there is to do!
Sorry if this problem is painstakingly easy; I am just a beginner.
Code:
public void redo()
{
for(int i = 0; i < 3; i++ ){
if(redo[0].get(0)!=null){
al.add((Shape) redo[0].get(redo[0].size()-1));
cl.add((Color) redo[1].get(redo[1].size()-1));
tl.add((Integer) redo[2].get(redo[2].size()-1));
lineEnd.add((Integer) redo[3].get(redo[3].size()-1));
junction.add((Component) redo[4].get(redo[4].size()-1));
}
redo[0].remove(redo[0].size()-1);
redo[1].remove(redo[1].size()-1);
redo[2].remove(redo[2].size()-1);
redo[3].remove(redo[3].size()-1);
redo[4].remove(redo[4].size()-1);
}
repaint();
}
public void undo()
{
for(int i = 0; i < 3; i++ ){
Shape alComponent = al.get(al.size()-1);
Color clComponent = cl.get(cl.size()-1);
Integer tlComponent = tl.get(tl.size()-1);
Integer lineEndComponent = lineEnd.get(lineEnd.size()-1);
Integer junctionComponent = juncture.get(juncture.size()-1);
if(al.get(0)!=null){
redo[0].add(alComponent);
redo[1].add(clComponent);
redo[2].add(tlComponent);
redo[3].add(lineEndComponent);
redo[4].add(junctionComponent);
}
al.remove(al.size()-1);
cl.remove(cl.size()-1);
tl.remove(tl.size()-1);
lineEnd.remove(lineEnd.size()-1);
juncture.remove(juncture.size()-1);
}
repaint();
}
P.S., I have a for loop in there because if you press it once, the change on the painting is minute.
Inside your redo loop, you
check that there is a redo-able item and redo if you can, then
(unconditionally) remove an item from the redo lists
Move the remove()s into the if block.
Also, don't use five arrays. Create a class that does all that for you, with well-named redo lists. (That's just a tip, has nothing to do with your question.)
Related
This is my first post, so sorry if I post incorrect or incomplete, I will answer every question and I am open for improvements.
My main method has a for-loop with a recursive method in it, the recursive method also has a for-loop (the recursive method basically replaces a lot of nested for-loops). When a specific case is reached, I want to jump out of the recursive method and out of the for-loop in my main. For visualization:
public static void main(..)
for (int i = 0, i < 100 ; i++) {
//do something
recursivemethod(...)
}
//jump here, if case in method is reached
------------------------
recursivemethod (...)
for (int i = 0; i < 10 ; i++) {
//do something
if (case reached) {//jump out of loop in main}
else {recursivemethod(modified)}
}
As I cannot label my for-loop in main and break Label; in my method (to my knowledge), I tried using a boolean, but because of for-loops and/or recursive call, boolean switches back and has not the wanted effect.
There was a similar question where the user later added his solution, but didn't specify it enough for me to understand and how to implement this in my code, the user was last seen years ago, so I cannot ask him. Can someone please help me?
Thanks a lot in advance!
You probably want to return boolean from your recursive method. E. g. true means that recursive call8ng should stop and exit loop
for (int i = 0, i < 100 ; i++) {
//do something
if(recursivemethod(...))
break;
}
Recursive method
boolean recursivemethod (...) {
for (int i = 0; i < 10 ; i++) {
//do something
if (case reached) {return true;}
else {return recursivemethod(modified)}
return false;
}
}
edit: As I was writing this post, I made my code simpler (lost arrays entirely) and got it working. Yet I am still not sure why this specific code won't work, so I'll keep the question.
Hello.
I am writing a small puzzle game in Java (using Eclipse 4.4.2) and stumbled upon a problem inside one of my methods. Basically - it won't complete the method, it just exits the method after the for loop is done without any warnings or errors (I'm not catching exceptions either). I hope I missed something simple..
Details:
I have a method to set the colors of an object and up to 5 other objects that are linked to it through lines. I set up the color of the main object, then find the linked objects through for-loops and in the end change their colors as well. (Double checked the code for Lines, there are simple return methods and nestA and nestB as data - no problem there). lines is an array with a length of 50, nests as its members.
Here's the code:
public void highlightNests(Nest nest) {
//setting the color of the main object (a nest).
Mappers.setColor(nest, nestHighlight);
//resetting the array. Temp solution, had a return method earlier,
//this is part of the debugging.
connectedNests = null;
connectedNests = new Nest[5];
int i = 0;
Gdx.app.log("highlightNests()", "starting the loop");
for (int j=0; j<lines.length; j++) {
if (lines[j].getNestA() == nest) {
connectedNests[i] = lines[j].getNestB();
i++;
}
if (lines[j].getNestB() == nest) {
connectedNests[i] = lines[j].getNestA();
i++;
}
}
//This is where the program exits the method. The following
//lines are not run.
Gdx.app.log("highlightNests()", "entering loop");
for (int l=0; i<connectedNests.length; l++) {
Mappers.setColor(connectedNests[l], nestHighlight);
Gdx.app.log("highlightNests", "set color");
}
}
Deleting the middle section makes the end part run, so there are no errors in the last part.
Your second loop is completely wrong, you declare the counter as l and increment another counter i, you should use l<connectedNests.length change it like this:
for (int l=0; l<connectedNests.length; l++) {
Mappers.setColor(connectedNests[l], nestHighlight);
Gdx.app.log("highlightNests", "set color");
}
And the program won't finish method and exits before the loop because, it doesn't even enter the loop as it's incorrect.
You have to use l instead of i in condition like,
for (int l=0; l<connectedNests.length; l++)...
//---------^ l not i
I need this for an array, but basically the idea is that a for loop will run, and whatever number you tell it to skip, it won't do. So for(int x=0; x<50; x++) if I want 1-50 except 22, how would I write that?
This would give me the ability to skip a certain number in my array.
Sorry if this is an extremely simple question, I am not too familiar with Java.
Make use of continue, something like this:
for(int x=0; x<50; x++) {
if(x == 22)
continue;
// do work
}
Suggested reading: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html
public static final void doSkippedIteration(final int[] pArray, final int pSkipIndex) {
for(int i = 0; i < pSkipindex; i++) {
// Do something.
}
for(int i = pSkipIndex + 1; i < pArray.length; i++) {
// Do something.
}
}
You would have to do some basic check to see whether pIndex lies within the confines of the array. This saves you from having to perform a check for every single iteration, but does require you to duplicate your code in this specific example. You could of course avoid this by wrapping the code in a wider control block which handles the two iterations in a cleaner manner.
I created two methods for my Bingo Game in Java. One method creates a new board which populates the Bingo Board with integers according to the Bingo rule (1-75). My second method generates random numbers with a range of 1 - 75.
public static int drawNum(){
Random rand = new Random();
int num = rand.nextInt(75)+1;
return num;
}
public static void bingoCard(){
int [][]card=new int [5][5];
ArrayList<Integer> alreadyUsed = new ArrayList<Integer>();
boolean valid = false;
int tmp = 0;
for(int i = 0; i <= 4; i++){
for(int row = 0; row < card.length; row++){
while(!valid){
tmp = (int)(Math.random() * 15) + 1 + 15 * i;
if(!alreadyUsed.contains(tmp)){
valid = true;
alreadyUsed.add(tmp);
}
}
card[row][i] = tmp;
valid = false;
}
}
card[2][2] = 0;
//create array to make title.
String title []={"B","I","N","G","O"};
for(int i=0;i<title.length;i++){
System.out.print(title[i]+ "\t");
}
System.out.println();
for(int row=0;row<card.length;row++){
for(int col=0;col<card[row].length;col++){
System.out.print(card[row][col]+ "\t");
}
System.out.println();
}
}
What I need help with is, how do I check whether or not the drawNum() method corresponds to any values stored inside my bingoCard() array? If so, print out a new array with the integers filled in. If the condition is met for a bingo, then you win.
I hope I don't make it sound like I want you to do it for me, but I am confused as to how to start coding that part. Thank you.
This my recommendation - Learn Object Oriented Programming immediately
I see you are using objects provided in the JDK, so why not learn to make your own?
Make two classes with the following methods (-) and members (+) (PS. This is not a formal way to document code)
BingoCard
+list of numbers on card
-reset() : gets new numbers for this card
-test(BingoDrawer) : Tests to see if this card won on this drawing
-toString() : returns a String representation of this card
BingoDrawer
+list of numbers drawn
-reset() : draws new numbers
-hasNumber(int number) : tests if this number was drawn
-toString() : returns a String representation of this drawing
One more suggestions
Instead of keeping track of what you used, keep track of what you have not used, it will make things much easier because you can just choose stuff from that list randomly. Unlike your current action which is choosing (a logical number) from thin air and hoping (which causes issues) it is not a collision
If you follow my recommendation you can write code like this
public static void main(String[] args) {
BingoCard bc = new BingoCard();
BingoDrawer bd = new BingoDrawer();
while(thePlayerWantsToPlay()) { //function to be defined by you
bc.reset();
bd.reset();
System.out.println(bc);
System.out.println(bd);
System.out.println(bc.test(bd));
}
}
You can take it a step further and make a BingoGame class and do what I did in main there and just create an instance of BingoGame and call some start method on the object.
For checking if you have the number in your board, read through the board in a similar manner as you do for the already_used numbers, except with the number the user just entered.
The conditions for the user to win should be checked after the board has another number guessed.
There are a few ways to do this, a simple one would be to iterate over every possible pattern that could win, checking to see if there are tokens there.
All of this would be in a loop, that goes a little like this:
Set up board via user entering numbers.
Start loop
set either a timer to wait for, or wait for a keypress (so the game doesn't just play really fast)
Get random number
Possibly add to board
Check if winner
if winner, break the loop and do something else.
Print the new board out.
(end of loop)
If they got here, that could mean they won!
Wait to exit
You can just write it out as pseudo-code and fill in the methods after that. It usually helps to work on these things in a top-down fashion. So, for bingo you might have:
board = generateBoard();
while (!bingoFound(board)) {
number = drawNumber();
board = stampNumbers(board, number);
}
If that makes sense, you can go a step deeper and define each method. For example, bingoFound might look like:
public boolean bingoFound(int[][] board) {
boolean wasFound = bingoRowFound(board)
|| bingoColFound(board)
|| bingoDiagonalFound(board);
return wasFound;
}
Again, I've defined everything in (mostly) pseudo-code. If this looks ok, you can move a step deeper. Let's define the bingoRowFound method.
public boolean bingoRowFound(int[][] board) {
for (int row = 0; row < NUM_ROWS; row++) {
boolean rowIsABingo = true;
for (int col = 0; col < NUM_COLS; col++) {
// We have to check that everything up until this point has
// been marked off. I am using -1 to indicate that a spot has
// been marked.
rowIsABingo = rowIsABingo && board[row][col] == -1;
}
if (rowIsABingo) { return rowIsABingo; }
}
return false; // If we didn't find a bingo, return false.
}
Some of the methods (like drawNumber) will be really easy to implement. Others, like looking for a diagonal bingo might be a bit more difficult.
Feb 12 2014 Update:
Retracted code, since this was a college course assignment, and I want to prevent people just copying the code. I almost got in trouble for being accused of sharing code (which is a nono in assignments) when another student lifted my code from my Github repo and sent it in as their own.
There were two classes, one main class and a class to hold my methods and constructors.
BINGOFINAL.java was my main class.
Bingo_Card.java held my constructor and methods.
If you want to run this, make sure you create a new project called BINGOFINAL, and put Bingo_Card.java into that same */src/ extension.
I'm trying to make a game in Java, and I've got already something. But i want to make the Player shoot bullets.
I've came up with the idea to make an object array, and put all the Bullet instances into the array. then in a thread, I want to make them all move(all the objects in the array).
This is what I put in the main class:
Bullet[] BulletArray;
public int Bullets = 0;
public void run() {
for(int i = 0; i < Bullets; i++){
BulletArray[i].Step();
}
if(Key.FireKey){
BulletArray[Bullets + 1] = new Bullet();
Bullets += 1;
}
}
I've just included the basic stuff, i.e. The run function runs fine, in the original code.
The code doesn't work, it gives me an error when I press Fire. The error is somewhere at
BulletArray[Bullets + 1] = new Bullet();
I hope you understand what I mean.
Well, for starters, your BulletArray is never initialized.
When you enter run(), your for() loop appears to work fine because it does not actually enter the block. Your int i = 0 is declared and is already greater than or equal to your limit, which is the int Bullet = 0. This means that the body of the loop never executes.
Then, when you press the Key.FireKey, it attempts to reference an array index that doesn't exist. It can't exist, because the array has never been initialized.
To initialize your array, you will need to do something more like this:
private int maxBullets = 10;
Bullet[] bulletArray = new Bullet[maxBullets];
Then your for() loop will actually enter. Note that in your Key.FireKey block, however, that you will have to perform some checking to make sure that you don't get an IndexOutOfBoundsException by trying to fire more bullets than you've created. i.e.,
if(Key.FireKey) {
if(bullets < maxBullets) {
bulletArray[++bullets] = new Bullet();
}
}