C++ OpenGL Graphics Program to Generate Sudoku Solver Game Using GLUT Library in Command Line

You are currently viewing C++ OpenGL Graphics Program to Generate Sudoku Solver Game Using GLUT Library in Command Line

C++ OpenGL Graphics Program to Generate Sudoku Solver Game Using GLUT Library in Command Line

#include<windows.h>
#include <GL/glut.h>
#include <iostream>
#include <fstream>
#include <ctime>
#include <cstdlib>
#include <cstring>
 
int checkTest=0;
const int xMax = 9, xMin = 0, yMax = 9, yMin = 0;
bool checkSolve=true, checkPressNumber=true, checkDemo=true;
unsigned char s[9][9],test_s[9][9], keyboardPress;
int posClick_x, posClick_y;
 
void Initialize();
void drawSquare(GLint x1, GLint y1, GLint x2, GLint y2, GLint x3, GLint y3, GLint x4, GLint y4);
void keyboard(unsigned char key, int x, int y);
void mouseClick(int button, int state, int x, int y);
void preDraw();
void test();
void clearBoard();
void display();
void printText(int x, int y, char *str);
void printText2(int x, int y, char *str);
void printNumber(unsigned char s, GLint x, GLint y);
void printNumber2(unsigned char s, GLint x, GLint y);
void inputBoard();
void solveBoard(int x, int y);
bool checkBoard(int x, int y, unsigned char check);
 
int main(int agrc, char ** argv)
{
    glutInit(&agrc, argv);
    glutInitDisplayMode(GLUT_SINGLE);
    glutInitWindowPosition(200, 100);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Solve Sudoku using OpenGL in C++");
    Initialize();
    glutDisplayFunc(display);
    glutMouseFunc(mouseClick);
    glutKeyboardFunc(keyboard);
    glutMainLoop();
}
 
void Initialize()
{
    glClearColor(0, 0, 0, 0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0, 800, 0,600);
    for(int i=0; i<xMax; i++)
    for(int j=0; j<yMax; j++)
    {
        s[i][j]='0';
        test_s[i][j]='0';
    }
 
}
 
void drawSquare(GLint x1, GLint y1, GLint x2, GLint y2, GLint x3, GLint y3, GLint x4, GLint y4)
{
    glLineWidth(3);
    glBegin(GL_LINE_LOOP);
        glVertex2i(x1, y1);
        glVertex2i(x2, y2);
        glVertex2i(x3, y3);
        glVertex2i(x4, y4);
    glEnd();
}
 
void keyboard(unsigned char key, int x, int y)
{
    switch(key)
    {
    case '1':
        {
            keyboardPress=key;
            break;
        }
    case '2':
        {
            keyboardPress=key;
            break;
        }
    case '3':
        {
            keyboardPress=key;
            break;
        }
    case '4':
        {
            keyboardPress=key;
            break;
        }
    case '5':
        {
            keyboardPress=key;
            break;
        }
    case '6':
        {
            keyboardPress=key;
            break;
        }
    case '7':
        {
            keyboardPress=key;
            break;
        }
    case '8':
        {
            keyboardPress=key;
            break;
        }
    case '9':
        {
            keyboardPress=key;
            break;
        }



    default:
        {
            break;
        }
    }
}
 
void mouseClick(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
    {
 
        posClick_x = x;
        posClick_y = 600-y;
    }
    glutPostRedisplay();
}
 
void preDraw()
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(255,255,255);
    GLint x, y;
    for (y = 510; y >= 30; y -= 60)
    {
        for (x = 510; x >= 30; x -= 60)
        {
            drawSquare(x, y + 60, x + 60, y + 60, x + 60, y, x, y);
        }
    }
    glLineWidth(5);
    glPushAttrib(GL_CURRENT_BIT);
        glColor3d(255, 255, 0);
 
        //draw square of "Load"
        glBegin(GL_LINE_LOOP);



            glVertex2i(765, 570);
            glVertex2i(765, 470);
            glVertex2i(600, 470);
            glVertex2i(600, 570);
        glEnd();
 
        //draw square of "Check"
        glBegin(GL_LINE_LOOP);
            glVertex2i(765, 430);
            glVertex2i(765, 330);
            glVertex2i(600, 330);
            glVertex2i(600, 430);
        glEnd();
 
        //draw square of "Solve"
        glBegin(GL_LINE_LOOP);
            glVertex2i(765, 280);
            glVertex2i(765, 180);
            glVertex2i(600, 180);
            glVertex2i(600, 280);
        glEnd();
 
        //draw square of "Clear Board"
        glBegin(GL_LINE_LOOP);
            glVertex2i(765, 130);
            glVertex2i(765, 30);
            glVertex2i(600, 30);
            glVertex2i(600, 130);
        glEnd();
 
 
    glPopAttrib();
 
    printText(650,515,"LOAD");
    if(checkTest ==0 )
        printText2(125,583,"Click on \"Load\" to open Sudoku board or input number from keyboard");



    else if (checkTest == 1)
        printText2(225,583,"Congratulations! You did it");
    else if(checkTest == -1)
        printText2(225,583,"Try again. That's wrong!!!");
    else printText2(225,583,"Get number from your keyboard");
    printText(640,370,"CHECK");
    printText(642,220,"SOLVE");
    printText(640,70,"CLEAR");
 
    //Slipt Sudoku Board into 9 parts
    glPushAttrib(GL_CURRENT_BIT);
        glColor3d(255,255,0);
        glLineWidth(10);
 
        glBegin(GL_LINE_LOOP);
            glVertex2i(30, 570);
            glVertex2i(570, 570);
            glVertex2i(570,30);
            glVertex2i(30,30);
        glEnd();
 
        glBegin(GL_LINES);
            glVertex2i(210, 572);
            glVertex2i(210, 29);
        glEnd();
 
        glBegin(GL_LINES);
            glVertex2i(390, 572);
            glVertex2i(390, 29);
        glEnd();
 
        glBegin(GL_LINES);
            glVertex2i(30, 390);
            glVertex2i(570, 390);
        glEnd();
 
        glBegin(GL_LINES);
            glVertex2i(30, 210);
            glVertex2i(570, 210);
        glEnd();
 
    glPopAttrib();
}
 
void test()



{
    //set all value of s[9][9] to equal 0 to get input from keyboard and we also can solve it
    if(checkPressNumber==true)
    {
        for(int i=0; i<xMax; i++)
            for(int j=0; j<yMax; j++)
                if (checkBoard(i,j,s[i][j])==false)
                {
                    checkTest = -1;
                    return;
                }
    }
    checkTest =1;
}
 
void clearBoard()
{
    checkTest = 0;
    //if s[i][j] = 0, it isn't display on the screen, so we set all value to 0
    for(int i=0; i<xMax; i++)
        for(int j=0; j<yMax; j++)
        {
            s[i][j]='0';
            test_s[i][j]='0';
        }
}
 
void display()
{
    preDraw();
    //Click on "Load"
    if(posClick_x>=600&&posClick_x<=765&&posClick_y<=570&&posClick_y>=470)
    {
        inputBoard();
        checkPressNumber=true;
        checkSolve=true;
        checkTest=-2;
    }
 
    //Click on "Solve"
    if(posClick_x>=600&&posClick_x<=765&&posClick_y<=280&&posClick_y>=180)
    {
        solveBoard(0,0);
        checkPressNumber=false;
        checkDemo=false;
        for(int i=0; i<xMax; i++)
            for(int j=0; j<yMax; j++)
                if (s[i][j]=='0')
                {
                    printText2(620,200,"Can't solve. Try again!");
                    break;
                }
    }
 
    //Click on "Test"
    if(posClick_x>=600&&posClick_x<=765&&posClick_y<=430&&posClick_y>=330)
    {
        checkSolve=true;
        test();
        checkDemo=false;
    }
 
    //Click on "Clear Board"
    if(posClick_x>=600&&posClick_x<=765&&posClick_y<=130&&posClick_y>=30)
    {
        clearBoard();
        checkSolve=true;
        checkPressNumber=true;
    }
 
    if(30<=posClick_x&&570>=posClick_x&&30<=posClick_y&&570>=posClick_y)
    {



        checkTest=-2;
        int j = 8-(posClick_x-30)/60;
        int i = (posClick_y-30)/60;
        if(test_s[i][j]=='0')s[i][j]=keyboardPress;
        keyboardPress=test_s[i][j];
        posClick_x=0;
        posClick_y=0;
    }
 
    GLint x, y;
    for (y = 510; y >= 30; y -= 60)
    {
        for (x = 510; x >= 30; x -= 60)
        {
            if(s[y/60][8-x/60]!='0')
            {
                glPushAttrib(GL_CURRENT_BIT);
                    if(test_s[y/60][8-x/60]=='0')
                    printNumber(s[y/60][8-x/60],x+25, y+20);
                    else printNumber2(s[y/60][8-x/60],x+25, y+20);
                glPopAttrib();
            }
        }
    }
    glFlush();
}
 
void printText(int x, int y, char *str)
{
    glPushAttrib(GL_CURRENT_BIT);
        glColor3f(229, 236, 234);
        glRasterPos2f(x,y);
        int n = (int) strlen(str);
        for (int i = 0; i < n; i++)
        {
            glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,str[i]);
        }
    glPopAttrib();
}
 
void printText2(int x, int y, char *str)
{
    glPushAttrib(GL_CURRENT_BIT);
        glColor3f(229, 236, 234);
        // Draw your text
        glRasterPos2f(x,y);
        int n = (int) strlen(str);
        for (int i = 0; i < n; i++)
        {
            glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12,str[i]);
        }
    glPopAttrib();
}
 
void printNumber(unsigned char s, GLint x, GLint y)
{
    glPushAttrib(GL_CURRENT_BIT);
        glColor3f(229, 236, 234);
        glRasterPos2i(x,y);
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,s);
    glPopAttrib();
}
 
void printNumber2(unsigned char s, GLint x, GLint y)
{
    glPushAttrib(GL_CURRENT_BIT);
        glColor3f(0, 255, 255);
        glRasterPos2i(x,y);
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,s);
    glPopAttrib();
}
 
void inputBoard()



{
    srand(time(NULL));
    int i = rand()%5+1;
    switch(i)
    {
        case 1:
        {
            std::ifstream file ("input1.txt");
            if(file.is_open())
                while(!file.eof())
                {
                    for(int i=xMax-1; i>=xMin; i--)
                        for(int j=yMax-1; j>=yMin; j--)
                        {
                            file >> s[i][j];
                            test_s[i][j]=s[i][j];
                        }
                }
            else std::cout << "Unable to open file";
            file.close();
            break;
        }
 
        case 2:
        {
            std::ifstream file ("input2.txt");
            if(file.is_open())
                while(!file.eof())
                {
                    for(int i=xMax-1; i>=xMin; i--)
                        for(int j=yMax-1; j>=yMin; j--)
                        {
                            file >> s[i][j];
                            test_s[i][j]=s[i][j];
                        }
                }
            else std::cout << "Unable to open file";
            file.close();
            break;
        }
 
        case 3:
        {
            std::ifstream file ("input3.txt");
            if(file.is_open())
                while(!file.eof())
                {
                    for(int i=xMax-1; i>=xMin; i--)
                        for(int j=yMax-1; j>=yMin; j--)
                        {
                            file >> s[i][j];
                            test_s[i][j]=s[i][j];
                        }
                }
            else std::cout << "Unable to open file";
            file.close();
            break;
        }
 
        case 4:
        {
            std::ifstream file ("input4.txt");
            if(file.is_open())
                while(!file.eof())
                {
                    for(int i=xMax-1; i>=xMin; i--)
                        for(int j=yMax-1; j>=yMin; j--)
                        {
                            file >> s[i][j];
                            test_s[i][j]=s[i][j];
                        }



                }
            else std::cout << "Unable to open file";
            file.close();
            break;
        }
 
        case 5:
        {
            std::ifstream file ("input5.txt");
            if(file.is_open())
                while(!file.eof())
                {
                    for(int i=xMax-1; i>=xMin; i--)
                        for(int j=yMax-1; j>=yMin; j--)
                        {
                            file >> s[i][j];
                            test_s[i][j]=s[i][j];
                        }
                }
            else std::cout << "Unable to open file";
            file.close();
            break;
        }
    }
}
 
void solveBoard(int x, int y)
{
    if(y==yMax)
    {
        if(x==xMax-1)
        {
            checkSolve = false;
            return;
        }
        else solveBoard(x+1,yMin);
    }
    else if(s[x][y]=='0')
    {
        for(int check = 1; check <= yMax; check++)
        {
            if(checkBoard(x,y,check+'0')==true)
            {
                s[x][y]=check+'0';
                solveBoard(x,y+1);
                if(checkSolve==true)s[x][y]='0';
            }
        }
    }
    else solveBoard(x,y+1);
}
 
bool checkBoard(int x, int y, unsigned char c_check)
{
    for(int i=0; i<yMax; i++)
    {
        if(s[x][i]==c_check) return false;
    }
    for(int i=0; i<xMax; i++)
    {
        if(s[i][y]==c_check) return false;
    }
    int a=x/3, b=y/3;
    for(int i=3*a; i<3*a+3; i++)
        for(int j=3*b; j<3*b+3; j++)
            if(s[i][j]==c_check) return false;
    return true;
}

Ranjith Kumar

Hi, I'm Ranjith a full-time Blogger, YouTuber, Affiliate Marketer, & founder of Coding Diksha. Here, I post about programming to help developers.

Leave a Reply