老师视频教程结束了,但是游戏并未完成。下面便开始自己动手完善部分功能

  需要完善的功能:

  1、设置给定的数独数据数字不可改变

  2、设置给定的数独数据数字和玩家填入的数字颜色不同,方便区分

  3、判断填写后的数独是否符合数独游戏规则

    4、数字选择兑对话框添加清除和取消按钮,并每次选择时显示所有的数字(原来思路是只显示符合规则的数字,这样当出现错误之后,后面的某些位置无法选择数字)

 

  解决方法:

  1、设置给定的数独数据数字不可改变

  

 我的思路,因为初始化的数据数字是给定的,而数据是放在一个字符串里的,如下:0代表需要玩家输入的,非0则是给定的

  

1        private final String str = "061030020050008107000007034009006078003279500570300902190760000802400060640010250";

  这样只需要在开一个整型数组来标记,0表示玩家需要填写的,1代表是系统给定的数独数据数字  

  在Game.java类中

  实现根据数独数据字符串获得一个整型数组(isdata[]),

  并给一个获取数组方法,

  

1 public int getIsData(int x,int y){
2         return isdata[y*9+x];
3     }
 1 //根据字符串数据生成整型数组
 2     public int[] fromPuzzleString(String str2) {
 3         // TODO Auto-generated method stub
 4 //        shudu[] = new int[str2.length()];
 5         for(int i=0;i<shudu.length;i++)
 6         {
 7             shudu[i]=str2.charAt(i)-'0'; //吧字符转换为数字]
 8             if(shudu[i]!=0)
 9             {
10                 isdata[i]=1;
11             }
12         }
13         
14         return shudu;
15     }

 

  若字符串某字符为'0'则整型数组对应数字0,若字符串某数字不为'0'则整型数组对应数字1,

  然后在调用对话框的时候判断试下是不是玩家输入的单元格即可

  

1 if(game.getIsData(selectx,selecty)!=1) //如果不是系统初始给定的,则调用对话框,提供数字选择
2         {
3             SelectDialog seldia = new SelectDialog(getContext(),used,this);
4             seldia.show();
5         }

 

  2、设置给定的数独数据数字和玩家填入的数字颜色不同,方便区分

  我的思路,因为给定的数据数字是给定的

  

1        private final String str = "061030020050008107000007034009006078003279500570300902190760000802400060640010250";

  在Game.java类中

  还是通过数组isdata[]

  

  

 1 //根据字符串数据生成整型数组
 2     public int[] fromPuzzleString(String str2) {
 3         // TODO Auto-generated method stub
 4 
 5         for(int i=0;i<shudu.length;i++)
 6         {
 7             shudu[i]=str2.charAt(i)-'0'; //吧字符转换为数字]
 8             if(shudu[i]!=0)
 9             {
10                 isdata[i]=1;
11             }
12         }
13         
14         return shudu;
15     }

  在ShuduView类中

  得到isdata[]整型数组,若为0,则表示该单元格是玩家填写的数字,用白色画笔构写数字

             若为1,则表示该单元格是给定的数独数据的数字,用黑色画笔构写数字

具体代码:

 1 //绘制数字-原始数据
 2         Paint numberpaint_data = new Paint();
 3         numberpaint_data.setColor(Color.BLACK);  //黑色字体
 4         numberpaint_data.setStyle(Style.STROKE);
 5         numberpaint_data.setTextSize((float) (height*0.75));
 6         numberpaint_data.setTextAlign(Align.CENTER);//居中对齐
 7         //绘制数字-玩家填写数据
 8         Paint numberpaint_new = new Paint();
 9         numberpaint_new.setColor(Color.WHITE);   //白色字体
10         numberpaint_new.setStyle(Style.STROKE);
11         numberpaint_new.setTextSize((float) (height*0.75));
12         numberpaint_new.setTextAlign(Align.CENTER);//居中对齐
13         
14         FontMetrics fm = numberpaint_data.getFontMetrics();
15         float x = width/2;
16         float y = height/2-(fm.ascent-fm.descent)/2;//获取画笔写数字的位置
17         // 计算文字高度 
18         float fontHeight = fm.bottom - fm.top; 
19         // 计算文字baseline 
20         float textBaseY = height - (height - fontHeight) / 2 - fm.bottom;         
21         //canvas.drawText("1", 3*width+x, textBaseY, numberpaint);
22         //绘制数字
23         for(int i=0;i<9;i++)
24         {
25             for(int j=0; j<9;j++)
26             {
27                 if(game.getIsData(i, j)==1)  //如果isdata[]数组对应位置的数字为1,则是系统初始化的数字,用黑色画笔,否则为玩家填写数字,用白色画笔
28                 canvas.drawText(game.getTitlStringe(i,j), i*width+x, j*height+textBaseY, numberpaint_data);
29                 else
30                     canvas.drawText(game.getTitlStringe(i,j), i*width+x, j*height+textBaseY, numberpaint_new);    
31             }
32         }

  3、判断填写后的数独是否符合数独游戏规则

  在给定初始数据时

  

1 private final String str = "061030020050008107000007034009006078003279500570300902190760000802400060640010250"; //初始化数据
2     private final String str_da = "761934825354628197928157634219546378483279516576381942195762483832495761647813259"; //答案数据

判断是否完成数独方法

 1     private void judge() {
 2         // TODO Auto-generated method stub
 3         StringBuffer a = new StringBuffer((String) game.getStr_da());
 4         int[] b = game.getShuduku();
 5         StringBuffer c = new StringBuffer();
 6         for(int i=0;i<b.length;i++)
 7         {
 8             c.append(b[i]);
 9         }
10 //        String c= String.valueOf(b);
11         if(a.toString().equals(c.toString()))  //注意StringBuffer不用直接用a.equals(c)这样对比的是对象
12         {
13             AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
14             builder.setTitle("~~通知~~");
15             builder.setIcon(R.drawable.app_xin);
16             builder.setMessage("恭喜通关!!!");
17             builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
18                         @Override
19                 public void onClick(DialogInterface arg0, int arg1) {
20                     // TODO Auto-generated method stub
21                 }
22             });
23             AlertDialog dialog = builder.create();
24             dialog.show(); //显示、
25         }
26     }  
27 }

   4、数字选择兑对话框添加清除和取消按钮

  (1)、先修改数字选择对话框布局文件

  

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:layout_gravity="center_horizontal"
 6     android:stretchColumns="*"
 7     android:orientation="vertical" >
 8     
 9     <TableRow >
10         <Button android:id="@+id/btn_1"
11             android:text="1"/>
12         <Button android:id="@+id/btn_2"
13             android:text="2"/>
14         <Button android:id="@+id/btn_3"
15             android:text="3"/>
16     </TableRow>
17     <TableRow >
18         <Button android:id="@+id/btn_4"
19             android:text="4"/>
20         <Button android:id="@+id/btn_5"
21             android:text="5"/>
22         <Button android:id="@+id/btn_6"
23             android:text="6"/>
24     </TableRow>
25     <TableRow >
26         <Button android:id="@+id/btn_7"
27             android:text="7"/>
28         <Button android:id="@+id/btn_8"
29             android:text="8"/>
30         <Button android:id="@+id/btn_9"
31             android:text="9"/>
32     </TableRow>
33     
34     <LinearLayout 
35         android:layout_width="wrap_content"
36         android:layout_height="wrap_content"
37         android:orientation="horizontal"
38         >
39         <Button                              //添加清除按钮
40         android:layout_weight="1"
41         android:
42         android:layout_width="wrap_content"
43         android:layout_height="wrap_content"
44         android:text="清除" />
45     <Button                                   //添加修改按钮
46         android:layout_weight="1"
47         android:
48         android:layout_width="wrap_content"
49         android:layout_height="wrap_content"
50         android:text="取消" />
51 
52     
53     </LinearLayout>
54 </TableLayout>

   (2)、SelectDialog.java文件中 修改响应事件

    

 1 //为按钮设置监听器
 2         public void setListener()
 3         {
 4             for(int i = 0; i<key.length; i++)
 5             {
 6                 final int t = i;
 7                 key[i].setOnClickListener(new View.OnClickListener()
 8                 {
 9                     
10                     @Override
11                     public void onClick(View v)
12                     {
13                         // TODO Auto-generated method stub
14                         returnResult(t);   //传值为选择的数字为,0--9,当为0时 即清除按钮
15                     }
16                 });
17             }
18         }
19         
20         //对话框将选择的数据传递给View对象,让其处理业务逻辑
21         public void returnResult(int tile)
22         {
23             shuduview.setSelectTile(tile);
24             dismiss();
25         }
26     
27 
28     private void findView() {
29         // TODO Auto-generated method stub
30         key[0] = findViewById(R.id.btn_0);
31         key[1] = findViewById(R.id.btn_1);
32         key[2] = findViewById(R.id.btn_2);
33         key[3] = findViewById(R.id.btn_3);
34         key[4] = findViewById(R.id.btn_4);
35         key[5] = findViewById(R.id.btn_5);
36         key[6] = findViewById(R.id.btn_6);
37         key[7] = findViewById(R.id.btn_7);
38         key[8] = findViewById(R.id.btn_8);
39         key[9] = findViewById(R.id.btn_9);
40         back = findViewById(R.id.btn_cannel);
41     }

  (3)、Game.java 文件中修改 

  public boolean setTileIfValid(int x, int y, int value)    将选择的数字显示出来
    {  
//        int[] tiles = getused(x, y);//得到不可用的数据  
      
          
//        if (value != 0)  
//        {  
//            for (int t : tiles)  
//            {  
//                if (t == value)  
//                    return false;  
//            }  
//        }  
        setSelectNum(x, y, value);//将对应的值value绘制在xy对应的格子中  
        calAllused();//重新计算所有格子的不可用数据  
  
        return true;  
    }  

 

总代码

1、

  1 package xqx.shudu;
  2 
  3 import myview.ShuduView;
  4 import android.app.AlertDialog;
  5 import android.content.DialogInterface;
  6 import android.util.Log;
  7 import android.widget.Toast;
  8 
  9 public class Game {
 10 
 11     //数独数据初始化
 12        private final String str = "061030020050008107000007034009006078003279500570300902190760000802400060640010250";
 13     private final String str_da = "761934825354628197928157634219546378483279516576381942195762483832495761647813259";
 14     private int shuduku[]=new int[9*9];
 15     public int shudu[] = new int[81];
 16     public int[] getShuduku() {
 17         return shuduku;
 18     }
 19 
 20     public void setShuduku(int[] shuduku) {
 21         this.shuduku = shuduku;
 22     }
 23 
 24     public int[] getShudu() {
 25         return shudu;
 26     }
 27 
 28     public void setShudu(int[] shudu) {
 29         this.shudu = shudu;
 30     }
 31 
 32     private int isdata[] = new int[9*9];//标记是否为原始数据
 33     //用来存储每个单元格不可填写的数字
 34     //1维 x坐标 2维 y坐标 3维 不可填写数字
 35     private int used[][][]=new int[9][9][];
 36     public Game(){
 37         shuduku = fromPuzzleString(str);
 38         calAllused();
 39     }
 40     
 41     //根据字符串数据生成整型数组
 42     public int[] fromPuzzleString(String str2) {
 43         // TODO Auto-generated method stub
 44 //        shudu[] = new int[str2.length()];
 45         for(int i=0;i<shudu.length;i++)
 46         {
 47             shudu[i]=str2.charAt(i)-'0'; //吧字符转换为数字]
 48             if(shudu[i]!=0)
 49             {
 50                 isdata[i]=1;
 51             }
 52         }
 53         
 54         return shudu;
 55     }
 56 
 57     //根据九宫格坐标返回该坐标所应该填写的数字
 58     public int getTitile(int x,int y){
 59         return shuduku[y*9+x];
 60     }
 61     public int getIsData(int x,int y){
 62         return isdata[y*9+x];
 63     }
 64     public String getTitlStringe(int x,int y){
 65         int v = getTitile(x, y);
 66         if(v==0){
 67             return "";
 68         }
 69         else
 70         {
 71             return String.valueOf(v);
 72         }
 73     }
 74     
 75     //计算某单元格已经不可填写的数字
 76     public int[] calUsed(int x,int y){
 77         int c[]= new int[9];
 78         
 79         //判断y这一列,如果遍历他自己 ,跳过,如果遍历单元格数字不为0,则放入数组中
 80         for(int i=0;i<9;i++)
 81         {
 82             if(i==y)
 83                 continue;
 84             int t = getTitile(x, i);
 85             if(t!=0)
 86                 c[t-1]=t;
 87         }
 88         //判断x这一行,如果遍历他自己 ,跳过,如果遍历单元格数字不为0,则放入数组中
 89         for(int i=0;i<9;i++)
 90         {
 91             if(i==x)
 92                 continue;
 93             int t = getTitile(i, y);
 94             if(t!=0)
 95                 c[t-1]=t;
 96         }
 97         //判断该单元格所在的九宫格出现的数字并放入不可填写数字数组当中
 98         int startx = (x/3)*3;
 99         int starty = (y/3)*3;
100         for(int i=startx;i<startx+3;i++)
101         {
102             for(int j=starty;j<starty+3;j++)
103             {
104                 if(i==x&&j==y)
105                     continue;
106                 int t = getTitile(i, j);
107                 if(t!=0)
108                 {
109                     c[t-1]=t;
110                 }
111             }
112         }
113         
114         int nused = 0;
115         for(int t:c){
116             if(t!=0)
117                 nused++;
118         }
119         int c1[] = new int[nused];
120         nused=0;
121         for(int t:c){
122             if(t!=0)
123             {
124                 c1[nused++]=t;
125             }
126         }
127         
128         return c;
129     }
130     
131     //计算所有单元格不可用数字数组
132     public void calAllused(){
133         for(int x=0;x<9;x++)
134         {
135             for(int y=0;y<9;y++){
136                 used[x][y]=calUsed(x, y);
137             }
138         }
139     }
140     
141     //得到该单元格不可用数字
142     public int[] getused(int x,int y){
143         return used[x][y];
144     }
145      //接收KeyDialog中点击的数字  
146     public boolean setTileIfValid(int x, int y, int value)  
147     {  
148         int[] tiles = getused(x, y);//得到不可用的数据  
149       
150           
151 //        if (value != 0)  
152 //        {  
153 //            for (int t : tiles)  
154 //            {  
155 //                if (t == value)  
156 //                    return false;  
157 //            }  
158 //        }  
159         setSelectNum(x, y, value);//将对应的值value绘制在xy对应的格子中  
160         calAllused();//重新计算所有格子的不可用数据  
161   
162         return true;  
163     }  
164     
165     //在数独数组中更改填写后的数字
166     private void setSelectNum(int x, int y, int num) {
167         // TODO Auto-generated method stub
168         shuduku[y*9+x]=num;
169     }
170     //判断是否正确完成数独游戏
171     private void judge() {
172     
173     }
174 
175     public String getStr() {
176         return str;
177     }
178 
179     public String getStr_da() {
180         return str_da;
181     }
182 }
183                             
Game.java

相关文章:

  • 2021-11-04
  • 2022-12-23
  • 2022-12-23
  • 2022-01-20
  • 2021-07-11
  • 2022-12-23
  • 2021-08-22
  • 2021-08-24
猜你喜欢
  • 2022-12-23
  • 2022-01-24
  • 2022-12-23
  • 2021-12-05
  • 2022-03-05
  • 2022-02-11
相关资源
相似解决方案