SlideShare a Scribd company logo
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
#include <sstream>
/* As Tetris runs on a standard 10x20 grid (displayed), each pixel has
width represented by a float value of 0.09f */
int score = 0;
int grid[10][22];
int nextPiece = 0;
int currShape[4][4];
int temp[4][4];
int horz = 0;
int vert = 0;
int ticks = 0;
int level = 1;
int gameOver = 0;
int gamePause = -1;
void drawWord(std::string word, int pos_x, int pos_y, float scale,
float red, float green, float blue) {
glColor3f(red, green, blue);
// Set the input color
glMatrixMode(GL_PROJECTION);
// Move into projection mode
glPushMatrix();
// push a matrix onto the stack
glLoadIdentity();
// load the identity matrix
glMatrixMode(GL_MODELVIEW);
// switch into model view
glPushMatrix();
// push a new matrix onto the stack
glLoadIdentity();
gluOrtho2D(0, 512, 0, 512);
// set our window co-ordinates
glTranslatef(pos_x, pos_y, 0.0f);
// translate by the inputted values
glScalef(scale, scale, 1.0f);
// scale based on inputted scale
int length = word.size();
// find the size of the word
for(int i=0; i<length; i++)
glutStrokeCharacter(GLUT_STROKE_ROMAN, word[i]);
//type out each letter in the word
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
// pop matrices in order to reset the changes and
complete function
}
std::string makeString(int value) {
std::stringstream convert;
convert << value;
return convert.str();
// convert an int into a string
}
void writeScore() {
// for each method, use drawWord to draw what we need
in this postion
drawWord("Score",390,400,0.3f,1.0f,0.0f,0.2f);
drawWord(makeString(score),390,365,0.2f,1.0f,1.0f,1.0f);
}
void writeLevel() {
drawWord("Level",390,256,0.3f,0.0f,0.5f,0.0f);
drawWord(makeString(level),430,225,0.2f,1.0f,1.0f,1.0f);
}
void drawNextPiece() {
float red = 0.0f;
float green = 0.0f;
float blue = 0.0f;
int nextGrid[4][4];
// reset the next piece tracker
for(int x = 0; x < 4; x++) {
for(int y =0; y < 4; y++) {
nextGrid[x][y] = 0;
}
}
switch(nextPiece) {
// based on our chosen next piece, fill in the relevant values in
our 4x4 array and set the colour
case 0: red = 1.0f; nextGrid[1][0] = 1; nextGrid[1][1] =
1; nextGrid[1][2] = 1; nextGrid[1][3] = 1; break;
case 1: blue = 1.0f; nextGrid[1][1] = 1;
nextGrid[1][2] = 1; nextGrid[2][2] = 1; nextGrid[2][1] = 1;
break;
case 2: green = 1.0f; red = 1.0f;
nextGrid[0][2] = 1; nextGrid[1][1] = 1; nextGrid[1][2] = 1;
nextGrid[2][1] = 1; break;
case 3: green = 1.0f; nextGrid[0][1] = 1;
nextGrid[1][1] = 1; nextGrid[1][2] = 1; nextGrid[2][2] = 1;
break;
case 4: red = 1.0f; green = 0.5f;
nextGrid[1][0] = 1; nextGrid[1][1] = 1; nextGrid[1][2] = 1;
nextGrid[2][0] = 1; break;
case 5: green = 1.0f; blue = 1.0f;
nextGrid[2][0] = 1; nextGrid[2][1] = 1; nextGrid[2][2] = 1;
nextGrid[1][0] = 1; break;
case 6: red = 0.5f; blue = 0.5f; nextGrid[0][1] =
1; nextGrid[1][1] = 1; nextGrid[2][1] = 1; nextGrid[1][2] = 1;
break;
}
for(int x = 0; x < 4; x++) {
// for each filled part of our 2d array, we draw a solid
cube and wire grid on screen
for(int y = 0; y < 4; y++) {
if(nextGrid[x][y] == 1) {
// As in drawGrid method, with alternate translation values (see
below)
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef((-
0.8125f+(x*0.075f)),(0.1375f+(y*0.075f)),0.0f);
glColor3f(red,green,blue);
glutSolidCube(0.075f);
glColor3f(0.0f,0.0f,0.0f);
glutWireCube(0.075f);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
}
}
}
}
void showNext() {
// we draw a box to enclose our nextPiece and draw the word and
piece required also
drawWord("Next",30,400,0.3f,0.0f,0.0f,1.0f);
glLineWidth(0.2f);
glColor3f(1.0f,1.0f,1.0f);
glBegin(GL_LINE_LOOP);
glVertex2f(-0.9f, 0.45f);
glVertex2f(-0.5f, 0.45f);
glVertex2f(-0.5f,0.05f);
glVertex2f(-0.9f,0.05f);
glEnd();
drawNextPiece();
}
void startGrid() {
// initialise a blank grid
for(int x = 0; x < 10; x++) {
for(int y = 0; y < 22; y++) {
grid[x][y] = 0;
}
}
}
void drawGrid() {
// draw our tetris board based on our 2d array
float red;
float green;
float blue;
for(int y = 0; y < 20; y++) {
for(int x = 0; x < 10; x++) {
red = 0.0f;
green = 0.0f;
blue = 0.0f;
switch(grid[x][y]) {
// set the colour based on the value of the array at this point
case 0: break;
case 1: red = 0.8f; green = 0.8f; blue =
0.8f; break;
case 2: red = 1.0f; break;
case 3: blue = 1.0f; break;
case 4: red = 1.0f; green = 1.0f; break;
case 5: green = 1.0f; break;
case 6: red = 1.0f; green = 0.5f; break;
case 7: green = 1.0f; blue = 1.0f;
break;
case 8: red = 0.5f; blue = 0.5f; break;
}
if(grid[x][y] != 0) {
// if we find a non-blank space, we must draw
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef((-0.405f+(x*0.09f)),(-
0.855f+(y*0.09f)),0.0f); // we translate by our bottom left
values corner for x and y, plus the change in x and y defined by the
array position
glColor3f(red,green,blue);
glutSolidCube(0.09f);
// we draw a solid cube of required colour, with single pixel
size
glColor3f(0.0f,0.0f,0.0f);
glutWireCube(0.09f);
// we then draw the black wire frame to show it as a pixel
glPopMatrix();
// we undo the translation by popping the matrix off the stack
glMatrixMode(GL_PROJECTION);
glPopMatrix();
}
}
}
}
void newPiece() {
nextPiece = rand() % 7;
// to randomly choose a piece, we pick a random number
between 0 and 6
}
void drawPiece() {
for(int y = 0; y < 20; y++) {
// this resets all non "dead-block" values in the board,
i.e. erases our live piece
for(int x = 0; x < 10; x++) {
if(grid[x][y] != 1)
grid[x][y] = 0;
}
}
for(int y = 0; y < 4; y++) {
// this then draws the piece into our 2d array, based on
the current shape array and the tracked vertical and horizontal
for(int x = 0; x < 4; x++) {
// values of our bottom left corner
if((horz+x >= 0) && (horz+x < 10) && (vert+y >= 0) && (vert+y <
20)) {
if(grid[horz + x][vert + y] != 1)
grid[horz + x][vert + y] = currShape[x][y];
}
}
}
}
void testGameOver() {
for(int y = 0; y < 4; y++) {
// if our piece is blocked from entering the grid, we state
it as game over
for(int x = 0; x < 4; x++) {
if((currShape[x][y] != 0) & (grid[horz + x][vert + y] == 1)) {
gameOver = 1;
gamePause = 1;
// we put the game into a state of pause to stop idle and user
input
}
}
}
}
void drawNewPiece() {
// this will add our next piece into our current piece array
for(int y = 0; y < 4; y++) {
// we first reset our current piece array
for(int x = 0; x < 4; x++) {
currShape[x][y] = 0;
}
}
switch (nextPiece) {
// then set the relevant values of our array
case 0: currShape[0][2] = 2; currShape[1][2] = 2;
currShape[2][2] = 2; currShape[3][2] = 2; break;
case 1: currShape[1][2] = 3; currShape[1][1] = 3;
currShape[2][2] = 3; currShape[2][1] = 3; break;
case 2: currShape[0][2] = 4; currShape[1][1] = 4;
currShape[1][2] = 4; currShape[2][1] = 4; break;
case 3: currShape[0][1] = 5; currShape[1][1] = 5;
currShape[1][2] = 5; currShape[2][2] = 5; break;
case 4: currShape[1][0] = 6; currShape[1][1] = 6;
currShape[1][2] = 6; currShape[2][0] = 6; break;
case 5: currShape[1][0] = 7; currShape[2][0] = 7;
currShape[2][1] = 7; currShape[2][2] = 7; break;
case 6: currShape[0][1] = 8; currShape[1][1] = 8;
currShape[2][1] = 8; currShape[1][2] = 8; break;
}
horz = 3;
// we must also reset the tracked position of our bottom left
corner
vert = 17;
testGameOver();
// we test if the piece can be inserted into our grid
if(gameOver == 0) {
drawPiece();
// if the piece can be drawn in, we add it to the board and
generate our new "next" piece
newPiece();
}
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
// we clear the display
glColor3f(1.0f, 1.0f, 1.0f); // set RGB values of colour to draw
glLineWidth(3.0f);
glBegin(GL_LINES);
// and draw the outline of the grid in white
glVertex2f(0.45f,0.9f);
glVertex2f(0.45f,-0.9f);
glVertex2f(0.45f,-0.9f);
glVertex2f(-0.45f,-0.9f);
glVertex2f(-0.45f,-0.9f);
glVertex2f(-0.45f,0.9f);
glEnd();
writeScore();
writeLevel();
showNext();
drawGrid();
drawWord("Press 'q' to quit, 'p' to pause and 'r' to
restart",120,10,0.1f,0.0f,1.0f,1.0f); // this adds some feature
instructions on the bottom of the screen
if(gameOver == 1) {
// if the game is over, draw this in
drawWord("Game",10,150,0.3f,1.0f,0.5f,0.0f);
drawWord("Over",25,120,0.3f,1.0f,0.5f,0.0f);
}
else if(gamePause == 1)
// if we are paused but not over, draw this in
drawWord("Paused",10,150,0.3f,1.0f,0.5f,0.0f);
else if(((ticks % 4500) <= 20) && (ticks > 20)) {
// if we are set to level up, show this message for 20
ticks
drawWord("Level",380,150,0.3f,0.3f,0.3f,1.0f);
drawWord("Up",400,100,0.3f,0.3f,0.3f,1.0f);
}
glutSwapBuffers();
}
int detect() {
// detect if a piece is colliding
int test = 0;
for(int y = 0; y < 20; y++) {
for(int x = 0; x < 10; x++) {
if((grid[x][y] != 0) & (grid[x][y] != 1)) {
// if we have found our live piece
if(y == 0) {
// if we have hit the floor, collision found
test = 1;
}
else if(grid[x][y-1] == 1) {
// if we are resting on a dead block, collision found
test = 1;
}
}
}
}
return test;
}
void removeRow(int y) {
// when a row is removed, this function grabs the rows
above to drop them down
for(int a = y; a < 19; a++) {
for(int x = 0; x < 10; x++) {
grid[x][a] = grid[x][(a+1)];
}
}
}
void testScore() {
// this tests for scoring rows
int change = 0;
// track the row changes
for(int y = 0; y < 20; y++) {
int test = 0;
for(int x = 0; x < 10; x++) {
if(grid[x][y] != 1)
// if we find a non-dead block, then we have no score for
this row
test = 1;
}
if(test == 0) {
// if this row scores, remove it, decrease y (to check row above
after change) and increase row change by 1
removeRow(y);
y--;
change++;
}
}
switch(change) {
// our score change is based on how many rows are removed
this sweep
case 1: score += (40*level); break;
case 2: score += (100*level); break;
case 3: score += (300*level); break;
case 4: score += (1200*level); break;
}
}
void idle() {
glutPostRedisplay();
// our idle function controls the display
if(gamePause == -1) {
// if we have not paused the game
ticks++;
// increase our number of ticks
if((ticks % 4500) == 0) {
// every 4500 ticks, increase the level to a maximum of 10
if(level < 10)
level++;
}
if((ticks % (int)(60/level)) == 0) {
// This controls the speed based on level. Every (60/level)
ticks, we move down a row
int count = 0;
int collision = detect();
if(collision == 0) {
// If we will not collide, decrease the y co-ord and draw
the piece into its new position
vert--;
drawPiece();
}
else {
for(int y = 0; y < 20; y++) {
// If we do collide, then turn each live piece into a dead
piece before resetting the collision
for(int x = 0; x < 10; x++) {
if((grid[x][y] != 0) & (grid[x][y] != 1)) {
grid[x][y] = 1;
count++;
if(count == 4)
collision = 0;
}
}
}
}
testScore();
// As a new dead block has been added, test to see if this scores
if(count == 4)
drawNewPiece();
// If we added a dead block, we need to draw in our new piece
}
}
}
void restart() {
// A restart function for the game, resetting all variables and
the board and pieces
level = 1;
score = 0;
gameOver = 0;
gamePause = -1;
startGrid();
newPiece();
drawNewPiece();
}
void drop() {
// A method to drop until we collide
int collision = 0;
int count = 0;
while(collision == 0) {
// Until we find a collision, continue to drop and update the
piece
vert--;
drawPiece();
collision = detect();
}
for(int y = 0; y < 20; y++) {
// Once we have the colision, turn our live piece into a
dead block
for(int x = 0; x < 10; x++) {
if((grid[x][y] != 0) & (grid[x][y] != 1)) {
grid[x][y] = 1;
count++;
if(count == 4)
collision = 0;
}
}
}
testScore();
// Again, we test score and draw in our new piece
drawNewPiece();
}
void keyboard(unsigned char key, int x, int y) {
// 4 functions. A quit, restart, piece drop and pause built
into the game
switch(key) {
case 'q': exit(1); break;
case 'r': restart(); break;
case ' ': if((gamePause == -1) && (detect() == 0)) drop();
break;
case 'p': if(gameOver == 0) gamePause*=-1; break;
}
}
int wallLeft() {
// Detect a block on the left
int test = 0;
for(int y = 0; y < 20; y++) {
for(int x = 0; x < 10; x++) {
if((grid[x][y] != 0) & (grid[x][y] != 1)) {
if(x == 0) {
// If we are against the left side of the grid, we cannot move
test = 1;
}
else if(grid[x-1][y] == 1) {
// Or if a dead piece lies to the left of us, we cannot
move
test = 1;
}
}
}
}
return test;
}
int wallRight() {
// As above, but with inversion to look to our right
int test = 0;
for(int y = 0; y < 20; y++) {
for(int x = 0; x < 10; x++) {
if((grid[x][y] != 0) & (grid[x][y] != 1)) {
if(x == 9) {
test = 1;
}
else if(grid[x+1][y] == 1) {
test = 1;
}
}
}
}
return test;
}
void moveLeft() {
// If there is no left collision, move the piece left and update
int collision = wallLeft();
if(collision == 0)
horz--;
drawPiece();
}
void moveRight() {
// As above, but with inversion to move right
int collision = wallRight();
if(collision == 0)
horz++;
drawPiece();
}
int rTest() {
// This is to test the validity of a rotation
int test = 0;
for(int x = 0; x < 4; x++) {
for(int y = 0; y < 4; y++) {
if(temp[x][y] != 0) {
if((horz + x < 0) || (horz + x > 9) || (vert + y < 0) ||
(vert + y > 19)) // If our rotation takes us out of range,
the rotation fails so must be blocked
test = 1;
else if(grid[horz + x][vert + y] == 1)
// Or if we would overwrite a dead piece, we again
block the rotation
test = 1;
}
}
}
return test;
}
void rotate() {
for(int x = 0; x < 4; x++) {
// Roatate our current shape 90 degrees and into a
temporary 2D array for testing
for(int y = 0; y < 4; y++) {
temp[y][3-x] = currShape[x][y];
}
}
if(rTest() == 0) {
// If our rotation is not blocked, copy over our temporary array
into our current shape
for(int x = 0; x < 4; x++) {
for(int y = 0; y < 4; y++) {
currShape[x][y] = temp[x][y];
}
}
drawPiece();
// In either case, we can update our current piece
}
}
void moveDown() {
// A function to move down on the user input
int collision = detect();
int count = 0;
if(collision == 0) {
// If we have no collision, we can move down and update the piece
vert--;
drawPiece();
}
else {
// If we do collide, then as above we make our live block dead,
test for score and generate a new piece
for(int y = 0; y < 20; y++) {
for(int x = 0; x < 10; x++) {
if((grid[x][y] != 0) & (grid[x][y] != 1)) {
grid[x][y] = 1;
count++;
if(count == 4)
collision = 0;
}
}
}
testScore();
if(count == 4)
drawNewPiece();
}
}
void special(int key, int x, int y) {
// Move or rotate the live piece based on the user arrow
input
if(gamePause == -1) {
switch(key) {
case GLUT_KEY_LEFT: moveLeft(); break;
case GLUT_KEY_RIGHT: moveRight(); break;
case GLUT_KEY_UP: rotate(); break;
case GLUT_KEY_DOWN: moveDown(); break;
}
}
}
int main(int argc, char* argv[]) {
// A method to initialise our window and set our display
and idle functions, as well as setting up the start of the board
startGrid();
srand(time(NULL));
// Ensure a truly random sequence by basing it off of the time
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(512,512);
glutInitWindowPosition(20,20);
glutCreateWindow("Tetris");
glClearColor(0.0f,0.0f,0.0f,1.0f);
glutDisplayFunc(display);
glutIdleFunc(idle);
newPiece();
drawNewPiece();
glutKeyboardFunc(keyboard);
glutSpecialFunc(special);
gluLookAt(0.04f,0.04f,0.2f,0.0f,0.0f,0.0f,0.0f,1.0f,0.0f);
// This moves the position of our camera to create a
3d effect on the board
glutMainLoop();
}

More Related Content

What's hot

Implicit Differentiation, Part 2
Implicit Differentiation, Part 2Implicit Differentiation, Part 2
Implicit Differentiation, Part 2
Pablo Antuna
 
ASFWS 2012 - Obfuscator, ou comment durcir un code source ou un binaire contr...
ASFWS 2012 - Obfuscator, ou comment durcir un code source ou un binaire contr...ASFWS 2012 - Obfuscator, ou comment durcir un code source ou un binaire contr...
ASFWS 2012 - Obfuscator, ou comment durcir un code source ou un binaire contr...
Cyber Security Alliance
 
ゲーム理論BASIC 演習4 -交渉集合を求める-
ゲーム理論BASIC 演習4 -交渉集合を求める-ゲーム理論BASIC 演習4 -交渉集合を求める-
ゲーム理論BASIC 演習4 -交渉集合を求める-
ssusere0a682
 
resposta do capitulo 15
resposta do capitulo 15resposta do capitulo 15
resposta do capitulo 15
silvio_sas
 
Math quota-cmu-g-455
Math quota-cmu-g-455Math quota-cmu-g-455
Math quota-cmu-g-455Rungroj Ssan
 
Cuaderno+de+integrales
Cuaderno+de+integralesCuaderno+de+integrales
Cuaderno+de+integralesjoseluisroyo
 
ゲーム理論BASIC 演習5 -カーネルを求める-
ゲーム理論BASIC 演習5 -カーネルを求める-ゲーム理論BASIC 演習5 -カーネルを求める-
ゲーム理論BASIC 演習5 -カーネルを求める-
ssusere0a682
 
Algebra and Trigonometry 9th Edition Larson Solutions Manual
Algebra and Trigonometry 9th Edition Larson Solutions ManualAlgebra and Trigonometry 9th Edition Larson Solutions Manual
Algebra and Trigonometry 9th Edition Larson Solutions Manual
kejeqadaqo
 
ゲーム理論NEXT 線形計画問題第9回 -シンプレックス法4 人工変数-
ゲーム理論NEXT 線形計画問題第9回 -シンプレックス法4 人工変数-ゲーム理論NEXT 線形計画問題第9回 -シンプレックス法4 人工変数-
ゲーム理論NEXT 線形計画問題第9回 -シンプレックス法4 人工変数-
ssusere0a682
 
Re call basic operations in mathematics
Re call basic operations in mathematics Re call basic operations in mathematics
Re call basic operations in mathematics
Nadeem Uddin
 
Pt 2 turunan fungsi eksponen, logaritma, implisit dan cyclometri-d4
Pt 2 turunan fungsi eksponen, logaritma, implisit dan cyclometri-d4Pt 2 turunan fungsi eksponen, logaritma, implisit dan cyclometri-d4
Pt 2 turunan fungsi eksponen, logaritma, implisit dan cyclometri-d4
lecturer
 
Estadistica U4
Estadistica U4Estadistica U4
Estadistica U4
FacundoOrtiz18
 
College algebra in context 5th edition harshbarger solutions manual
College algebra in context 5th edition harshbarger solutions manualCollege algebra in context 5th edition harshbarger solutions manual
College algebra in context 5th edition harshbarger solutions manual
Annuzzi19
 
Texto de matemática y lógica
Texto de matemática y lógicaTexto de matemática y lógica
Texto de matemática y lógica
Odín Zapata
 
Program Language - Fall 2013
Program Language - Fall 2013 Program Language - Fall 2013
Program Language - Fall 2013
Yun-Yan Chi
 
Differntials equatoin
Differntials equatoinDifferntials equatoin
Differntials equatoin
nitishguptamaps
 

What's hot (18)

Ejercicio 211 del libro de baldor
Ejercicio 211 del libro de baldorEjercicio 211 del libro de baldor
Ejercicio 211 del libro de baldor
 
Implicit Differentiation, Part 2
Implicit Differentiation, Part 2Implicit Differentiation, Part 2
Implicit Differentiation, Part 2
 
ASFWS 2012 - Obfuscator, ou comment durcir un code source ou un binaire contr...
ASFWS 2012 - Obfuscator, ou comment durcir un code source ou un binaire contr...ASFWS 2012 - Obfuscator, ou comment durcir un code source ou un binaire contr...
ASFWS 2012 - Obfuscator, ou comment durcir un code source ou un binaire contr...
 
ゲーム理論BASIC 演習4 -交渉集合を求める-
ゲーム理論BASIC 演習4 -交渉集合を求める-ゲーム理論BASIC 演習4 -交渉集合を求める-
ゲーム理論BASIC 演習4 -交渉集合を求める-
 
resposta do capitulo 15
resposta do capitulo 15resposta do capitulo 15
resposta do capitulo 15
 
Math quota-cmu-g-455
Math quota-cmu-g-455Math quota-cmu-g-455
Math quota-cmu-g-455
 
Cuaderno+de+integrales
Cuaderno+de+integralesCuaderno+de+integrales
Cuaderno+de+integrales
 
ゲーム理論BASIC 演習5 -カーネルを求める-
ゲーム理論BASIC 演習5 -カーネルを求める-ゲーム理論BASIC 演習5 -カーネルを求める-
ゲーム理論BASIC 演習5 -カーネルを求める-
 
Algebra and Trigonometry 9th Edition Larson Solutions Manual
Algebra and Trigonometry 9th Edition Larson Solutions ManualAlgebra and Trigonometry 9th Edition Larson Solutions Manual
Algebra and Trigonometry 9th Edition Larson Solutions Manual
 
ゲーム理論NEXT 線形計画問題第9回 -シンプレックス法4 人工変数-
ゲーム理論NEXT 線形計画問題第9回 -シンプレックス法4 人工変数-ゲーム理論NEXT 線形計画問題第9回 -シンプレックス法4 人工変数-
ゲーム理論NEXT 線形計画問題第9回 -シンプレックス法4 人工変数-
 
Basic m4-2-chapter1
Basic m4-2-chapter1Basic m4-2-chapter1
Basic m4-2-chapter1
 
Re call basic operations in mathematics
Re call basic operations in mathematics Re call basic operations in mathematics
Re call basic operations in mathematics
 
Pt 2 turunan fungsi eksponen, logaritma, implisit dan cyclometri-d4
Pt 2 turunan fungsi eksponen, logaritma, implisit dan cyclometri-d4Pt 2 turunan fungsi eksponen, logaritma, implisit dan cyclometri-d4
Pt 2 turunan fungsi eksponen, logaritma, implisit dan cyclometri-d4
 
Estadistica U4
Estadistica U4Estadistica U4
Estadistica U4
 
College algebra in context 5th edition harshbarger solutions manual
College algebra in context 5th edition harshbarger solutions manualCollege algebra in context 5th edition harshbarger solutions manual
College algebra in context 5th edition harshbarger solutions manual
 
Texto de matemática y lógica
Texto de matemática y lógicaTexto de matemática y lógica
Texto de matemática y lógica
 
Program Language - Fall 2013
Program Language - Fall 2013 Program Language - Fall 2013
Program Language - Fall 2013
 
Differntials equatoin
Differntials equatoinDifferntials equatoin
Differntials equatoin
 

Similar to tetris

Im trying again -Okay, Im in need of some help - this is the c.pdf
Im trying again -Okay, Im in need of some help - this is the c.pdfIm trying again -Okay, Im in need of some help - this is the c.pdf
Im trying again -Okay, Im in need of some help - this is the c.pdf
eyeonsecuritysystems
 
i need an input of this program.  anything good or bad.  what could .docx
i need an input of this program.  anything good or bad.  what could .docxi need an input of this program.  anything good or bad.  what could .docx
i need an input of this program.  anything good or bad.  what could .docx
ursabrooks36447
 
include ltiostreamgt include ltstringgt include .pdf
include ltiostreamgt include ltstringgt include .pdfinclude ltiostreamgt include ltstringgt include .pdf
include ltiostreamgt include ltstringgt include .pdf
contact32
 
The Ring programming language version 1.5.3 book - Part 69 of 184
The Ring programming language version 1.5.3 book - Part 69 of 184The Ring programming language version 1.5.3 book - Part 69 of 184
The Ring programming language version 1.5.3 book - Part 69 of 184
Mahmoud Samir Fayed
 
The Ring programming language version 1.9 book - Part 69 of 210
The Ring programming language version 1.9 book - Part 69 of 210The Ring programming language version 1.9 book - Part 69 of 210
The Ring programming language version 1.9 book - Part 69 of 210
Mahmoud Samir Fayed
 
Need to make a ReversiOthello Board game in JAVAThe board size ca.pdf
Need to make a ReversiOthello Board game in JAVAThe board size ca.pdfNeed to make a ReversiOthello Board game in JAVAThe board size ca.pdf
Need to make a ReversiOthello Board game in JAVAThe board size ca.pdf
flashfashioncasualwe
 
Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語
ikdysfm
 
import java.util.Scanner;public class Main {    public static in.pdf
import java.util.Scanner;public class Main {    public static in.pdfimport java.util.Scanner;public class Main {    public static in.pdf
import java.util.Scanner;public class Main {    public static in.pdf
anwarsadath111
 
write the TODO part of the program.docx
write the TODO part of the program.docxwrite the TODO part of the program.docx
write the TODO part of the program.docx
annetnash8266
 
AI CHALLENGE ADMIN
AI CHALLENGE ADMINAI CHALLENGE ADMIN
AI CHALLENGE ADMINAnkit Gupta
 
draw a sphere and use raytracing on the sphere in OpenGL glut. .pdf
 draw a sphere and use raytracing on the sphere in OpenGL glut. .pdf draw a sphere and use raytracing on the sphere in OpenGL glut. .pdf
draw a sphere and use raytracing on the sphere in OpenGL glut. .pdf
aquacosmossystems
 
import java.awt.;import java.awt.event.;import javax.swing.;.pdf
import java.awt.;import java.awt.event.;import javax.swing.;.pdfimport java.awt.;import java.awt.event.;import javax.swing.;.pdf
import java.awt.;import java.awt.event.;import javax.swing.;.pdf
aoneonlinestore1
 
Integers And Order of Operations
Integers And Order of OperationsIntegers And Order of Operations
Integers And Order of Operations
nickromero76
 
Create a C program that implements The Game of Life cellular auto.pdf
Create a C program that implements The Game of Life cellular auto.pdfCreate a C program that implements The Game of Life cellular auto.pdf
Create a C program that implements The Game of Life cellular auto.pdf
arihantsherwani
 
Mobile Game and Application with J2ME - Collision Detection
Mobile Gameand Application withJ2ME  - Collision DetectionMobile Gameand Application withJ2ME  - Collision Detection
Mobile Game and Application with J2ME - Collision Detection
Jenchoke Tachagomain
 
Mobile Game and Application with J2ME
Mobile Gameand Application with J2MEMobile Gameand Application with J2ME
Mobile Game and Application with J2ME
Jenchoke Tachagomain
 
NewTetrisScore.cppNewTetrisScore.cpp newTetris.cpp  Defines t.docx
NewTetrisScore.cppNewTetrisScore.cpp newTetris.cpp  Defines t.docxNewTetrisScore.cppNewTetrisScore.cpp newTetris.cpp  Defines t.docx
NewTetrisScore.cppNewTetrisScore.cpp newTetris.cpp  Defines t.docx
curwenmichaela
 
In Java using Eclipse, Im suppose to write a class that encapsulat.pdf
In Java using Eclipse, Im suppose to write a class that encapsulat.pdfIn Java using Eclipse, Im suppose to write a class that encapsulat.pdf
In Java using Eclipse, Im suppose to write a class that encapsulat.pdf
anjandavid
 

Similar to tetris (20)

Im trying again -Okay, Im in need of some help - this is the c.pdf
Im trying again -Okay, Im in need of some help - this is the c.pdfIm trying again -Okay, Im in need of some help - this is the c.pdf
Im trying again -Okay, Im in need of some help - this is the c.pdf
 
i need an input of this program.  anything good or bad.  what could .docx
i need an input of this program.  anything good or bad.  what could .docxi need an input of this program.  anything good or bad.  what could .docx
i need an input of this program.  anything good or bad.  what could .docx
 
include ltiostreamgt include ltstringgt include .pdf
include ltiostreamgt include ltstringgt include .pdfinclude ltiostreamgt include ltstringgt include .pdf
include ltiostreamgt include ltstringgt include .pdf
 
openGl example
openGl exampleopenGl example
openGl example
 
The Ring programming language version 1.5.3 book - Part 69 of 184
The Ring programming language version 1.5.3 book - Part 69 of 184The Ring programming language version 1.5.3 book - Part 69 of 184
The Ring programming language version 1.5.3 book - Part 69 of 184
 
The Ring programming language version 1.9 book - Part 69 of 210
The Ring programming language version 1.9 book - Part 69 of 210The Ring programming language version 1.9 book - Part 69 of 210
The Ring programming language version 1.9 book - Part 69 of 210
 
Need to make a ReversiOthello Board game in JAVAThe board size ca.pdf
Need to make a ReversiOthello Board game in JAVAThe board size ca.pdfNeed to make a ReversiOthello Board game in JAVAThe board size ca.pdf
Need to make a ReversiOthello Board game in JAVAThe board size ca.pdf
 
Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語Haskellで学ぶ関数型言語
Haskellで学ぶ関数型言語
 
import java.util.Scanner;public class Main {    public static in.pdf
import java.util.Scanner;public class Main {    public static in.pdfimport java.util.Scanner;public class Main {    public static in.pdf
import java.util.Scanner;public class Main {    public static in.pdf
 
Include
IncludeInclude
Include
 
write the TODO part of the program.docx
write the TODO part of the program.docxwrite the TODO part of the program.docx
write the TODO part of the program.docx
 
AI CHALLENGE ADMIN
AI CHALLENGE ADMINAI CHALLENGE ADMIN
AI CHALLENGE ADMIN
 
draw a sphere and use raytracing on the sphere in OpenGL glut. .pdf
 draw a sphere and use raytracing on the sphere in OpenGL glut. .pdf draw a sphere and use raytracing on the sphere in OpenGL glut. .pdf
draw a sphere and use raytracing on the sphere in OpenGL glut. .pdf
 
import java.awt.;import java.awt.event.;import javax.swing.;.pdf
import java.awt.;import java.awt.event.;import javax.swing.;.pdfimport java.awt.;import java.awt.event.;import javax.swing.;.pdf
import java.awt.;import java.awt.event.;import javax.swing.;.pdf
 
Integers And Order of Operations
Integers And Order of OperationsIntegers And Order of Operations
Integers And Order of Operations
 
Create a C program that implements The Game of Life cellular auto.pdf
Create a C program that implements The Game of Life cellular auto.pdfCreate a C program that implements The Game of Life cellular auto.pdf
Create a C program that implements The Game of Life cellular auto.pdf
 
Mobile Game and Application with J2ME - Collision Detection
Mobile Gameand Application withJ2ME  - Collision DetectionMobile Gameand Application withJ2ME  - Collision Detection
Mobile Game and Application with J2ME - Collision Detection
 
Mobile Game and Application with J2ME
Mobile Gameand Application with J2MEMobile Gameand Application with J2ME
Mobile Game and Application with J2ME
 
NewTetrisScore.cppNewTetrisScore.cpp newTetris.cpp  Defines t.docx
NewTetrisScore.cppNewTetrisScore.cpp newTetris.cpp  Defines t.docxNewTetrisScore.cppNewTetrisScore.cpp newTetris.cpp  Defines t.docx
NewTetrisScore.cppNewTetrisScore.cpp newTetris.cpp  Defines t.docx
 
In Java using Eclipse, Im suppose to write a class that encapsulat.pdf
In Java using Eclipse, Im suppose to write a class that encapsulat.pdfIn Java using Eclipse, Im suppose to write a class that encapsulat.pdf
In Java using Eclipse, Im suppose to write a class that encapsulat.pdf
 

tetris

  • 1. #ifdef __APPLE__ #include <GLUT/glut.h> #else #include <GL/glut.h> #endif #include <sstream> /* As Tetris runs on a standard 10x20 grid (displayed), each pixel has width represented by a float value of 0.09f */ int score = 0; int grid[10][22]; int nextPiece = 0; int currShape[4][4]; int temp[4][4]; int horz = 0; int vert = 0; int ticks = 0; int level = 1; int gameOver = 0; int gamePause = -1; void drawWord(std::string word, int pos_x, int pos_y, float scale, float red, float green, float blue) { glColor3f(red, green, blue); // Set the input color glMatrixMode(GL_PROJECTION); // Move into projection mode glPushMatrix(); // push a matrix onto the stack glLoadIdentity(); // load the identity matrix glMatrixMode(GL_MODELVIEW); // switch into model view glPushMatrix(); // push a new matrix onto the stack glLoadIdentity(); gluOrtho2D(0, 512, 0, 512); // set our window co-ordinates glTranslatef(pos_x, pos_y, 0.0f); // translate by the inputted values glScalef(scale, scale, 1.0f); // scale based on inputted scale int length = word.size(); // find the size of the word for(int i=0; i<length; i++) glutStrokeCharacter(GLUT_STROKE_ROMAN, word[i]); //type out each letter in the word glPopMatrix();
  • 2. glMatrixMode(GL_PROJECTION); glPopMatrix(); // pop matrices in order to reset the changes and complete function } std::string makeString(int value) { std::stringstream convert; convert << value; return convert.str(); // convert an int into a string } void writeScore() { // for each method, use drawWord to draw what we need in this postion drawWord("Score",390,400,0.3f,1.0f,0.0f,0.2f); drawWord(makeString(score),390,365,0.2f,1.0f,1.0f,1.0f); } void writeLevel() { drawWord("Level",390,256,0.3f,0.0f,0.5f,0.0f); drawWord(makeString(level),430,225,0.2f,1.0f,1.0f,1.0f); } void drawNextPiece() { float red = 0.0f; float green = 0.0f; float blue = 0.0f; int nextGrid[4][4]; // reset the next piece tracker for(int x = 0; x < 4; x++) { for(int y =0; y < 4; y++) { nextGrid[x][y] = 0; } } switch(nextPiece) { // based on our chosen next piece, fill in the relevant values in our 4x4 array and set the colour case 0: red = 1.0f; nextGrid[1][0] = 1; nextGrid[1][1] = 1; nextGrid[1][2] = 1; nextGrid[1][3] = 1; break; case 1: blue = 1.0f; nextGrid[1][1] = 1; nextGrid[1][2] = 1; nextGrid[2][2] = 1; nextGrid[2][1] = 1; break; case 2: green = 1.0f; red = 1.0f; nextGrid[0][2] = 1; nextGrid[1][1] = 1; nextGrid[1][2] = 1; nextGrid[2][1] = 1; break;
  • 3. case 3: green = 1.0f; nextGrid[0][1] = 1; nextGrid[1][1] = 1; nextGrid[1][2] = 1; nextGrid[2][2] = 1; break; case 4: red = 1.0f; green = 0.5f; nextGrid[1][0] = 1; nextGrid[1][1] = 1; nextGrid[1][2] = 1; nextGrid[2][0] = 1; break; case 5: green = 1.0f; blue = 1.0f; nextGrid[2][0] = 1; nextGrid[2][1] = 1; nextGrid[2][2] = 1; nextGrid[1][0] = 1; break; case 6: red = 0.5f; blue = 0.5f; nextGrid[0][1] = 1; nextGrid[1][1] = 1; nextGrid[2][1] = 1; nextGrid[1][2] = 1; break; } for(int x = 0; x < 4; x++) { // for each filled part of our 2d array, we draw a solid cube and wire grid on screen for(int y = 0; y < 4; y++) { if(nextGrid[x][y] == 1) { // As in drawGrid method, with alternate translation values (see below) glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef((- 0.8125f+(x*0.075f)),(0.1375f+(y*0.075f)),0.0f); glColor3f(red,green,blue); glutSolidCube(0.075f); glColor3f(0.0f,0.0f,0.0f); glutWireCube(0.075f); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); } } } } void showNext() { // we draw a box to enclose our nextPiece and draw the word and piece required also drawWord("Next",30,400,0.3f,0.0f,0.0f,1.0f); glLineWidth(0.2f); glColor3f(1.0f,1.0f,1.0f); glBegin(GL_LINE_LOOP); glVertex2f(-0.9f, 0.45f); glVertex2f(-0.5f, 0.45f); glVertex2f(-0.5f,0.05f); glVertex2f(-0.9f,0.05f); glEnd(); drawNextPiece();
  • 4. } void startGrid() { // initialise a blank grid for(int x = 0; x < 10; x++) { for(int y = 0; y < 22; y++) { grid[x][y] = 0; } } } void drawGrid() { // draw our tetris board based on our 2d array float red; float green; float blue; for(int y = 0; y < 20; y++) { for(int x = 0; x < 10; x++) { red = 0.0f; green = 0.0f; blue = 0.0f; switch(grid[x][y]) { // set the colour based on the value of the array at this point case 0: break; case 1: red = 0.8f; green = 0.8f; blue = 0.8f; break; case 2: red = 1.0f; break; case 3: blue = 1.0f; break; case 4: red = 1.0f; green = 1.0f; break; case 5: green = 1.0f; break; case 6: red = 1.0f; green = 0.5f; break; case 7: green = 1.0f; blue = 1.0f; break; case 8: red = 0.5f; blue = 0.5f; break; } if(grid[x][y] != 0) { // if we find a non-blank space, we must draw glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glTranslatef((-0.405f+(x*0.09f)),(- 0.855f+(y*0.09f)),0.0f); // we translate by our bottom left values corner for x and y, plus the change in x and y defined by the array position glColor3f(red,green,blue); glutSolidCube(0.09f); // we draw a solid cube of required colour, with single pixel size glColor3f(0.0f,0.0f,0.0f);
  • 5. glutWireCube(0.09f); // we then draw the black wire frame to show it as a pixel glPopMatrix(); // we undo the translation by popping the matrix off the stack glMatrixMode(GL_PROJECTION); glPopMatrix(); } } } } void newPiece() { nextPiece = rand() % 7; // to randomly choose a piece, we pick a random number between 0 and 6 } void drawPiece() { for(int y = 0; y < 20; y++) { // this resets all non "dead-block" values in the board, i.e. erases our live piece for(int x = 0; x < 10; x++) { if(grid[x][y] != 1) grid[x][y] = 0; } } for(int y = 0; y < 4; y++) { // this then draws the piece into our 2d array, based on the current shape array and the tracked vertical and horizontal for(int x = 0; x < 4; x++) { // values of our bottom left corner if((horz+x >= 0) && (horz+x < 10) && (vert+y >= 0) && (vert+y < 20)) { if(grid[horz + x][vert + y] != 1) grid[horz + x][vert + y] = currShape[x][y]; } } } } void testGameOver() { for(int y = 0; y < 4; y++) { // if our piece is blocked from entering the grid, we state it as game over for(int x = 0; x < 4; x++) { if((currShape[x][y] != 0) & (grid[horz + x][vert + y] == 1)) { gameOver = 1; gamePause = 1; // we put the game into a state of pause to stop idle and user input
  • 6. } } } } void drawNewPiece() { // this will add our next piece into our current piece array for(int y = 0; y < 4; y++) { // we first reset our current piece array for(int x = 0; x < 4; x++) { currShape[x][y] = 0; } } switch (nextPiece) { // then set the relevant values of our array case 0: currShape[0][2] = 2; currShape[1][2] = 2; currShape[2][2] = 2; currShape[3][2] = 2; break; case 1: currShape[1][2] = 3; currShape[1][1] = 3; currShape[2][2] = 3; currShape[2][1] = 3; break; case 2: currShape[0][2] = 4; currShape[1][1] = 4; currShape[1][2] = 4; currShape[2][1] = 4; break; case 3: currShape[0][1] = 5; currShape[1][1] = 5; currShape[1][2] = 5; currShape[2][2] = 5; break; case 4: currShape[1][0] = 6; currShape[1][1] = 6; currShape[1][2] = 6; currShape[2][0] = 6; break; case 5: currShape[1][0] = 7; currShape[2][0] = 7; currShape[2][1] = 7; currShape[2][2] = 7; break; case 6: currShape[0][1] = 8; currShape[1][1] = 8; currShape[2][1] = 8; currShape[1][2] = 8; break; } horz = 3; // we must also reset the tracked position of our bottom left corner vert = 17; testGameOver(); // we test if the piece can be inserted into our grid if(gameOver == 0) { drawPiece(); // if the piece can be drawn in, we add it to the board and generate our new "next" piece newPiece(); } } void display() { glClear(GL_COLOR_BUFFER_BIT); // we clear the display glColor3f(1.0f, 1.0f, 1.0f); // set RGB values of colour to draw glLineWidth(3.0f); glBegin(GL_LINES); // and draw the outline of the grid in white
  • 7. glVertex2f(0.45f,0.9f); glVertex2f(0.45f,-0.9f); glVertex2f(0.45f,-0.9f); glVertex2f(-0.45f,-0.9f); glVertex2f(-0.45f,-0.9f); glVertex2f(-0.45f,0.9f); glEnd(); writeScore(); writeLevel(); showNext(); drawGrid(); drawWord("Press 'q' to quit, 'p' to pause and 'r' to restart",120,10,0.1f,0.0f,1.0f,1.0f); // this adds some feature instructions on the bottom of the screen if(gameOver == 1) { // if the game is over, draw this in drawWord("Game",10,150,0.3f,1.0f,0.5f,0.0f); drawWord("Over",25,120,0.3f,1.0f,0.5f,0.0f); } else if(gamePause == 1) // if we are paused but not over, draw this in drawWord("Paused",10,150,0.3f,1.0f,0.5f,0.0f); else if(((ticks % 4500) <= 20) && (ticks > 20)) { // if we are set to level up, show this message for 20 ticks drawWord("Level",380,150,0.3f,0.3f,0.3f,1.0f); drawWord("Up",400,100,0.3f,0.3f,0.3f,1.0f); } glutSwapBuffers(); } int detect() { // detect if a piece is colliding int test = 0; for(int y = 0; y < 20; y++) { for(int x = 0; x < 10; x++) { if((grid[x][y] != 0) & (grid[x][y] != 1)) { // if we have found our live piece if(y == 0) { // if we have hit the floor, collision found test = 1; } else if(grid[x][y-1] == 1) { // if we are resting on a dead block, collision found test = 1; } } } } return test; }
  • 8. void removeRow(int y) { // when a row is removed, this function grabs the rows above to drop them down for(int a = y; a < 19; a++) { for(int x = 0; x < 10; x++) { grid[x][a] = grid[x][(a+1)]; } } } void testScore() { // this tests for scoring rows int change = 0; // track the row changes for(int y = 0; y < 20; y++) { int test = 0; for(int x = 0; x < 10; x++) { if(grid[x][y] != 1) // if we find a non-dead block, then we have no score for this row test = 1; } if(test == 0) { // if this row scores, remove it, decrease y (to check row above after change) and increase row change by 1 removeRow(y); y--; change++; } } switch(change) { // our score change is based on how many rows are removed this sweep case 1: score += (40*level); break; case 2: score += (100*level); break; case 3: score += (300*level); break; case 4: score += (1200*level); break; } } void idle() { glutPostRedisplay(); // our idle function controls the display if(gamePause == -1) { // if we have not paused the game
  • 9. ticks++; // increase our number of ticks if((ticks % 4500) == 0) { // every 4500 ticks, increase the level to a maximum of 10 if(level < 10) level++; } if((ticks % (int)(60/level)) == 0) { // This controls the speed based on level. Every (60/level) ticks, we move down a row int count = 0; int collision = detect(); if(collision == 0) { // If we will not collide, decrease the y co-ord and draw the piece into its new position vert--; drawPiece(); } else { for(int y = 0; y < 20; y++) { // If we do collide, then turn each live piece into a dead piece before resetting the collision for(int x = 0; x < 10; x++) { if((grid[x][y] != 0) & (grid[x][y] != 1)) { grid[x][y] = 1; count++; if(count == 4) collision = 0; } } } } testScore(); // As a new dead block has been added, test to see if this scores if(count == 4) drawNewPiece(); // If we added a dead block, we need to draw in our new piece } } } void restart() { // A restart function for the game, resetting all variables and the board and pieces level = 1; score = 0; gameOver = 0;
  • 10. gamePause = -1; startGrid(); newPiece(); drawNewPiece(); } void drop() { // A method to drop until we collide int collision = 0; int count = 0; while(collision == 0) { // Until we find a collision, continue to drop and update the piece vert--; drawPiece(); collision = detect(); } for(int y = 0; y < 20; y++) { // Once we have the colision, turn our live piece into a dead block for(int x = 0; x < 10; x++) { if((grid[x][y] != 0) & (grid[x][y] != 1)) { grid[x][y] = 1; count++; if(count == 4) collision = 0; } } } testScore(); // Again, we test score and draw in our new piece drawNewPiece(); } void keyboard(unsigned char key, int x, int y) { // 4 functions. A quit, restart, piece drop and pause built into the game switch(key) { case 'q': exit(1); break; case 'r': restart(); break; case ' ': if((gamePause == -1) && (detect() == 0)) drop(); break; case 'p': if(gameOver == 0) gamePause*=-1; break; } } int wallLeft() { // Detect a block on the left
  • 11. int test = 0; for(int y = 0; y < 20; y++) { for(int x = 0; x < 10; x++) { if((grid[x][y] != 0) & (grid[x][y] != 1)) { if(x == 0) { // If we are against the left side of the grid, we cannot move test = 1; } else if(grid[x-1][y] == 1) { // Or if a dead piece lies to the left of us, we cannot move test = 1; } } } } return test; } int wallRight() { // As above, but with inversion to look to our right int test = 0; for(int y = 0; y < 20; y++) { for(int x = 0; x < 10; x++) { if((grid[x][y] != 0) & (grid[x][y] != 1)) { if(x == 9) { test = 1; } else if(grid[x+1][y] == 1) { test = 1; } } } } return test; } void moveLeft() { // If there is no left collision, move the piece left and update int collision = wallLeft(); if(collision == 0) horz--; drawPiece(); } void moveRight() { // As above, but with inversion to move right int collision = wallRight(); if(collision == 0) horz++; drawPiece();
  • 12. } int rTest() { // This is to test the validity of a rotation int test = 0; for(int x = 0; x < 4; x++) { for(int y = 0; y < 4; y++) { if(temp[x][y] != 0) { if((horz + x < 0) || (horz + x > 9) || (vert + y < 0) || (vert + y > 19)) // If our rotation takes us out of range, the rotation fails so must be blocked test = 1; else if(grid[horz + x][vert + y] == 1) // Or if we would overwrite a dead piece, we again block the rotation test = 1; } } } return test; } void rotate() { for(int x = 0; x < 4; x++) { // Roatate our current shape 90 degrees and into a temporary 2D array for testing for(int y = 0; y < 4; y++) { temp[y][3-x] = currShape[x][y]; } } if(rTest() == 0) { // If our rotation is not blocked, copy over our temporary array into our current shape for(int x = 0; x < 4; x++) { for(int y = 0; y < 4; y++) { currShape[x][y] = temp[x][y]; } } drawPiece(); // In either case, we can update our current piece } } void moveDown() { // A function to move down on the user input int collision = detect(); int count = 0; if(collision == 0) { // If we have no collision, we can move down and update the piece
  • 13. vert--; drawPiece(); } else { // If we do collide, then as above we make our live block dead, test for score and generate a new piece for(int y = 0; y < 20; y++) { for(int x = 0; x < 10; x++) { if((grid[x][y] != 0) & (grid[x][y] != 1)) { grid[x][y] = 1; count++; if(count == 4) collision = 0; } } } testScore(); if(count == 4) drawNewPiece(); } } void special(int key, int x, int y) { // Move or rotate the live piece based on the user arrow input if(gamePause == -1) { switch(key) { case GLUT_KEY_LEFT: moveLeft(); break; case GLUT_KEY_RIGHT: moveRight(); break; case GLUT_KEY_UP: rotate(); break; case GLUT_KEY_DOWN: moveDown(); break; } } } int main(int argc, char* argv[]) { // A method to initialise our window and set our display and idle functions, as well as setting up the start of the board startGrid(); srand(time(NULL)); // Ensure a truly random sequence by basing it off of the time glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA); glutInitWindowSize(512,512); glutInitWindowPosition(20,20); glutCreateWindow("Tetris"); glClearColor(0.0f,0.0f,0.0f,1.0f); glutDisplayFunc(display);