`
zwhc
  • 浏览: 266233 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

《求解关灯游戏》源码分析

阅读更多

http://blog.163.com/prevBlogPerma.do?host=simplesource&srl=10341406200981362416959&mode=prev

 

这个代码写得相当不错。

 

这里先对蛮力搜索做个分析。

 

LightsOffAppDlg.h 添加了些调试内容。

 

// LightsOffAppDlg.h : 头文件
//

#pragma once
#include "lightsoff.h"
#include "afxwin.h"

// CLightsOffAppDlg 对话框
class CLightsOffAppDlg : public CDialog
{
// 构造
public:
	CLightsOffAppDlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
	enum { IDD = IDD_LIGHTSOFFAPP_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持

    int m_iUnitWidth;
    int m_iX0;
    int m_iY0;
    CField m_field;
    CField m_mask;
    CField m_recorder;
    bool   m_bKillMsg;
    int    m_iState;
    CMatrix m_trans;
    CMatrix m_switch;

	FILE * fp ;

    // 设置大小
    void SetSize()
    {
        int iWidth = m_cbWidth.GetCurSel() + 1;
        int iHeight = m_cbHeight.GetCurSel() + 1;
        m_field.Create(iWidth, iHeight);
        m_mask = m_field;
        m_recorder = m_field;
        int w, h;
        int fw = m_iUnitWidth * iWidth;
        int fh = m_iUnitWidth * iHeight;
        w = fw + 128;
        h = fh + 100;
        if(w < 360)
        {
            w = 360;
        }
        if(h < 200)
        {
            h = 200;
        }
        MoveWindow(
            (::GetSystemMetrics(SM_CXSCREEN) - w) / 2,
            (::GetSystemMetrics(SM_CYSCREEN) - h) / 2,
            w, h);
        CRect rect;
        GetClientRect(&rect);
        m_iX0 = 50 + (rect.Width() - fw) / 2;
        m_iY0 = 50;
        // 计算求解矩阵
        m_switch.Create(iWidth, iHeight);
        m_trans.Create(iWidth, iHeight);
        m_trans.SetAsI();
        m_switch.SetAsL(m_mask);
        m_switch.Inverse(m_trans);
        m_switch.SetAsL(m_mask);
        Invalidate();
    }
    // 执行线程
    static UINT ThreadProc(LPVOID pParm)
    {
        CLightsOffAppDlg * pClass = (CLightsOffAppDlg *)pParm;
        //pClass->m_iMode = PRO_MODE_ASYN;

        pClass->m_iState = 1;
        CField fld;
        fld.Create(pClass->m_field.Width(), pClass->m_field.Height());
        pClass->m_recorder = fld;
		
		pClass->fp = fopen("m.txt", "w");
        if(pClass->fp)
        {
            fld.Print(pClass->fp);
            pClass->m_recorder.Print(pClass->fp);
			pClass->m_mask.Print(pClass->fp);
			pClass->m_field.Print(pClass->fp);
        }

        if(pClass->FindRecord(fld, pClass->m_recorder))
        {
            pClass->Invalidate(false);
            if(pClass->m_bKillMsg == false)
            {
                pClass->MessageBox("找到解", "成功", MB_ICONINFORMATION);
            }
        }
        else
        {
            pClass->Invalidate(false);
            if(pClass->m_bKillMsg == false)
            {
                pClass->MessageBox("未找到解", "失败", MB_ICONERROR);
            }
        }
        pClass->KillTimer(0);
        pClass->m_iState = 0;
        pClass->SetDlgItemText(IDC_BT_SEARCH, "蛮力搜索");
        //pClass->m_iMode = PRO_MODE_BLOCK;

		if(pClass->fp)
		{
			fclose(pClass->fp);
		}

        return 0;
    }
    bool FindRecord(CField &fld, CField &rcd, int x = 0, int y = 0)
    {
        if(m_bKillMsg)
        {
            return false;
        }
        fld.AndNot(m_mask);
		
        if(fld == m_field)
        {
            return true;
        }
        if(x >= fld.Width())
        {
            y++;
            x = 0;
            if(y >= fld.Height())
            {
				if(fp)
				{
					fprintf(fp, "out of range. x=%d, y=%d", x, y);
					fprintf(fp, "\n");
				}

                return false;
            }
        }
        int i;

        if(fp)
        {
			fprintf(fp, "x=%d, y=%d", x, y);
			fprintf(fp, "\n");
            fld.Print(fp);
            rcd.Print(fp);
			m_mask.Print(fp);
			m_field.Print(fp);
        }


        if(m_mask.IsLightOn(x, y))
        {
			fprintf(fp, "m_mask.IsLightOn(%d, %d)", x, y);
			fprintf(fp, "\n");

            if(FindRecord(fld, rcd, x + 1, y))
            {
                return true;
            }
        }
        else
        {
			fprintf(fp, "not m_mask.IsLightOn(%d, %d)", x, y);
			fprintf(fp, "\n");
            for(i = 0; i < 2 && !m_bKillMsg; i++)
            {
                if(FindRecord(fld, rcd, x + 1, y))
                {
                    return true;
                }
								if(fp)
								{
									fprintf(fp, "x=%d, y=%d", x, y);
									fprintf(fp, "\n");
									fprintf(fp, "i=%d", i);
									fprintf(fp, "\n");
								}
                fld.LightsOff(x, y);
                rcd.SetLight(x, y);

								if(fp)
								{
									fprintf(fp, "fld.LightsOff(%d, %d);", x, y);
									fprintf(fp, "\n");
									fld.Print(fp);
									rcd.Print(fp);
									m_mask.Print(fp);
									m_field.Print(fp);
								}

            }
        }
        return false;
    }

// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
    afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
    afx_msg void OnTimer(UINT nIDEvent);
    afx_msg void OnBnClickedBtCompute();
    CComboBox m_cbWidth;
    CComboBox m_cbHeight;
    afx_msg void OnBnClickedBtSearch();
    afx_msg void OnCbnSelchangeCbWidth();
    afx_msg void OnCbnSelchangeCbHeight();
    afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point);
    afx_msg void OnBnClickedBtReverse();
    afx_msg void OnBnClickedBtClear();
};

 

他这解法,是从右下角开始往回开灯求解的。如果用我这个测试代码,千万别从左上角进行测试。否则,日志信息将极宠大。

 

以下列出一小段开灯的递归顺序。

 

44
44

34
 44
 44
34

24
 44
 44

 34
  44
  44
 34
24

14
 44
 44

 34
  44
  44
 34

 24
  44
  44

  34
   44
   44
  34
 24
14

0
0
分享到:
评论

相关推荐

    《求解关灯游戏》源码分析之二

    《求解关灯游戏》源码分析之二 在编程世界中,关灯游戏(Lights Out)是一款经典的逻辑游戏,它的目标是通过点击一个5x5的网格中的按钮,使得所有的灯都熄灭。每当你点击一个按钮时,它会改变自身的状态(开或关)...

    求解关灯游戏的全部解

    《全面解析“关灯游戏”的解决方案》 关灯游戏,又称Lights Out,是一款经典的逻辑谜题,玩家需要在二维网格上操作开关,使得所有灯光熄灭。这个游戏看似简单,但其实蕴含了丰富的数学原理和算法知识。下面我们将...

    关灯游戏解题程序

    "关灯游戏解题程序"是一款专门用于解决经典益智游戏——关灯游戏的软件。关灯游戏,又称为“熄灯游戏”,起源于1995年Tandy公司的一款手持电子游戏,其规则简单而富有挑战性。游戏通常在一个方格网格上进行,每个...

    关灯游戏求解算法含代码

    关灯游戏,又称为“开关灯谜题”,是一种经典的逻辑思维和计算机科学问题。在这个游戏中,一排灯(通常数量很大)被设定为开或关的状态。玩家每次可以选择一个特定的灯,然后改变该灯以及它所有相邻灯的状态——即...

    双层规划模型的遗传算法求解的Matlab源码-双层规划模型的遗传算法求解的Matlab源码.doc

    双层规划模型的遗传算法求解的Matlab源码 双层规划模型的遗传算法求解是指使用遗传算法解决双层规划问题,这类问题广泛应用于管理科学、经济学、工程等领域。遗传算法是一种基于自然选择和遗传的优化算法,模拟生物...

    C++大作业基于C++实现Eigen求解曲线拟合源码.zip

    C++大作业基于C++实现Eigen求解曲线拟合源码.zipC++大作业基于C++实现Eigen求解曲线拟合源码.zipC++大作业基于C++实现Eigen求解曲线拟合源码.zipC++大作业基于C++实现Eigen求解曲线拟合源码.zipC++大作业基于C++实现...

    Python 实现的有限元方程求解程序源码课设项目.zip

    Python 实现的有限元方程求解程序源码课设项目.zipPython 实现的有限元方程求解程序源码课设项目.zipPython 实现的有限元方程求解程序源码课设项目.zipPython 实现的有限元方程求解程序源码课设项目.zipPython 实现...

    VC游戏编写中的求解最短路径算法源码

    VC游戏编写中的求解最短路径算法源码,本示例是自动寻径演示,篮点是起点,红点是终点,按确定键开始。源码爱好者注:编译后运行的时候请把EXE文件从Debug目录中拷贝到项目根目录中,若不然会出错。  编著、程序...

    数独求解程序游戏设计报告书

    ### 数独求解程序游戏设计报告书 #### 一、数独游戏介绍 数独(Sudoku)是一种逻辑填数字游戏,玩家需按照一定的规则在9×9的网格内填入1至9的数字,使得每一行、每一列以及每一个3×3的小宫格内的数字都不重复。...

    推箱子自动求解及游戏(最终算法源码及程序)

    推箱子界面程序, 可以玩游戏, 包括源码 推箱子界面程序内置演示解法和求解调用, 使用sokoban.exe的解法表达式 推箱子也叫搬运工,仓库小子 ************************* 算法DLL模块已经完全成熟并完成32位Windows...

    自动求解的iPad 3.2 拼图游戏工程源码

    通过阅读和分析源码,开发者可以学习如何创建游戏对象模型、处理触摸事件、动画效果以及如何实现自动求解算法。源码中的每个类、方法和变量都对应着游戏的某个特定部分,例如,可能有一个名为`JigsawPiece`的类代表...

    基于MATLAB实现微分方程有限元离散+隐式梯度计算+SQP求解优化问题源码(常微分系统).zip

    基于MATLAB实现微分方程有限元离散+隐式梯度计算+SQP求解优化问题源码(常微分系统).zip基于MATLAB实现微分方程有限元离散+隐式梯度计算+SQP求解优化问题源码(常微分系统).zip基于MATLAB实现微分方程有限元离散+隐式...

    双层规划模型的遗传算法求解的Matlab源码.doc

    双层规划模型的遗传算法求解 Matlab 源码 本文档提供了一个双层规划模型的遗传算法求解的 Matlab 源码,用于解决复杂的优化问题。该源码实现了一个基于遗传算法的双层规划模型,能够高效地解决复杂的优化问题。 ...

    倒水解密游戏源码2012918

    倒水解密游戏源码 游戏介绍: 《倒水解密》是一款很不错的益智类游戏 有N个容量不同的瓶子,指定「将a升水倒入容量为b的瓶子」。 游戏要求通过装水、倒水,达成给定的目标。 游戏操作方式如下: ?在瓶子上双击...

    基于Python实现的迷宫求解小游戏.zip

    基于Python实现的迷宫求解小游戏.zip 这是95分以上高分必过课程设计项目,下载即用无需修改,确保可以运行。也可作为期末大作业。 基于Python实现的迷宫求解小游戏.zip 这是95分以上高分必过课程设计项目,下载即...

    数独(Sudoku,九宫格游戏)求解程序(源码)

    本项目"数独(Sudoku,九宫格游戏)求解程序"是一个能够自动求解各种难度数独谜题的软件。它利用计算机算法瞬间完成复杂的游戏解题过程,为玩家提供了极大的便利。源码开放,这意味着编程爱好者可以深入研究其内部机制...

    python实现基于仿生群智算法的无人机任务分配 (多旅行商问题的求解)+源码+项目文档(期末大作业&课程设计&项目开发)

    python实现基于仿生群智算法的无人机任务分配 (多旅行商问题的求解)+源码+项目文档,适合期末大作业、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用~ python实现基于仿生群智算法...

    标准数独 数独求解 批量求解(附源码)

    数独作为一种经典的逻辑游戏,在全球范围内拥有众多爱好者,它的核心魅力在于通过推理解决谜题的快感。标准数独遵循严格的规则:在一个9x9的格子中,分为9个3x3的小九宫格,每个小九宫格内以及每行每列内必须填入1到...

    高等应用数学问题的MATLAB求解_matlab源码.rar

    它提供了丰富的函数库,支持线性代数、统计分析、微积分、优化问题、信号处理等多种计算任务。在这个"高等应用数学问题的MATLAB求解"压缩包中,我们可能找到了一系列用MATLAB编写的源代码,用于解决复杂的数学问题。...

    【优化求解】粒子群优化和重力搜索算法求解MLP问题matlab源码.md

    【优化求解】粒子群优化和重力搜索算法求解MLP问题matlab源码.md

Global site tag (gtag.js) - Google Analytics