@[TOC]GUI设计之马的遍历(5*5)

象棋中马遍历棋盘

【问题描述】
在N*N棋盘上,任意一个位置放置一个棋子马,要能选择一套合适的移动路线,按象棋中“马走日”的移动规则不重复地遍历棋盘上每一个位置点。
【基本要求】
用图形化的界面显示结果。
样例1:

样例2:

【扩展要求】
有兴趣的同学可在棋盘上设置一个或多个憋马腿的棋子,尝试遍历过程如何完善。

样例1:

样例2:

GameFrame类继承JFrame

import javax.swing.*;
public class GameFrame extends JFrame {public GameFrame(){setTitle("象棋中马的遍历");  //标题setSize(600,400);//窗口大小setResizable(false);//禁止改变窗口大小this.setLocationRelativeTo(null);// 居中展示窗口this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口终止程序}public static void main(String[] args) {GameFrame frame=new GameFrame();//窗口对象GamePanel panel=new GamePanel();//新建一个面板frame.add(panel);//添加面板到窗口frame.setVisible(true);//可见性}}

GamePanel 继承 JPanel类

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;public class GamePanel extends JPanel {boolean one=false;/* 马走日字,可能到达的8个点相对当前点的偏移坐标 */static int dx[] = { 1, 2, 2, 1, -1, -2, -2, -1 };static int dy[] = { 2, 1, -1, -2, -2, -1, 1, 2 };/* 马走日字,8个蹩脚的点相对当前点的偏移坐标 */static int dx_obstacle[]={0,1,1,0,0,-1,-1,0};static int dy_obstacle[]={1,0,0,-1,-1,0,0,1};static int boardSize=4;static int count=1;//其实点的数static int obstacleNum=0;//卒的个数int oneX = 0,oneY = 0;public static JButton button[][]=new JButton[5][5];public GamePanel() {setLayout(new GridLayout(6,5));//布局GamePanel.MyButtonListener Listener=new MyButtonListener();for(int i=0;i<button.length;i++){for(int k=0;k<button[i].length;k++){button[i][k]=new JButton();button[i][k].addActionListener(Listener);//给每一个数组元素装一个监听器add(button[i][k]);//将按钮添加到面板中}}repaint();}private  class  MyButtonListener implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {JButton clickedButton= (JButton) e.getSource();if(one==false){clickedButton.setText("马");//起点马for(int i=0;i<button.length;i++){for(int k=0;k<button[i].length;k++){if (!button[i][k].getText().equals("")){//获取初始位置数组的横纵坐标;oneX=i;oneY=k;clickedButton.setText("1");//将初始位置变为一one=true;} }}}}}static boolean DFS(int x, int y) {/* 经过了所有的空位置=所有的格子数-预留的棋子数 */if (count == (boardSize+1) * (boardSize+1)-obstacleNum)return true;/* 遍历从当前点走日字能够到达的8个点 */for (int dir = 0; dir < 8; dir++) {/*走日字到达下一个点 */int next_x = x+ dx[dir];int next_y = y+ dy[dir];/*马走下一个点,蹩脚的位置*/int obstacle_x=x+dx_obstacle[dir];int obstacle_y=y+dy_obstacle[dir];/* 超出边界 */if (next_x < 0|| next_x > boardSize || next_y < 0|| next_y > boardSize)continue;//这个位置走过或蹩马腿的位置有棋子(卒)if (!button[next_x][next_y].getText().equals("") ||button[obstacle_x][obstacle_y].getText().equals("卒"))continue;/* 访问过的点计数 */count++;/* 可以走一步,在下一个位置放入步数 */button[next_x][next_y].setText(String.valueOf(count));if (DFS(next_x, next_y)) //从下一个位置开始,继续遍历return true;/* 从日字的一个对角点出发不能到达所有的位置 */count--; // 后退一步button[next_x][next_y].setText("");}return false;}public void paint(Graphics g) {super.paint(g);g.setColor(Color.red);if (one==false){g.drawString("提示:单击某一个按钮,作为马的起始点",150,335);}if (one==true&&DFS(oneX,oneY)){g.drawString("提示:遍历成功",150,335);}if (one==true&&!DFS(oneX,oneY)){g.drawString("提示:遍历失败",150,335);}repaint();}}

【方法】
(1)从递归、回溯的角度思考解决途径
(2)马走日字,可能到达的8个点(如图1所示)相对当前点的偏移坐标为:
int dx[8] = {1, 2, 2, 1, -1, -2, -2, -1};
int dy[8] = {2, 1, -1, -2, -2, -1, 1, 2};

图1 马走日字能到达的位置

(3)马走日字,8个方向对应的蹩脚点(如图2所示)相对当前点的偏移坐标为:
int dx_obstacle[8]={0,1,1,0,0,-1,-1,0};
int dy_obstacle[8]={1,0,0,-1,-1,0,0,1};

图2 马走日字8个方向对应的蹩脚点

【主要算法】
函数DFS从(x,y)开始,按马走日字的方法,能够走遍所有的格子时,返回True,否则返回false。
/* 马走日字,可能到达的8个点相对当前点的偏移坐标 */
static int dx[] = { 1, 2, 2, 1, -1, -2, -2, -1 };
static int dy[] = { 2, 1, -1, -2, -2, -1, 1, 2 };
/* 马走日字,8个蹩脚的点相对当前点的偏移坐标 */
static int dx_obstacle[]={0,1,1,0,0,-1,-1,0};
static int dy_obstacle[]={1,0,0,-1,-1,0,0,1};
static boolean DFS(int x, int y) {/* 经过了所有的空位置=所有的格子数-预留的棋子数 */if (count == boardSize * boardSize-obstacleNum)return true;/* 遍历从当前点走日字能够到达的8个点 */for (int dir = 0; dir < 8; dir++) {/*走日字到达下一个点 */int next_x = x + dx[dir];int next_y = y + dy[dir];/*马走下一个点,蹩脚的位置*/int obstacle_x=x+dx_obstacle[dir];int obstacle_y=y+dy_obstacle[dir];/* 超出边界 */if (next_x < 1 || next_x > boardSize || next_y < 1|| next_y > boardSize)continue;//这个位置走过或蹩马腿的位置有棋子(卒) if (!button[next_x][next_y].getText().equals("") ||button[obstacle_x][obstacle_y].getText().equals("卒"))continue;/* 访问过的点计数 */count++;/* 可以走一步,在下一个位置放入步数 */button[next_x][next_y].setText(String.valueOf(count));if (DFS(next_x, next_y)) //从下一个位置开始,继续遍历return true;/* 从日字的一个对角点出发不能到达所有的位置 */count--; // 后退一步button[next_x][next_y].setText("");}return false;}
}

测试结果



当添加卒后马的遍历情况
在第二列第三行添加一个卒 button[1][2].setText(“卒”);
obstacleNum=1;

当添加卒后马的遍历情况
在第1列第1行添加一个卒 button[0][0].setText(“卒”);
在第5列第1行添加一个卒 button[4][0].setText(“卒”);
obstacleNum=2

GUI设计之马的遍历相关推荐

  1. 基于MATLAB金属表面缺陷分类与测量的GUI设计

    前言: 好久不搞图像处理了(一年了吧),终于大三有门图像处理的选修课有个课设,我就怀着强迫症的思想把它好好做了下(话说好久没看其他专业课了...),其他两名女生全程躺...算法不好,脑子有点蠢熬夜太多 ...

  2. Python GUI设计 tkinter 笔记

    # <Python GUI设计 tkinter菜鸟编程>学习笔记,可直接执行代码 # 排版混乱,可设置Tab缩进为2个空格查看 # 此处整个笔记为python程序,可直接运,生成各类GUI ...

  3. 基于matlab的自动人脸识别系统GUI设计

    基于matlab的自动人脸识别系统GUI设计 之前做的一个课设项目半成品,一边网上找资料一边自己瞎捣鼓,完成了GUI界面的设计,实时视频中的人脸检测和追踪,PCA算法训练,单张人脸识别.但是识别率比较 ...

  4. C语言象棋马的遍历程序,象棋中马的遍历

    1.问题描述: 在N*N棋盘上,任意一个位置放置一个棋子马,要能选择一套合适的移动路线,按象棋中"马走日"的移动规则不重复地遍历棋盘上每一个位置点. 2.基本要求: 用图形化的界面 ...

  5. 回溯法之马的遍历问题(递归)

    马的遍历问题:在n*m的棋盘上,马只能走日字.马从位置(x,y)处出发,把棋盘的每一点都走一次,且只走一次,找出所有路径. 问题分析:行n,列m,马在不出边界的情况下有8个方向可以行走(走日字),如当 ...

  6. 【java毕业设计】基于java+swing+CS的图书销售管理系统GUI设计与实现(毕业论文+程序源码)——图书销售管理系统

    基于java+swing+CS的图书销售管理系统GUI设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+swing+CS的图书销售管理系统GUI设计与实现,文章末尾附有本毕业设计的 ...

  7. Python Qt GUI设计:QPushButton、QRadioButton和QCheckBox按钮类(基础篇—12)

    目录 1.QPushButton按钮类 2.QRadioButton按钮类 3.QCheckBox按钮类 在GUI设计中,按钮都是最重要的和常用的触发动作请求的方式,用来与用户进行交互操作.在PyQt ...

  8. Python Qt GUI设计:信号与槽的使用方法(基础篇—7)

    目录 1.信号与槽的概念 2.信号与槽的基础函数 2.1.创建信号函数 2.2.连接信号函数 2.3.断开信号函数 2.4.发射信号函数 3.信号和槽的使用方法 3.1.内置信号与槽的使用 3.2.自 ...

  9. Python Qt GUI设计:窗口布局管理方法【强化】(基础篇—6)

    目录 1. 水平布局类(QHBoxLayout) 2.垂直布局类(QVBoxLayout) 3.网格布局类(QGridLayout) 3.1.单一的网络布局 3.2.跨越行.列的网络布局 4.表单布局 ...

最新文章

  1. java指令集_javap 指令集
  2. VirtualBox的四种网络连接方式
  3. 2.数据库的基本操作针对于库层面的操作
  4. springboot 打卡功能_实战:如果让你用SpringBoot实现签到奖励的功能,你会怎么做?...
  5. python3 匹配空格 正则_玩转正则表达式
  6. Oracle数据库设计要做到五戒
  7. 计算机应用基础第二版在线作业c,计算机应用基础作业二(答案)
  8. SQL 语句优化--IN语句优化案例
  9. Java类class getClasses()方法及示例
  10. python编程字符输入连接_python字符串连接的N种方式总结
  11. [转]ExtJS的使用方法汇总—配置和表格控件使用
  12. [转载] python numpy.random.randn()与numpy.random.rand()的区别 (正态分布公式)(标准正态分布 standard normal distribution
  13. C/C++[codeup 2066]分组统计
  14. 鸿蒙处理器985相当于内核多少,麒麟985处理器相当于骁龙多少_麒麟985处理器性能测评...
  15. 读《红楼梦》和《百年孤独》后关于爱、孤独和回忆的一点体会
  16. 你知道Message.obtain()什么原理吗?
  17. 他是年薪几十万的微软工程师,现在却在成都街头收破烂......
  18. mysql cluster 分片_MySQL Cluster --01
  19. 读取四则运算的字符串(Formula)返回计算结果 c#
  20. mysql备份文件如何还原数据库文件_数据库备份文件还原方法

热门文章

  1. 各类通信协议归纳整理(偏硬件)
  2. Airplay、DLNA和Miracast三种技术的介绍
  3. [日语二级词汇]动词(3)
  4. 考驾照科目二需有的天时 地利 人和
  5. P1_M3_L3 Safety Frameworks for Self Driving(自动驾驶安全框架)
  6. 来看看移动端小程序技术的前世今生!小白也能看明白
  7. STemwin----开发问题锦集
  8. CSS3 @font-face实现颜色大小可控的三角效果——张鑫旭
  9. CentOS 8 安装golang
  10. yocs_velocity_smoother速度平滑包的动态参数设置