当前位置: 首页 > 编程笔记 >

java版数独游戏核心算法(一)

邰昀
2023-03-14
本文向大家介绍java版数独游戏核心算法(一),包括了java版数独游戏核心算法(一)的使用技巧和注意事项,需要的朋友参考一下

之前学习javascript时用javascript写过一个数独游戏,最近看了一点java的内容,于是就心血来潮想搞一个java版的数独游戏。

现在将全部代码分享出来和大家学习交流,当然代码中有着各种各样的问题和不足之处,望各位朋友批评指点。

以下是生成数独地图的核心算法,算法不是很好,也是之前参考过网上的一些思想:

package hlc.shudu.src;

/*
 * 数独的帮助类,里面提供数据所需的所有算法
 */
public class ShuduHelper {
 //数独地图数组
 private static int[][] maps = new int[9][9];
 //每个小九宫格可放置位置的数
 private static int[] canPutSum = new int[9];
 //用来存储之前放置过的位置
 static int[] used = new int[9];
 //是否已经完成地图的生成
 static boolean isOk = true;

 /*
  * 得到数独地图数组
  */
 public static int[][] getMap() {
 //判断是否已经完成地图的生成,要是没有完成就重新生成。
 //从这里就可以看出算法还有待优化,如果回溯的好的话就一直可以通过回溯来重新生成,而这里是通过重新执行生成算法来重新生成。希望感兴趣的朋友可以去实现以下。
  do{
   isOk = true;
   initMaps();
  }while(!isOk);
  return maps;
 }

 /*
  * 初始化maps
  */
 private static void initMaps() {
  // 初始化地图数组中没有填入任何数字
  for (int i = 0; i < 9; i++) {
   for (int j = 0; j < 9; j++) {
    maps[i][j] = -1;
   }
  }

  // 依次填入1~9
  for (int num = 1; num <= 9; num++) {
   for (int i = 0; i < 9; i++) {
    used[i] = -1;
    canPutSum[i] = -1;
   }
   // 遍历大九宫格中的每个小九宫格
   for (int i = 0; i < 9; i++) {
    if (canPutSum[i]==-1) {
     canPutSum[i] = getCanPutSum(i, num);
    }
    if (canPutSum[i]==1) {
     used[i] = -1;
    }

    if (canPutSum[i] == 0) {
     canPutSum[i] = -1;
     used[i] = -1;
     // 如果当前小九宫格中不能放入数字num,则回到前一个小九宫格
     if (i > 0) {
      // 将前一个九宫格中放num的位置清空
      if (used[i-1]!=-1) {
       //maps[(int) (Math.floor(used[i-1]/3)+Math.floor((i-1)/3)*3)][used[i-1]%3+((i-1)%3)*3]=-1;
       clearNum(i - 1, num);
      }
      // i回退一个,因为等会for循环灰给i加一,所以这里减2
      i -= 2;
      continue;
     } else {
      isOk = false;
      return;
     }
    } else {
     // 将num放入当前小九宫格中
     boolean flag = false;
     while (!flag) {
      int j = (int) (Math.random() * 9);
      // 当前小方格横坐标
      int ii = (i / 3) * 3 + j / 3;
      // 当前小方格纵坐标
      int jj = (i % 3) * 3 + j % 3;
      //System.out.println("num:"+num+"\tii:"+ii+"\tjj:"+jj);
      // 如果可以放置num则放置
      if (maps[ii][jj] == -1 && j!=used[i] && isCanPut(ii, jj, num)) {
       maps[ii][jj] = num;
       used[i] = j;
       canPutSum[i] -= 1;
       flag = true;
      }

     }
    }

   }
  }

 }

 /*
  * 清空第i个小九宫格中的num
  */
 private static void clearNum(int i, int num) {
  for (int j = 0; j < 9; j++) {
   // 当前小方格横坐标
   int ii = (i / 3) * 3 + j / 3;
   // 当前小方格纵坐标
   int jj = (i % 3) * 3 + j % 3;
   // 判断当前小方格是否可以放置
   if (maps[ii][jj] == num) {
    maps[ii][jj] = -1;
   }
  }

 }

 /*
  * 得到当前小九宫格可以放入数字num的位置数目
  */
 private static int getCanPutSum(int i, int num) {
  int sum = 0;
  // 遍历小九宫格
  for (int j = 0; j < 9; j++) {
   // 当前小方格横坐标
   int ii = (i / 3) * 3 + j / 3;
   // 当前小方格纵坐标
   int jj = i % 3 * 3 + j % 3;
   // 判断当前小方格是否可以放置
   if (maps[ii][jj] == -1 && isCanPut(ii, jj, num)) {
    ++sum;
   }
  }

  return sum;

 }

 /*
  * 指定横纵坐标点是否可以放置num
  */
 private static boolean isCanPut(int ii, int jj, int num) {
  // 判断指定坐标点的同行或同列是否有相同数字,要是有则为false
  for (int i = 0; i < 9; i++) {
   if (maps[ii][i] == num) {
    return false;
   }
   if (maps[i][jj] == num) {
    return false;
   }
  }
  return true;
 }
}

完整程序包可在GitHub上下载:https://github.com/houlongchao/s

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 数独游戏,游戏分三个难度来生成数独矩阵,有标记功能。关于挑战模式还没有实现。 [Code4App.com]

  • 本文向大家介绍Java游戏开发拼图游戏经典版,包括了Java游戏开发拼图游戏经典版的使用技巧和注意事项,需要的朋友参考一下 游戏介绍: 拼图游戏是一款经典的益智游戏,游戏难度分为 简单、正常、困难 三种难度,分别对应3*3,4*4,5*5布局,游戏开始前图片被随机打乱,空块位于最右下角,玩家通过点击空块周围图片或者按键方式对图片和空块进行相互交换,直到所有图片都回到原位即为游戏胜利。 本次制作的拼

  • 本文向大家介绍Java计算器核心算法代码实现,包括了Java计算器核心算法代码实现的使用技巧和注意事项,需要的朋友参考一下 在进行一个表达式的计算时,先将表达式分割成数字和字符串然后利用出入栈将分割后的表达式进行中缀转后缀,再将后缀表达式进行计算得到结果(思想在上一篇写过)现在贴下Java语言的代码实现。(学习Java时间不长所以可能会有很多不足的地方,我会改进也欢迎大神可以给我一些意见和建议~谢

  • 两天前,我得到了一个我试图用Python 3解决的数独问题。我被告知确实存在一个解决方案,但我不确定是否存在多个解决方案。 问题如下:一个9x9的数独网格完全是空的。然而,它确实包含彩色框,在这些框中,数字的总和必须是一个平方数。除此之外,通常的数独规则也适用。 这里的问题不是解决一个数独谜题,而是生成一个可行的谜题,满足彩色框的规则。 我的策略 使用numpy数组,我将网格划分为81个索引,这些

  • 我已经创建了一个数独解算器,它可以像人类一样解数独,通过检查与被检查方格对应的方格中的可能性确定值。 (来源:http://pastebin.com/KVrXUDBF) 但是,我想创建一个随机数独生成器(从空白网格),因此决定使用回溯算法。我理解回溯的概念,但对一件事感到困惑: 一旦我知道某个解决方案是不允许的,我如何知道要返回(和更改)哪个前一个节点?我应该简单地返回到前一个节点并循环浏览所有可

  • 我是JAVA新手,我一直在写一个数字猜谜游戏的代码,计算机从0-500的条件下选择数字:如果数字太低,用户输入0,计算机猜更低的数字;如果数字太高,用户输入1,计算机猜更高的数字 以5个猜测结束游戏 任何建议都将不胜感激!!!:d