Added code
This commit is contained in:
65
Logic/PieceGenerator.cpp
Normal file
65
Logic/PieceGenerator.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* PieceGenerator.cpp
|
||||
*
|
||||
* Created on: May 5, 2013
|
||||
* Author: chibi_000
|
||||
*/
|
||||
|
||||
#include "PieceGenerator.h"
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
|
||||
const int PieceGenerator::pieces_array[][8] = {
|
||||
{4, 1, 1, 1, 1, 1, 0, 0},
|
||||
{3, 2, 2, 2, 2, 2, 0, 0},
|
||||
{3, 2, 3, 0, 0, 3, 3, 3},
|
||||
{3, 2, 0, 4, 0, 4, 4, 4},
|
||||
{3, 2, 5, 5, 0, 0, 5, 5},
|
||||
{3, 2, 0, 6, 6, 6, 6, 0},
|
||||
{2, 2, 7, 7, 7, 7, 0, 0},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
PieceGenerator::PieceGenerator()
|
||||
{
|
||||
// Create pieces
|
||||
this->initializePieces();
|
||||
|
||||
// Set random seed
|
||||
srand(time(NULL));
|
||||
}
|
||||
|
||||
PieceGenerator::~PieceGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
void PieceGenerator::initializePieces()
|
||||
{
|
||||
for (int i = 0; this->pieces_array[i][0] != 0; i++)
|
||||
{
|
||||
int w = this->pieces_array[i][0];
|
||||
int h = this->pieces_array[i][1];
|
||||
this->pieces.push_back(Piece(w, h, this->pieces_array[i] + 2));
|
||||
}
|
||||
}
|
||||
|
||||
Piece PieceGenerator::getRandomPiece() const
|
||||
{
|
||||
int i = rand() % this->pieces.size();
|
||||
|
||||
return this->pieces[i];
|
||||
}
|
||||
|
||||
Piece PieceGenerator::getRandomPieceRotated() const
|
||||
{
|
||||
// Get random piece
|
||||
Piece p = this->getRandomPiece();
|
||||
|
||||
// Rotate random times
|
||||
for (int i = rand() % 4; i >= 0; i--)
|
||||
p = p.rotate();
|
||||
|
||||
// Return
|
||||
return p;
|
||||
}
|
42
Logic/PieceGenerator.h
Normal file
42
Logic/PieceGenerator.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* PieceGenerator.h
|
||||
*
|
||||
* Created on: May 5, 2013
|
||||
* Author: chibi_000
|
||||
*/
|
||||
|
||||
#ifndef PIECEGENERATOR_H_
|
||||
#define PIECEGENERATOR_H_
|
||||
|
||||
#include "../Domain/Piece.h"
|
||||
#include <vector>
|
||||
|
||||
class PieceGenerator {
|
||||
|
||||
private:
|
||||
|
||||
// Constants
|
||||
static const int pieces_array[][8];
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Private fields
|
||||
std::vector<Piece> pieces;
|
||||
|
||||
// Private functions
|
||||
virtual void initializePieces();
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
PieceGenerator();
|
||||
virtual ~PieceGenerator();
|
||||
|
||||
// Getters
|
||||
virtual Piece getRandomPiece() const;
|
||||
virtual Piece getRandomPieceRotated() const;
|
||||
};
|
||||
|
||||
|
||||
#endif /* PIECEGENERATOR_H_ */
|
237
Logic/TetrisGame.cpp
Normal file
237
Logic/TetrisGame.cpp
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
* TetrisGame.cpp
|
||||
*
|
||||
* Created on: May 5, 2013
|
||||
* Author: chibi_000
|
||||
*/
|
||||
|
||||
#include "TetrisGame.h"
|
||||
#include <math.h>
|
||||
|
||||
TetrisGame::TetrisGame(int w, int h, const PieceGenerator& pg)
|
||||
: grid(w, h), gen(pg)
|
||||
{
|
||||
this->score = 0;
|
||||
this->level = 1;
|
||||
this->cx = 0;
|
||||
this->cy = 0;
|
||||
this->next = gen.getRandomPieceRotated();
|
||||
|
||||
this->pickNextPiece();
|
||||
}
|
||||
|
||||
TetrisGame::~TetrisGame()
|
||||
{
|
||||
}
|
||||
|
||||
int TetrisGame::xToPiece(int x_g)
|
||||
{
|
||||
return x_g - cx;
|
||||
}
|
||||
|
||||
int TetrisGame::xToGrid(int x_p)
|
||||
{
|
||||
return x_p + cx;
|
||||
}
|
||||
|
||||
int TetrisGame::yToPiece(int y_g)
|
||||
{
|
||||
return y_g - cy;
|
||||
}
|
||||
|
||||
int TetrisGame::yToGrid(int y_p)
|
||||
{
|
||||
return y_p + cy;
|
||||
}
|
||||
|
||||
void TetrisGame::pickNextPiece()
|
||||
{
|
||||
// Next becomes current
|
||||
this->current = this->next;
|
||||
|
||||
// Pick a new piece
|
||||
this->next = gen.getRandomPieceRotated();
|
||||
|
||||
// Set position to middle center
|
||||
this->cy = -this->current.getHeight();
|
||||
this->cx = ( grid.getWidth() - current.getWidth() ) / 2;
|
||||
}
|
||||
|
||||
|
||||
void TetrisGame::putPieceInGrid()
|
||||
{
|
||||
for (int x = 0; x < current.getWidth(); x++)
|
||||
for (int y = 0; y < current.getHeight(); y++)
|
||||
grid.set( xToGrid(x), yToGrid(y), grid.get( xToGrid(x), yToGrid(y) ) + current.get(x, y) );
|
||||
}
|
||||
|
||||
int TetrisGame::markFullLines()
|
||||
{
|
||||
int total_rows = 0;
|
||||
|
||||
// For each row
|
||||
for (int y = 0; y < grid.getHeight(); y++)
|
||||
{
|
||||
// Count non-empty cells
|
||||
int count = 0;
|
||||
|
||||
for (int x = 0; x < grid.getWidth(); x++)
|
||||
count += ( grid.get(x, y) > 0 ) ? 1 : 0;
|
||||
|
||||
// Count equal to width = full line
|
||||
if (count == grid.getWidth())
|
||||
{
|
||||
total_rows++;
|
||||
|
||||
for (int x = 0; x < grid.getWidth(); x++)
|
||||
grid.set(x, y, -1);
|
||||
}
|
||||
}
|
||||
|
||||
// Return found rows
|
||||
return total_rows;
|
||||
}
|
||||
|
||||
void TetrisGame::removeFullLines()
|
||||
{
|
||||
for (int yto = grid.getHeight()-1, yfrom = yto; yto >= 0; yto--, yfrom--)
|
||||
{
|
||||
// Skip full lines
|
||||
while (grid.get(0, yfrom) == -1 && yfrom >= 0)
|
||||
yfrom--;
|
||||
|
||||
// Remove content
|
||||
for (int x = 0; x < grid.getWidth(); x++)
|
||||
if (yfrom < 0)
|
||||
grid.set(x, yto, 0);
|
||||
else
|
||||
grid.set(x, yto, grid.get(x, yfrom));
|
||||
}
|
||||
}
|
||||
|
||||
bool TetrisGame::isGameOver()
|
||||
{
|
||||
for (int x = 0; x < grid.getWidth(); x++)
|
||||
if (grid.get(x, 0) != 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TetrisGame::collides(int cx, int cy, const Piece& p)
|
||||
{
|
||||
// Check bounds
|
||||
if (cx < 0 || cx + p.getWidth() > grid.getWidth())
|
||||
return true;
|
||||
|
||||
if (cy + p.getHeight() > grid.getHeight())
|
||||
return true;
|
||||
|
||||
// Check every piece
|
||||
for (int x = 0; x < p.getWidth(); x++)
|
||||
for (int y = 0; y < p.getHeight(); y++)
|
||||
if ( y+cy >= 0 && p.get(x, y) != 0 && grid.get(x+cx, y+cy) != 0 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TetrisGame::collidesDown()
|
||||
{
|
||||
return this->collides(cx, cy+1, current);
|
||||
}
|
||||
|
||||
bool TetrisGame::collidesLeft()
|
||||
{
|
||||
return this->collides(cx-1, cy, current);
|
||||
}
|
||||
|
||||
bool TetrisGame::collidesRight()
|
||||
{
|
||||
return this->collides(cx+1, cy, current);
|
||||
}
|
||||
|
||||
void TetrisGame::moveLeft()
|
||||
{
|
||||
if (!this->collidesLeft())
|
||||
this->cx--;
|
||||
}
|
||||
|
||||
void TetrisGame::moveRight()
|
||||
{
|
||||
if (!this->collidesRight())
|
||||
this->cx++;
|
||||
}
|
||||
|
||||
void TetrisGame::moveDown()
|
||||
{
|
||||
while (!this->collidesDown())
|
||||
this->cy++;
|
||||
}
|
||||
|
||||
void TetrisGame::rotate()
|
||||
{
|
||||
Piece rot = current.rotate();
|
||||
|
||||
if (!this->collides(cx, cy, rot))
|
||||
current = rot;
|
||||
}
|
||||
|
||||
void TetrisGame::tick()
|
||||
{
|
||||
// Check if game is over
|
||||
if (this->isGameOver())
|
||||
return;
|
||||
|
||||
// Remove full lines
|
||||
this->removeFullLines();
|
||||
|
||||
// Piece is down
|
||||
if (this->collidesDown())
|
||||
{
|
||||
this->putPieceInGrid();
|
||||
this->pickNextPiece();
|
||||
|
||||
int count = this->markFullLines();
|
||||
|
||||
// Calculate score
|
||||
this->score += (1<<(count - 1)) * 100;
|
||||
if (this->score > (1<<(level - 1)) * 5000)
|
||||
this->level++;
|
||||
}
|
||||
|
||||
// Piece is not down, simply move it
|
||||
else this->cy++;
|
||||
}
|
||||
|
||||
int TetrisGame::get(int x, int y)
|
||||
{
|
||||
bool col = cx <= x && x < cx + current.getWidth();
|
||||
bool row = cy <= y && y < cy + current.getHeight();
|
||||
|
||||
if (col && row)
|
||||
return grid.get(x, y) + current.get( xToPiece(x), yToPiece(y) );
|
||||
|
||||
return grid.get(x, y);
|
||||
}
|
||||
|
||||
Piece TetrisGame::getNextPiece()
|
||||
{
|
||||
return next;
|
||||
}
|
||||
|
||||
int TetrisGame::getScore()
|
||||
{
|
||||
return score;
|
||||
}
|
||||
|
||||
int TetrisGame::getLevel()
|
||||
{
|
||||
return level;
|
||||
}
|
||||
|
||||
int TetrisGame::getTickTime()
|
||||
{
|
||||
float l = sqrtf(this->level);
|
||||
return 800 / l;
|
||||
}
|
65
Logic/TetrisGame.h
Normal file
65
Logic/TetrisGame.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* TetrisGame.h
|
||||
*
|
||||
* Created on: May 5, 2013
|
||||
* Author: chibi_000
|
||||
*/
|
||||
|
||||
#ifndef TETRISGAME_H_
|
||||
#define TETRISGAME_H_
|
||||
|
||||
#include "../Domain/Array2.h"
|
||||
#include "PieceGenerator.h"
|
||||
|
||||
class TetrisGame {
|
||||
|
||||
private:
|
||||
Array2 grid;
|
||||
Piece current, next;
|
||||
PieceGenerator gen;
|
||||
|
||||
int score, level;
|
||||
int cy, cx;
|
||||
|
||||
// Position convert
|
||||
int xToPiece(int col_g);
|
||||
int xToGrid(int col_p);
|
||||
int yToPiece(int row_g);
|
||||
int yToGrid(int row_p);
|
||||
|
||||
// Pieces
|
||||
void pickNextPiece();
|
||||
void putPieceInGrid();
|
||||
|
||||
// Lines
|
||||
int markFullLines();
|
||||
void removeFullLines();
|
||||
|
||||
// Collisions
|
||||
bool collides(int cx, int cy, const Piece& p);
|
||||
bool collidesDown();
|
||||
bool collidesLeft();
|
||||
bool collidesRight();
|
||||
|
||||
public:
|
||||
TetrisGame(int w=10, int h=20, const PieceGenerator& gen = PieceGenerator());
|
||||
virtual ~TetrisGame();
|
||||
|
||||
// Gameplay
|
||||
bool isGameOver();
|
||||
void tick();
|
||||
|
||||
void moveLeft();
|
||||
void moveRight();
|
||||
void moveDown();
|
||||
void rotate();
|
||||
|
||||
// Getters
|
||||
int get(int x, int y);
|
||||
int getScore();
|
||||
int getLevel();
|
||||
int getTickTime();
|
||||
Piece getNextPiece();
|
||||
};
|
||||
|
||||
#endif /* TETRISGAME_H_ */
|
Reference in New Issue
Block a user