Public feed #889789

Something

public cpp v1 · immutable
Raw Edit
·published 2008-02-03 05:34 UTC
rendered paste body
// tetromino.h#pragma once#ifndef ROTAERK__TETRIS__TETROMINO_H#define ROTAERK__TETRIS__TETROMINO_H#include <boost/array.hpp>namespace rotaerk{	namespace tetris	{		// A tetromino is a set of 4 blocks chained together into a shape fit into a grid.		// These blocks occupy cells in the grid, and one of those cells is the tetromino's		// center, or origin.  Thus all the blocks are specified in terms of the offsets of		// their cells with respect to the origin.  The offsets of all four blocks are		// together called the tetromino's block configuration.		// A tetromino can be pseudo-rotated, in that it is not true rotation around an axis,		// but rather a cycle through a set of block configurations.  These block		// configurations are the orientations across which the tetromino rotates.		struct tetromino		{			enum shape			{ J_SHAPE			, L_SHAPE			, T_SHAPE			, I_SHAPE			, S_SHAPE			, Z_SHAPE			, O_SHAPE			, FIRST_SHAPE = J_SHAPE			, LAST_SHAPE = O_SHAPE			};			// The offset of a cell relative to the origin.			// +X is to the right, and +Y is upwards.			struct cell_offset			{				signed char X, Y;			};			// The offsets of the tetromino's 4 blocks.			typedef boost::array< cell_offset, 4 > block_configuration;			tetromino( shape Shape );			shape get_shape() const;			block_configuration const * get_block_configuration() const;			void rotate_to_next_orientation();			void rotate_to_prev_orientation();		private:			struct shape_data			{				unsigned int NumOrientations;				block_configuration const * Orientations;			};			static shape_data get_shape_data( shape Shape );			shape Shape;			shape_data ShapeData;			unsigned int OrientationIndex;		};	}}#endif// tetromino.cpp#include "tetromino.h"#include <cassert>#include <boost/array.hpp>namespace rotaerk{	namespace tetris	{		namespace		{			// The orientations through which the tetromino rotates.			template< unsigned int NumOrientations >			struct orientation_cycle			{				boost::array< tetromino::block_configuration, NumOrientations > Orientations;			};		}		tetromino::tetromino( shape Shape )			: Shape( Shape )			, ShapeData( get_shape_data( Shape ) )			, OrientationIndex( 0 )		{		}		tetromino::shape tetromino::get_shape() const		{			return Shape;		}		tetromino::block_configuration const * tetromino::get_block_configuration() const		{			assert( ShapeData.Orientations != NULL );			assert( OrientationIndex < ShapeData.NumOrientations );			return ShapeData.Orientations + OrientationIndex;		}		void tetromino::rotate_to_next_orientation()		{			std::size_t NextOrientationIndex = ( OrientationIndex + 1 ) % ShapeData.NumOrientations;			assert( NextOrientationIndex < ShapeData.NumOrientations );			OrientationIndex =  NextOrientationIndex;		}		void tetromino::rotate_to_prev_orientation()		{			std::size_t NextOrientationIndex = ( OrientationIndex + ShapeData.NumOrientations - 1 ) % ShapeData.NumOrientations;			assert( NextOrientationIndex < ShapeData.NumOrientations );			OrientationIndex =  NextOrientationIndex;		}		tetromino::shape_data tetromino::get_shape_data( shape Shape )		{			static orientation_cycle< 4 > const JOrientationCycle =			{				{{					{{  {  1, -1 }, {  1,  0 }, {  0,  0 }, { -1,  0 }  }},					{{  { -1, -1 }, {  0, -1 }, {  0,  0 }, {  0,  1 }  }}, 					{{  { -1,  1 }, { -1,  0 }, {  0,  0 }, {  1,  0 }  }},					{{  {  1,  1 }, {  0,  1 }, {  0,  0 }, {  0, -1 }  }}				}}			};			static orientation_cycle< 4 > const LOrientationCycle =			{				{{					{{  { -1, -1 }, { -1,  0 }, {  0,  0 }, {  1,  0 }  }},					{{  { -1,  1 }, {  0,  1 }, {  0,  0 }, {  0, -1 }  }}, 					{{  {  1,  1 }, {  1,  0 }, {  0,  0 }, { -1,  0 }  }},					{{  {  1, -1 }, {  0, -1 }, {  0,  0 }, {  0,  1 }  }}				}}			};			static orientation_cycle< 4 > const TOrientationCycle =			{				{{					{{  {  0, -1 }, { -1,  0 }, {  0,  0 }, {  1,  0 }  }},					{{  { -1,  0 }, {  0,  1 }, {  0,  0 }, {  0, -1 }  }}, 					{{  {  0,  1 }, {  1,  0 }, {  0,  0 }, { -1,  0 }  }},					{{  {  1,  0 }, {  0, -1 }, {  0,  0 }, {  0,  1 }  }}				}}			};			static orientation_cycle< 2 > const IOrientationCycle =			{				{{					{{  { -1,  0 }, {  0,  0 }, {  1,  0 }, {  2,  0 }  }},					{{  {  0,  1 }, {  0,  0 }, {  0, -1 }, {  0, -2 }  }}				}}			};			static orientation_cycle< 2 > const SOrientationCycle =			{				{{					{{  {  1,  0 }, {  0,  0 }, {  0, -1 }, { -1, -1 }  }},					{{  {  0,  1 }, {  0,  0 }, {  1,  0 }, {  1, -1 }  }}				}}			};			static orientation_cycle< 2 > const ZOrientationCycle =			{				{{					{{  { -1,  0 }, {  0,  0 }, {  0, -1 }, {  1, -1 }  }},					{{  {  0,  1 }, {  0,  0 }, { -1,  0 }, { -1, -1 }  }}				}}			};			static orientation_cycle< 1 > const OOrientationCycle =			{				{{					{{  {  0,  0 }, {  1,  0 }, {  1, -1 }, {  0, -1 }  }}				}}			};			std::size_t OrientationsSize = 0;			block_configuration const * Orientations = NULL;			switch( Shape )			{			case J_SHAPE:				OrientationsSize = JOrientationCycle.Orientations.size();				Orientations = JOrientationCycle.Orientations.data();				break;			case L_SHAPE:				OrientationsSize = LOrientationCycle.Orientations.size();				Orientations = LOrientationCycle.Orientations.data();				break;			case T_SHAPE:				OrientationsSize = TOrientationCycle.Orientations.size();				Orientations = TOrientationCycle.Orientations.data();				break;			case I_SHAPE:				OrientationsSize = IOrientationCycle.Orientations.size();				Orientations = IOrientationCycle.Orientations.data();				break;			case S_SHAPE:				OrientationsSize = SOrientationCycle.Orientations.size();				Orientations = SOrientationCycle.Orientations.data();				break;			case Z_SHAPE:				OrientationsSize = ZOrientationCycle.Orientations.size();				Orientations = ZOrientationCycle.Orientations.data();				break;			case O_SHAPE:				OrientationsSize = OOrientationCycle.Orientations.size();				Orientations = OOrientationCycle.Orientations.data();				break;			default:				assert( ( "Unhandled tetromino shape.", false ) );			}			shape_data ShapeData = { static_cast< unsigned int >( OrientationsSize ), Orientations };			return ShapeData;		}	}}