diff --git a/.gitignore b/.gitignore deleted file mode 100644 index fab7372d796ea95c80d02df6caa7eb2b411a7ac1..0000000000000000000000000000000000000000 --- a/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# This file is used to ignore files which are generated -# ---------------------------------------------------------------------------- - -*~ -*.autosave -*.a -*.core -*.moc -*.o -*.obj -*.orig -*.rej -*.so -*.so.* -*_pch.h.cpp -*_resource.rc -*.qm -.#* -*.*# -core -!core/ -tags -.DS_Store -.directory -*.debug -Makefile* -*.prl -*.app -moc_*.cpp -ui_*.h -qrc_*.cpp -Thumbs.db -*.res -*.rc -/.qmake.cache -/.qmake.stash - -# qtcreator generated files -*.pro.user* - -# xemacs temporary files -*.flc - -# Vim temporary files -.*.swp - -# Visual Studio generated files -*.ib_pdb_index -*.idb -*.ilk -*.pdb -*.sln -*.suo -*.vcproj -*vcproj.*.*.user -*.ncb -*.sdf -*.opensdf -*.vcxproj -*vcxproj.* - -# MinGW generated files -*.Debug -*.Release - -# Python byte code -*.pyc - -# Binaries -# -------- -*.dll -*.exe - diff --git a/Carre.qml b/Carre.qml index 9e8414e427e45d535350053c225be2ac2ae969f9..dc596d6de0d2d820d2f67bf8d6613d7f50c2a452 100644 --- a/Carre.qml +++ b/Carre.qml @@ -1,191 +1,93 @@ -import QtQuick 2.0 +import QtQuick 2.11 +import QtQuick.Window 2.11 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 1.4 Item { - id: monCarre - width: 154 - height: 154 - property alias case9: case9 - property alias case8: case8 - property alias case7: case7 - property alias case6: case6 - property alias case5: case5 - property alias case4: case4 - property alias case3: case3 - property alias case2: case2 - property alias case1: case1 - - - Rectangle { - id: backgroudcarre - color: "#ffffff" - border.width: 2 - anchors.fill: parent - focus: true - - Case { - id: case1 - anchors.left: parent.left - anchors.top: parent.top - chiffreText: qsTr("9") - anchors.leftMargin: 2 - anchors.topMargin: 2 - - MouseArea { - id: mouseArea1 - focus: true - anchors.fill: parent - onClicked: { - console.log(Math.floor(monCarre.x/50)+1, Math.floor(monCarre.y/50)+1) - } - } - } - - Case { - id: case2 - x: 50 - anchors.top: parent.top - chiffreText: qsTr("9") - anchors.topMargin: 2 - anchors.horizontalCenter: parent.horizontalCenter - MouseArea { - id: mouseArea2 - focus: true - anchors.fill: parent - onClicked: { - console.log(Math.floor(monCarre.x/50)+2, Math.floor(monCarre.y/50)+1) - } - } - } - - Case { - id: case3 - x: 100 - y: 0 - anchors.right: parent.right - anchors.top: parent.top - chiffreText: qsTr("9") - anchors.rightMargin: 2 - anchors.topMargin: 2 - MouseArea { - id: mouseArea3 - focus: true - anchors.fill: parent - onClicked: { - console.log(Math.floor(monCarre.x/50)+3, Math.floor(monCarre.y/50)+1) - } - } - } - - Case { - id: case4 - x: 0 - y: 50 - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - chiffreText: qsTr("9") - anchors.leftMargin: 2 - MouseArea { - id: mouseArea4 - focus: true - anchors.fill: parent - onClicked: { - console.log(Math.floor(monCarre.x/50)+1, Math.floor(monCarre.y/50)+2) + function envoyer_valeur(app){ + var i; + var j; + for(i=0;i<9;i++){ + for(j=0;j<9;j++){ + var carr = repeater.itemAt(i).rep.itemAt(j).input + if (app === carr){ + vueObjetCpt.changer_valeur(app.text,i,j); } } } - - Case { - id: case5 - x: 50 - y: 50 - anchors.verticalCenter: parent.verticalCenter - chiffreText: "9" - anchors.horizontalCenter: parent.horizontalCenter - MouseArea { - id: mouseArea5 - focus: true - anchors.fill: parent - onClicked: { - console.log(Math.floor(monCarre.x/50)+2, Math.floor(monCarre.y/50)+2) - } + var values = vueObjetCpt.values; + var l + var c + for(l=0;l<9;l++){ + for(c=0;c<9;c++){ + var v = repeater.itemAt(l).rep.itemAt(c).input + v.text=values[l][c]; } } - - - - - Case { - id: case6 - x: 0 - y: 102 - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - chiffreText: qsTr("9") - anchors.rightMargin: 2 - MouseArea { - id: mouseArea6 - focus: true - anchors.fill: parent - onClicked: { - console.log(Math.floor(monCarre.x/50)+3, Math.floor(monCarre.y/50)+2) - } + var colors = vueObjetCpt.colors; + for(i=0;i<9;i++){ + for(j=0;j<9;j++){ + var w = repeater.itemAt(i).rep.itemAt(j) + w.color=colors[i][j]; } } + } - Case { - id: case7 - y: 106 - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.leftMargin: 2 - anchors.bottomMargin: 2 - MouseArea { - id: mouseArea7 - focus: true - anchors.fill: parent - onClicked: { - console.log(Math.floor(monCarre.x/50)+1, Math.floor(monCarre.y/50)+3) + function changer_couleur(app, focus){ + var i; + var j; + for(i=0;i<9;i++){ + for(j=0;j<9;j++){ + var carr = repeater.itemAt(i).rep.itemAt(j).input + if (app === carr){ + vueObjetCpt.colorer_voisins(i,j,focus); } } } - - Case { - id: case8 - x: 68 - y: 114 - anchors.bottom: parent.bottom - anchors.horizontalCenterOffset: 0 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: 2 - MouseArea { - id: mouseArea8 - focus: true - anchors.fill: parent - onClicked: { - console.log(Math.floor(monCarre.x/50)+2, Math.floor(monCarre.y/50)+3) - } + var colors = vueObjetCpt.colors; + for(i=0;i<9;i++){ + for(j=0;j<9;j++){ + var v = repeater.itemAt(i).rep.itemAt(j) + v.color=colors[i][j]; } } - - Case { - id: case9 - x: 115 - y: 122 - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.bottomMargin: 2 - anchors.rightMargin: 2 - MouseArea { - id: mouseArea9 - focus: true - anchors.fill: parent - onClicked: { - console.log(Math.floor(monCarre.x/50)+3, Math.floor(monCarre.y/50)+3) + } + property alias rep : repeater1 + + Grid{ + id : grid + x: 3; y:3 + rows:3; columns:3; spacing :2 + + + Repeater{ id : repeater1 + model : 9 + + Rectangle{ + color : "#ffffff" + width : 68; height: 68 + property alias input : input + border.width : 2 + border.color : "#000000" + + TextInput{ + id:input + color:'#333333' + width : parent.width + height:parent.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + readOnly: false + font.pointSize: 24 + maximumLength: 1 + validator: RegExpValidator { regExp: /[1-9]+/ } + onFocusChanged: { + changer_couleur(this, focus) + } + onTextEdited : envoyer_valeur(this) } } } - - } - } + diff --git a/Case.qml b/Case.qml deleted file mode 100644 index 38aa8629fea14c634d1bfa8d27ceb49e329ce44c..0000000000000000000000000000000000000000 --- a/Case.qml +++ /dev/null @@ -1,49 +0,0 @@ -import QtQuick 2.0 - -Item { - id: maCase - width: 50 - height: 50 - property alias backgroundCaseBordercolor: backgroundCase.border.color - property alias backgroundCaseColor: backgroundCase.color - property alias chiffreColor: chiffre.color - property alias chiffreText: chiffre.text - - Rectangle { - id: backgroundCase - color: "#ffffff" - radius: 0 - border.width: 2 - anchors.fill: parent - focus: true - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - onEntered: { - parent.color = "#998c8c" - } - onExited: { - parent.color = "#ffffff" - } - onClicked: { - console.log(maCase.x, maCase.y) - - } - } - - Text { - id: chiffre - text: qsTr("9") - anchors.fill: parent - font.pixelSize: 25 - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.bold: true - font.family: "Verdana" - } - - } - -} diff --git a/Grille.qml b/Grille.qml deleted file mode 100644 index 483ec2677bd28c8fd66336fa9116fbedb97f310d..0000000000000000000000000000000000000000 --- a/Grille.qml +++ /dev/null @@ -1,120 +0,0 @@ -import QtQuick 2.0 - -Item { - id: maGrille - width: 466 - height: 466 - property alias carre9: carre9 - property alias carre8: carre8 - property alias carre7: carre7 - property alias carre6: carre6 - property alias carre5: carre5 - property alias carre4: carre4 - property alias carre3: carre3 - property alias carre2: carre2 - property alias carre1: carre1 - - Rectangle { - id: backgroundGrille - color: "#ffffff" - border.width: 2 - anchors.fill: parent - - Carre { - id: carre1 - anchors.left: parent.left - anchors.top: parent.top - case9.chiffreText: qsTr("9") - case8.chiffreText: qsTr("9") - case7.chiffreText: qsTr("9") - case6.chiffreText: qsTr("9") - case5.chiffreText: qsTr("9") - case4.chiffreText: qsTr("9") - case3.chiffreText: qsTr("9") - case2.chiffreText: qsTr("9") - case1.chiffreText: qsTr("9") - anchors.leftMargin: 2 - anchors.topMargin: 2 - } - - Carre { - id: carre2 - x: 178 - anchors.top: parent.top - case9.chiffreText: qsTr("") - case8.chiffreText: qsTr("") - case7.chiffreText: qsTr("") - case6.chiffreText: qsTr("") - case5.chiffreText: qsTr("") - case4.chiffreText: qsTr("") - case3.chiffreText: qsTr("") - case2.chiffreText: qsTr("") - case1.chiffreText: qsTr("9") - anchors.horizontalCenter: parent.horizontalCenter - anchors.topMargin: 2 - } - - Carre { - id: carre3 - x: 347 - anchors.right: parent.right - anchors.top: parent.top - anchors.rightMargin: 2 - anchors.topMargin: 2 - } - - Carre { - id: carre4 - y: 191 - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: 2 - } - - Carre { - id: carre5 - x: 279 - y: 219 - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - } - - Carre { - id: carre6 - x: 361 - y: 199 - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 2 - } - - Carre { - id: carre7 - y: 338 - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.leftMargin: 2 - anchors.bottomMargin: 2 - } - - Carre { - id: carre8 - x: 225 - y: 330 - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: 2 - } - - Carre { - id: carre9 - x: 316 - y: 316 - anchors.right: parent.right - anchors.bottom: parent.bottom - anchors.rightMargin: 2 - anchors.bottomMargin: 2 - } - } - -} diff --git a/README.md b/README.md index 41d84e862acedaed190d3ba40e35d8a1af5af4c3..428bce639d910dc1ef05ffdf1fb94f44d0934b76 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,2 @@ -# Projet Sudoku +# sudoku -Le projet est en cours de développement diff --git a/Sudoku.pro b/Sudoku.pro index d4de6702dadb987f0d1476788824565a50f0b349..623aa044ea58c29d80f58fdd4c4795b541dadc98 100644 --- a/Sudoku.pro +++ b/Sudoku.pro @@ -23,11 +23,7 @@ qnx: target.path = /tmp/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin !isEmpty(target.path): INSTALLS += target +DISTFILES += + HEADERS += \ grille.h - -DISTFILES += \ - Carre.qml \ - Case.qml \ - Case.qml \ - Grille.qml diff --git a/erase.png b/erase.png deleted file mode 100644 index 35c050e839b3c17d9ed89cebe90f916eb37c9500..0000000000000000000000000000000000000000 Binary files a/erase.png and /dev/null differ diff --git a/grille.cpp b/grille.cpp index b564f883865a62a719f9af0847a1a6a7d9a6d7ec..4cfc68f0c6b084385f85638bd5d45ecb42128ec6 100644 --- a/grille.cpp +++ b/grille.cpp @@ -1,191 +1,280 @@ -#include "grille.h" - -Grille::Grille(int vd) -{ - Alloc(); - Init(vd); -} - - -Grille::Grille(const Grille &D) -{ - Alloc(); - - for(int i=0; i<9; i++) - for(int j=0; j<9; j++) - T[i][j] = D.T[i][j]; -} - +#include<iostream> +#include <fstream> +#include <typeinfo> +#include <string> -Grille::~Grille(){ - if (T != NULL) { - Free(); - T = NULL; +#include "grille.h" +using namespace std; + +Grille::Grille(QObject *parent) : QObject(parent){ + ifstream myFile("../sudoku/grilles/grilleDebutant.csv"); //choisir la grille ici + string ligne[9]; + + int i = 0; + + while(myFile.good() & (i<9)){ + getline(myFile,ligne[0],'|'); + getline(myFile,ligne[1],'|'); + getline(myFile,ligne[2],'|'); + getline(myFile,ligne[3],'|'); + getline(myFile,ligne[4],'|'); + getline(myFile,ligne[5],'|'); + getline(myFile,ligne[6],'|'); + getline(myFile,ligne[7],'|'); + getline(myFile,ligne[8],'\n'); + for(int k=0;k<9;k++){ + if (ligne[k]!="."){ + grille[i][k]=ligne[k]; + } + } + i++; } -} + Print(); + matriceToVectors(); - -void Grille::Free(){ - for (int i=0; i<9; i++) { - delete [] T[i]; + // coloriage des cases en blanc + QList<QString> colors_case; + for(int i =0;i<9;i++){ + colors_case.push_back("white"); + } + for(int j =0;j<9;j++){ + colors.push_back(colors_case); } - delete [] T; -} - - -void Grille::Alloc(){ - T = new int*[9]; - for(int i=0; i<9; i++) - T[i] = new int[9]; } +void Grille::verif_matrice(){ + // verifie si la grille remplie par le joueur vérifie les règles du sudoku ou non + bool victoire = true; + list<string> lok= {"1", "2", "3", "4", "5", "6","7","8", "9"}; -void Grille::Print(){ - for(int i=0; i<9; i++) { - cout << endl; - for(int j=0; j<9; j++) - cout << T[i][j] << ", "; + // vérification par ligne + for(int i=0; i<9; i++){ + list<string> L; + for(int j= 0; j<9; j++){ + L.push_back(grille[i][j]); + } + L.sort(); + victoire = victoire && (L==lok); } - cout <<endl<<endl; -} + // vérification par colonne + for(int i=0; i<9; i++){ + list<string> L; + for(int j= 0; j<9; j++){ + L.push_back(grille[j][i]); + } + L.sort(); + victoire = victoire && (L==lok); + } + // vérification par case 3x3 + for(int l=0; l<3;l++){ + for(int c = 0; c<3; c++){ + list<string> L; + for(int i=3*l; i<3*l+3; i++){ + for(int j=3*c; j<3*c+3; j++){ + L.push_back(grille[i][j]); + } + } + L.sort(); + victoire = victoire && (L==lok); + } + } -void Grille::Init(int value){ - for(int i=0; i<9; i++) - for(int j=0; j<9; j++) - T[i][j]=value; + verif = victoire; + emit verifClicked(); } +void Grille::set_chiffre_actif(int i){ + changer_valeur(i, caseselected[0], caseselected[1]); + emit chiffreActifChanged(); +} -void Grille::Set(int x, int y, int value) { - /* Modifie la valeur de la grille aux coordonnées (x,y) par value*/ - - if (x<9 && 0<=x && 0<=y && y<9){ - if (value<=9 && value>0) - T[x][y]=value; - else - cout << "La valeur n'est pas comprise entre 1 et 9." << endl << endl; +void Grille::matriceToVectors(){ + //passage d'un array nommé grille de taille 9x9 de string à valeurs qui est une QList<QList<QString>> + QList<QString> case1,case2,case3,case4,case5,case6,case7,case8,case9; + + // on peut encore simplifier tout ca + + for(int i=0;i<3;i++){ + for (int j=0;j<3;j++){ + case1.append(QString::fromStdString(grille[i][j])); + case2.append(QString::fromStdString(grille[i][j+3])); + case3.append(QString::fromStdString(grille[i][j+6])); + case4.append(QString::fromStdString(grille[i+3][j])); + case5.append(QString::fromStdString(grille[i+3][j+3])); + case6.append(QString::fromStdString(grille[i+3][j+6])); + case7.append(QString::fromStdString(grille[i+6][j])); + case8.append(QString::fromStdString(grille[i+6][j+3])); + case9.append(QString::fromStdString(grille[i+6][j+6])); + } } - else - cout << "Les coordonnées ne sont pas adaptées." << endl << endl; + valeurs = {case1,case2,case3,case4,case5,case6,case7,case8,case9}; } - -int Grille::Get(int x, int y){ - return T[x][y]; +void Grille::colorer_X(int i, int l){ + // coloriage dans les carrés i à i+3 de la ligne l + for(int k =i;k<i+3;k++) + for(int m=l*3;m<l*3+3;m++) + colors[k][m]="#eaeaea"; } +void Grille::colorer_Y(int i, int c){ + // coloriage dans tous les carrés de la colonne i (entre 0 et 2) de la colonne l (entre 0 et 2 également) + for (int k=i;k<i+7;k+=3) + for (int m=c;m<c+7;m+=3) + colors[k][m]="#eaeaea"; +} -void Grille::EssaiJoueur(){ - /* Appelée quand le joueur à sélectionné à la fois une case et un chiffre - * on vérifie alors avec les règles du sudoku (ligne/colonne/case) que le coup est permit*/ - - bool essai=true; +void Grille::colorer_voisins( int Carre,int Case,bool focus){ + caseselected[0] = Carre; + caseselected[1]= Case; -// on vérifie pour la colonne et la ligne - for (int i=0;i<9;i++){ - if (chiffre_actif==T[x_actif][i] ){ - essai = false; - cout << "Le chiffre " << chiffre_actif << " est déjà présent dans la ligne." << endl << endl; - } - else if (chiffre_actif==T[i][y_actif]){ - essai = false; - cout << "Le chiffre " << chiffre_actif << " est déjà présent dans la colonne." << endl << endl; + if(focus){ + // reset les couleurs de toute la grille au blanc + for(int k =0;k<9;k++){ + for(int j =0;j<9;j++){ + colors[k][j]="white"; } } -//on vérifie pour la case de 3x3 - int case_3_x=floor(x_actif/3); - int case_3_y=floor(y_actif/3); - for(int i=3*case_3_x;i<3*case_3_x+3;i++) - for (int j=3*case_3_y;j<3*case_3_y+3;j++){ - if (T[i][j]==chiffre_actif){ - essai = false; - cout << "Le chiffre " << chiffre_actif << " est déjà présent dans le carré 3x3." << endl << endl; + // recolore les cases du carré selectionné + for(int k =0;k<9;k++){ + colors[Carre][k]="#eaeaea"; + } + + //colorer les lignes horizontales + switch(Carre/3){ + case 0: + colorer_X(0,Case/3); + break; + case 1: + colorer_X(3,Case/3); + break; + case 2: + colorer_X(6,Case/3); + break; + } + // colorer les lignes verticales + switch(Carre%3){ + case 0: + colorer_Y(0,Case%3); + break; + case 1: + colorer_Y(1,Case%3); + break; + case 2: + colorer_Y(2,Case%3); + break; + } + // coloriage des cases avec le même chiffre -- ne fonctionne pour l'instant + if (grille[3*(Carre/3)+(Case/3)][3*(Carre%3)+(Case%3)]!= "" && grille[3*(Carre/3)+(Case/3)][3*(Carre%3)+(Case%3)]!="0"){ + for (int i=0;i<9;i++){ + for (int j=0;j<9;j++){ + if (grille[3*(i/3)+(j/3)][3*(i%3)+(j%3)]==grille[3*(Carre/3)+(Case/3)][3*(Carre%3)+(Case%3)]){ + colors[i][j]="#9eaac8"; + + } } } - -// On indique si l'on peut remplir la case ou non et si oui, on le fait - if (essai){ - cout << "L'essai est réussi." << endl << endl; - Set(x_actif,y_actif,chiffre_actif); - x_actif=0; - y_actif=0; - chiffre_actif=0; - } + Print(); - else - cout << "L'essai a échoué." << endl << endl; -} - - -void Grille::SelectChiffre(int c){ - /* On sélectionne le chiffre que l'on veut mettre par la suite.*/ - - if (1<=c && c<=9 && c!=chiffre_actif){ - cout << "Le chiffre selectionné est " << c << "." << endl<<endl; - chiffre_actif = c; - } - else if(c==chiffre_actif){ - chiffre_actif=0; //on déselectionne en tapant une deuxième fois sur le chiffre - } - else{ - cout << "Le chiffre selectionné n'est pas compris entre 1 et 9." << endl; + emit focusChanged(); } } +void Grille::changer_valeur(int valeur, int Carre,int Case){ + string value =to_string(valeur); + if (value == "0"){ + value=""; + } -void Grille::SelectCase(int x, int y){ - /* On sélectionne la case que l'on veut mettre par la suite.*/ + int ligne, colonne; + switch(Carre){ + case 0: + colonne = Case%3; + ligne = Case/3; + break; + case 1: + colonne = Case%3+3; + ligne = Case/3; + break; + case 2: + colonne = Case%3+6; + ligne = Case/3; + break; + case 3: + colonne = Case%3; + ligne = Case/3+3; + break; + case 4: + colonne = Case%3+3; + ligne = Case/3+3; + break; + case 5: + colonne = Case%3+6; + ligne = Case/3+3; + break; + case 6: + colonne = Case%3; + ligne = Case/3+6; + break; + case 7: + colonne = Case%3+3; + ligne = Case/3+6; + break; + case 8: + colonne = Case%3+6; + ligne = Case/3+6; + break; + } - if (0<=x && x<9 && 0<=y && y<9 ){ - // si on sélectionne la case déja active, on la déselectionne. - if (x_actif==x && y_actif==y){ - x_actif=0; - y_actif=0; - cout << "La case a été désélectionnée."<<endl; + // on teste si les règles sont respectées + bool possible=true; + + // test sur le carré + if(value!=""){ + for (int i=0;i<3;i++){ + for (int j=0;j<3;j++){ + if (grille[3*(ligne/3)+i][3*(colonne/3)+j]==value){ + possible=false; + cout <<3*((3*(ligne/3)+i)/3)+(3*(colonne/3)+j)/3<<3*((3*(ligne/3)+i)%3)+(3*(colonne/3)+j)%3<<endl; + colors[3*((3*(ligne/3)+i)/3)+(3*(colonne/3)+j)/3][3*((3*(ligne/3)+i)%3)+(3*(colonne/3)+j)%3]="#d14545"; + break; + } + } } - // si ce n'est pas le cas, on la sélectionne. - else{ - x_actif=x; - y_actif=y; - cout << "La case sélectionnée est (" << x_actif << "," << y_actif <<")" << endl<<endl; + // test sur les lignes et colonnes + for (int j=0;j<9;j++){ + if (grille[j][colonne]==value && j!=ligne){ + possible=false; + colors[3*(j/3)+(colonne)/3][3*(j%3)+(colonne)%3]="#d14545"; + } + else if (grille[ligne][j]==value && j!=colonne){ + possible=false; + colors[3*(ligne/3)+(j)/3][3*(ligne%3)+(j)%3]="#d14545"; + } } } -} -bool Grille::TestWin(){ -/* on teste juste que toute la grille soit remplie.*/ - for (int i=0;i<9;i++) - for (int j=0;j<9;j++) - if (Get(i,j)==0) - return false; - return true; -} + if(possible) + grille[ligne][colonne]=value; + else + cout << "impossible de modifier la valeur" << endl; + matriceToVectors(); -Grille& Grille::operator= (const Grille &D){ - if ( this != &D) { // protection autoréférence - Free(); - Alloc(); - for(int i=0; i<9; i++) - for(int j=0; j<9; j++) - T[i][j] = D.T[i][j]; - } - return *this; -} + // affichage de la grille + Print(); +} -ostream& operator<< (ostream& sortie, Grille& V) -{ - sortie << endl; +void Grille::Print(){ for(int i=0; i<9; i++) { - sortie << endl; + cout << endl; for(int j=0; j<9; j++) - sortie << V.T[i][j] << ", "; + cout << grille[i][j] << ", "; } - return sortie; + cout <<endl<<endl; } - diff --git a/grille.h b/grille.h index 04e5cd2e35f18dfc2050d8cb47748dabacd9efe1..999aec29044b158fa4a3db3f1b92b304ab920f9f 100644 --- a/grille.h +++ b/grille.h @@ -2,58 +2,47 @@ #define GRILLE_H #include <QObject> -#include <iostream> -#include <math.h> - -#include <QFile> -#include <QStringList> -#include <QDebug> - -#include <algorithm> -#include <string> - +#include<string> using namespace std; -class Grille //: public QObject +class Grille : public QObject { -// Q_OBJECT -public: - Grille(int vd=0); - Grille(const Grille &D); - ~Grille(); - -// Q_PROPERTY(QList<QString> tableauQML READ readGrille NOTIFY grilleChanged) + Q_OBJECT - Grille& operator= (const Grille &D); // opérateur d'affectation - friend ostream& operator<< (ostream& sortie, Grille& V); + Q_PROPERTY(QList<QList<QString>> values MEMBER valeurs NOTIFY valChanged) + Q_PROPERTY(QList<QList<QString>> colors MEMBER colors NOTIFY focusChanged) + Q_PROPERTY(int verifier MEMBER verif NOTIFY verifClicked) + Q_PROPERTY(int coloration MEMBER chiffre_IsActif NOTIFY chiffreActifChanged) +public: + explicit Grille(QObject *parent = nullptr); + Q_INVOKABLE void changer_valeur(int valeur, int Carre,int Case); + Q_INVOKABLE void colorer_voisins( int Carre,int Case, bool focus); + Q_INVOKABLE void verif_matrice( ); + Q_INVOKABLE void set_chiffre_actif(int i); void Print(); - void Init(int value); - void Set(int x, int y, int value); - int Get(int x, int y); - void EssaiJoueur(); // on regarde si la case (x_actif,y_actif) a la valeur chiffre_actif - void SelectChiffre(int c); - void SelectCase(int x,int y); - bool TestWin(); private: - int** T; // c'est le tableau que l'on complète - int chiffre_actif; //la valeur sélectionnée à l'écran - int x_actif; //abscisse case active - int y_actif; //ordonnée case active - bool win; // la partie est gagnée ou non + void matriceToVectors(); + void colorer_X(int i, int l ); + void colorer_Y(int i, int c ); + QList<QList<QString>> colors; // contient les couleurs de chaque case + QList<QList<QString>> valeurs; // contient les valeurs de chaque case sous forme de Qstring + string grille[9][9]; + int caseselected[2] = {0,0};// contient les valeurs de chaque case sous forme de string + int verif; + int chiffre_actif; + int chiffre_IsActif; - // Méthode privée (factorisation de code) - void Alloc(); - void Free(); +signals: + void valChanged(); + void focusChanged(); + void verifClicked(); + void chiffreActifChanged(); -/* -signals : - void grilleChanged(); -*/ }; #endif // GRILLE_H diff --git a/grilles/grilleFacile.csv b/grilles/grilleFacile.csv index 6347bf713c05e3e49799ceac366a17ad43d6a5fb..23fbe36d5221b4f66b04284e3a52e7154f8035eb 100644 --- a/grilles/grilleFacile.csv +++ b/grilles/grilleFacile.csv @@ -1,4 +1,3 @@ -# Grille extraite de https://qqwing.com/generate.html 4|.|.|2|7|5|.|8|. .|.|.|.|1|.|4|7|. .|.|.|.|.|.|9|.|5 diff --git a/grilles/grilleIntermediaire.csv b/grilles/grilleIntermediaire.csv index 21ba5d03df183a862b52c206faf8a44655e95b6a..857acac06817a8c0defddf4fab5e0082503d72a2 100644 --- a/grilles/grilleIntermediaire.csv +++ b/grilles/grilleIntermediaire.csv @@ -1,4 +1,3 @@ -# Grille extraite de https://qqwing.com/generate.html .|.|4|8|.|.|.|1|. .|.|.|9|.|1|.|2|. .|6|.|2|.|.|4|3|. diff --git a/main.cpp b/main.cpp index 9cac1fb61198043c5bbb8199d0d3856e7c3baafa..cbca0cbcf7142600d75670d1a9a945a29ef47d76 100644 --- a/main.cpp +++ b/main.cpp @@ -1,71 +1,18 @@ #include <QGuiApplication> #include <QQmlApplicationEngine> -#include <QtQml> - -#include <QFile> -#include <QStringList> -#include <QDebug> - #include <iostream> -#include <math.h> -#include "grille.h" - -#include <algorithm> #include <string> +#include <QQmlContext> +#include "grille.h" -int main(int argc, char *argv[]){ - -// Lecture de la grille .csv de départ -// SI POSSIBLE CHANGER CELA EN FCT, UTILE POUR ENREGISTRER UNE PARTIE EN COURS ET LA REOUVRIR -// Pb avec QFile qui ne veut pas s'initialiser - Grille G; - QFile file("../Sudoku/grilles/grilleFacile.csv"); - if (!file.open(QIODevice::ReadOnly)) { - qDebug() << file.errorString(); - return 1; - } - - QStringList matrice_List; - file.readLine(); // on ne veut pas la première ligne - int i=0; // permet de savoir quelle ligne ou lit - while (!file.atEnd()) { - QByteArray line = file.readLine(); // on lit ligne par ligne le fichier - std::replace(line.begin(), line.end(), '.','0'); // on remplace les . du .csv par des 0 - for (int j=0; j<9;j++){ - if (int(line[2*j])-48>0) - G.Set(i,j,int(line[2*j])-48); // on remplit le tableau avec les valeurs de départ - } - i+=1; - } - G.Print(); - - -// test sélection et remplissage de case - G.SelectCase(2,2); - G.SelectChiffre(4); - G.EssaiJoueur(); - - G.SelectCase(8,1); // pas besoin de reselectionner de nouveau le chiffre si on veut le mm - G.EssaiJoueur(); - G.SelectCase(4,8); - G.SelectChiffre(7); - G.EssaiJoueur(); - - G.Print(); - -// Updated upstream -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - - -// Stashed changes +int main(int argc, char *argv[]){ QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif QGuiApplication app(argc, argv); - + Grille aGrille ; QQmlApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, @@ -73,12 +20,8 @@ int main(int argc, char *argv[]){ if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); + engine.rootContext()->setContextProperty("vueObjetCpt", &aGrille); engine.load(url); return app.exec(); -// Updated upstream - - - return(0); -// Stashed changes } diff --git a/main.qml b/main.qml index 39c8864fd4731b841cc72d107863a96065c3a50e..fabb9d86a5ccc85e3a210e478657ef51de142239 100644 --- a/main.qml +++ b/main.qml @@ -1,164 +1,348 @@ -import QtQuick 2.12 -import QtQuick.Window 2.12 +import QtQuick 2.11 +import QtQuick.Window 2.11 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.15 Window { - width: 900 - height: 700 + id : root + color: "#e6ecfa" + width: 650+5 + height: 712+5 visible: true title: qsTr("Sudoku") - Rectangle { - id: rectangle - color: "#eae1c3" - anchors.fill: parent - focus: true - Keys.onPressed: { - switch (event.key) { - case Qt.Key_A: - grille.carre4.case2.chiffreText=qsTr("0") - break; - } + function check(){ + vueObjetCpt.verif_matrice(); + var verif = vueObjetCpt.verifier; + if(verif===1){ + result.visible=true; + result.rectangle.color="#8ee637"; + result.rectangle.text1.text="Bravo vous avez réussi la partie !"; } - - Grille { - id: grille - x: 217 - y: 103 - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter + else{ result.visible=true; + result.rectangle.color="#666666"; + result.rectangle.text1.text="Il y a une erreur, réessayez !"; } + } - Text { - id: textdyn - x: 431 - text: qsTr("Ici un texte pour les instructions et etc (Type : Bravo)") - anchors.top: parent.top - font.pixelSize: 30 - font.weight: Font.DemiBold - font.family: "Tahoma" - anchors.topMargin: 30 - anchors.horizontalCenter: parent.horizontalCenter + function set_chiffre_actif(i){ + vueObjetCpt.set_chiffre_actif(i); + var chiffre_IsActif = vueObjetCpt.coloration + var values = vueObjetCpt.values; + var l + var c + for(l=0;l<9;l++){ + for(c=0;c<9;c++){ + var v = repeater.itemAt(l).rep.itemAt(c).input + v.text=values[l][c]; + } } + } - Case { - id: bouton6 - x: 425 - y: 620 - anchors.bottom: parent.bottom - chiffreText: "6" - anchors.horizontalCenterOffset: 30 - anchors.bottomMargin: 30 - anchors.horizontalCenter: parent.horizontalCenter + Component.onCompleted:{ + var values=vueObjetCpt.values; + var i; + for(i=0;i<9;i++){ + var t = repeater.itemAt(0).rep.itemAt(i).input + t.text=values[0][i] + if(values[0][i]!==''){ + t.readOnly=true + t.color="#000000" + t.font.bold = true + } } - - Case { - id: bouton5 - x: 392 - y: 620 - anchors.bottom: parent.bottom - chiffreText: "5" - anchors.horizontalCenterOffset: -30 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: 30 + for(i=0;i<9;i++){ + var k = repeater.itemAt(1).rep.itemAt(i).input + k.text=values[1][i] + if(values[1][i]!==''){ + k.readOnly=true + k.color="#000000" + k.font.bold = true + } } - - Case { - id: bouton4 - x: 331 - y: 620 - anchors.bottom: parent.bottom - chiffreText: "4" - anchors.horizontalCenterOffset: -90 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: 30 + for(i=0;i<9;i++){ + var l = repeater.itemAt(2).rep.itemAt(i).input + l.text=values[2][i] + if(values[2][i]!==''){ + l.readOnly=true + l.color="#000000" + l.font.bold = true + } } - - Case { - id: bouton3 - x: 266 - y: 620 - anchors.bottom: parent.bottom - chiffreText: "3" - anchors.horizontalCenterOffset: -150 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: 30 + for(i=0;i<9;i++){ + var m = repeater.itemAt(3).rep.itemAt(i).input + m.text=values[3][i] + if(values[3][i]!==''){ + m.readOnly=true + m.color="#000000" + m.font.bold = true + } } - - Case { - id: bouton2 - x: 201 - y: 620 - anchors.bottom: parent.bottom - chiffreText: "2" - anchors.horizontalCenterOffset: -210 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: 30 + for(i=0;i<9;i++){ + var n = repeater.itemAt(4).rep.itemAt(i).input + n.text=values[4][i] + if(values[4][i]!==''){ + n.readOnly=true + n.color="#000000" + n.font.bold = true + } } - - Case { - id: bouton1 - x: 98 - y: 627 - anchors.bottom: parent.bottom - chiffreText: "1" - anchors.horizontalCenterOffset: -270 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: 30 + for(i=0;i<9;i++){ + var p = repeater.itemAt(5).rep.itemAt(i).input + p.text=values[5][i] + if(values[5][i]!==''){ + p.readOnly=true + p.color="#000000" + p.font.bold = true + } } - - Case { - id: bouton7 - x: 545 - y: 627 - anchors.bottom: parent.bottom - chiffreText: "7" - anchors.horizontalCenterOffset: 90 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: 30 + for(i=0;i<9;i++){ + var q = repeater.itemAt(6).rep.itemAt(i).input + q.text=values[6][i] + if(values[6][i]!==''){ + q.readOnly=true + q.color="#000000" + q.font.bold = true + } } - - Case { - id: bouton8 - x: 621 - y: 627 - anchors.bottom: parent.bottom - chiffreText: "8" - anchors.horizontalCenterOffset: 150 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: 30 + for(i=0;i<9;i++){ + var s = repeater.itemAt(7).rep.itemAt(i).input + s.text=values[7][i] + if(values[7][i]!==''){ + s.readOnly=true + s.color="#000000" + s.font.bold = true + } } - - Case { - id: bouton9 - x: 699 - y: 620 - anchors.bottom: parent.bottom - anchors.horizontalCenterOffset: 210 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: 30 + for(i=0;i<9;i++){ + var j = repeater.itemAt(8).rep.itemAt(i).input + j.text=values[8][i] + if(values[8][i]!==''){ + j.readOnly=true + j.color="#000000" + j.font.bold = true + } } + } + property alias repeater : repeater + + Rectangle{ + id : background + x:3 + y:3 + color : "black" + anchors.verticalCenter: parent.verticalCenter + anchors.verticalCenterOffset: -30 + anchors.horizontalCenter: parent.horizontalCenter + width : childrenRect.width+6 + height : childrenRect.height+6 + + + Grid{ + id : grid + x: 3 + y:3 + rows:3 + columns:3 + spacing :2 + Repeater{ + id : repeater + model : 9 - Case { - id: bouton10 - x: 781 - y: 620 - anchors.bottom: parent.bottom - chiffreText: " " - anchors.horizontalCenterOffset: 270 - anchors.horizontalCenter: parent.horizontalCenter - anchors.bottomMargin: 30 - - Image { - id: gomme - anchors.fill: parent - source: "erase.png" - anchors.rightMargin: 2 - anchors.leftMargin: 2 - anchors.bottomMargin: 2 - anchors.topMargin: 2 - fillMode: Image.PreserveAspectFit + Carre{ + id : case1 + width : 213 + height:213 } } } +} + + Button { + id: button_check + x: 8 + y: 660 + width: 132 + height: 40 + text: qsTr("Vérifier la grille") + anchors.bottom: parent.bottom + highlighted: false + anchors.horizontalCenterOffset: -250 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 10 + font.weight: Font.ExtraLight + font.pointSize: 12 + onClicked:{ check(); + button_check.highlighted = true + } + } + + Resultat{ + id :result + visible: false + } + + Button { + id: button1 + x: 200 + y: 660 + width: 40 + height: 40 + text: qsTr("1") + anchors.bottom: parent.bottom + anchors.horizontalCenterOffset: -120 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 10 + font.weight: Font.ExtraLight + font.pointSize: 12 + onPressed: {highlighted = true} + onReleased: {highlighted= false} + onClicked:set_chiffre_actif(1) + } + + Button { + id: button2 + x: 250 + y: 660 + width: 40 + height: 40 + text: qsTr("2") + anchors.bottom: parent.bottom + anchors.horizontalCenterOffset: -70 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 10 + font.weight: Font.ExtraLight + font.pointSize: 12 + onPressed: {highlighted = true} + onReleased: {highlighted= false} + onClicked: set_chiffre_actif(2) + } + + Button { + id: button3 + x: 300 + y: 660 + width: 40 + height: 40 + text: qsTr("3") + anchors.bottom: parent.bottom + anchors.horizontalCenterOffset: -20 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 10 + font.weight: Font.ExtraLight + font.pointSize: 12 + onPressed: {highlighted = true} + onReleased: {highlighted= false} + onClicked: set_chiffre_actif(3) + } + + Button { + id: button4 + x: 350 + y: 660 + width: 40 + height: 40 + text: qsTr("4") + anchors.bottom: parent.bottom + anchors.horizontalCenterOffset: 30 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 10 + font.weight: Font.ExtraLight + font.pointSize: 12 + onPressed: {highlighted = true} + onReleased: {highlighted= false} + onClicked: set_chiffre_actif(4) + } + + Button { + id: button5 + x: 400 + y: 660 + width: 40 + height: 40 + text: qsTr("5") + anchors.bottom: parent.bottom + anchors.horizontalCenterOffset: 80 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 10 + font.weight: Font.ExtraLight + font.pointSize: 12 + onPressed: {highlighted = true} + onReleased: {highlighted= false} + onClicked: set_chiffre_actif(5) + } + + Button { + id: button6 + x: 450 + y: 660 + width: 40 + height: 40 + text: qsTr("6") + anchors.bottom: parent.bottom + anchors.horizontalCenterOffset: 130 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 10 + font.weight: Font.ExtraLight + font.pointSize: 12 + onPressed: {highlighted = true} + onReleased: {highlighted= false} + onClicked: set_chiffre_actif(6) + } + + Button { + id: button7 + x: 500 + y: 660 + width: 40 + height: 40 + text: qsTr("7") + anchors.bottom: parent.bottom + anchors.horizontalCenterOffset: 180 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 10 + font.weight: Font.ExtraLight + font.pointSize: 12 + onPressed: {highlighted = true} + onReleased: {highlighted= false} + onClicked: set_chiffre_actif(7) + } + + Button { + id: button8 + x: 550 + y: 660 + width: 40 + height: 40 + text: qsTr("8") + anchors.bottom: parent.bottom + anchors.horizontalCenterOffset: 230 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 10 + font.weight: Font.ExtraLight + font.pointSize: 12 + onPressed: {highlighted = true} + onReleased: {highlighted= false} + onClicked: set_chiffre_actif(8) + } + + Button { + id: button9 + x: 600 + y: 660 + width: 40 + height: 40 + text: qsTr("9") + anchors.bottom: parent.bottom + anchors.horizontalCenterOffset: 280 + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottomMargin: 10 + font.weight: Font.ExtraLight + font.pointSize: 12 + onPressed: {highlighted = true} + onReleased: {highlighted= false} + onClicked: set_chiffre_actif(9) + } } + diff --git a/qml.qrc b/qml.qrc index 9d8b5a10957c69939f869a30575a696b9cf2957c..f68ca9875d53e2b3307b6d983d5b5cfe6f32a8b4 100644 --- a/qml.qrc +++ b/qml.qrc @@ -1,9 +1,7 @@ <RCC> <qresource prefix="/"> <file>main.qml</file> - <file>Case.qml</file> - <file>Grille.qml</file> <file>Carre.qml</file> - <file>erase.png</file> + <file>Resultat.qml</file> </qresource> </RCC>