Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

*Java Assignment Help - Falling blocks puzzle game* I am struggling with this assignment, any help would be greatly appreciated. In the game, random pieces

*Java Assignment Help - Falling blocks puzzle game*

I am struggling with this assignment, any help would be greatly appreciated.

In the game, random pieces will fall from above into a well of dimensions 10x20, and as the piece falls, the player must guide the piece into a suitable landing spot by either moving it left or right, or rotating it left or right. The player may also decide to instantly drop the piece onto the landing spot below. Blocks that have landed in the well will stack on top of each other. If the stack becomes so high that the next piece to fall from above cannot fit into the well, the game is over. The player can survive longer by completing rows of 10 blocks. If any row of 10 blocks is formed after a piece lands, those rows of blocks will be cleared and every row above the deleted row will be shifted down one position. The player can survive the game longer by carefully stacking blocks into rows of 10 so that the stack never reaches too high.

Each Block represents one square of a piece and has a color and a points value. Each Piece is composed of 4 blocks. A PieceFactory randomly generates pieces of the 7 different types. A Well is composed of a 10x20 storage array into which pieces fall. The currently falling piece is called the activePiece. The Screen provides methods for drawing pixels to the screen. Main is the main class used to start the application.

Task 1: Piece.clone Class Piece is composed of a 4x4 array of blocks. Your task is to implement the clone() method of class Piece to create a new Piece which is an identical copy of the original piece. That is, every element of the old 4x4 array must be copied into the 4x4 array of the new piece. The code has been started for you, and you need to complete the code. Submit to plate now, and after each subsequent task, to receive feedback and marks.

Task 2: Well constructor

The well contains a 2-dimensional array into which falling blocks will be placed and stacked. The usable region of this array for the player is a 10x20 area. However, the actual array must be defined to be of size 12x22. This is to allow an extra column on each side and an extra row on the top and bottom which will be used to represent a wall around the well. Implement the Well constructor to do the following: 1. Create and initialise the wells PieceFactory. 2. Initialise the activePiece to null. 3. Create the grid of size 12x22. 4. Using a loop, fill the the left and right column and also the top and bottom row with blocks to represent the wall. Each block should have color X and value 0.

Task 3: Piece.paint Class Screen provides methods to draw pixels onto the screen. (Actually, this class is implemented to display its output in a terminal window, and each pixel will be drawn as a character where different characters represent different colours). In the code pad, experiment by using the following methods: Screen.setPixel(x, y, color) and Screen.paint() and Screen.clear() Your task is to implement the paint() method of class Piece to loop over all of the blocks in the 4x4 array and set a corresponding pixel on the Screen for each block. Note that some elements of the array will be null, and only 4 of the elements will contain actual block objects. For each element in the array, only set a pixel on the screen if it is not null. For each block in the array at position row/col, you should set a pixel on the screen at position (x+col, y+row) in order to consider the current x and y position of the piece. For example, if a piece is at y position 7, then the first row (0) of the piece should be painted to the screen at y position 7, and the second row (1) of the piece should be painted at y position 8. The colour of the pixel should be set to the colour of the block you are currently painting to the screen. You can test if your code is correct in the BlueJ code pad by typing: PieceFactory factory = new PieceFactory(); Piece piece = factory.generateRandomPiece(); piece.paint(); Screen.paint(); Screen.clear();

Task 4: Well.paint Implement the paint() method of class Well to do the following: 1. Clear the screen 2. Loop over each element in the 12x22 grid in class Well, and for each element at position row/col, if a block exists at that location, draw it onto the screen using Screen.setPixel, at x position (col) and at y position (row). If no block exists at that location, instead set the pixel to _.

3. Paint the active piece onto the screen using the method you defined in the previous task 4. Paint the screen itself onto the terminal using Screen.paint().

Task 5: Piece.move and Piece.rotate Implement method move(dx, dy) of class Piece to change the current x,y position of the piece by adding the parameters dx and dy onto the fields x and y respectively. Implement the rotate(amount) method of class Piece to change the 4x4 array of blocks by moving each element to a new position rotated clockwise around the centre. The amount parameter specifies how far to rotate. To understand how this should work, assume that the rotation amount is 1. Then, if the 4x4 array initially contains the following: A1 A2 A3 A4 B1 B2 B3 B4 C1 C2 C3 C4 D1 D2 D3 D4 Then, your rotate method should rearrange the contents of this array by copying each element from its current position to a new position as follows: D1 C1 B1 A1 D2 C2 B2 A2 D3 C3 B3 A3 D4 C4 B4 A4 There are 16 blocks that need to be moved, and it suffices to use 16 individual variable assignments (without a loop) plus temporary variable assignments, to achieve this. Using a loop is allowed, but would be extremely difficult to work out, and so is not advised for the average student. NOW: This much is the result of rotating with an amount of 1. If the amount is greater than 1, you simply wrap a loop around your code to repeat this transformation amount times. Note that you should not need to check whether each block is null. Both nulls and actual blocks should be copied to their new positions in the same way.

Task 6: Well.haveTurn Implement method overlaps(grid) in class Piece to check if any block in the 4x4 piece overlaps with a block in the given 12x22 grid, taking into account the current x and y position of the piece relative to the grid. Your method should return true if there is an overlap, or false otherwise. The haveTurn() method of class Well is written to prompt the user to enter l to move left, r to move right, L to rotate left, R to rotate right, and d to drop the active piece immediately. To handle each case, these Well methods are used: move(dx, dy), rotate(amount) and drop(). Note that the former two are distinct from the methods you created in the previous step since they are defined in class Well.

Implement Well method move(dx, dy) to move the active piece by dx,dy. If after moving, the piece now overlaps with the grid, undo the move. This method should return true if it was able to move unobstructed, or false otherwise. Implement Well method rotate(amount) to rotate the active piece by the given amount. If after rotating, the piece now overlaps with the grid, undo the rotate. This method should return true if it was able to rotate unobstructed, or false otherwise. Implement Well method drop() to repeatedly move the piece down, 1 row at a time, until it hits a landing spot. Like above, use the overlaps() method to detect whether you have moved too far, and if so, undo the last move.

Task 7: Lock When a piece lands on the stack of blocks in the well, the piece must be locked. Method lock() of class Well should be invoked whenever this happens. Modify your drop() method from the previous task to lock the piece after it has landed. Several things must happen when a piece is locked. Implement the lock() method as follows: 1. Copy all of the blocks from the activePiece into the wells grid. 2. Detect any rows of 10 blocks in the grid and delete them. Each time a row is deleted, make sure all rows above it are moved down one position. 3. Generate a new random piece and set it as the activePiece 4. If the activePiece, upon creation, overlaps with the grid, set gameOver = true.

Given Code:

public class Piece { private int x; private int y; private Block[][] blocks; public Piece(Block[][] blocks) { x = 3; y = 1; this.blocks = blocks; } public Piece clone() { Block[][] blocks = new Block[4][4]; // insert code to copy each block // from this.blocks into blocks return new Piece(blocks); // create and return a piece with the copied blocks } public void rotate(int amount) { } public void move(int dx, int dy) { } public void paint() { } public boolean overlaps(Block[][] grid) { return false; } }

public class Screen { private static char[][] pixels; static { pixels = new char[22][25]; clear(); } public static void setPixel(int x, int y, char color) { if (y < 0 || y >= pixels.length) return; char[] scanline = pixels[y]; if (x < 0 || x >= scanline.length) return; scanline[x] = color; } public static void paint() { for (int row = 0; row < pixels.length; row++) { char[] scanline = pixels[row]; for (int col = 0; col < scanline.length; col++) { System.out.print(scanline[col] + " "); } System.out.println(); } } public static void clear() { for (int row = 0; row < pixels.length; row++) { char[] scanline = pixels[row]; for (int col = 0; col < scanline.length; col++) { scanline[col] = ' '; } } }

}

public class Main { public static void main(String[] args) { Well well = new Well(); well.play(); } }

import java.util.Scanner;

/** * Text mode falling blocks game. * * Copyright (C) 2012 Ryan Heise * @author Ryan Heise */ public class Well { public static final int ROWS=20; public static final int COLS=10; private static Scanner keyboard = new Scanner(System.in); private PieceFactory factory; private Piece activePiece; private Block[][] grid; private int time; private boolean gameOver; public Well() { } public void spawnNewPiece() { activePiece = factory.generateRandomPiece(); } public void play() { time = 0; gameOver = false; spawnNewPiece(); while (!gameOver) { paint(); haveTurn(); } System.out.println("Game over!"); } public void haveTurn() { System.out.print("Turn (l/r/L/R/d): "); String line = keyboard.nextLine(); if (line.length() > 0) { char command = line.charAt(0); switch (command) { case 'l': move(-1, 0); break; case 'r': move(1, 0); break; case 'L': rotate(3); break; case 'R': rotate(1); break; case 'd': drop(); break; default: System.out.println("Invalid command: " + command); break; } } time++; if (time % 4 == 0) { if (!move(0, 1)) lock(); } } public boolean rotate(int amount) { return true; } public boolean move(int dx, int dy) { return true; } private void drop() { } private void lock() { } private void paint() { } }

import java.util.Random;

public class PieceFactory { private Random rng = rng(); private static Random rng() { try { return new Random(Integer.parseInt(System.getenv("rand_seed"))); } catch (Exception e) { return new Random(); } } public static final Block _ = null; // No block public static final Block A = new Block('A', 1); public static final Block B = new Block('B', 1); public static final Block C = new Block('C', 1); public static final Block D = new Block('D', 2); public static final Block E = new Block('D', 2); public static final Block F = new Block('F', 2); public static final Block G = new Block('G', 2); private Piece[] templates = { createOPiece(), createIPiece(), createSPiece(), createZPiece(), createLPiece(), createJPiece(), createTPiece() }; public Piece generateRandomPiece() { int randomNumber = rng.nextInt(7); return templates[randomNumber].clone(); } private static Piece createOPiece() { Block[][] blocks = { {_,_,_,_}, {_,A,A,_}, {_,A,A,_}, {_,_,_,_}, }; return new Piece(blocks); } private static Piece createIPiece() { Block[][] blocks = { {_,_,_,_}, {B,B,B,B}, {_,_,_,_}, {_,_,_,_}, }; return new Piece(blocks); } private static Piece createSPiece() { Block[][] blocks = { {_,_,_,_}, {_,C,C,_}, {C,C,_,_}, {_,_,_,_}, }; return new Piece(blocks); } private static Piece createZPiece() { Block[][] blocks = { {_,_,_,_}, {D,D,_,_}, {_,D,D,_}, {_,_,_,_}, }; return new Piece(blocks); } private static Piece createLPiece() { Block[][] blocks = { {_,_,_,_}, {_,_,E,_}, {E,E,E,_}, {_,_,_,_}, }; return new Piece(blocks); } private static Piece createJPiece() { Block[][] blocks = { {_,_,_,_}, {_,F,_,_}, {_,F,F,F}, {_,_,_,_}, }; return new Piece(blocks); } private static Piece createTPiece() { Block[][] blocks = { {_,_,_,_}, {_,G,_,_}, {G,G,G,_}, {_,_,_,_}, }; return new Piece(blocks); } }

public class Block { private char color; private int value; public Block(char color, int value) { this.color = color; this.value = value; } public char getColor() { return color; } public int getValue() { return value; } public String toString() { return String.valueOf(color); } }

Step by Step Solution

There are 3 Steps involved in it

Step: 1

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Modern Database Management

Authors: Heikki Topi, Jeffrey A Hoffer, Ramesh Venkataraman

13th Edition

0134773659, 978-0134773650

Students also viewed these Databases questions