联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp

您当前位置:首页 >> C/C++编程C/C++编程

日期:2019-12-17 11:20

BlockuDoku is a block puzzle game getting popular recently. The main goal of the game is to

match blocks of different shapes to complete lines and squares to get them removed from a

9x9 grid board. Download our provided zip of source files that implement a C++ console

program simulating this game. Most of the program is already written. Your task is to finish a

few missing functions. We will explain the components used in the game below.

1. Board: The game board is a grid of 9 rows and 9 columns. We use row index 1-9 and

column index A-I to uniquely identify every cell on the board. For example, 2H and 5E are

the cell addresses of the indicated cells in the diagram below.

(1) (2) (3)

2. Blocks: they are building blocks to be placed onto the board, each of which has a given

shape. For each move, the player is presented with 3 random choices of blocks, and

should pick one to drop onto the board. Each successful move will score some basic

points that equal the number of tiles (or grid points) of a block. In the above diagram,

placing block (1) [vertical bar of 5 grid points] on the board scores 5 points while placing

block (3) gets 4 points. Extra points are rewarded if a move fills up a line or square.

3. Line: a group of 9 cells arranged in a vertical or horizontal

line. This game ignores diagonal lines. Filling up a line will

score 9 x 2 = 18 extra points. A line, once filled up, will be

destroyed, i.e. removed from the board. An example on

the right illustrates how a line isformed. The player places

block (2) on the board filling the gap at cell 6A. The whole

column A gets filled, i.e. a vertical line is formed, scoring

18 extra points. All the 9 cells of column A will be unfilled

right away to free space for new blocks.

4. Square: a group of 3x3 cells at specific locations. Filling up a square will score 9 x 2 = 18

extra points. Just like a line, a square, once filled up, will be destroyed. Note that there

are only 9 valid squares for scoring on the board as shown below:

They are numbered with indices 0 to 8. A square is obtained if all the 9 cells under one of

the above numbered squares are filled. Filling up 3x3 cells at locations other than the

above does not get a square and scores no points. On the left diagram below, if the player

drops block (1) at 1B, the top 3 cells of columns B, C and D (a square shape) are filled. But

this 3x3 cell group is not one of the 9 designated squares. So, it is not counted as a scoring

square. On the right diagram, if the player places block (1) at 1G, this will fill up the top 3

cells of columns G, H and I. This gets the designated square 2, scoring 18 extra points.

5. Combo: a combo is achieved if several elements (e.g. two lines, or two squares, or one

line and one square) are destroyed at once. A move getting a combo will score 50 bonus

points besides the basic points from the block and extra points from the elementsformed.

For example, on the left diagram below, placing block (2) at cell 1A gets two lines (row 1

and column A) at the same time, scoring total 1 + 2 x 18 + 50 points. On the right diagram,

placing block (3) at the indicated position gets two squares and one line (square 1 and

square 2 and row 1) at once, scoring total 5 + 3 x 18 + 50 points.

6. Streak: a streak is achieved if elements (lines or squares) are destroyed in two or more

consecutive moves. Assume that the k-th move has destroyed an element. If the (k+1)-th

move destroys another element, this will score 30 bonus points. If the (k+2)-th move also

destroys an element, this leads to 60 bonus points. The next will score 90 and so on until

a move fails to destroy any elements; bonus points will be reset to zero. A new streak will

score 30 bonus points again. Combo and streak can be obtained at the same move.

Simulating BlockuDoku using C++

A B C D E F G H I

As our program output is text-based, the board is represented by a 9x9 2D array of 1’s and

0’s which denote filled and empty cells respectively. When the board is printed to the screen,

a space instead of 0 gets printed for an empty cell for ease of viewing. Likewise, a block is

represented by a 5x5 2D array of 1’s and 0’s where 1’s denote its solid grid points.

There are two classes Board and Block encapsulating the core data and functionality for this

program.

Board class:

? Data members:

o int grid[9][9]: the 2D array of integers representing the game board;

o int score: the current score obtained by the player;

o int streak: a counter recording the level of streak achieved so far;

? Member functions:

o for printing the board, moving a block onto the board, updating score, checking if a

move is valid at a given location, checking if a move is valid on the board by scanning

all locations, counting number of lines (or squares) formed, deleting all lines (or

squares) formed, checking if the game is over (i.e. no more valid moves possible)

Block class:

? Data members:

o int rows: number of rows taken by the shape;

o int cols: number of columns taken by the shape;

o int grid[5][5]: the 2D array of integers representing the block shape;

o int value: the number of grid points (how many 1’s in grid);

o bool placed: a flag indicating if this block has been placed onto the board;

? Member functions:

o for printing the block, getting rows, cols, and value, getting and setting placed,

returning the value (1 or 0) of a grid point of the block at a specific position

The Block.h header file has predefined S (= 45) blocks of different sizes and shapes using

two constant arrays: SIZE[S][2] and SHAPE[S][25]. The Block() constructor will pick

randomly one of the S elements in these arrays to construct a Block object. For example, a

T-shaped block below is represented by a Block object with content below.


The grid array (5x5) of a Block object can support up to 5 rows and 5 columns but for most

shapes, only a subset of which is used. The unused array elements are initialized to zeros.

Block object:

int rows = 2;

int cols = 3; 0 1 0 0 0

int grid[5][5]; 1 1 1 0 0

int value = 4; 0 0 0 0 0

bool placed = false; 0 0 0 0 0

0 0 0 0 0

3 cols

2 rows

7

Block Placements (Moves)

Placing a block x at a specified cell address on the board means matching the top left corner,

i.e. x.grid[0][0], of the block to the cell. See illustrations below to understand this.

For block (1), note that it can’t be placed at location 8B because we count from the top left

corner of the block. Putting it at 8B will cause a conflict (overlapping 1’s) at cell 9D which

contains value 1 already. Block (1) can be put at location 8A however to destroy column A. Its

grid[0][0] is 0 (shown as a blank) and can overlap with cell 8A (whose value is 1). For block

(2) – a diagonal shape of 3 grid points, the only valid positions for placing it are 7F and 7G.

A Snapshot of Sample Run

Below is a snapshot of a sample run. For ease of understanding, we highlighted some areas

of the output in colour while the real output to the console screen has no colour. Please refer

to our provided sample run log files and the sample program executable to understand the

correct behaviour of this program. Note that the random number sequences generated by

different compilers (Visual Studio on Windows vs. XCode on Mac) for the same seed could be

different, thus different blocks may be presented across different platforms.

Score: 128

Choose which block to drop [2][3]: 2

Invalid choice!

Choose which block to drop [2][3]: 3

Enter position to drop ([1-9][A-I]): 1d

Got a combo: +50

Cleared 1 line(s): +18

Cleared 1 square(s): +18

Score: 222

Note that at some later stage of a game run, the board

may run out of sufficient space to let some blocks in.

Block (2) in this case is such an example. Since it is unfit

to the board, we show a special mark "[X]" next to it to

indicate that it is an invalid choice at the moment. The

player must choose block (3) instead in this case to let

the game continue. If placing block (3) can clear some

lines or squares freeing the space needed, then block (2)

will become a valid choice again for the next move.

For the column index, typing

lower case or upper case does

not matter.

… (skipped the rest of output)

Programming Tasks

Based on the above problem specification, complete the game program by implementing the

following member functions in Board.cpp. Apart from adding these member functions,

don’t change any other parts of our provided source code (including the header files).

(a) bool move(Block &block, char pos[]); (25%)

Simulates placing the specified block at the given cell address on the game board. The

grid array of this Board object is updated to reflect the block placement. It accepts two

parameters:

1. block: a Block object chosen by the player

2. pos[]: a 2-element array denoting the cell address, e.g. {'1','A'}

It returnstrue if block can be placed at the location denoted by pos and false otherwise.

Now block (2) becomes a valid choice again.

10

Steps to do in this function:

1. Translate the cell address to grid array indexes (r, c), e.g. 1A → (0,0), 3D → (2,3). This

step has been done for you. Finish the rest under the TODO comment in move().

2. Check whether the move of the block is valid at (r, c). Hint: think of which member

function can help, and just call it.

3. If valid, copy the block's grid onto the board's grid. The block's grid[0][0] (the

block's top left corner) should match with the board's grid[r][c] (i.e. the specified

cell address). Note: don't overwrite the existing 1's in the board’s grid array.

4. Check for any lines and squares formed due to this move.

o To get the count of lines, call countLines(), passing two 1D bool arrays of size

9 for marking which of the 9 rows and 9 columns have line(s).

o To get the count of squares, call countSquares(), passing one 1D bool array

of size 9 for marking which of the 9 designated squares are formed.

o Delete line(s) and square(s), if any, based on the marked bool arrays.

5. Update the score for the move by calling updateScore(), passing the block object,

the counts of lines and squares obtained from the last step.

(b) bool isMoveValid(Block &block, int r, int c) const; (20%)

Checksif a move (block placement) is valid at location (r, c). It returnstrue if the specified

block can be placed at (r, c) on the board, and false otherwise.

Suppose the block has y rows and x columns, and its top left corner is placed at (r, c).

The move is invalid (return false)

? if r or c exceeds the range of the board’s grid array indexes (0 – 8);

? if (r + y) or (c + x) exceeds the board’s width or height, i.e. some grid points of the

block are outside the board area;

? if any grid point of the block is 1 while the overlapping point on the board's grid is

already 1, i.e. a conflict.

If no such cases are found, the move is valid (return true).

(c) void deleteLines(bool rows[], bool cols[]); (10%)

Deletes the row(s) and column(s) indicated by rows[] and cols[] by changing all their

corresponding elements in board’s grid array from 1 to 0. For instance, if rows[2] is true,

all elements of the 3rd row of the board’s grid will be set to 0. The caller should pass a

1D bool array of size 9 with all elements initialized to zero for each of the parameters.

(d) int countSquares(bool squares[]) const; (15%)

Scansthe board’s grid array for any squares formed, and marks which of the 9 designated

squares are formed by setting the corresponding element(s) in squares[] to true. It

returnsthe total number of squares found. The caller should pass a 1D bool array of size

9 with all elements initialized to zero.

- The End -


版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp