This is a fun little Tetris implementation! I wrote this in C++ using the SFML framework. Silly graphics courtesy of my talented little sister.

If you’ve ever tried to program Tetris, you probably found that programming wall kicks was the most difficult part. Wall kicks are what happens when you try to rotate a piece near a wall and have to account for the wall’s location in your rotation. The Tetris wiki was a fascinating and invaluable resource for programming the minute details of Tetris logic. To handle wall kicks, I created a class called WallKickOffset which basically stores a 2d vector. Creating a 3d array of WallKickOffsets allowed me to individually set the kicking pattern for each Tetris piece. The following code is the wall kick algorithm.

// WALL KICK IMPLEMENTATION
		
for (int i = 1; i <= 5; i++) {
	bool okay = true;
	for (int j = 0; j < 4; j++) {
		int blockFilledIndex = (SCREEN_HEIGHT - (blockList[j].y + TILE_SIZE)) / TILE_SIZE;
		if (blockList[j].x >= SCREEN_WIDTH || blockList[j].x < 0 || blockList[j].y >= SCREEN_HEIGHT) {
			okay = false;
		}
		else for (int k = 0; k < blockFilledRows[blockFilledIndex].size(); k++) {
			if ((blockList[j].x == blockFilledRows[blockFilledIndex][k].x && blockList[j].y == blockFilledRows[blockFilledIndex][k].y) ) {
				okay = false;
			}
		}
	}
	if (okay) {
		curForm = desiredForm;
		return;
	}
	else if (i < 5) {
		WallKickOffset transform = wkOffsets[type][curForm][i].getOffset(wkOffsets[type][desiredForm][i]);
		int xOffset = transform.x * TILE_SIZE;
		int yOffset = transform.y * TILE_SIZE;
		for (int j = 0; j < 4; j++) {
			blockList[j] = IRBL[j];
			blockList[j].x += xOffset;
			blockList[j].y -= yOffset;
		}
	}
}

Basically, the algorithm checks if the Tetris piece is overlapping with a wall or another static piece after rotation. If it is overlapping with something, then we dig into my 3d array of wall kick offsets in order to kick the piece in a set direction. If the piece continues to overlap with something, we keep trying each available wall kick which is specific to each piece. If we run out of wall kicks then the piece is determined to be unable to rotate, resigned to its fate.

Back to Projects…