这个是我的算法课程的期末大作业

我是参考了网课老师讲的骑士回游法写的

花了一天半写的,感觉有些冗余,到时候再改一下

代码

import java.awt.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Scanner;import static java.lang.System.exit;/*** 游戏功能介绍* (1)马的形象可辨认,可用键盘操纵马的跳跃方向* (2)不可选择超出范围的位置* (3)正确检测,若马儿走完全部的棋盘格,提示成功,否则提示失败* (4)添加地图编辑功能,可以修改当前地图的大小,并检测地图的是否可执行* (5)优化路径-->贪心算法** 贪心算法优化:* 每次递归时,都优先拿【下一个位置列表】中的第【1】个为孩子* 如果我们每次先拿一个值,它的【下一个位置列表】最少,那么可以避免很多无效的重复递归* 而用size()方法获得这些值的【下一个位置列表】的数量,把数量最少的放在第【1】个位置就行了*/public class horse {private static Scanner scanner = new Scanner(System.in);private static int X; // 初始化棋盘的列数为8private static int Y; // 初始化棋盘的行数为8private static boolean visited[];//创建一个数组,标记棋盘的各个位置是否被访问过//使用一个属性,标记是否棋盘的所有位置都被访问private static boolean finished; // 如果为true,表示成功private static int chessMap[][] ;//棋盘数组private static int step;//步数private static int size;//棋盘的尺寸private static int change;//控制检查位置合不合法private static ArrayList<Point> workedPoints = new ArrayList<>();//记录所有走过的点private static int row;//马儿起始的行private static int column;//马儿起始的列public static void main(String[] args) {int choice;//主菜单选择boolean start = true;//游戏是否退出的控件row = 6;//马儿起始的行column = 1;//马儿起始的列Point point = new Point(column - 1, row - 1);//马儿起始点ArrayList<Point> pointList = new ArrayList<>();//存储可以动的点while(start){flushTage();//刷新游戏界面System.out.println("===================马踏棋盘游戏===================");System.out.println("|请选择:\t\t\t\t\t\t\t\t\t   |");System.out.println("|\t\t\t\t\t1.开始游戏\t\t\t\t   |");//进去选择你所需要创建的地图System.out.println("|\t\t\t\t\t2.查看答案\t\t\t\t   |");//多种不同的答案System.out.println("|\t\t\t\t\t3. 退 出 \t\t\t\t   |");System.out.println("================================================");System.out.print("请输入相应数字执行其功能:");choice = scanner.nextInt();switch (choice){case 1://开始游戏step = 1;//初始化步数为1System.out.print("请输入棋盘的尺寸(大于2的整数):");size = scanner.nextInt();//输入棋盘的尺寸System.out.print("请输入马儿的起始行和列:");column = scanner.nextInt();row = scanner.nextInt();point = new Point(column - 1, row - 1);//马儿起始点pointList = new ArrayList<>();//存储可以动的点X = size;Y = size;chessMap = new int[size][size];if(chessBoard(size)){//判断棋盘的大小是否合法ArrayList<Point> next = next(point);//显示可走的点paintChess(workedPoints, point, next, step);}break;case 2:System.out.print("请输入棋盘的尺寸(大于2的整数):");size = scanner.nextInt();//输入棋盘的尺寸step = 1;//初始化步数为1X = size;Y = size;System.out.print("请输入马儿的起始行和列:");row = scanner.nextInt();column = scanner.nextInt();chessMap = new int[size][size];visited = new boolean[size * size];//测试一下耗时long startT = System.currentTimeMillis();if(chessBoard(size)){//判断棋盘的大小是否合法travelChessBoard(chessMap, row-1, column-1, step);//输出棋盘的最后情况for(int[] rows : chessMap) {for(int step: rows) {System.out.print(step + "\t");}System.out.println();}}long endT = System.currentTimeMillis();System.out.println("共耗时: " + (endT - startT) + " 毫秒");break;case 3:start = false;flushTage();//刷新页面System.out.println("===================马踏棋盘游戏===================");System.out.println("|\t\t\t\t\t\t\t\t\t\t\t   |");System.out.println("|\t\t\t\t\t退出成功 \t\t\t\t   |");System.out.println("|\t\t\t\t\t\t\t\t\t\t\t   |");System.out.println("================================================");break;default:System.out.println("输入的数字不合法,请重新输入");break;}}//选择地图大小//目前所在的位置为马头♞//游戏页面出现可选择的位置,使用★号标志//去过的位置标志为相应的步数,黑白格子分明//走过的步数也显示出来}//游戏界面刷新public static void flushTage(){for (int i = 0; i < 5; i++){System.out.println();}}//判断棋盘大小是否合法public static boolean chessBoard(int size){Scanner scanner = new Scanner(System.in);while (size < 3){//判断棋盘尺寸是否合法System.out.print("请输入棋盘的尺寸(大于2的整数):");size = scanner.nextInt();}return true;}/*** 绘制地图* @param workedPoints 存储马儿经过的点的集合* @param point 马儿的起始点* @param pointList 马儿可走的点* @param step 表示第几步*/public static void paintChess(ArrayList<Point> workedPoints, Point point, ArrayList<Point> pointList, int step) {flushTage();int chessMap[][] = new int[X][Y];//每次进入该方法都会新建一个空白地图chessMap[point.x][point.y] = 2;//马儿目前所在位置♞int m = chessMap[0].length * chessMap[0].length + 10;//设置一个特定的数值代表可以移动的位置for (int i = 0; i < pointList.size(); i++) {int x = (int) pointList.get(i).getX();int y = (int) pointList.get(i).getY();chessMap[x][y] = m;//设置特殊字作为可移动点☆}for (int i = 0; i < workedPoints.size(); i++) {int x = (int) workedPoints.get(i).getX();int y = (int) workedPoints.get(i).getY();chessMap[x][y] = 1;//设置1为走过的点■}if (change == 1){chessMap[point.x][point.y] = 2;//马儿目前所在位置♞}System.out.println("===================马踏棋盘游戏===================");System.out.print("\t\t\t\t ");for (int i = 0; i < size; i++){System.out.print((i+1)+" ");}System.out.println();paintmap1(chessMap, m);System.out.println("                 【step = " + step+"】");System.out.println("================================================");workedPoints.add(new Point(point));//添加新选中的位置作为已走过的点int xi = X + 10;//取特殊点,防止取中与列相同的数字int xj = X + 12;//取特殊点,防止取中与列相同的数字System.out.println("【退回上一步请输入:"+xi+" "+xi+"】");System.out.println("【退出游戏请输入:"+xj+" "+xj+"】");System.out.print("请选择你所需要走的点(如3行2列,则输入3 2):");int a = scanner.nextInt();//行数int b = scanner.nextInt();//列数//一系列撤回change = 0;//作为检查位置合不合法的控制//马头没回去if (a == xi && b == xi){//在集合里面所有的点都是有顺序的int len = workedPoints.size();//获取长度workedPoints.remove(len-1);//删除最后一个走过的点//回到上一个点Point point1 = workedPoints.get(len - 2);a = point1.x + 1;b = point1.y + 1;step = step - 2;change = 1;//当chang=1时,不检查位置合不合法workedPoints.remove(workedPoints.size()-1);}else if (a == xj && b == xj){flushTage();//刷新页面System.out.println("===================马踏棋盘游戏===================");System.out.println("|\t\t\t\t\t\t\t\t\t\t\t   |");System.out.println("|\t\t\t\t\t游戏失败 \t\t\t\t   |");System.out.println("|\t\t\t\t\t\t\t\t\t\t\t   |");System.out.println("|\t\t【1】继续游戏\t\t\t【2】结束游戏\t\t   |");System.out.println("================================================");System.out.print("请输入相应数字执行其功能:");int choice = scanner.nextInt();if (choice == 2){exit(0);}else if (choice == 1){return;}else {while (choice != 1 || choice != 2){System.out.print("请输入【1~2】之间的数字:");choice = scanner.nextInt();if (choice == 2){exit(0);}else if (choice == 1){return;}}}}Point cp = new Point(a-1, b-1);//做出判断,不能选择其他地方的,只能选择星星的//且不能走回走过的点//有冗余while(true){if (change==1)break;if (pointList.contains(cp)){if(workedPoints.contains(cp)){System.out.print("输入的位置不合法,请重新输入:");a = scanner.nextInt();//行数b = scanner.nextInt();//列数cp = new Point(a-1, b-1);}else break;}else {System.out.print("输入的位置不合法,请重新输入:");a = scanner.nextInt();//行数b = scanner.nextInt();//列数cp = new Point(a-1, b-1);}}//下一个可移动的所有点ArrayList<Point> nextPoints = next(cp);//不报结束是因为还有重复的点可移动,却没有去除for (Point p : workedPoints){if (nextPoints.contains(p)){nextPoints.remove(p);}}//下一步的点的集合为0,有两种情况//1、step == X * Y ----> 胜利//2、step < X * Y  ----> 失败step++;if(nextPoints.size() == 0){if (step == X * Y)winGame();//游戏胜利else failGame();//游戏失败}//workedPoints可能还需要再删除多一个,因为它包含了cppaintChess(workedPoints, cp, nextPoints, step);}/*** 传入现在的位置,返回可以移动的位置的集合* @param curPoint* @return*/public static ArrayList<Point> next(Point curPoint){ArrayList<Point> ps = new ArrayList<>();//存储可移动的位置Point point = new Point();//找出可以移动的点,八个位置挨个判断if ((point.x = curPoint.x + 2) < X && (point.y = curPoint.y - 1) >= 0){ps.add(new Point(point));}if ((point.x = curPoint.x + 2) < X && (point.y = curPoint.y + 1) < Y){ps.add(new Point(point));}if ((point.x = curPoint.x - 2) >= 0 && (point.y = curPoint.y - 1) >= 0){ps.add(new Point(point));}if ((point.x = curPoint.x - 2) >= 0 && (point.y = curPoint.y + 1) < Y){ps.add(new Point(point));}if ((point.x = curPoint.x + 1) < X && (point.y = curPoint.y - 2) >= 0){ps.add(new Point(point));}if ((point.x = curPoint.x - 1) >= 0 && (point.y = curPoint.y - 2) >= 0){ps.add(new Point(point));}if ((point.x = curPoint.x + 1) < X && (point.y = curPoint.y + 2) < Y){ps.add(new Point(point));}if ((point.x = curPoint.x - 1) >= 0 && (point.y = curPoint.y + 2) < Y){ps.add(new Point(point));}return ps;}//游戏失败public static void failGame(){flushTage();//刷新页面System.out.println("===================马踏棋盘游戏===================");System.out.println("|\t\t\t\t\t\t\t\t\t\t\t   |");System.out.println("|\t\t\t\t\t游戏失败 \t\t\t\t   |");System.out.println("|\t\t\t\t\t\t\t\t\t\t\t   |");System.out.println("|\t\t【1】继续游戏\t\t\t【2】结束游戏\t\t   |");System.out.println("================================================");System.out.print("请输入相应数字执行其功能:");int choice = scanner.nextInt();if (choice == 2){exit(0);}else if (choice == 1){return;}else {while (choice != 1 || choice != 2){System.out.print("请输入【1~2】之间的数字:");choice = scanner.nextInt();if (choice == 2){exit(0);}else if (choice == 1){return;}}}}//游戏胜利public static void winGame(){flushTage();//刷新页面System.out.println("===================马踏棋盘游戏===================");System.out.println("|\t\t\t\t\t\t\t\t\t\t\t   |");System.out.println("|\t\t\t\t\t游戏胜利 \t\t\t\t   |");System.out.println("|\t\t\t\t\t\t\t\t\t\t\t   |");System.out.println("|\t\t【1】继续游戏\t\t\t【2】结束游戏\t\t   |");System.out.println("================================================");System.out.print("请输入相应数字执行其功能:");int choice = scanner.nextInt();if (choice == 2){exit(0);}else if (choice == 1){return;}else {while (choice != 1 || choice != 2){System.out.print("请输入【1~2】之间的数字:");choice = scanner.nextInt();if (choice == 2){exit(0);}else if (choice == 1){return;}}}}//绘制动态地图public static void paintmap1(int[][]chessMap, int m){for (int i = 0; i < chessMap.length; i++) {System.out.print("\t\t\t\t"+(i+1));for (int j = 0; j < chessMap[i].length; j++) {if (chessMap[i][j] == 2) {System.out.print("♞");//表示走过的点}if (chessMap[i][j] == 1) {System.out.print("■");//表示走过的点}if (chessMap[i][j] == 0) {System.out.print("□");//表示未走过的点}//添加==1为黑猩猩,表示走过的点if (chessMap[i][j] == m) {System.out.print("☆");//表示可选择的点}}System.out.println();}}/**** @param chessMap 棋盘* @param row 马儿当前的位置的行 从0开始* @param column 马儿当前的位置的列  从0开始* @param step 是第几步 ,初始位置就是第1步*/public static void travelChessBoard(int [][] chessMap, int row, int column, int step){chessMap[row][column] = step;visited[row * X +column] = true;//表示位置已被访问过ArrayList<Point> ps = next(new Point(column, row));//获取当前位置可以走的下一个位置的集合sort(ps);//遍历 pswhile (!ps.isEmpty()){Point p = ps.remove(0);//判断该点是否已经访问过if (!visited[p.y * X + p.x]) {//说明还没有访问过travelChessBoard(chessMap, p.y, p.x, step + 1);}}//判断马儿是否完成了任务,使用   step 和应该走的步数比较 ,//如果没有达到数量,则表示没有完成任务,将整个棋盘置0//说明: step < X * Y  成立的情况有两种//1. 棋盘到目前位置,仍然没有走完//2. 棋盘处于一个回溯过程if (step < X * Y && !finished){chessMap[row][column] = 0;visited[row * X + column] = false;}else {finished = true;}}//根据当前这个一步的所有的下一步的选择位置,进行非递减排序, 减少回溯的次数public static void sort(ArrayList<Point> ps){ps.sort(new Comparator<Point>() {@Overridepublic int compare(Point o1, Point o2) {//获取o1的下一步的所有位置个数int count1 = next(o1).size();//获取o2的下一步的所有位置的个数int count2 = next(o2).size();if (count1 < count2){return -1;}else if (count1 == count2){return 0;}else {return 1;}}});}
}

实现图

马踏棋盘(java)相关推荐

  1. java 马踏棋盘优化_我所知道的十大常用算法之马踏棋盘算法(深度搜索、贪心思想优化 )...

    前言需求 今天我们学习的是马踏棋盘算法,我们还是从一个场景里引入看看 马踏棋盘算法也被称为骑士周游问题 将马随机放在国际象棋的6×6棋盘Board0-5的某个方格中 提示:马按走棋规则(马走日字)进行 ...

  2. Java对马踏棋盘问题(骑士周游问题)的实现

    14.10.2 马踏棋盘游戏代码实现 马踏棋盘问题(骑士周游问题)实际上是图的深度优先搜索(DFS)的应用. 如果使用回溯(就是深度优先搜索)来解决,假如马儿踏了 53 个点,如图:走到了第 53 个 ...

  3. Day600601.马踏棋盘算法 -数据结构和算法Java

    马踏棋盘算法 图的深度优先DFS 回溯 八皇后问题.小老鼠找迷宫问题 一.介绍 二.思路分析 三.代码实现 package com.achang.algorithm;import java.awt.* ...

  4. 用java写的马踏棋盘算法

    用java写的马踏棋盘算法 将马随机放在国际象棋的8×8棋盘Board[0-7][0-7]的某个方格中,马按走棋规则进行移动.要求每个方格只进入一次,走遍棋盘上全部64个方格. 代码 /* 马踏棋盘问 ...

  5. 基于Java Swing 的马踏棋盘小游戏(附源码!免费下载!)

    马踏棋盘游戏小项目 设计主要功能 运用的数据结构 运行流程讲解及录像 项目分类截图及源码链接! 设计主要功能 (1)设计内容:设计一个马踏棋盘游戏,马作为棋子,以马走日字的走法,将整个棋盘一次性走完, ...

  6. 马踏棋盘(Java版)

    问题: 国际象棋的棋盘为8*8的方格棋盘.现将"马"放在任意指定的方格中,按照"马"走棋的规则将"马"进行移动.要求每个方格只能进入一次,最 ...

  7. 【算法篇】/*一篇博客带你详细了解马踏棋盘问题*/(java语言实现)

    [前言]本文部分内容引用于b站尚硅谷老师的资料,如有侵权,请及时联系作者! hello大家好! 我依然是你们熟悉的槿凉.那么最近呢由于躺平了几天,也没有来得及更新博客,没有办法啦!学校封的严严实实,闷 ...

  8. 剑指Offer_12_矩阵中的路径(参考问题:马踏棋盘)

    题目描述  请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径.路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子.如果一条路径经过了矩阵 ...

  9. 骑士周游(马踏棋盘)问题

    1,马踏棋盘算法介绍 马踏棋盘问题也被称为骑士周游问题 将马随机放在国际象棋的8*8的棋盘中的某个格子里,马按照走棋规则(日子)进行移动.要求每个方格只进入一次,走遍64个方格 2,马踏棋盘算法思路分 ...

  10. 单链表实现图书管理系统(销售系统,马踏棋盘)

    这篇文章主要介绍三个数据结构的课程设计,一共设涉及到三个课程设计,分别是图书管理系统,销售管理系统,马踏棋盘. 声明:图书管理系统为作者所写,其他两个来源于网络,如有侵权,请通知作者删除. 以下代码经 ...

最新文章

  1. 用jquery mobile 实现幻灯片效果
  2. 【数字图像处理】七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解
  3. LeetCode 102. Binary Tree Level Order Traversal
  4. 『数学』--数论--组合数+卢卡斯定理+扩展卢卡斯定理
  5. bzoj 2179 FFT快速傅立叶 FFT
  6. aws emr 大数据分析_DataOps —使用AWS Lambda和Amazon EMR的全自动,低成本数据管道
  7. 漫步者头戴式蓝牙耳机一边有声音一边没声音
  8. configure: error: no acceptable cc found in $PATH
  9. 《期权、期货及其他衍生产品》读书笔记(第四章:利率)
  10. 正则表达式匹配身份证号
  11. smbd配置windows访问linux centos的共享文件
  12. 【腾讯云】记录一次Could not connect to SMTP host: smtp.163.com, port: 25的解决办法
  13. mybitplus name or service not known或quartz couldn‘t get host name
  14. CSS单位px、em、rem及它们之间的换算关系
  15. flag.Args()和 flag.NArg()的用法
  16. NLP学习笔记(四) Seq2Seq基本介绍
  17. STM32 CUBEIDE MacOS首次使用笔记
  18. 【挑战30天掌握】算法与数据结构!!!
  19. 变色龙嗅探卡功能_变色龙功能
  20. 前端架构之路(3) - 前端开发规范

热门文章

  1. 跟朋友合伙创业股权怎么分配
  2. ★一人一首成名歌曲★
  3. 干货 | 关于SwiftUI,看这一篇就够了
  4. 【unity 保卫星城】--- 开发笔记02(陀螺仪移动)
  5. CentOS搭建SVN服务器
  6. java/php/net/python守望先锋网站设计
  7. 13_Pinia组件库
  8. pandas read_excel 和 to_excel 读写Excel的参数详解
  9. win7上怎么安装linux系统安装教程,怎么装系统双系统安装教程 win7 linux
  10. 基尔霍夫定律的验证与multisim仿真(附工程文件)