三角板棋盘覆盖问题及棋盘覆盖着色效果
程序员文章站
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;
}
上一篇: 棋盘覆盖-分治法(代码实现)
下一篇: dedecms 空间迁移步骤_PHP教程