Copy Array onto a larger array?

BlitzMax Forums/BlitzMax Programming/Copy Array onto a larger array?

Yahfree(Posted 2010) [#1]
Hey, I'm making a Tetris clone, (for the first time :D)

How would I copy a defined 4x4 peice array (for example):


Onto a larger tile map, (the screen):
Global Screen:Int[25, 24]


That way I can just loop through the screen and draw the tiles.

Thanks!


Scaremonger(Posted 2010) [#2]
In Tetris, I seem to remember there are 7 tiles of 5x5 blocks. Each Tile pivots in the center (5x5 allows the 1x4 block to rotate correctly), although I like the idea of a 4x4.

To position a piece on the screen you'll need a function that takes the position of the Tile relative to the scren array, the tile, and the tile orientation. A nested loop will be required to map the pieces onto the screen a square at a time.


Czar Flavius(Posted 2010) [#3]
As wierd as it might sound, it can be better to store shapes as a list of points rather than a 2d array as it wastes less space, but it can get complicated and what's a few bytes on a modern computer? :P

A hint - there's no need to store 4 different variations for each rotation. Just store the piece in one rotation, and then when you create a new piece to use, rotated it 0-3 times randomly.

For your screen grid, you can store the colour code of whichever block occupies that space. Give each possible colour a unique id constant.. eg Red is 1, Green is 2, and leave 0 for Empty. Update your arrays so that instead of just 1s, they'll have the number that corresponds to their colour. So if you want the Z piece as Green, give it 2s.

To place a piece on the grid, use double nested for loops.

Const Empty:Int = 0, Red:Int = 1 '.......
'......
Function PlacePiece:Int(atX:Int, atY:Int, Piece:Int[,])
	For X = 0 Until 4
		For Y = 0 Until 4.
			If Piece[X, Y] <> Empty And Screen[atX + X, atY + Y] <> Empty
				'you are trying to place a piece where one already exists!
				Return False
			End If
		Next
	Next
	For X = 0 Until 4
		For Y = 0 Until 4
			'copy over the piece's colour info to the grid
			If Piece[X, Y] <> Empty ' you don't want to overwrite any other pieces nearby with Empty's
				Screen[atX + X, atY + Y] = Piece[X, Y]
			End If
		Next
	Next
	'Piece placed successfully
	Return True
End Function

You can use this to easily check for losing. When placing the next piece at the top of the board, if this function returns False, there is no space and the player has lost!

Remove a piece in the same way. It doesn't do any checks, so if the piece is not in fact there it could mess up the grid. None of the functions also check that the target coordinates are on the grid either. That's for you to worry about :)
Function RemovePiece(atX:Int, atY:Int, Piece:Int[,])
	For X = 0 Until 4
		For Y = 0 Until 4.
			If Piece[X, Y] <> Empty Then Screen[atX + X, atY + Y] = Empty
		Next
	Next
End Function


How to move a piece? Don't create a complex collision checking algorithm as you try to move each individual block down one at time! This lazy way is better :)
1. Remove the piece from the board.
2. Try to place the piece 1 downwards (for gravity, but you can use any new location)
3. If that fails, replace at original location.
Function MovePiece:Int(atX:Int, atY:Int, toX:Int, toY:Int, Piece:Int[,])
	RemovePiece(atX, atY, Piece)
	If Not PlacePiece(toX, toY, Piece)
		'cannot place here, put back
		PlacePiece(atX, atY, Piece)
		Return False
	Else
		'placed in new location
		Return True
	End If
End Function


You can rotate using the same method. Pick up, rotate, attempt to place down. If this fails, reverse the rotation so it's back to how it was, and replace in the old location.

Ok this should get you started. If you need more help, just ask :)

Disclaimer: code above writen fresh and therefore untested!


Yahfree(Posted 2010) [#4]
alright, I went with a data route.... but I'm having some problems.. when the piece rotates near the edge of the screen it goes out of bounds sometimes, the obvious answer would be to test where it goes before putting it there..

Another weird thing which I don't know the answer to is this weird effect when I use different pieces (I was testing with just the L piece).


Here's my code:



And my peice data: