微信小程序华容道最优解

以前自己写过搜索华容道的最优解程序,想起来真是效率感人>﹏<,虽然如此,但是全是自己独立完成的,心里还是很高兴的,现在在微信小程序中看到了华容道,决定要再写一次华容道的程序。
这次看了网上的华容道程序,修改自许剑伟先生(福建莆田第十中学)的华容道程序(又是C语言,又是不友好的变量命名,看得我好辛苦≡(▔﹏▔)≡)
程序支持棋子三种移动类型

  1. 同一颗棋子为一步
  2. 直线为一步
  3. 一格为一步

    目录

盘面分析

这一步是将图片转为数组盘面,以前是采用取特定的点的颜色,确定棋子的类型,效果不是很好,这次使用的是图片相识算法,用了最简单的图片感知算法,效果非常好,也是因为图片比较简单的关系

基本样本

基本样本来源,包含了所有的横、竖棋子
《微信小程序华容道最优解》 《微信小程序华容道最优解》

	private final static String[][] HASH_CODE = { 
	        // 兵
	        { "3878EEDACB8BBEA1", "387CCEDACA8BBEA1", "387CCADACA8BBEA1", "387CEADACA8BBEA1", "3878D6DACBC9BE81",
	                "3858D2DACBC9BE81", "3878D6DACB89BEA1", "387CD2DACBC9BEA1"
	        },
	        // 横将
	        { "F9FAFB71238283C1", "030200E1F7F5F3FB", "0F0C1199E3E2F7E7", "F7F2F9F8FB720B09", "F9F9FBF3E3E1E0C0"},
	        // 竖将
	        { "C793BB9CB05C2E13", "7F7FFBB5980182AE", "EFF72707278DCDDB", "6EB79B075842073B", "DB91ADA1986E7E2A"},
	        // 曹操
	        { "E082810E04008FCF"}
	};

示例

《微信小程序华容道最优解》

10,  1,  5,  5,
10, 15, 15,  0,
11, 15, 15, 12,
11,  0, 13, 12,
 2,  3, 13,  4

感知哈希算法

1. 缩小图片尺寸

这一步的作用是去除各种图片尺寸和图片比例的差异, 只保留结构、明暗等基本信息

2.转为灰度图片

简化色彩
1,2步直接使用下面代码完成

	BufferedImage part = new BufferedImage(8, 8, BufferedImage.TYPE_BYTE_GRAY);

3.计算平均值

计算所有像素的灰度平均值

	/** * 计算数组平均值 * @param rgb * @return */
	public static double average(int[] rgb) { 
	    double sum = 0;
	    for (int i = 0; i < rgb.length; i++) { 
	        sum += rgb[i];
	    }
	    return sum / rgb.length;
	}

4.比较像素的灰度

将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0

    private static int[] rgbToBinariesHashCode(int[] rgb) { 
        int[] hashCode = new int[rgb.length];
        double average = KlotskiNodeUtil.average(rgb);
        for (int i = 0; i < rgb.length; i++) { 
            if (rgb[i] >= average) { 
                hashCode[i] = 1;
            }
        }
        return hashCode;
    }
    
    /** * 二进制数组转16进制字符 * @param binaries * @return */
    public static String binariesToHex(int[] binaries) { 
        char[] hashCode = new char[binaries.length >> 2];
        for (int i = 0, j = 0; i < binaries.length; i += 4, j++) { 
            int sum = (binaries[i] << 3) + (binaries[i + 1] << 2) + (binaries[i + 2] << 1) + binaries[i + 3];
            switch (sum) { 
                case 0:
                    hashCode[j] = '0';
                    break;
                case 1:
                    hashCode[j] = '1';
                    break;
                case 2:
                    hashCode[j] = '2';
                    break;
                case 3:
                    hashCode[j] = '3';
                    break;
                case 4:
                    hashCode[j] = '4';
                    break;
                case 5:
                    hashCode[j] = '5';
                    break;
                case 6:
                    hashCode[j] = '6';
                    break;
                case 7:
                    hashCode[j] = '7';
                    break;
                case 8:
                    hashCode[j] = '8';
                    break;
                case 9:
                    hashCode[j] = '9';
                    break;
                case 10:
                    hashCode[j] = 'A';
                    break;
                case 11:
                    hashCode[j] = 'B';
                    break;
                case 12:
                    hashCode[j] = 'C';
                    break;
                case 13:
                    hashCode[j] = 'D';
                    break;
                case 14:
                    hashCode[j] = 'E';
                    break;
                case 15:
                    hashCode[j] = 'F';
                    break;
                default:
            }
        }
        return String.valueOf(hashCode);
    }

5.计算hash值

将上一步的比较结果,组合在一起,就构成了一个64位的整数(转16进制),这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了
得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算”汉明距离”(Hamming distance)。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片

    private final static char[] INDEX_TO_CHAR_TYPE = { KlotskiNodeUtil.E, KlotskiNodeUtil.S,
            KlotskiNodeUtil.H, KlotskiNodeUtil.V, KlotskiNodeUtil.T};
    /** * 汉明距离 * @param hashCode * @return */
    private static char hanMingDifference(String hashCode) { 
        int difference = 16, index = 0;
        for (int i = 0; i < HASH_CODE.length; i++) { 
            for (int j = 0; j < HASH_CODE[i].length; j++) { 
                int count = 0;
                for (int k = 0; k < HASH_CODE[i][j].length(); k++) { 
                    if (HASH_CODE[i][j].charAt(k) != hashCode.charAt(k)) { 
                        count++;
                    }
                }
                // 取最近接近的棋子类型
                if (count < 10 && count < difference) { 
                    index = i + 1;
                    difference = count;
                }
            }
        }
        return INDEX_TO_CHAR_TYPE[index];
    }

代码

GitHub

    原文作者:L8426936
    原文地址: https://blog.csdn.net/lcl1997/article/details/90141844
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞