骑士周游问题、马踏棋盘算法的实现及使用贪心算法进行优化代码实现

package Algorithm;

import java.awt.*;
import java.util.ArrayList;
import java.util.Comparator;

public class HorseAlgorithm {
    private static int X;//棋盘的行数
    private static int Y;//棋盘的列数
    private static boolean [] isVisited;
    private static boolean isFinished;

    public static void main(String[] args) {
        X = 8;
        Y = 8;
        int row = 1;
        int column = 1;

        int [][] chessboard = new int[X][Y];
        isVisited = new boolean[X * Y];

        long start = System.currentTimeMillis();
        travelChessboard(chessboard,row - 1, column - 1, 1);
        long end = System.currentTimeMillis();
        System.out.println("花了" + (end - start) + "毫秒");
        //输出结果(走法)
        for(int [] rows : chessboard){
            for(int step : rows){
                System.out.print(step + "  ");
            }
            System.out.println();
        }
    }

    /**
     *
     * @param chessboard 棋盘
     * @param row 马儿当前的位置所在的行
     * @param column 马儿当前的位置所在的列
     * @param step 是第几步,初始化为 1
     */
    public static void travelChessboard(int [][] chessboard, int row, int column, int step){
        chessboard[row][column] = step;//记录步数
        isVisited[row * Y + column] = true;//标志已经访问

        ArrayList<Point> ps = next(new Point(row,column));
        //优化,对ps进行非递减排序
        sort(ps);

        //遍历当前位置所有可以走的下一步
        while (!ps.isEmpty()) {
            Point p = ps.remove(0);//取出下一个可走的位置
            //判断是否访问过
            if(!isVisited[p.x * Y + p.y]){//没有访问过
                travelChessboard(chessboard,p.x,p.y,step + 1);
            }
        }

        //表示未走完棋盘或者没有解
        //此时,回溯
        if( step < X * Y && !isFinished ) {
            chessboard[row][column] = 0;
            isVisited[row * Y + column] = false;
        } else {
            isFinished = true;//退出
        }
    }

    public static ArrayList<Point> next(Point curPoint){
        Point p1 = new Point();
        ArrayList<Point> ps = new ArrayList<>();

        //判断马儿还能走哪个位置
        //往左2步,向上一步走日
        if(( p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y - 1) >= 0 ){
            ps.add(new Point(p1));
        }

        //往左1步,向上2步走日
        if( (p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y - 2) >= 0 ){
            ps.add(new Point(p1));
        }

        //往右1步,向上2步走日
        if( (p1.x = curPoint.x + 1) < Y && (p1.y = curPoint.y - 2) >= 0 ){
            ps.add(new Point(p1));
        }

        //往右2步,向上1步走日
        if((p1.x = curPoint.x + 2) < Y && (p1.y = curPoint.y - 1) >= 0 ){
            ps.add(new Point(p1));
        }

        //往右2步,向下1步走日
        if((p1.x = curPoint.x + 2) < Y && (p1.y = curPoint.y + 1) < X ){
            ps.add(new Point(p1));
        }

        //往右一步,向下2步走日
        if((p1.x = curPoint.x + 1) < Y && (p1.y = curPoint.y + 2) < X ){
            ps.add(new Point(p1));
        }

        //往左一步,向下两步走日
        if((p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y + 2) < X ){
            ps.add(new Point(p1));
        }

        //往左两步,向下一步走日
        if((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y + 1) < X ){
            ps.add(new Point(p1));
        }

        return ps;
    }

    //使用贪心算法进行优化:
    //1.获取当前位置的下一个可以走的所有位置的集合ps
    //2.对ps中所有的Point进行非递减排序
    //1 2 2 2 3 4 5 6 -->非递减

    //根据当前这一步的所有下一步的选择位置,进行非递减排序
    public static void sort(ArrayList<Point> ps){
        ps.sort(new Comparator<Point>() {
            @Override
            public 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;
                }
            }
        });
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
井字棋是一种简单而经典的棋类游戏,设计一种人机对弈算法需要考虑以下几个方面: 1. 游戏策略设计:井字棋有许多不同的策略,例如优先占据中心位置、尽可能占据角落等。在设计人机对弈算法时需要考虑这些策略,并根据实际情况进行调整。 2. 状态评估函数:评估当前棋盘状态的好坏可以通过一个函数来实现。这个函数应该能够根据当前的棋盘状态给出一个分数,表示当前局面的好坏程度。在设计这个函数时可以考虑当前棋子的落点、连子情况、棋子分布等因素。 3. 搜索算法:在实现人机对弈算法时,需要设计搜索算法来寻找最优解。常见的搜索算法包括贪心算法、最小最大算法和Alpha-Beta剪枝算法等。在选择搜索算法时需要考虑时间复杂度和空间复杂度等因素,并根据实际情况进行调整。 4. 交互设计:在人机对弈过程中需要设计良好的交互界面,使得用户能够方便地进行棋子选择和操作。同时需要设计合适的提示功能,帮助用户更好地理解当前局面和下一步的操作方向。 基于以上几个方面,我们可以设计一个简单的人机对弈算法。具体实现步骤如下: 1. 设计游戏策略:我们可以采用优先占据中心位置和尽可能占据角落的策略。 2. 设计状态评估函数:我们可以根据当前棋子的落点、连子情况、棋子分布等因素来评估当前棋盘状态的好坏程度。具体实现可以采用线性加权函数,根据不同的因素进行加权求和。 3. 设计搜索算法:我们可以采用最小最大算法和Alpha-Beta剪枝算法结合的方法来进行搜索。具体实现可以采用递归调用函数的方式,每次搜索到一定深度后,调用状态评估函数来评估当前局面的好坏程度,并返回分数值。 4. 设计交互界面:我们可以采用简单的图形化界面,让用户可以方便地进行棋子选择和操作。同时可以设计一个提示功能,帮助用户更好地理解当前局面和下一步的操作方向。 总体而言,井字棋人机对弈算法的设计和实现需要综合考虑多个方面,包括游戏策略、状态评估函数、搜索算法和交互设计等。通过合理的设计和实现,我们可以实现一个简单而实用的人机对弈程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值