Results 1 to 10 of 10
  1. #1
    BJ1110 is offline Member
    Join Date
    Oct 2009
    Posts
    13
    Rep Power
    0

    Default Object Construction ends Program in GridWorld

    I am attempting to create a rather generic Tetris clone in Java using GridWorld. In case you are unfamiliar with the software, it's the AP Computer Science class's case study. I found a tutorial to create a Tetris game in Java, and have been following it fairly smoothly with no errors.

    If you'll read the page or so of text that describes the process of creating the game, you will find the part which mentions to "Choose one of the 7 TetrisBlocks to create: TetrisBlockO, TetrisBlockI, TetrisBlockT, TetrisBlockL, TetrisBlock_L, TetrisBlockZ, TetrisBlock_Z". I am at this part of the process, and have pretty much verified that all of my methods work just fine, however, when I use the code that was included in the .pdf file, the code that was behind comment marks, I get errors. I am referring specifically to this code:

    Java Code:
    //if(randNum == 1)
    // randomBlock = new TetrisBlockO();
    //if(randNum == 2)
    // randomBlock = new TetrisBlockI();
    //if(randNum == 3)
    // randomBlock = new TetrisBlockT();
    //if(randNum == 4)
    // randomBlock = new TetrisBlockL();
    //if(randNum == 5)
    // randomBlock = new TetrisBlock_L();
    //if(randNum == 6)
    // randomBlock = new TetrisBlockZ();
    //if(randNum == 7)
    // randomBlock = new TetrisBlock_Z();
    Using a similar format, I have gone and created classes for both the TetrisBlockO and TetrisBlockI portions of this, doing almost the exact same things for the TetrisBlockO and I methods as I had done for the original TetrisBlock method. However, when the comment lines are removed to call the constructors for TetrisBlockO and TetrisBlockI, the program ends with a game over screen. I have put print statements into both the if statements and the constructors themselves, and have determined that as soon as the program reaches a line of code for the construction of the I or O blocks, the program just ends.

    It doesn't even get to the constructor, and it doesn't start running that class. The program literally just ends. Why is that?

    Can someone explain to me what it is doing and if there is any way to solve the problem? Please and thank you.

    If anyone requests to see the rest of my code thus far, I'll post it.

  2. #2
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    as soon as the program reaches a line of code for the construction of the I or O blocks, the program just ends.

    You need to figure out precisely the path of execution that leads to the "game over screen".

    Deal with just one block to begin with, eg TetrisBlockO, and replace all the commented code with

    Java Code:
    System.out.println("block about to be constructed")
    randomBlock = new TetrisBlockO();
    System.out.println("block constructed ok")

    Notice how the System.out.println() statements will tell you unambiguously whether it is something in your block constructor (or its super classes) that is leading to the game over screen, or whether it is something that happens after the commented code.

    You have to proceed in a similar fashion to determine what is leading to that game over screen.

    -------------------------------

    Most likely "game over" only occurs after some check of the location of existing blocks. Again System.out.println() can be used to tell you things about the state of the game just before the line of code that generates the game over screen. It might just be that the game logic that detects whether a block can fall is faulty and your newly created block (at the top of the screen) is determined to be in a state that means "game over".

    ---------------------------

    Work one very small step at a time. Have a precise and documented expectation for every class, constructor, and method you write. (Ie have documented what it will do under every circumstance) And test: every small step of the way.

    It is very hard to do anything but guess or give very general guidelines without code and without knowing anything about GridWorld or anything (good) about the AP Computer Science supplied code.

  3. #3
    BJ1110 is offline Member
    Join Date
    Oct 2009
    Posts
    13
    Rep Power
    0

    Default

    With regards to the first part of your response, putting the code before and after the construction of the TetrisBlockO: I had already tried that before posting here. I also inserted print statements into the TetrisBlockO class itself, to see whether or not the program was beginning the construction process of the TetrisBlockO object. Instead, the only thing that came out of the console was the first print statement--the one before the object being constructed.

    I've debugged programs and such so much to the point that I'm very familiar with the process, but when the class constructor causes the game to crash because it just doesn't want to call it, it confuses me greatly. Inside of Eclipse, the editor reveals no errors, has no problems, and no quick-fix suggestions.

    In an ideal program, the constructor will construct the object with no issues. But for whatever reason, the console reveals that the program reaches the construction line, and then terminates immediately, without executing the code after it.

    The original TetrisBlock code and my own TetrisBlockO code are very similar in the constructors. And even if I copy character-for-character what is in the TetrisBlock constructor, it refuses to run. A comparison of the TetrisBlock and TetrisBlockO constructors' code:

    TetrisBlockO:
    Java Code:
    public TetrisBlockO() {
    		rotationPos = 0;
    		gr = TetrisGame.world.getGrid();
    		
    		//GAME OVER!
    		if (gr.get(new Location(0, 5)) != null 
    		 || gr.get(new Location(1, 5)) != null
    		 || gr.get(new Location(0, 6)) != null
    		 || gr.get(new Location(1, 6)) != null) {
    			javax.swing.JOptionPane.showMessageDialog(null, "Score: " + TetrisGame.score, "GAME OVER!", 0);
    			System.exit(0);
    		}
    		
    		putSelfInGrid(gr, new Location(1, 5));
    		
    		blocks = new ArrayList<TetrisBrick>();
    		
    		TetrisBrick a;
    		a = new TetrisBrick(Color.blue);
    		a.putSelfInGrid(gr, new Location(0, 5));
    		blocks.add(a);
    		
    		TetrisBrick b;
    		b = new TetrisBrick(Color.blue);
    		b.putSelfInGrid(gr, new Location(1, 6));
    		blocks.add(b);
    		
    		TetrisBrick c;
    		c = new TetrisBrick(Color.blue);
    		c.putSelfInGrid(gr, new Location(0, 6));
    		blocks.add(c);
    TetrisBlock:
    Java Code:
    public TetrisBlock() {
    		super(Color.blue);
    		rotationPos = 0;
    		gr = TetrisGame.world.getGrid();
    		// ==> LAMEST GAME OVER EVER !!! <==
    		// if the Grid does not have room for the TetrisBlock.. GameOver
    		if (gr.get(new Location(0, 5)) != null || gr.get(new Location(1, 5)) != null) {
    			javax.swing.JOptionPane.showMessageDialog(null, "Score: " + TetrisGame.score, "GAME OVER!", 0);
    			System.exit(0);
    		}
    		putSelfInGrid(gr, new Location(1, 5));
    		blocks = new ArrayList<TetrisBrick>();
    		TetrisBrick a;
    		// create TetrisBugs for ArrayList blocks and put them in Grid gr	
    		a = new TetrisBrick(Color.blue);
    		a.putSelfInGrid(gr, new Location(0, 5));
    		blocks.add(a);
    		// TetrisBlock subclasses will add two more TetrisBug objects to blocks
    	}
    The code is very similar, and yet, issues still arise.

    I do have a theory as to why the program is acting up, but it doesn't even begin to explain what it is doing now. According to the GridWorld Tetris tutorial pdf, it tells the one writing the code to create the new Block classes and telling them to extends TetrisBlock as opposed to TetrisBrick. Because I am not limited by this tutorial, I could extends TetrisBrick for each block instead, but that would be adding a whole lot of unnecessary work.

    Additionally, because it extends TetrisBlock, it should inherit all of the methods inside TetrisBlock, without affecting the result of a constructed object. But for whatever reason, the sole existence of the fact that a constructor for a child-class-object is being called seems to result in catastrophic failure, without even running the constructor to create a problem.

    I'm almost sure that there must be some syntax error or a better way of handling the problem without any issues, but I just don't know any way to approach it.

  4. #4
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    but when the class constructor causes the game to crash because it just doesn't want to call it, it confuses me greatly.

    It confuses me too - I have never seen pieces of code that have developed volition and desire like this.

    In your earlier post you said you got a "game over" screen (which I took to be normal program termination). Now it crashes. Which is it?

    The code you posted suggests further useful places for SYstem.out.println() statements. In addition to before and after the TetrisBlockO constructor call, put them at the very start of the constructor and just after the if statement and its block. Do this for both the TetrisBlockO constructor and the TetrisBlock constructor. (I am assuming TetrisBlock is the super class of TetrisBlockO) WHat happens when you do that? (code and output.)

    The aim remains finding precisely what is leading to the game over screen (which of those two if blocks, or somewhere else).

    --------------------------------

    The suggestion of faulty game-over detection looks even nicer given the code you've posted. Assuming TetrisBlock to be a parent class, you have a new block "putting itself" at a grid location in the super class constructor and then, in the child class constructor, checking that very position and, if it's occupied, ending the game.

  5. #5
    BJ1110 is offline Member
    Join Date
    Oct 2009
    Posts
    13
    Rep Power
    0

    Default

    My bad, it is a "GAME OVER!" However, whenever it happens, there is also a termination afterwards, so in a way, it was like a crash.

    As for putting the print statements inside the constructor, particularly at the very beginning of the constructor, absolutely no difference. The output is still "Block O creating...." If it had gotten to the constructor, it would have printed "Constructor reached." And if it had finished the creation, it would have said "DONE." But it only does the first print statement, and proceeds to game over at the creation of the object. If the statements are put into the TetrisBlock's constructor, however, it functions appropriately, and prints them all out where they should be.

    With regards to that last part, I believe that you may be somewhat right. However, given the way that the program was written, I assumed that I needed to rewrite a game over screen for the subclass (TetrisBlockO). And I still think I do, but I'm confused as to why it works for a regular block but not for an O or an I.

  6. #6
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,416
    Rep Power
    20

    Default

    Are you aware that in the absence of an explicit call to a parameterized superclass constructor, the superclass's default (no-param) constructor is invoked before execution of your constructor code? That is, the compiler inserts a call to super() at the beginning of the constructor.

    What class does TetrisBlockO extend? Put some debugging statements in its default constructor.

    db

  7. #7
    BJ1110 is offline Member
    Join Date
    Oct 2009
    Posts
    13
    Rep Power
    0

    Default

    TetrisBlockO extends TetrisBlock; TetrisBlock extends TetrisBrick.

    And no, I wasn't aware that it is making a default superclass call at the beginning of the file. So I added a print statement to the default constructor of TetrisBlock, the parent class, just to see if this is true. And it turns out that every time a Block O is attempting to be constructed, the superclass reaches the print statement and prints it.

    I think... this could mean that it is attempting to construct objects on top of each other, and the if statements are overlapping, which would cause a problem. I will attempt to fix this ASAP.

    EDIT: Well, that didn't work. I figured that the goal of the assignment would have been changed to make all the bricks in a single TetrisBlock appear through two separate constructors, but that doesn't appear to be the case. I will insert more debug statements for the time being.

    EDIT Part 2: So I've added debug print statements. I've put one every time any block is created, reading "A new block has been created." I've put two inside the if statement for TetrisBlockO, one that says "Block O creating....", and one that says "DONE." Additionally, I've entered print statements throughout the TetrisBlock and TetrisBlockO constructors, and here's what I've learned:

    1. Before the Tetris game really even starts, the first thing that seems to be called is the constructor for TetrisBlock. It doesn't reach the method for creating a new TetrisBlock at all, as none of the statements inside of that method are printed.

    2. After a few random number cycles for selecting which block is going to come next, it will eventually become time to call TetrisBlockO's constructor. Here is the result of its printouts.

    TetrisBlock(), before if. <--First print statement inside of the TetrisBlock constructor. Verifies that the constructor was reached.
    TetrisBlock(), after if. No game over. <--Second print statement inside of the TetrisBlock constructor. Only called if the game over if statement has been passed without ending the program.
    A new block has been created. <--Printed whenever a new TetrisBlock object is created.
    Block O creating.... <--Printed when the if statement for construction of a TetrisBlockO object has been called. The TetrisBlock object from before is changed to its child class's type.
    TetrisBlock(), before if. <--Once again, it has hit the superclass constructor.
    tetris.TetrisBrick[location=(0, 5),direction=180,color=java.awt.Color[r=0,g=0,b=255]] <--This object is in location (0, 5) which triggers a game over.
    tetris.TetrisBlock[location=(1, 5),direction=180,color=java.awt.Color[r=0,g=0,b=255]] <--This object is in location (1, 5), which also triggers a game over.
    It's obvious that the program is reaching the constructor for TetrisBlock two separate times. And what appears to be the case, is after the two blocks are created and put into the grid, it tests to see if they are there to get a game over. Because they are there and haven't moved yet, they will always be there, nad therefore, there will always be a gameover.
    Last edited by BJ1110; 02-01-2011 at 05:42 PM.

  8. #8
    pbrockway2 is offline Moderator
    Join Date
    Feb 2009
    Location
    New Zealand
    Posts
    4,565
    Rep Power
    12

    Default

    Was the last debug line supposed to be "tetris.TetrisBrick[location=etc"?

    And do you understand the constructor call sequence now?

    I think the thing to do is have the subclasses only check the locations for which they add bricks. So remove the (0,5) and (1,5) bricks from the TetrisBlockO constructor and also the corresponding bits of the if statement.

  9. #9
    BJ1110 is offline Member
    Join Date
    Oct 2009
    Posts
    13
    Rep Power
    0

    Default

    Unfortunately, I've already tried that, and the results are what I'm giving now. The program simply is unable to reach the TetrisBlockO class or its constructor, because for some reason, the program is trying to run through the TetrisBlock constructor more than one time, and because of that, it runs the detections for blocks which were already placed, but haven't moved twice, causing a game over each time.

    I realize that that is the problem, but I don't know what I could do to make it stop running through the TetrisBlock constructor more than once.

    And yes, that line is supposed to be TetrisBrick as opposed to TetrisBlock.

  10. #10
    BJ1110 is offline Member
    Join Date
    Oct 2009
    Posts
    13
    Rep Power
    0

Similar Threads

  1. Need help with a construction of a tree of objects
    By macwadu in forum AWT / Swing
    Replies: 5
    Last Post: 08-09-2010, 10:48 AM
  2. Need gridworld help
    By robertbob in forum New To Java
    Replies: 2
    Last Post: 05-03-2010, 05:18 PM
  3. AVL-tree construction
    By student89 in forum Advanced Java
    Replies: 0
    Last Post: 10-27-2008, 05:33 AM
  4. How to know when a thread ends.
    By new_2_java in forum New To Java
    Replies: 8
    Last Post: 10-24-2008, 11:22 AM
  5. Does any file in an FTP server ends up in an HTTP server?
    By islamfunny in forum CLDC and MIDP
    Replies: 4
    Last Post: 08-15-2008, 04:30 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •