opencv实现拼图游戏

#include <fstream>
#include <iostream>
#include <cstdlib>
#include<atlstr.h> 
#include<stdlib.h>
#include<math.h>
#include<direct.h>
#define NO_WIN32_LEAN_AND_MEAN 
#include <shlobj.h>
#include<opencv.hpp>
#include<time.h>
#include <algorithm> 


using namespace cv;
using namespace std;

CString Get_Filder_Path()
{

	CString strpath;

	TCHAR Buffer[MAX_PATH];
	BROWSEINFO bi;
	ZeroMemory(&bi, sizeof(BROWSEINFO));
	bi.hwndOwner = NULL;
	bi.ulFlags = BIF_RETURNONLYFSDIRS;    //要求返回文件系统的目  

	bi.ulFlags = BIF_NEWDIALOGSTYLE;        //窗口可以调整大小,有新建文件夹按钮  

	bi.pszDisplayName = Buffer;           //此参数如为NULL则不能显示对话框   
	bi.lpszTitle = _T("请选择文件夹");
	bi.lpfn = NULL;


	LPITEMIDLIST pIDList = SHBrowseForFolder(&bi);//调用显示选择对话框  
	if (pIDList)
	{
		SHGetPathFromIDList(pIDList, Buffer);
		//取得文件夹路径到Buffer里  

		strpath.Format(_T("%s"), Buffer);
	}
	else
	{
		strpath = _T("");  // 用户点了取消  
	}

	LPMALLOC lpMalloc;
	if (FAILED(SHGetMalloc(&lpMalloc)))
		strpath = _T("");


	//释放内存  
	lpMalloc->Free(pIDList);
	lpMalloc->Release();

	return strpath;
}

CString Get_File_Path()
{

	CString strpath;


	TCHAR szBuffer[MAX_PATH] = { 0 };
	BROWSEINFO bi;
	ZeroMemory(&bi, sizeof(BROWSEINFO));
	bi.hwndOwner = NULL;
	bi.pszDisplayName = szBuffer;
	bi.lpszTitle = _T("从下面选择文件或文件夹:");
	bi.ulFlags = BIF_BROWSEINCLUDEFILES;
	LPITEMIDLIST idl = SHBrowseForFolder(&bi);
	if (NULL == idl)
	{
		return strpath;
	}
	SHGetPathFromIDList(idl, szBuffer);

	strpath.Format(_T("%s"), szBuffer);


	LPMALLOC lpMalloc;
	if (FAILED(SHGetMalloc(&lpMalloc)))
		strpath = _T("");

	//释放内存  
	lpMalloc->Free(idl);
	lpMalloc->Release();

	return strpath;
}

Mat mergeRows(Mat& A, Mat& B)//行[A ; B]
{
	//CV_ASSERT(A.cols == B.cols&&A.type() == B.type());
	int totalRows = A.rows + B.rows;

	Mat mergedDescriptors(totalRows, A.cols, B.type());
	Mat submat = mergedDescriptors.rowRange(0, A.rows);
	A.copyTo(submat);
	submat = mergedDescriptors.rowRange(A.rows, totalRows);
	B.copyTo(submat);
	return mergedDescriptors;
}

Mat mergecols(Mat& A, Mat& B)//列[A   B]
{
	//CV_ASSERT(A.cols == B.cols&&A.type() == B.type());
	int totalCols = A.cols + B.cols;

	Mat mergedDescriptors(A.rows, totalCols, B.type());
	Mat submat = mergedDescriptors.colRange(0, A.cols);
	A.copyTo(submat);
	submat = mergedDescriptors.colRange(A.cols, totalCols);
	B.copyTo(submat);
	return mergedDescriptors;
}

class picc
{
public:
	Mat pic;
	Point2i id;
	picc()
	{

	}
	picc(const picc &obj1)
	{
		pic = obj1.pic.clone();
		id.x = obj1.id.x;
		id.y = obj1.id.y;
	}

	void operator = (const picc& obj1)
	{
		pic = obj1.pic.clone();
		id.x = obj1.id.x;
		id.y = obj1.id.y;
	}
};

class midle
{
public:
	Mat tt;
	vector<vector<picc> > arry;
	vector<picc> start;
	int raw = 2;
	int col = 3;

	Point2i cur;
	int cur_index;

	midle(Mat& tt)
	{
		this->tt = tt;
		vector<vector<picc> > a(raw, vector<picc>(col));
		arry = a;
	}

	void splid()
	{
		int x_step = tt.cols / col;
		int y_step = tt.rows / raw;

		srand((int)time(0));
		cur.x = rand() % raw;
		cur.y = rand() % col;

		cout << "cur: " << cur.x << " " << cur.y << endl << endl;


		for (int i = 0; i < raw; i++)
		{
			for (int j = 0; j < col; j++)
			{
				Point2i naw=Point2i{ i, j };
				if (naw == cur)
				{
					Mat temm=Mat(y_step, x_step, CV_8UC3, Scalar(0, 0, 0));
					arry[i][j].pic = temm.clone();
					//cout << "i j : " << i << " " << j << endl << endl;
				}
				else
				{
					Mat temm(tt, Rect(x_step*j, y_step*i, x_step, y_step));
					arry[i][j].pic = temm.clone();
				}
				arry[i][j].id = naw;
				//imshow("cccc", arry[i][j].pic);
				//waitKey(0);
			}
		}
	}

	void daluan()
	{
		vector<int>order;
		for (int k = 0; k < 4; k++)
		{
			order.push_back(k);
		}
		for (int k = 0; k < 100; k++)
		{
			random_shuffle(order.begin(), order.end());
			int mod = order[1];

			Point2i nest = cur;
			if (mod == 0)//上
			{
				nest.x += 1;
			}
			else if (mod == 1)//下
			{
				nest.x -= 1;
			}
			else if (mod == 2)//左
			{
				nest.y += 1;
			}
			else if (mod == 3)//右
			{
				nest.y -= 1;
			}
			if (nest.x < 0 || nest.x >= raw)
			{
				nest = cur;
			}
			if (nest.y<0 || nest.y >= col)
			{
				nest = cur;
			}
			if (nest == cur)continue;

			picc temp = arry[cur.x][cur.y];
			arry[cur.x][cur.y] = arry[nest.x][nest.y];
			arry[nest.x][nest.y] = temp;
			cur = nest;
		}
	}


	void move()
	{
		int mod = waitKey(100);
		Point2i nest = cur;
		if (mod == 2490368)//上
		{
			nest.x += 1;
		}
		else if (mod == 2621440)//下
		{
			nest.x -= 1;
		}
		else if (mod == 2424832)//左
		{
			nest.y += 1;
		}
		else if (mod == 2555904)//右
		{
			nest.y -= 1;
		}
		if (nest.x < 0 || nest.x >= raw)
		{
			nest = cur;
		}
		if (nest.y < 0 || nest.y >= col)
		{
			nest = cur;
		}
		if (nest == cur)return;

		picc temp = arry[cur.x][cur.y];
		arry[cur.x][cur.y] = arry[nest.x][nest.y];
		arry[nest.x][nest.y] = temp;
		cur = nest;
	}

	void show()
	{
		Mat res;
		for (int i = 0; i < raw; i++)
		{
			Mat raw = arry[i][0].pic;
			for (int j = 1; j < col; j++)
			{
				raw = mergecols(raw, arry[i][j].pic);
			}
			if (i == 0)res = raw;
			else
				res = mergeRows(res, raw);
		}
		imshow("res", res);
		waitKey(1);
	}

	bool if_finish()
	{
		for (int i = 0; i < raw; i++)
		{
			for (int j = 0; j < col; j++)
			{
				if (i != (arry[i][j].id.x) || j != (arry[i][j].id.y))return false;
			}
		}
		return true;
	}
};


int main()
{
	//GetSavePath();
	CString x;
	x = Get_File_Path();
	
	USES_CONVERSION;
	string str(W2A(x));

	Mat pic = imread(str);
	imshow("your choice", pic);

	midle my(pic);

	my.splid();
	my.daluan();
	while (!my.if_finish())
	{
		my.move();
		my.show();
	}


	cout << "finish";
	waitKey(0);

	return 0;
}



 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值