用
java
实现的数独运算
Number Placement(Sudoku)
用手机玩数独游戏时,突发奇想,如果用程序来解的话,该如何解呢?于是,花了一个晚上写了一个
java
程序。
数独游戏游戏规则是在一个
4
×
4
或
9
×
9
的格上,预先随机分布了一些数字,然后要求把剩下的格上填上数字,让每一列,行及区的数字都不能重复。数字的范围取决于数独的大小,例如:
4
×
4
格的只能选择
1
至
4
,
9
×
9
格的可以选
1
至
9
。这里的区指的是把这个
n
×
n
的格分成
n
个的小区,如
4
×
4
的格分成
4
个区,
9
×
9
分成
9
个区,而每个区的数字也不能重复。
好,开始进入计算:
这是一个随机生成的
9
×
9
的格:
4,0,3,0,8,0,0,0,1
0,9,0,0,0,5,0,0,0
8,0,0,0,2,0,0,0,0
0,0,0,0,0,4,0,0,5
6,0,0,0,0,9,0,0,0
0,0,0,8,0,0,6,3,0
0,0,1,0,0,2,3,6,0
0,6,0,0,0,0,0,2,0
0,0,7,1,0,0,0,0,8
其中非
0
的数就是系统预先定义的数字,为
0
的就是要填数的格。最后,填满数的格不论横,竖及区都不能有重复的数字。
第一步:
我先是为每个格的数定义了一个
Number
类,它的属性有行,列,区坐标,以及与之比邻的其他
Number
。代码见下:
package alonenumber;
import java.util.ArrayList;
/*
* author zhousy
*/
public class Number {
private int row;
private int col;
private int areaX;
private int areaY;
private int value = 0;
private int pos = -1;
private ArrayList<Integer> valueArray = new ArrayList<Integer>();
private boolean preSet = false;
private boolean isEva = false;
private Number next = null;
private Number prior = null;
public Number getPrior() {
return prior;
}
public void setPrior(Number prior) {
this.prior = prior;
}
public Number getNext() {
return next;
}
public void setNext(Number next) {
this.next = next;
}
public void setPreSet(boolean preSet) {
this.preSet = preSet;
}
public boolean isPreSet() {
return preSet;
}
public void setPreSet(int preSetValue) {
this.preSet = true;
this.value = preSetValue;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public ArrayList getValueArray() {
return valueArray;
}
public void setValueArray(ArrayList valueArray) {
this.valueArray = valueArray;
}
public int getAreaX() {
return areaX;
}
public void setAreaX(int areaX) {
this.areaX = areaX;
}
public int getAreaY() {
return areaY;
}
public void setAreaY(int areaY) {
this.areaY = areaY;
}
public boolean isEva() {
return isEva;
}
public void setEva(boolean isEva) {
this.isEva = isEva;
}
public int getPos() {
return pos;
}
public void setPos(int pos) {
this.pos = pos;
}
}
第二步:
开始写数独运算类
AloneNumber
先定义静态属性
cols,rows,
都初始为
9
(因为是
9
×
9
,如是
16
×
16
就是
16
),再将随机生成带有预置数字的
9
×
9
格设为
input
数组。
具体代码如下:
package alonenumber;
import java.util.ArrayList;
/*
* author zhousy
*/
public class AloneNumber {
static final int MAXVALUE = 9;
static final int COLS = 9;
static final int ROWS = 9;
static final int AREAROWS = 3;
static final int AREACOLS = 3;
Number[][] numberArray = new Number[COLS][ROWS];
int input[][] = {{4,0,3,0,8,0,0,0,1},
{0,9,0,0,0,5,0,0,0},
{8,0,0,0,2,0,0,0,0},
{0,0,0,0,0,4,0,0,5},
{6,0,0,0,0,9,0,0,0},
{0,0,0,8,0,0,6,3,0},
{0,0,1,0,0,2,3,6,0},
{0,6,0,0,0,0,0,2,0},
{0,0,7,1,0,0,0,0,8}};
public void preSet(){
for(int i=0;i<ROWS;i++){
for(int j=0;j<COLS;j++){
numberArray[i][j] = new Number();
if (input[i][j]!=0) numberArray[i][j].setPreSet(input[i][j]);
}
}
}
public void init() {
int nextI,nextJ;
for (int i=0;i<ROWS;i++){
for (int j=0;j<COLS;j++){
numberArray[i][j].setRow(i);
numberArray[i][j].setAreaX(i/AREAROWS);
numberArray[i][j].setAreaY(j/AREACOLS);
numberArray[i][j].setCol(j);
if (!((i==ROWS-1)&&(j==COLS-1))){
if(j==COLS-1){
nextI = i+1;
nextJ = 0;
}else{
nextI = i;
nextJ = j + 1;
}
numberArray[i][j].setNext(numberArray[nextI][nextJ]);
numberArray[i][j].getNext().setPrior(numberArray[i][j]);
}else{
numberArray[i][j].setNext(null);
numberArray[i][j].setPrior(numberArray[i][j - 1]);
}
}
}
}
public boolean evaluate(Number element){
if (!element.isEva()){
ArrayList<Integer> invalidList = new ArrayList();
element.setEva(true);
for (int i=0;i<AREAROWS;i++){
for (int j=0;j<AREACOLS;j++){
int x = element.getAreaX()*AREAROWS + i;
int y = element.getAreaY()*AREACOLS + j;
if (!(numberArray[x][y].getValue()==0)){
invalidList.add(numberArray[x][y].getValue());
}
}
}
for (int j=0;j<COLS;j++){
int x = element.getRow();
int y = j;
if (!(numberArray[x][y].getValue()==0)){
invalidList.add(numberArray[x][y].getValue());
}
}
for (int i=0;i<ROWS;i++){
int x = i;
int y = element.getCol();
if (!(numberArray[x][y].getValue()==0)){
invalidList.add(numberArray[x][y].getValue());
}
}
element.getValueArray().clear();
for (int i=1;i<=MAXVALUE;i++){
if (invalidList.contains((Integer)i)) continue;
element.getValueArray().add(i);
}
element.setPos(-1);
}
boolean success = false;
if (!element.getValueArray().isEmpty()){
int i = element.getPos() + 1;
if (i >= element.getValueArray().size()) {
success = false;
}else{
int value = (Integer)element.getValueArray().get(i);
element.setValue(value);
element.setPos(i);
success = true;
}
}
return success;
}
public boolean fill(){
Number element = numberArray[0][0];
boolean isComplete = false;
boolean isForward = true;
int i = 0;
while (null!=element){
i++;
if (element.isPreSet()) {
if (isForward){
element = element.getNext();
if (element == null) isComplete = true;
}else{
element = element.getPrior();
}
continue;
}
if (evaluate(element)){
System.out.println("count:"+ i + " row:"+element.getRow()+" col:"+element.getCol()+" value:"+element.getValue());
isForward = true;
element = element.getNext();
if (element == null) isComplete = true;
}else{
isForward = false;
element.setValue(0);
element.setEva(false);
element = element.getPrior();
}
}
return isComplete;
}
/**
* @param args
*/
public static void main(String[] args) {
AloneNumber aloneNumber = new AloneNumber();
aloneNumber.preSet();
aloneNumber.init();
if (aloneNumber.fill()){
System.out.println("AloneNumber caculate is Completed!");
System.out.println("--belowed--");
for (int i=0;i<ROWS;i++){
for (int j=0;j<COLS;j++){
System.out.print(aloneNumber.numberArray[i][j].getValue());
}
System.out.println();
}
}else{
System.out.println("this is no Answer!please check your preSet!");
}
}
}
第三步:
哈,代码已经
Ok
了,下面就交给
java
来执行了,注意:得要
jdk1.5
以上才行哦