抄的第一个项目数独游戏

学习完,java基础,android基础   开始跟随视频做一个实战训练,第一个:数独游戏

*************************************************************************************************************************************************************************************

下面粘贴代码,并以此勉励自己,加油!加油!加油!

*************************************************************************************************************************************************************************************

分析下数独游戏的制作过程,数独功能:1.有方格,2.有初始数字,3.点击空白处能填写数字

/*步骤:
 * 1.定义方格
 * 2.画方格
 * 3.定义数字
 * 4.填写数字
 * 5.点击判断
 * 6.出现按钮
 * 7.定义按钮数字
 * 8.点击填写数字
 * 9.刷新重复步骤3
 * 10.重复3-9*/

分三个类模块:

1.ShuduView类:总体类,包括数独游戏的界面(方格和数字),填写数字后更新界面。

2.Game类:数独游戏的内容代码,各种方法,单独建类是为了可移植性好。包括:设置数字,判断数字,更改数字。

3.KeyDialog类:点击空白处,出现按钮框架,这个类主要是定义对话框。

注意需要自己在res文件夹下建立xml文件,一共三个:1.colors.xml 2.dialog.xml 3.kepad.xml

还需要在strings.xml下增加下面代码        android:text="@string/hello"/>

下面展示下代码,这一部分是转载的,百度上就能搜到,粘贴为了自己以后查看用!

*************************************************************************************************************************************************************************************

ShuduView:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

public class ShuduView extends View {  
    
    //单元格的宽度和高度  
    private float width ;  
    private float height ;  
      
    private Game game = new Game();  
      
    public ShuduView(Context context)  
    {  
        super(context);  
    }  
      
    //w:整个 veiw 的宽度;  h:整个 veiw 的高度  
  
    @Override  
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
        // TODO Auto-generated method stub  
        //把整个屏幕分成 九宫格 的每个格子的宽度和高度  
        this.width = w/9f ;  
        this.height = h/9f ;  
          
        super.onSizeChanged(w, h, oldw, oldh);  
    }  
  
  
    @Override  
    public void onDraw(Canvas canvas) {  
          
          
          
        Paint backgroundPaint = new Paint();  
        //从配置文件中 获取颜色值  
        backgroundPaint.setColor(this.getResources().getColor(R.color.shudu_background));  
        //画出整个手机屏幕的 的背景色  
        canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), backgroundPaint);  
          
        //----------------------------------------  
          
        Paint darkPaint = new Paint();  
        darkPaint.setColor(this.getResources().getColor(R.color.shudu_dark));  
          
        Paint hilitePaint = new Paint();  
        hilitePaint.setColor(this.getResources().getColor(R.color.shudu_hilite));  
          
        Paint lightPaint = new Paint();  
        lightPaint.setColor(this.getResources().getColor(R.color.shudu_light));  
          
        //画九宫格里面的 横线,纵线,每次画出的线要想达到某种效果,需画两条 之间格1像素的位置,且颜色也要搭配好  
        for(int i = 0 ; i < 9 ; i++ )  
        {  
            canvas.drawLine(0, i*height, this.getWidth(), i*height, lightPaint);  
            canvas.drawLine(0, i*height+1, this.getWidth(), i*height+1, hilitePaint);  
              
            canvas.drawLine(i*width,0, i*width, this.getHeight(), lightPaint);  
            canvas.drawLine(i*width+1,0, i*width+1, this.getHeight(), hilitePaint);  
        }  
          
        //把整个 屏幕的格子 分成9个大的 9 宫格,每个大的9宫格 里面又有9个小格,   实际上就是 用颜色比较深的线隔开  
        for(int i = 0 ; i < 9 ; i ++)  
        {  
            if(i%3 != 0)  
            {  
                continue ;  
            }  
              
            canvas.drawLine(0, i*height, this.getWidth(), i*height, darkPaint);  
            canvas.drawLine(0, i*height+1, this.getWidth(), i*height+1, hilitePaint);  
              
            canvas.drawLine(i*width,0, i*width, this.getHeight(), darkPaint);  
            canvas.drawLine(i*width+1,0, i*width+1, this.getHeight(), hilitePaint);  
              
        }  
          
        //设置在表格上显示的数字  
        Paint numberPaint = new Paint();  
          
        numberPaint.setColor(Color.BLACK);  
        numberPaint.setStyle(Paint.Style.STROKE); //让其画出来的东西是 空的  
        numberPaint.setTextSize(height*0.75f); //设置字体大小  
        numberPaint.setTextAlign(Paint.Align.CENTER); //让字体居中  
          
        float x = width/2f ;  
        //调整字体的位置 ( 度量)  比如居中,调整垂直方向上的居中  
        FontMetrics fm = numberPaint.getFontMetrics();  
        // 这些  fm.ascent 都是基于 基准线 而言  
        float y = height/2f - (fm.ascent+fm.descent)/2 ;  
        //System.out.println("y:"+y+"fm.ascent:"+fm.ascent+"fm.descent:"+fm.descent);  
          
        //初始化数据  
        for(int i = 0 ; i < 9 ; i ++)  
        {  
            for(int j = 0 ; j < 9 ; j ++)  
            {  
                  
                canvas.drawText(game.getTileString(i, j), i*width+x,j*height+y , numberPaint);  
            }  
        }  
          
        super.onDraw(canvas);  
    }  
      
    int selectedX ;  
    int selectedY ;  
    //鼠标(手) 触动 手机屏幕 事件,当 手 触动 该 view 时 该函数会被调用  
    @Override  
    public boolean onTouchEvent(MotionEvent event) {  
          
        if( event.getAction() != event.ACTION_DOWN )  
        {  
            return super.onTouchEvent(event);  
        }  
          
        //获取 点击 哪个单元格的坐标  
        selectedX = (int)(event.getX()/width) ;  
        selectedY = (int)(event.getY()/height) ;  
          
        //把获取某单元格 不可用的数据  
        int used[] = game.getUsedTilesByCoor(selectedX, selectedY);  
          
        //把获取某单元格 不可用的数据 打印出来  
//      for(int i = 0 ; i < used.length ; i ++)  
//      {  
//          System.out.println(used[i]);  
//      }  
          
        KeyDialog keyDialog = new KeyDialog(this.getContext(),used,this) ;  
          
        keyDialog.show() ;  
          
          
          
        return true;  
    }  
      
    //刷新整个九宫格里的数据  
    public void setSelectedTile(int tile)  
    {  
        if(game.setTileIfValid(selectedX, selectedY, tile))  
        {  
            invalidate();//重新绘制整个视图,也就相当于 重新生成一次该对象  
        }  
    }  
  
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Game:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

public class Game {  
    
    //初始化 九宫格的数据  
    private final String initStr =  
            "360000000004230800000004200"+  
            "070460003820000014500013020"+  
            "001900000007048300000000045";  
    //定义一个 数组 存放 初始化数据,首先 要将 initStr里面的数据分离开,存放在数组里  
    private int[] shuduku = new int[9*9] ;  
      
    //用于存储 已经使用过的 数据  
    private int[][][] used = new int[9][9][]  ;  
      
    public Game()  
    {  
        shuduku = fromPuzzleString(initStr) ;     
        calculateAllUsedTiles() ; //一创建对象的时候,就把每个单元格中 不可用的数据存到 三维数组里  
    }  
      
    //通过传来的坐标值,获取 该坐标 的 具体值(整数)  
    private int getTile(int x , int y)  
    {  
        return shuduku[y*9+x] ;  
    }  
      
    public String getTileString(int x , int y)  
    {  
        int v = getTile(x , y);  
        if(0 == v)  
            return "" ;  
        else  
  
            return String.valueOf(v); //把获取的 整数 转成 字符串  
    }  
      
    //把字符串 一个个分离出来,存放至 shudu数组中,通过返回值,赋值给 shuduku数组中  
    public int[] fromPuzzleString(String str)  
    {  
        int[] shudu = new int[str.length()] ;  
          
        for(int i = 0 ; i < str.length() ; i++)  
        {  
            shudu[i] = str.charAt(i) - '0' ; //把获取的单个字符减去 '0' 转成整数,赋给 整形 shudu数组中  
        }  
          
        return shudu ;  
    }  
      
    //用于计算 所有单元格中 不可用的 数据,返回一个 一维数组赋值给 三维数组   
    public void calculateAllUsedTiles()  
    {  
        for(int i = 0 ; i < 9 ; i++)  
        {  
            for(int j = 0 ; j < 9 ; j ++)  
            {  
                // 这里的 数组 赋值,只要 它们 加起来 是 三维 即可,假如是 四维 也一样  
                used[i][j] = calculateUsedTiles(i , j) ;  
            }  
        }  
    }  
      
    // 取出某个单元格中 不可用的 数  
    public int[] getUsedTilesByCoor(int x , int y )  
    {  
        return used[x][y] ;  
    }  
      
      
    //用于计算  某一单元格 已经不可用的 数据  
    public int[] calculateUsedTiles(int x , int y)  
    {  
          
        int[] c = new int[9] ;  
          
        //计算 该单元格中  列上不可用的数据  
        for(int i =0 ; i < 9 ; i++ )  
        {  
            // 在 该选中的单元格 中 不需计算  
            if(i == y)  
                continue ;  
              
            int t = getTile(x, i) ;  
              
            if(t != 0)  
               c[t-1] = t ;  
              
        }  
          
        //计算 该单元格中 行上不可用的数据  
        for(int i =0 ; i < 9 ; i++ )  
        {  
            // 在 该选中的单元格 中 不需计算  
            if(i == x)  
                continue ;  
              
            int t = getTile(i, y) ;  
              
            if(t != 0)  
               c[t-1] = t ;  
              
        }  
          
        //用于计算一个九宫格 里面不可用的数据  
          
        int startX = (x/3)*3 ;  
        int startY = (y/3)*3 ;  
          
        for(int i = startX ; i < startX + 3 ; i ++)  
        {  
            for(int j = startY ; j < startY + 3 ; j ++)  
            {  
                if(i == x && j == y)  
                     continue ;  
                  
                int t = getTile(i, j) ;  
                  
                if(t != 0)  
                   c[t-1] = t ;  
            }  
        }  
          
        // 经过 上面的程序 检测出不可用的数据,存在c数组中,由于还有一些没有 赋值,默认为 0,需要进行压缩,把默认设置为0的数组值,进行删除  
          
        // 把数组里面为0 的数 过滤 掉,用 nused 来标识有几个不为0的数  
        int nused = 0 ;  
          
        for(int t : c)  
        {  
            if(t != 0)  
                nused ++ ;  
        }  
          
        int[] c1 = new int[nused] ;  
        nused = 0 ;  
        for(int t : c)  
        {  
            if(t != 0)  
            {  
                c1[nused++] = t ;  
            }  
        }     
          
        return c1;  
    }  
    //把用户选的字,设置到 soduku数组中  
    public boolean setTileIfValid(int x , int y , int value)  
    {  
        // 取出某个单元格中 不可用的 数  
        int tiles[] = getUsedTilesByCoor(x, y);  
          
        if(value != 0)  
        {  
            for(int tile : tiles)  
            {  
                //如果用户选的数字和 “ 不可用数组” 里面的数字相同,则返回false,  
                if(tile == value)  
                {  
                    return false ;  
                }  
            }  
        }  
           
        setTile(x,y,value) ;  
          
        //每次修改之后都得 进行重新计算 不可用的值  
        calculateAllUsedTiles() ;  
          
        return true;  
    }  
    //进行修改 数独数组 里的值  
    private void setTile(int x , int y , int value)  
    {  
        shuduku[9*y+x] = value ;  
    }  
  
}

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

KeyDialog:

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

public class KeyDialog extends Dialog{  
 
    private final View keys[]=new View[9];//用来存放代表对话框当中按钮的对象  
    private final int used[];  
    private ShuduView shuduView=null;  
    //used【】保存着当前单元格已经使用过的数字。  
    public KeyDialog(Context context,int[]used,ShuduView shuduTest) {  
        super(context);  
        this.used=used;  
        this.shuduView=shuduTest;  
          
          
    }  
  
      
    //当一个dialog第一次显示的时候,会调用其oncreate方法  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
  
        super.onCreate(savedInstanceState);  
        //设置对话框的标题  
        setTitle("韩帅 warnning ! ! !");  
        //用于为该dialog设置布局文件。  
        setContentView(R.layout.keypad);  
        findViews();//把按钮对象添加到keys数组中    
          
          
        //遍历整个used数组,已经使用过的数字就让它隐藏。  
        for(int i=0;i<used.length;i++){  
            if(used[i]!=0){  
                keys[used[i]-1].setVisibility(View.INVISIBLE);  
            }  
        }  
        //为对话框当中所有的按钮设置监听器  
        setListeners();  
    }  
  
      
  
  
    //为每一个按钮设置一个ID,然后方便找到  
    private void findViews() {  
        keys[0]=findViewById(R.id.keypad_1);  
        keys[1]=findViewById(R.id.keypad_2);  
        keys[2]=findViewById(R.id.keypad_3);  
        keys[3]=findViewById(R.id.keypad_4);  
        keys[4]=findViewById(R.id.keypad_5);  
        keys[5]=findViewById(R.id.keypad_6);  
        keys[6]=findViewById(R.id.keypad_7);  
        keys[7]=findViewById(R.id.keypad_8);  
        keys[8]=findViewById(R.id.keypad_9);  
          
          
    }  
      
      
      
      
      
private void setListeners() {  
          
        //遍历整个数组。  
        for(int i=0;i<keys.length;i++){  
              
            final int t=i+1;//用T表示用户点击的数字。  
            //为每一个按钮设置监听器。  
            keys[i].setOnClickListener(new View.OnClickListener() {  
                  
              
                public void onClick(View v) {  
                    returnResult(t);  
                      
                }  
                  
                  
                  
            });  
        }  
    }  
  
  
  
  
//通知shuduTest对象,刷新整个九宫格显示的数据。  
    public void returnResult(int tile) {  
        shuduView.setSelectedTile(tile);//把用户点击的数字传到setSelectedTile函数里面。  
        dismiss();//取消对话框的显示。  
          
    }  
}

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

colors.xml

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

<?xml version="1.0" encoding="UTF-8"?>
<resources>
    <color name="shudu_background">#ffe6f0ff</color>
    <color name="shudu_hilite">#ffffffff</color>
    <color name="shudu_light">#64c6d4ef</color>
    <color name="shudu_dark">#6456648f</color>
</resources>

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

dialog.xml

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    >
    
    <TextView
        android:id="@+id/usedTextId"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello"/>
    
    </LinearLayout>

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

kepad.xml

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

<?xml version="1.0" encoding="UTF-8"?>
<TableLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keypad"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:stretchColumns="*">
    
    <TableRow>
        <Button android:id="@+id/keypad_1"
            android:text="1"></Button>
        <Button android:id="@+id/keypad_2"
            android:text="2"></Button>
        <Button android:id="@+id/keypad_3"
            android:text="3"></Button>
        </TableRow>
    <TableRow>    
        <Button android:id="@+id/keypad_4"
            android:text="4"></Button>
        <Button android:id="@+id/keypad_5"
            android:text="5"></Button>
        <Button android:id="@+id/keypad_6"
            android:text="6"></Button>            
        </TableRow>
    <TableRow>             
        <Button android:id="@+id/keypad_7"
            android:text="7"></Button>
        <Button android:id="@+id/keypad_8"
            android:text="8"></Button>
        <Button android:id="@+id/keypad_9"
            android:text="9"></Button>
    </TableRow>
   
</TableLayout>

*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值