diff --git a/Jeu_2048/game2048.cpp b/Jeu_2048/game2048.cpp index 8427ae7a129a2d4f6d6befcae2cc83362d12864c..5f9d183607261e99dbb881a100ee6149e33fa10a 100644 --- a/Jeu_2048/game2048.cpp +++ b/Jeu_2048/game2048.cpp @@ -35,53 +35,185 @@ QVector<int> Game2048::board() const { } void Game2048::spawnTile() { - QVector<QPair<int,int>> emptyTiles; - for (int row = 0; row < 4; row++) { - for (int col = 0; col < 4; col++) { - if (m_board[row][col] == 0) - flatBoard.append(row * 4 + col); - } - } - if (!flatBoard.isEmpty()) { - int randIndex = QRandomGenerator::global()->bounded(flatBoard.size()); - int index = flatBoard[randIndex]; - int row = index / 4; - int col = index % 4; - m_board[row][col] = (QRandomGenerator::global()->bounded(10) == 0) ? 4 : 2; + QVector<QPair<int,int>> emptyPositions; + for(int i=0; i<4; i++) + for(int j=0; j<4; j++) + if(m_board[i][j] == 0) + emptyPositions.append(qMakePair(i,j)); + + if(!emptyPositions.isEmpty()) { + int randIndex = QRandomGenerator::global()->bounded(emptyPositions.size()); + auto pos = emptyPositions[randIndex]; + m_board[pos.first][pos.second] = (QRandomGenerator::global()->bounded(10)==0) ? 4 : 2; } } + bool Game2048::moveLeft() { bool moved = false; - // Implémentation à venir + for(int i=0; i<4; i++) { // Pour chaque ligne, on compresse, fusionne et re compresse + // Compression à gauche + for(int k=0; k<3; k++) + for(int j=0; j<3; j++) + if(m_board[i][j]==0 && m_board[i][j+1]!=0) { + m_board[i][j]=m_board[i][j+1]; + m_board[i][j+1]=0; + moved=true; + } + // Fusion + for(int j=0; j<3; j++) + if(m_board[i][j]!=0 && m_board[i][j]==m_board[i][j+1]) { + m_board[i][j]*=2; + m_score+=m_board[i][j]; + m_board[i][j+1]=0; + moved=true; + } + // Recompression après fusion + for(int k=0; k<3; k++) + for(int j=0; j<3; j++) + if(m_board[i][j]==0 && m_board[i][j+1]!=0) { + m_board[i][j]=m_board[i][j+1]; + m_board[i][j+1]=0; + } + } + if(moved) { + spawnTile(); + updateGameState(); + emit boardChanged(); + emit scoreChanged(); + } return moved; } bool Game2048::moveRight() { bool moved = false; - // Implémentation à venir + for(int i=0; i<4; i++) { // Pour chaque ligne, on compresse, fusionne et re compresse + // Compression à droite + for(int k=0; k<3; k++) + for(int j=3; j>0; j--) + if(m_board[i][j]==0 && m_board[i][j-1]!=0) { + m_board[i][j]=m_board[i][j-1]; + m_board[i][j-1]=0; + moved=true; + } + // Fusion + for(int j=3; j>0; j--) + if(m_board[i][j]!=0 && m_board[i][j]==m_board[i][j-1]) { + m_board[i][j]*=2; + m_score+=m_board[i][j]; + m_board[i][j-1]=0; + moved=true; + } + // Recompression après fusion + for(int k=0; k<3; k++) + for(int j=3; j>0; j--) + if(m_board[i][j]==0 && m_board[i][j-1]!=0) { + m_board[i][j]=m_board[i][j-1]; + m_board[i][j-1]=0; + } + } + if(moved) { + spawnTile(); + updateGameState(); + emit boardChanged(); + emit scoreChanged(); + } return moved; } bool Game2048::moveUp() { bool moved = false; - // Implémentation à venir + for(int j=0; j<4; j++) { // Pour chaque colonne, on compresse, fusionne et re compresse + // Compression à droite + for(int k=0; k<3; k++) + for(int i=0; i<3; i++) + if(m_board[i][j]==0 && m_board[i+1][j]!=0) { + m_board[i][j]=m_board[i+1][j]; + m_board[i+1][j]=0; + moved=true; + } + // Fusion + for(int i=0; i<3; i++) + if(m_board[i][j]!=0 && m_board[i][j]==m_board[i+1][j]) { + m_board[i][j]*=2; + m_score+=m_board[i][j]; + m_board[i+1][j]=0; + moved=true; + } + // Recompression après fusion + for(int k=0; k<3; k++) + for(int i=0; i<3; i++) + if(m_board[i][j]==0 && m_board[i+1][j]!=0) { + m_board[i][j]=m_board[i+1][j]; + m_board[i+1][j]=0; + } + } + if(moved) { + spawnTile(); + updateGameState(); + emit boardChanged(); + emit scoreChanged(); + } return moved; } + bool Game2048::moveDown() { bool moved = false; - // Implémentation à venir + for(int j=0; j<4; j++) { // Pour chaque colonne, on compresse, fusionne et re compresse + // Compression à droite + for(int k=0; k<3; k++) + for(int i=3; i>0; i--) + if(m_board[i][j]==0 && m_board[i-1][j]!=0) { + m_board[i][j]=m_board[i-1][j]; + m_board[i-1][j]=0; + moved=true; + } + // Fusion + for(int i=3; i>0; i--) + if(m_board[i][j]!=0 && m_board[i][j]==m_board[i-1][j]) { + m_board[i][j]*=2; + m_score+=m_board[i][j]; + m_board[i-1][j]=0; + moved=true; + } + // Recompression après fusion + for(int k=0; k<3; k++) + for(int i=3; i>0; i--) + if(m_board[i][j]==0 && m_board[i-1][j]!=0) { + m_board[i][j]=m_board[i-1][j]; + m_board[i-1][j]=0; + } + } + if(moved) { + spawnTile(); + updateGameState(); + emit boardChanged(); + emit scoreChanged(); + } return moved; } +bool Game2048::canMove() const { + for (int i=0; i<4; i++){ + for (int j=0; j<4; j++){ + if (m_board[i][j]==0){ + return true; + } + if (i<3 && m_board[i][j]==m_board[i+1][j]){ + return true; + } + if (j<3 && m_board[i][j]==m_board[i][j+1]){ + return true; + } + } + } + return true; +} + + void Game2048::updateGameState() { if (!canMove()) { emit gameOver(); } } - -bool Game2048::canMove() const { - // Implémentation basique à compléter - return true; -}