Organize Grid cpp code
This commit is contained in:
parent
afd4ba110f
commit
af7f2fc870
1 changed files with 255 additions and 248 deletions
|
@ -1,5 +1,7 @@
|
|||
#include "Grid.hpp"
|
||||
|
||||
//==================== Constructor and Destructor ====================
|
||||
|
||||
//Constructor
|
||||
Grid::Grid(): m_size(4), m_grid(4){
|
||||
|
||||
|
@ -16,6 +18,251 @@ Grid::~Grid(){
|
|||
}
|
||||
|
||||
|
||||
//==================== Merge and defragment methods ====================
|
||||
|
||||
//Defragment the line to the right
|
||||
std::vector<int> Grid::rightDefragment(std::vector<int> line){
|
||||
for(int j=0; j<m_size-1;j++){
|
||||
for(int i=0; i<m_size-1;i++){
|
||||
int val1=line.at(i);
|
||||
int val2=line.at(i+1);
|
||||
|
||||
if(val1 != 0 && val2 == 0){
|
||||
line.at(i)=0;
|
||||
line.at(i+1)=val1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
//Defragment the line to the left using right defragmentation
|
||||
std::vector<int> Grid::leftDefragment(std::vector<int> line){
|
||||
|
||||
std::vector<int> reversedLine= this->reverseLine(line);
|
||||
|
||||
return this->reverseLine(this->rightDefragment(reversedLine));
|
||||
}
|
||||
|
||||
//Merge line to the right
|
||||
std::vector<int> Grid::rightMerge(std::vector<int> line){
|
||||
for(int i=0; i< m_size-1;i++){
|
||||
int val1=line.at(i);
|
||||
int val2=line.at(i+1);
|
||||
|
||||
if(val1==val2){
|
||||
line.at(i)=0;
|
||||
line.at(i+1)=val1*2;
|
||||
m_lastMoveScore+=val1*2;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
//Merge line to the left
|
||||
std::vector<int> Grid::leftMerge(std::vector<int> line){
|
||||
for(int i=m_size-1; i>0;i--){
|
||||
int val1=line.at(i);
|
||||
int val2=line.at(i-1);
|
||||
|
||||
if(val1==val2){
|
||||
line.at(i)=0;
|
||||
line.at(i-1)=val1*2;
|
||||
m_lastMoveScore+=val1*2;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
//==================== Swipe methods ====================
|
||||
|
||||
|
||||
//Swipe to the right
|
||||
bool Grid::swipeRight(){
|
||||
|
||||
m_lastMoveScore=0;
|
||||
bool moveDone=false;
|
||||
for(int i=0; i<m_size;i++){
|
||||
std::vector<int> swipedLine(this->rightDefragment(this->leftMerge(this->rightDefragment(m_grid.at(i)))));
|
||||
|
||||
if(!this->compareLines(m_grid.at(i), swipedLine)){
|
||||
moveDone=true;
|
||||
m_grid.at(i)=swipedLine;
|
||||
}
|
||||
}
|
||||
return moveDone;
|
||||
}
|
||||
|
||||
//Swipe to the left
|
||||
bool Grid::swipeLeft(){
|
||||
m_lastMoveScore=0;
|
||||
bool moveDone=false;
|
||||
for(int i=0; i<m_size;i++){
|
||||
std::vector<int> swipedLine(this->leftDefragment(this->rightMerge(this->leftDefragment(m_grid.at(i)))));
|
||||
if(!this->compareLines(m_grid.at(i), swipedLine)){
|
||||
moveDone=true;
|
||||
m_grid.at(i)=swipedLine;
|
||||
}
|
||||
}
|
||||
return moveDone;
|
||||
}
|
||||
|
||||
|
||||
//Swipe to the top
|
||||
bool Grid::swipeUp(){
|
||||
m_lastMoveScore=0;
|
||||
bool moveDone=false;
|
||||
for(int i=0; i<m_size;i++){
|
||||
std::vector<int> colVect=this->getCol(i);
|
||||
|
||||
std::vector<int> swipedLine(this->leftDefragment(this->rightMerge(this->leftDefragment(colVect))));
|
||||
if(!this->compareLines(colVect, swipedLine)){
|
||||
moveDone=true;
|
||||
this->setCol(i,swipedLine);
|
||||
}
|
||||
}
|
||||
return moveDone;
|
||||
}
|
||||
//Swipe to the bottom
|
||||
bool Grid::swipeDown(){
|
||||
m_lastMoveScore=0;
|
||||
bool moveDone=false;
|
||||
for(int i=0; i<m_size;i++){
|
||||
std::vector<int> colVect=this->getCol(i);
|
||||
|
||||
std::vector<int> swipedLine(this->rightDefragment(this->leftMerge(this->rightDefragment(colVect))));
|
||||
|
||||
if(!this->compareLines(colVect, swipedLine)){
|
||||
moveDone=true;
|
||||
this->setCol(i,swipedLine);
|
||||
}
|
||||
}
|
||||
return moveDone;
|
||||
}
|
||||
|
||||
//==================== Helpers ====================
|
||||
|
||||
//Get the max len of a string of the numbers in the grid :
|
||||
// Exemple:
|
||||
// - 1 return 1
|
||||
// - 22 return 2
|
||||
// - 120 return 3
|
||||
// - 1000 return 4
|
||||
//This method help to calculate the columns size
|
||||
int Grid::maxStrLenInGrid(){
|
||||
int max=0;
|
||||
for(int i=0;i<m_size;i++){
|
||||
for(int j=0;j<m_size;j++){
|
||||
std::string number=std::to_string(m_grid.at(i).at(j));
|
||||
if(number.size() > max)
|
||||
max=number.size();
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
//Test if the cell at (i,j) is empty
|
||||
bool Grid::isEmpty(int i, int j){
|
||||
if(m_grid.at(i).at(j) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
//Return a tuple that contain a random empty cell
|
||||
std::tuple<int, int> Grid::getRandomEmptyCellCoord(){
|
||||
|
||||
//Init list of candidate
|
||||
std::vector<std::tuple<int, int> > candidates;
|
||||
|
||||
//Construct list of candidates
|
||||
for(int i=0;i<m_size;i++){
|
||||
for(int j=0;j<m_size;j++){
|
||||
if(this->isEmpty(i,j)){
|
||||
std::tuple<int, int> currentCandidate(i,j);
|
||||
candidates.push_back(currentCandidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//If no candidate available
|
||||
if(candidates.size() == 0)
|
||||
return std::tuple<int, int>(-1, -1);
|
||||
|
||||
//Select the candidates
|
||||
int winnerIs(rand() % candidates.size());
|
||||
|
||||
//Return the candidate
|
||||
return candidates.at(winnerIs);
|
||||
|
||||
}
|
||||
|
||||
//Reverse a line
|
||||
std::vector<int> Grid::reverseLine(std::vector<int> line){
|
||||
std::vector<int> reversedLine;
|
||||
|
||||
for(int j=m_size-1; j>=0;j--){
|
||||
reversedLine.push_back(line.at(j));
|
||||
}
|
||||
|
||||
return reversedLine;
|
||||
}
|
||||
|
||||
//Return true if the grid is full. False else.
|
||||
bool Grid::isFull(){
|
||||
|
||||
for(int i=0;i<m_size;i++){
|
||||
for(int j=0;j<m_size;j++){
|
||||
if(m_grid.at(i).at(j) == 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//Return true if the grid is full and no move can be performed. False else.
|
||||
bool Grid::isOver(){
|
||||
|
||||
if(!this->isFull())
|
||||
return false;
|
||||
|
||||
for(int i=0;i<m_size;i++){
|
||||
for(int j=0;j<m_size-1;j++){
|
||||
if(m_grid.at(i).at(j) == m_grid.at(i).at(j+1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0;i<m_size;i++){
|
||||
std::vector<int> colVect(this->getCol(i));
|
||||
|
||||
for(int j=0;j<m_size-1;j++){
|
||||
if(colVect.at(j) == colVect.at(j+1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
//Return true if line1 is equals to line2. False else.
|
||||
bool Grid::compareLines(std::vector<int> line1, std::vector<int> line2){
|
||||
|
||||
for(int i=0;i<m_size;i++){
|
||||
|
||||
if(line1.at(i) != line2.at(i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//Return the description of the grid in a string.
|
||||
//In other terms, the grid in ASCII
|
||||
std::string Grid::description(){
|
||||
|
||||
//Init stringstream description
|
||||
|
@ -53,55 +300,15 @@ std::string Grid::description(){
|
|||
return description.str();
|
||||
}
|
||||
|
||||
//==================== Getters and Setters ====================
|
||||
|
||||
int Grid::maxStrLenInGrid(){
|
||||
int max=0;
|
||||
for(int i=0;i<m_size;i++){
|
||||
for(int j=0;j<m_size;j++){
|
||||
std::string number=std::to_string(m_grid.at(i).at(j));
|
||||
if(number.size() > max)
|
||||
max=number.size();
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
bool Grid::isEmpty(int i, int j){
|
||||
if(m_grid.at(i).at(j) == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::tuple<int, int> Grid::getRandomEmptyCellCoord(){
|
||||
|
||||
//Init list of candidate
|
||||
std::vector<std::tuple<int, int> > candidates;
|
||||
|
||||
//Construct list of candidates
|
||||
for(int i=0;i<m_size;i++){
|
||||
for(int j=0;j<m_size;j++){
|
||||
if(this->isEmpty(i,j)){
|
||||
std::tuple<int, int> currentCandidate(i,j);
|
||||
candidates.push_back(currentCandidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//If no candidate available
|
||||
if(candidates.size() == 0)
|
||||
return std::tuple<int, int>(-1, -1);
|
||||
|
||||
//Select the candidates
|
||||
int winnerIs(rand() % candidates.size());
|
||||
|
||||
//Return the candidate
|
||||
return candidates.at(winnerIs);
|
||||
|
||||
//Getter for m_lastMoveScore
|
||||
int Grid::getLastMoveScore(){
|
||||
return m_lastMoveScore;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Change value of cell
|
||||
//Change value of cell with a tuple
|
||||
bool Grid::setCell(std::tuple<int, int> coord, int value){
|
||||
int i=std::get<0>(coord);
|
||||
int j=std::get<1>(coord);
|
||||
|
@ -114,157 +321,20 @@ bool Grid::setCell(std::tuple<int, int> coord, int value){
|
|||
return false;
|
||||
}
|
||||
|
||||
//Another setCell method
|
||||
//Change value of cell with int
|
||||
bool Grid::setCell(int i, int j, int value){
|
||||
std::tuple<int, int> coord(i,j);
|
||||
return this->setCell(coord, value);
|
||||
}
|
||||
|
||||
|
||||
std::vector<int> Grid::rightDefragment(std::vector<int> line){
|
||||
for(int j=0; j<m_size-1;j++){
|
||||
for(int i=0; i<m_size-1;i++){
|
||||
int val1=line.at(i);
|
||||
int val2=line.at(i+1);
|
||||
|
||||
if(val1 != 0 && val2 == 0){
|
||||
line.at(i)=0;
|
||||
line.at(i+1)=val1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
std::vector<int> Grid::leftDefragment(std::vector<int> line){
|
||||
|
||||
//for(int j=0; j<m_size-1;j++){
|
||||
//for(int i=m_size-1; i>0;i--){
|
||||
//int val1=line.at(i);
|
||||
//int val2=line.at(i-1);
|
||||
|
||||
//if(val1 != 0 && val2 == 0){
|
||||
//line.at(i)=0;
|
||||
//line.at(i-1)=val1;
|
||||
//}
|
||||
//}
|
||||
//}
|
||||
|
||||
std::vector<int> reversedLine= this->reverseLine(line);
|
||||
|
||||
return this->reverseLine(this->rightDefragment(reversedLine));
|
||||
}
|
||||
std::vector<int> Grid::rightMerge(std::vector<int> line){
|
||||
for(int i=0; i< m_size-1;i++){
|
||||
int val1=line.at(i);
|
||||
int val2=line.at(i+1);
|
||||
|
||||
if(val1==val2){
|
||||
line.at(i)=0;
|
||||
line.at(i+1)=val1*2;
|
||||
m_lastMoveScore+=val1*2;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
|
||||
std::vector<int> Grid::leftMerge(std::vector<int> line){
|
||||
for(int i=m_size-1; i>0;i--){
|
||||
int val1=line.at(i);
|
||||
int val2=line.at(i-1);
|
||||
|
||||
if(val1==val2){
|
||||
line.at(i)=0;
|
||||
line.at(i-1)=val1*2;
|
||||
m_lastMoveScore+=val1*2;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
std::vector<int> Grid::swipeLine(std::vector<int> line){
|
||||
|
||||
//Swipe line is :
|
||||
//- A defragmentation
|
||||
//- A merging
|
||||
//- Another defragmentation
|
||||
line=this->rightDefragment(line);
|
||||
line=this->rightMerge(line);
|
||||
line=this->rightDefragment(line);
|
||||
|
||||
//Return swiped line
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
//Swipe to right
|
||||
bool Grid::swipeRight(){
|
||||
|
||||
m_lastMoveScore=0;
|
||||
bool moveDone=false;
|
||||
for(int i=0; i<m_size;i++){
|
||||
std::vector<int> swipedLine(this->rightDefragment(this->leftMerge(this->rightDefragment(m_grid.at(i)))));
|
||||
|
||||
if(!this->compareLines(m_grid.at(i), swipedLine)){
|
||||
moveDone=true;
|
||||
m_grid.at(i)=swipedLine;
|
||||
}
|
||||
}
|
||||
return moveDone;
|
||||
}
|
||||
|
||||
//Swipe to right
|
||||
bool Grid::swipeLeft(){
|
||||
m_lastMoveScore=0;
|
||||
bool moveDone=false;
|
||||
for(int i=0; i<m_size;i++){
|
||||
std::vector<int> swipedLine(this->leftDefragment(this->rightMerge(this->leftDefragment(m_grid.at(i)))));
|
||||
if(!this->compareLines(m_grid.at(i), swipedLine)){
|
||||
moveDone=true;
|
||||
m_grid.at(i)=swipedLine;
|
||||
}
|
||||
}
|
||||
return moveDone;
|
||||
}
|
||||
|
||||
|
||||
bool Grid::swipeUp(){
|
||||
m_lastMoveScore=0;
|
||||
bool moveDone=false;
|
||||
for(int i=0; i<m_size;i++){
|
||||
std::vector<int> colVect=this->getCol(i);
|
||||
|
||||
std::vector<int> swipedLine(this->leftDefragment(this->rightMerge(this->leftDefragment(colVect))));
|
||||
if(!this->compareLines(colVect, swipedLine)){
|
||||
moveDone=true;
|
||||
this->setCol(i,swipedLine);
|
||||
}
|
||||
}
|
||||
return moveDone;
|
||||
}
|
||||
bool Grid::swipeDown(){
|
||||
m_lastMoveScore=0;
|
||||
bool moveDone=false;
|
||||
for(int i=0; i<m_size;i++){
|
||||
std::vector<int> colVect=this->getCol(i);
|
||||
|
||||
std::vector<int> swipedLine(this->rightDefragment(this->leftMerge(this->rightDefragment(colVect))));
|
||||
|
||||
if(!this->compareLines(colVect, swipedLine)){
|
||||
moveDone=true;
|
||||
this->setCol(i,swipedLine);
|
||||
}
|
||||
}
|
||||
return moveDone;
|
||||
}
|
||||
|
||||
//Assign a vector to a column.
|
||||
void Grid::setCol(int col, std::vector<int> colVect){
|
||||
for(int i=0;i<m_size;i++){
|
||||
m_grid.at(i).at(col)=colVect.at(i);
|
||||
}
|
||||
}
|
||||
|
||||
//Retrieve a specific column.
|
||||
std::vector<int> Grid::getCol(int col){
|
||||
|
||||
std::vector<int> colVect;
|
||||
|
@ -275,66 +345,3 @@ std::vector<int> Grid::getCol(int col){
|
|||
|
||||
return colVect;
|
||||
}
|
||||
|
||||
std::vector<int> Grid::reverseLine(std::vector<int> line){
|
||||
std::vector<int> reversedLine;
|
||||
|
||||
for(int j=m_size-1; j>=0;j--){
|
||||
reversedLine.push_back(line.at(j));
|
||||
}
|
||||
|
||||
return reversedLine;
|
||||
}
|
||||
|
||||
|
||||
bool Grid::isFull(){
|
||||
|
||||
for(int i=0;i<m_size;i++){
|
||||
for(int j=0;j<m_size;j++){
|
||||
if(m_grid.at(i).at(j) == 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Grid::isOver(){
|
||||
|
||||
if(!this->isFull())
|
||||
return false;
|
||||
|
||||
for(int i=0;i<m_size;i++){
|
||||
for(int j=0;j<m_size-1;j++){
|
||||
if(m_grid.at(i).at(j) == m_grid.at(i).at(j+1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0;i<m_size;i++){
|
||||
std::vector<int> colVect(this->getCol(i));
|
||||
|
||||
for(int j=0;j<m_size-1;j++){
|
||||
if(colVect.at(j) == colVect.at(j+1))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
|
||||
}
|
||||
|
||||
bool Grid::compareLines(std::vector<int> line1, std::vector<int> line2){
|
||||
|
||||
for(int i=0;i<m_size;i++){
|
||||
|
||||
if(line1.at(i) != line2.at(i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int Grid::getLastMoveScore(){
|
||||
return m_lastMoveScore;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue