昨天晚上,在kfc网站看到了一个玩游戏赢游戏机的宣传.
打开一看,原来是sudoku 81宫格游戏.对这个游戏,以前我曾经看到过,没有怎么留意,今天来了兴趣,
玩了一会,没有进展,有点着急了.心想何不用程序来算一下?
算法比较笨,采用的是排除法. 希望能籍此能得到各位朋友的更好算法
根据所在行,所在列,所在3X3 宫格的数字,确定该格子数字的侯选数字,然后再逐步排除.
下面是我的代码:
package dyt.game;
import java.util.ArrayList;
import java.util.List;
/**
* 每个宫格是个对象
* @author Tom
* ValueObject.java
*
*/
public class ValueObject {
private List<Integer> values=new ArrayList<Integer>();
private int value=0;
public int getX() {
return x;
}
import java.util.List;
/**
* 每个宫格是个对象
* @author Tom
* ValueObject.java
*
*/
public class ValueObject {
private List<Integer> values=new ArrayList<Integer>();
private int value=0;
public int getX() {
return x;
}
public int getY() {
return y;
}
return y;
}
public void setX(int x) {
this.x = x;
}
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public ValueObject(){
}
public int getValue() {
return value;
}
private int x,y;
public ValueObject(int value,int x,int y){
this.value=value;
this.x=x;
this.y=y;
addValue(1);
addValue(2);
addValue(3);
addValue(4);
addValue(5);
addValue(6);
addValue(7);
addValue(8);
addValue(9);
}
this.y = y;
}
public ValueObject(){
}
public int getValue() {
return value;
}
private int x,y;
public ValueObject(int value,int x,int y){
this.value=value;
this.x=x;
this.y=y;
addValue(1);
addValue(2);
addValue(3);
addValue(4);
addValue(5);
addValue(6);
addValue(7);
addValue(8);
addValue(9);
}
public void setValue(int value) {
this.value = value;
}
this.value = value;
}
public List getValues() {
return values;
}
return values;
}
public void setValues(List<Integer> values) {
this.values = values;
}
public void addValue(Integer value){
if(!this.values.contains(value))
this.values.add(value);
}
//注意不要把Integer,写成了int
//那样调用list.remove 的时候会出错.
//因为我们这里是期望直接移动对象,
//但是如果使用int,就回按照index移动.
public void removeValue(Integer value1){
if(this.values.contains(value1)){
this.values.remove(value1);
}
if(this.values.size()==1)
this.value=this.values.get(0);
//千万不能合并,合并就会出错.
if(this.values.size()==1)
values.clear();
}
}
this.values = values;
}
public void addValue(Integer value){
if(!this.values.contains(value))
this.values.add(value);
}
//注意不要把Integer,写成了int
//那样调用list.remove 的时候会出错.
//因为我们这里是期望直接移动对象,
//但是如果使用int,就回按照index移动.
public void removeValue(Integer value1){
if(this.values.contains(value1)){
this.values.remove(value1);
}
if(this.values.size()==1)
this.value=this.values.get(0);
//千万不能合并,合并就会出错.
if(this.values.size()==1)
values.clear();
}
}
package dyt.game;
import java.util.Iterator;
/**
* Sudoku.java
* @author Tom
*
*/
public class Sudoku {
private boolean isok=false;
public ValueObject o[][]= new ValueObject[9][9];
//判断只有一个
public void isOne(){
/**
* 已知的数据
*/
int a[][]={
{7, 0, 0, 0, 0, 0, 8, 4, 0},
{0, 0, 3, 7, 5, 0, 6, 0, 0},
{1, 0, 0, 9, 0, 2, 0, 0, 0},
{0, 9, 5, 3, 0, 7, 2, 0, 0},
{6, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 8, 6, 0, 4, 0, 9, 0},
{0, 0, 0, 2, 0, 9, 0, 6, 4},
{9, 0, 4, 0, 3, 0, 7, 0, 0},
{0, 6, 2, 4, 0, 1, 0, 0, 3}
* Sudoku.java
* @author Tom
*
*/
public class Sudoku {
private boolean isok=false;
public ValueObject o[][]= new ValueObject[9][9];
//判断只有一个
public void isOne(){
/**
* 已知的数据
*/
int a[][]={
{7, 0, 0, 0, 0, 0, 8, 4, 0},
{0, 0, 3, 7, 5, 0, 6, 0, 0},
{1, 0, 0, 9, 0, 2, 0, 0, 0},
{0, 9, 5, 3, 0, 7, 2, 0, 0},
{6, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 8, 6, 0, 4, 0, 9, 0},
{0, 0, 0, 2, 0, 9, 0, 6, 4},
{9, 0, 4, 0, 3, 0, 7, 0, 0},
{0, 6, 2, 4, 0, 1, 0, 0, 3}
};
// 赋值给数组
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
o[i][j]=new ValueObject(a[i][j],i,j);
}
}
//剔除不允许的值
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(o[i][j].getValue()==0){
o[i][j]=this.removeSame(o[i][j],a);
}else{
o[i][j].getValues().clear();
}
}
}
System.out.println("可选值和已知值");
print(o);
while(!isok){
o=remove(o);
System.out.println("筛选");
print(o);
}
}
public ValueObject[][] remove (ValueObject o[][]){
isok=true;
for(int a=0;a<9;a++){
for(int b=0;b<9;b++){
ValueObject oo=o[a][b];
//如果这个数已经确定
//那么横向,纵向,所在方格内,不能再有这个数.
if(oo.getValue()!=0){
o=removeSame1(o, a,b);
}
if(o[a][b].getValues().size()>0){
o=removeSame2(o,a,b);
isok=false;
}
}
}
return o;
}
public void print(ValueObject o[][]){
System.out.println("");
System.out.println("---------------------------------");
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(o[i][j].getValue()==0){
Iterator it=o[i][j].getValues().iterator();
while (it.hasNext()){
System.out.print(it.next()+" ");
}
}
else {
System.out.print(o[i][j].getValue());
}
if(j==8){
System.out.println("");
}else{
System.out.print(",");
}
}
}
}
/**
*剔除 该方格侯选值.
* $Author:Tom
*/
public ValueObject[][] removeSame2 (ValueObject old[][] ,int x1,int y1){
int x2=x1-(x1+3)%3;
int y2=y1-(y1+3)%3;
for(int c=x2;c<x2+3&&c!=x1;c++)
for(int d=y2;d<y2+3&&d!=y1;d++){
old[x1][y1].removeValue(old[c][d].getValue());
}
for(int d=0;d<9&&d!=y1;d++){
old[x1][y1].removeValue(old[x1][d].getValue());
}
for(int c=0;c<9&&c!=x1;c++){
old[x1][y1].removeValue(old[c][y1].getValue());
}
// 赋值给数组
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
o[i][j]=new ValueObject(a[i][j],i,j);
}
}
//剔除不允许的值
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(o[i][j].getValue()==0){
o[i][j]=this.removeSame(o[i][j],a);
}else{
o[i][j].getValues().clear();
}
}
}
System.out.println("可选值和已知值");
print(o);
while(!isok){
o=remove(o);
System.out.println("筛选");
print(o);
}
}
public ValueObject[][] remove (ValueObject o[][]){
isok=true;
for(int a=0;a<9;a++){
for(int b=0;b<9;b++){
ValueObject oo=o[a][b];
//如果这个数已经确定
//那么横向,纵向,所在方格内,不能再有这个数.
if(oo.getValue()!=0){
o=removeSame1(o, a,b);
}
if(o[a][b].getValues().size()>0){
o=removeSame2(o,a,b);
isok=false;
}
}
}
return o;
}
public void print(ValueObject o[][]){
System.out.println("");
System.out.println("---------------------------------");
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(o[i][j].getValue()==0){
Iterator it=o[i][j].getValues().iterator();
while (it.hasNext()){
System.out.print(it.next()+" ");
}
}
else {
System.out.print(o[i][j].getValue());
}
if(j==8){
System.out.println("");
}else{
System.out.print(",");
}
}
}
}
/**
*剔除 该方格侯选值.
* $Author:Tom
*/
public ValueObject[][] removeSame2 (ValueObject old[][] ,int x1,int y1){
int x2=x1-(x1+3)%3;
int y2=y1-(y1+3)%3;
for(int c=x2;c<x2+3&&c!=x1;c++)
for(int d=y2;d<y2+3&&d!=y1;d++){
old[x1][y1].removeValue(old[c][d].getValue());
}
for(int d=0;d<9&&d!=y1;d++){
old[x1][y1].removeValue(old[x1][d].getValue());
}
for(int c=0;c<9&&c!=x1;c++){
old[x1][y1].removeValue(old[c][y1].getValue());
}
return old;
}
/**
* 剔除与这个格子相关的其他格子内的这个值
* $Author:Tom
*/
public ValueObject[][] removeSame1(ValueObject old[][],int x1,int y1){
int x2=x1-(x1+3)%3;
int y2=y1-(y1+3)%3;
//3X3方格
for(int c=x2;c<x2+3&&c!=x1;c++){
for(int d=y2;d<y2+3&&d!=y1;d++){
old[c][d].removeValue(old[x1][y1].getValue());
}
}
for(int d=0;d<9&&d!=y1;d++){
o[x1][d].removeValue(old[x1][y1].getValue());
}
for(int c=0;c<9&&c!=x1;c++){
o[c][y1].removeValue(old[x1][y1].getValue());
}
return old;
}
public ValueObject removeSame (ValueObject old,int a[][]){
int x=old.getX()-old.getX()%3;
int y=old.getY()-old.getY()%3;
for(int i=x;i<x+3;i++)
for(int j=y;j<y+3;j++)
old.removeValue(a[i][j]);
for(int j=0;j<9;j++){
old.removeValue(a[old.getX()][j]);
}
for(int i=0;i<9;i++){
old.removeValue(a[i][old.getY()]);
}
return old;
}
/**
* $Author:Tom
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Sudoku s=new Sudoku();
s.isOne();
}
}
/**
* 剔除与这个格子相关的其他格子内的这个值
* $Author:Tom
*/
public ValueObject[][] removeSame1(ValueObject old[][],int x1,int y1){
int x2=x1-(x1+3)%3;
int y2=y1-(y1+3)%3;
//3X3方格
for(int c=x2;c<x2+3&&c!=x1;c++){
for(int d=y2;d<y2+3&&d!=y1;d++){
old[c][d].removeValue(old[x1][y1].getValue());
}
}
for(int d=0;d<9&&d!=y1;d++){
o[x1][d].removeValue(old[x1][y1].getValue());
}
for(int c=0;c<9&&c!=x1;c++){
o[c][y1].removeValue(old[x1][y1].getValue());
}
return old;
}
public ValueObject removeSame (ValueObject old,int a[][]){
int x=old.getX()-old.getX()%3;
int y=old.getY()-old.getY()%3;
for(int i=x;i<x+3;i++)
for(int j=y;j<y+3;j++)
old.removeValue(a[i][j]);
for(int j=0;j<9;j++){
old.removeValue(a[old.getX()][j]);
}
for(int i=0;i<9;i++){
old.removeValue(a[i][old.getY()]);
}
return old;
}
/**
* $Author:Tom
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Sudoku s=new Sudoku();
s.isOne();
}
}