欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

三角板棋盘覆盖问题及棋盘覆盖着色效果

程序员文章站 2022-05-13 17:18:26
...

综述

最近在写数据机构第三个课程设计,是一个棋盘覆盖问题。采用分治思想,比较简单,开源一下。

环境

mac xcode
不必担心。你可能需要替换的只有简单的一行

#include<GLUT/GLUT.h>
#include <GLUT/GLUT.h>
#include <iostream>
using namespace std;
int size_con[5] = { 8,16,32,64,128};
int all_p[5] = {12,18,40,70,130};
int p_size[5] ={50,38,20,9,5};
int dex = 0;
int n ;                             //实际的点数
int allpoint_number = all_p[0];
int point_size = p_size[0];
int SIZE = size_con[0];
struct Point{
    //定义点的结构体,主要用于编码
    float x,y;
    int code;
};
double color_con[5][3]= {
    {0,1,0},            //绿色
    {1,0,0},            //红色
    {1,1,1},             //白色
    {0,0.90,0.91},      //蓝色
    {1,0,0}                 //黄色
};
Point a,b;//定义两个点,我们最多只需两个点;
int wmin = 0 ,wmax = 600;//描述裁剪区间的大小
int hmin = 0 ,hmax = 600; //这里为了简化采用的是硬编码
int flag = 1;                         //用于记录用户点击的次数,单次画点,双次画线。
int window_size=600;           //这是我们显示界面的大小


static int title = 1;    //title表示L型骨牌的编号
static int board[200][200];


/**
 * 功能:棋盘覆盖
 * @param tr表示棋盘左上角行号
 * @param tc表示棋盘左上角列号
 * @param dr表示特殊棋盘的行号
 * @param dc表示特殊棋盘的列号
 * @param size = 2^k
 * 棋盘的规格为2^k * 2^k
 **/

void ChessBoard(int tr, int tc, int dr, int dc, int size,int index)
{
    if(1 == size)
    {
        return;
    }
    int t = title++;    //L型骨牌号
    int s = size / 2;    //分割棋盘
    //覆盖左上角子棋盘
    if(dr < tr + s && dc < tc + s)
    {
        //特殊方格在此棋盘中
        if(s==2)
            ChessBoard(tr, tc, dr, dc, s,1);
        else
            ChessBoard(tr, tc, dr, dc, s,0);
    }
    else
    {
        //此棋盘无特殊方格
        //用t号L型骨牌覆盖右下角
        if(s!=1){
            board[tr + s - 1][tc + s - 1] = 2;
            }
        else{
            if(index == 1){
                board[tr + s - 1][tc + s - 1] =4;
            }else if(index ==2)
                board[tr + s - 1][tc + s - 1] =3;
            else
            board[tr + s - 1][tc + s - 1] = 1;
        }
        //覆盖其余方格
        if(s==2){
            ChessBoard(tr, tc, tr + s - 1, tc + s - 1, s,1);
        }else{
            ChessBoard(tr, tc, tr + s - 1, tc + s - 1, s,0);

        }
    }

    //覆盖右上角
    if(dr < tr + s && dc >= tc + s)
    {
        //特殊方格在此棋盘中
        if(s==2)
            ChessBoard(tr, tc + s, dr, dc, s,2);
        else
            ChessBoard(tr, tc + s, dr, dc, s,0);

    }
    else
    {
        //此子棋盘中无特殊方格
        //用t号L型骨牌覆盖左下角
        if(s!=1){
            board[tr + s - 1][tc + s] = 2;}
        else{
            if(index == 1)
                board[tr + s - 1][tc + s] = 4;
            else if (index ==2)
                board[tr + s - 1][tc + s] = 3;
            else
            board[tr + s - 1][tc + s] = 1;}
        //覆盖其余方格
        if(s==2)
            ChessBoard(tr, tc + s, tr + s - 1, tc + s, s,2);
        else
            ChessBoard(tr, tc + s, tr + s - 1, tc + s, s,0);

    }

    //覆盖左下角子棋盘
    if(dr >= tr + s && dc < tc + s)
    {
        //特殊方格在此棋盘中
        if(s==2)
            ChessBoard(tr + s, tc, dr, dc, s,2);
        else
            ChessBoard(tr + s, tc, dr, dc, s,0);
    }
    else
    {
        //用t号L型骨牌覆盖右上角
        if(s!=1){
            board[tr + s][tc + s -1] = 2;}
        else{
            if(index ==1)
                board[tr + s][tc + s -1] = 4;
            else if(index == 2)
                board[tr + s][tc + s -1] = 3;
            else
                board[tr + s][tc + s -1] = 1;
        }
        //覆盖其余方格
        if(s==2)
            ChessBoard(tr + s, tc, tr + s, tc + s - 1, s,2);
        else
            ChessBoard(tr + s, tc, tr + s, tc + s - 1, s,0);

    }
    //覆盖右下角子棋盘
    if(dr >= tr + s && dc >= tc + s)
    {
        //特殊方格在此棋盘中
        if(s==2)
            ChessBoard(tr + s, tc + s, dr, dc, s,1);
        else
            ChessBoard(tr + s, tc + s, dr, dc, s,0);

    }
    else
    {
        //用t号L型骨牌覆盖左上角
        if(s!=1)
        {
            board[tr + s][tc + s] = 2;}else{
                if(index == 1)
                 board[tr + s][tc + s] = 4;
                else if (index == 2)
                    board[tr + s][tc + s] = 3;
                else
                    board[tr + s][tc + s] =1;
            }
        //覆盖其余方格
        if(s==2)
            ChessBoard(tr + s, tc + s, tr + s, tc + s, s,1);
        else
        ChessBoard(tr + s, tc + s, tr + s, tc + s, s,0);
    }
}

void InitEnvironment()
{
    /*
     函数说明:初始化绘制环境
     将基本的视图设置完毕
     */
    //一些初始化操作
    glClearColor(0.0,0.0,0.0,0);
    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluOrtho2D(0,window_size,0,window_size);
}
void draw_point(int x,int y ,double c1,double c2,double c3){
    glPointSize(point_size);
    glColor3f(c1,c2,c3);
    glBegin(GL_POINTS);
    glVertex2f(wmin +( y) *(wmax-wmin)/allpoint_number,hmin+(allpoint_number- x)*(hmax- hmin)/allpoint_number);
    glEnd();
//    glFlush();
}
//打印
void ChessPrint()
{
    int i;
    int j;
    for(i = 0; i < SIZE; i++)
    {
        for(j = 0; j < SIZE; j++)
        {
            int move = (allpoint_number -SIZE)/2;
            draw_point(i+move, j+move, color_con[board[i][j]][0] ,color_con[board[i][j]][1],color_con[board[i][j]][2]);
//            printf("%d\t", board[i][j]);
        }
//        printf("\n");
    }
}
void OnMouse(int button,int state,int x,int y)
/*
 函数说明:进行用户交互的操作
 每两个点一组进行操作。设置左键、右键手势动作
 */
{if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
{
    cout << "切换" << endl;
    dex = (dex +1)%5;
    allpoint_number = all_p[dex];
    point_size = p_size[dex];
    SIZE = size_con[dex];}
    glClear(GL_COLOR_BUFFER_BIT);
    // 首先绘制裁剪区域
//    glColor3f(0.98f, 0.625f, 0.12f);
    //绘制矩形,第一对坐标表示左上角,第二对表示右下角
    for (int i = 1; i < allpoint_number ; i ++ ) { //利用循环绘制网格
        glBegin(GL_LINES);
        glVertex2f(wmin+i*(wmax-wmin)/allpoint_number,hmin);
        glVertex2f(wmin+i*(wmax-wmin)/allpoint_number, hmax);
        glEnd();
        glBegin(GL_LINES);
        glVertex2f(wmin,hmin+i*(hmax-hmin)/allpoint_number);
        glVertex2f( wmax,hmin+i*(hmax-hmin)/allpoint_number);
        glEnd();}

        ChessBoard(0, 0, 3,6, SIZE,0);
        ChessPrint();
        glFlush();

    if(button==GLUT_RIGHT_BUTTON&&state==GLUT_DOWN)
    {   //点击右键
        cout << "回置" << endl;
    }
}
void init_Display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    // 首先绘制裁剪区域
    glColor3f(0.98f, 0.625f, 0.12f);
//    //绘制矩形,第一对坐标表示左上角,第二对表示右下角
//    for (int i = 1; i < allpoint_number ; i ++ ) { //利用循环绘制网格
//        glBegin(GL_LINES);
//        glVertex2f(wmin+i*(wmax-wmin)/allpoint_number,hmin);
//        glVertex2f(wmin+i*(wmax-wmin)/allpoint_number, hmax);
//        glEnd();
//        glFlush();
//        glBegin(GL_LINES);
//        glVertex2f(wmin,hmin+i*(hmax-hmin)/allpoint_number);
//        glVertex2f( wmax,hmin+i*(hmax-hmin)/allpoint_number);
//        glEnd();
//        glFlush();
//    }
//    //刷新队列
//    //在内部,openGL的命令和语句常常等待在队列里
//    //直到openGL驱动程序同时处理几个“命令”
//    ChessBoard(0, 0, 3,6, SIZE,0);
//    ChessPrint();
//    glFlush();
}

int main(int argc, char *argv[])
{
    cout << "begin!"<<endl;
    glutInit(&argc, argv);   //初始化GLUT
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(300, 100);
    glutInitWindowSize(window_size, window_size);
    glutCreateWindow("残缺棋盘最少着色项目");
    InitEnvironment();   //初始化
    glutMouseFunc(&OnMouse);  //注册鼠标事件
    glutDisplayFunc(&init_Display);   //回调函数
    glutMainLoop();    //持续显示,当窗口改变会重新绘制图形
    return 0;
}