The beauty of programming 1.17-tetris games

Source: Internet
Author: User

Problem:
Let the computer automatically go to The Tetris game.

Solution:
For the current building block, enumerate each shape after it is rotated from the board of each column, compare the board with the previous one, and score, finally, the shape with the highest score and the column are used as the current operation of the computer. (Since some readers do not use this program, it indicates that file redirection is required to run this program. <41017.txt, you can also change the console input scanf in the program to a FILE input FILE * fin = fopen ("42517.txt"); fscanf (fin, "% d ",...);)

[Cpp]
# Include <iostream>
# Include <algorithm>
# Include <cstdlib>
# Include <ctime>
Using namespace std;
 
// Block information
# Define BLOCK_SIZE 7
# Define ROTATE_SIZE 4
# Define SIDE_LEN 4
Const int BLOCK_AREA = SIDE_LEN * SIDE_LEN;
// Information of the Board
# Define HORIZ_LEN 12
# Define VERT_LEN 15
Const int CHESS_AREA = HORIZ_LEN * VERT_LEN;
// Other information
# Define TOP_STEP 25
# Define inf 10000
// Scoring Information
Const int clearLineScore [] = {0, 1, 3, 7, 13 };
 
Struct Block // Block
{
Void init (unsigned char * l)
{
Memcpy (layout, l, BLOCK_AREA );
Int I, j;
For (I = 0; I <SIDE_LEN; I ++)
{
For (j = SIDE_LEN-1; j> = 0 & layout [j * SIDE_LEN + I] = 0; j --);
MaxRow [I] = j + 1;
}
For (I = 0; I <SIDE_LEN & maxRow [I] = 0; I ++ );
MinCol = I;
For (I = SIDE_LEN-1; I> = 0 & maxRow [I] = 0; I --);
MaxCol = I;
}
Unsigned char layout [BLOCK_AREA]; // Block layout
Unsigned char maxRow [SIDE_LEN]; // The largest row of the region occupied by each column in the block. The value starts from 1.
Unsigned char minCol; // The minimum and maximum columns of the area occupied by the block. The value starts from 0.
Unsigned char maxCol;
};
 
Block blockSet [BLOCK_SIZE] [ROTATE_SIZE]; // 7 blocks, each of which has four rotation directions
Unsigned char chess [CHESS_AREA]; // board Layout
Unsigned char nextChess [CHESS_AREA]; // layout of the next checkboard
Int height [HORIZ_LEN]; // the smallest row of the area occupied by each column on the board, that is, the height.
 
Void calcHeight (unsigned char * curchess) // calculate the height of the current Board
{
Int I, j;
For (I = 0; I <HORIZ_LEN; I ++)
{
For (j = 0; j <VERT_LEN & curchess [j * HORIZ_LEN + I] = 0; j ++ );
Height [I] = j;
}
}
 
// Calculate the number of rows in which the block falls from the offsetX column, that is, offsetY
Int calcBottomOffsetY (const Block & B, int offsetX)
{
Int offsetY = VERT_LEN;
For (int I = 0; I <SIDE_LEN; I ++)
{
If (B. maxRow [I] = 0) continue;
OffsetY = min (offsetY, height [offsetX + I]-B. maxRow [I]);
}
Return offsetY;
}
 
// Mount the block to the board
Void pasteTo (unsigned char * curchess, const Block & B,
Int offsetX, int offsetY)
{
For (int I = B. minCol; I <= B. maxCol; I ++)
For (int j = 0; j <SIDE_LEN; j ++)
{
Unsigned char bij = B. layout [j * SIDE_LEN + I];
Unsigned char & cij = curchess [(j + offsetY) * HORIZ_LEN + I + offsetX];
If (bij & cij = 0)
Cij = bij;
Else if (bij & cij)
Cout <"ERROR" <endl;
}
}
 
// Delete the rows whose remline is 1 in [offsetY, offsetY + SIDE_LEN)
Void clearLines (unsigned char * curchess, int offsetY, unsigned char * remline)
{
Int I, j, gap = 0;
For (j = offsetY + SIDE_LEN-1; j> = 0; j --)
{
If (j-offsetY> = 0 & remline [j-offsetY])
Gap ++;
Else if (gap)
{
Memcpy (curchess + (j + gap) * HORIZ_LEN, curchess + j * HORIZ_LEN, HORIZ_LEN );
}
}
}
 
// Calculate the number of holes in the [offsetX, offsetX + SIDE_LEN) Column
Int calcHoles (unsigned char * curchess, int offsetX, int offsetY)
{
Int I, j;
Int holeCount = 0;
For (I = offsetX; I <offsetX + SIDE_LEN; I ++)
{
If (I <0 | I> = HORIZ_LEN) continue;
For (j = offsetY; j <VERT_LEN & curchess [j * HORIZ_LEN + I] = 0; j ++ );
For (; j <VERT_LEN; j ++)
If (curchess [j * HORIZ_LEN + I] = 0)
HoleCount ++;
}
Return holeCount;
}
 
// Calculate the score of the current chessboard
Int calcScore (unsigned char * curchess, int offsetX, int offsetY)
{
Int I, j, score = 0;
Int remlineCount = 0;
Unsigned char remline [SIDE_LEN] = {0 };
// Count the number of lines deleted
For (j = offsetY; j <offsetY + SIDE_LEN; j ++)
{
For (I = 0; I <HORIZ_LEN & curchess [j * HORIZ_LEN + I]; I ++ );
If (I = HORIZ_LEN)
{
RemlineCount ++;
Remline [j-offsetY] = 1;
}
}
Score + = clearLineScore [remlineCount];
// Count the number of holes
If (remlineCount)
ClearLines (curchess, offsetY, remline );
Int holeCount = calcHoles (curchess, offsetX, offsetY )-
CalcHoles (chess, offsetX, offsetY );
Score-= holeCount * 4;
// If the position is too high, the score is deducted.
If (holeCount> 5) score-= 15;
If (offsetY-remlineCount <VERT_LEN * 3/5)
Score-= VERT_LEN * 3/5-(offsetY-remlineCount );
Return score;
}
 
Void output (unsigned char * curchess)
{
For (int j = 0; j <VERT_LEN; j ++)
{
For (int I = 0; I <HORIZ_LEN; I ++)
Cout <curchess [j * HORIZ_LEN + I] <"";
Cout <endl;
}
}
 
Int main ()
{
Srand (time (0 ));
Int I, j, k, n, m;
// Initialize the block
For (I = 0; I <BLOCK_SIZE; I ++)
For (j = 0; j <ROTATE_SIZE; j ++)
{
Unsigned char l [BLOCK_AREA];
For (k = 0; k <BLOCK_AREA; k ++)
Scanf ("% d", & l [k]);
BlockSet [I] [j]. init (l );
}
// Initialize the chessboard
For (I = 0; I <CHESS_AREA; I ++)
Scanf ("% d", & chess [I]);
// Display the previous TOP_STEP
Int offsetX, offsetY;
Unsigned char tmpchess [CHESS_AREA];
For (n = TOP_STEP; n> = 0; n --)
{
Output (chess );
CalcHeight (chess); // calculate the height array for each step to avoid excessive repeated calculations when offsetY is calculated.
Int bind = rand () % BLOCK_SIZE; // the serial number of the block.
Int maxScore =-inf;
For (j = 0; j <ROTATE_SIZE; j ++) // you need to consider the rotation of blocks.
{
Const Block & B = blockSet [bind] [j]; // obtain the current Block
For (offsetX =-B. minCol; offsetX <HORIZ_LEN-b.maxCol; offsetX ++)
{
// Calculate the offsetY position that falls from the offsetX column on the board.
OffsetY = calcBottomOffsetY (B, offsetX );
If (offsetY <0) continue;
Memcpy (tmpchess, chess, CHESS_AREA );
PasteTo (tmpchess, B, offsetX, offsetY); // Add a block to the board
Int curScore = calcScore (tmpchess, offsetX, offsetY); // calculate the current score
If (curScore> maxScore)
{
MaxScore = curScore; www.2cto.com
Memcpy (nextChess, tmpchess, CHESS_AREA );
}
}
}
Memcpy (chess, nextChess, CHESS_AREA );
}
}


 

Author: linyunzju

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.