基于Android实现数独游戏 基于Android实现数独游戏
水木轩昊昊 人气:0想了解基于Android实现数独游戏的相关内容吗,水木轩昊昊在本文为您仔细讲解基于Android实现数独游戏的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:Android,数独,游戏,下面大家一起来学习吧。
1、在src中有4个Java类:
其中代码分别是:
Game.java:
package com.example.test1; import android.R.integer; public class Game { public final String str="360000000004230800000004200" +"070460003820000014500013020" +"001900000007048300000000045"; /*public final String str="124576893"+"967348521"+"835291674"+ "259784316"+"316952748"+"748613902"+"582439160"+"493167285"+"671825430";*/ static int sudoku[]=new int [9*9]; private int used[][][]=new int[9][9][]; int sum=0; public int[] getSudoku(){ return sudoku; } public int sum(int a[]){ for(int i=0;i<a.length;i++) sum+=a[i]; return sum; } public Game() { sudoku=fromPuzzleString(str); calculateAllUesdTiles(); } // 根据九宫格中的坐标,返回该坐标,所应该返回的数字 public int getTile(int x,int y){ return sudoku[y*9+x]; } public String getTileString(int x,int y) { int v=getTile(x,y); if(v==0) { return ""; } else { return String.valueOf(v); } } //根据一个字符串数据,生成一个整型数组,作为数独游戏的初始化数据 protected int[] fromPuzzleString(String src) { int []sudo=new int [src.length()]; for(int i=0;i<sudo.length;i++) { sudo[i]=src.charAt(i)-'0'; } return sudo; } //用于计算所有单元格对应的不可用数据 public void calculateAllUesdTiles() { for(int x=0;x<9;x++) { for(int y=0;y<9;y++) { used[x][y]=calculateUesdTiles(x,y); } } } //取出某一单元格当中已经不可用的数据 public int[] getUsedTileByCoor(int x, int y) { return used[x][y]; } //计算某一单元格当中不可用的数据 private int[] calculateUesdTiles(int x,int y) { // TODO Auto-generated method stub 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; } } 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; } protected boolean setTileIfValid(int x,int y,int value) { int tiles[]=getUsedTiles(x,y); if(value !=0) { for(int tile:tiles) { if(tile==value) return false; } } setTile(x,y,value); calculateAllUesdTiles(); return true; } private int[] getUsedTiles(int x, int y) { return used[x][y]; } private void setTile(int x,int y,int value) { sudoku[y*9+x]=value; } }
KeyDialog.java:
package com.example.test1; import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.view.View; //该类用于实现Dialog,实现自定义的对话框功能 public class KeyDialog extends Dialog{ //用来存放代表对话框中按钮的对象 private final View keys[]=new View[9]; private final int used[]; private ShuduView myView; //构造函数的第二个参数当中保存着当前单元格已经使用过的数字 public KeyDialog(Context context,int[] used,ShuduView myView) { super(context); this.used=used; this.myView=myView; } //当一个Dialog第一次显示的时候,会调用Oncreate方法 @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); //设置标题 setTitle("KeyDialog"); //用于为该Dialog设置布局文件 setContentView(R.layout.keypad); findViews(); //遍历整个used数组 for(int i=0;i<used.length;i++) { if(used[i]!=0) { keys[used[i]-1].setVisibility(View.INVISIBLE); } } setListeners(); } 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); } //通知MyView对象,刷新整个九宫格显示的数据 private void returnResult(int tile) { myView.setSelectedTile(tile); //取消对话框显示 dismiss(); } private void setListeners(){ //遍历整个keys数组 for(int i=0;i<keys.length;i++) { final int t=i+1; keys[i].setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub returnResult(t); } }); } } }
ShuduView.java:
package com.example.test1; import android.R.integer; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.FontMetrics; import android.graphics.Paint.FontMetricsInt; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.widget.TextView; public class ShuduView extends View{ private float width; private float height; int selectedX; int selectedY; private Game game=new Game(); public ShuduView(Context context) { super(context); // TODO Auto-generated constructor stub } @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 protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub //绘制背景颜色 Paint background_paint = new Paint(); background_paint.setColor(getResources().getColor(R.color.shudu_background)); canvas.drawRect(0, 0, getWidth(), getHeight(), background_paint); Paint white=new Paint(); white.setColor(getResources().getColor(R.color.shudu_hilite)); Paint light=new Paint(); light.setColor(getResources().getColor(R.color.shudu_light)); Paint dark=new Paint(); dark.setColor(getResources().getColor(R.color.shudu_dark)); for(int i=0;i<9;i++) { //画出横向的线 canvas.drawLine(0, i*height, getHeight(), i*height, light); canvas.drawLine(0, i*height+1, getHeight(), i*height+1, white); //画出纵向的线 canvas.drawLine( i*width,0, i*width,getHeight(), light); canvas.drawLine( i*width+1,0, i*width+1, getHeight(), white); } for(int i=0;i<9;i++) { if(i%3!=0) { continue; } canvas.drawLine(0, i*height, getHeight(), i*height, dark); canvas.drawLine(0, i*height+1, getHeight(), i*height+1, white); //画出纵向的线 canvas.drawLine( i*width,0, i*width,getHeight(), dark); canvas.drawLine( i*width+1,0, i*width+1, getHeight(), white); } Paint number_paint=new Paint(); number_paint.setColor(Color.BLACK); //number_paint.setStyle(Paint.Style.STROKE); number_paint.setTextSize(height*0.75f); number_paint.setTextAlign(Paint.Align.CENTER); FontMetrics fm=number_paint.getFontMetrics(); float x=width/2; float y=height/2-(fm.ascent+fm.descent)/2; for(int i=0;i<9;i++) { for(int j=0;j<9;j++) { canvas.drawText(game.getTileString(i, j), width*i+x, height*j+y, number_paint); } } super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { // TODO Auto-generated method stub if(event.getAction()!=MotionEvent.ACTION_DOWN) { return super.onTouchEvent(event); } selectedX=(int)(event.getX()/width); selectedY=(int)(event.getY()/height); int used[]=game.getUsedTileByCoor(selectedX, selectedY); int sum=0; int sumNumber=0; sumNumber=game.sum(game.getSudoku()); if(sumNumber==45*9){ AlertDialog.Builder builder=new AlertDialog.Builder(getContext()); builder.setMessage("Success!") .setPositiveButton("Exit", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { arg0.cancel(); } }); AlertDialog alertDialog=builder.create(); alertDialog.show(); } else { for(int i=0;i<used.length;i++){ sum+=used[i]; } if(sum==45){ AlertDialog.Builder builder=new AlertDialog.Builder(getContext()); builder.setMessage("No Number!") .setNegativeButton("Exit", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, int arg1) { arg0.cancel(); } }); AlertDialog alertDialog=builder.create(); alertDialog.show(); } else { StringBuffer sb=new StringBuffer(); for(int i=0;i<used.length;i++) { sb.append(used[i]); // System.out.println(used[i]); } KeyDialog keyDialog= new KeyDialog(getContext(),used,this); keyDialog.show(); } } /*StringBuffer sb=new StringBuffer(); for(int i=0;i<used.length;i++) { sb.append(used[i]); // System.out.println(used[i]); }*/ // //生成一个LayoutInflater对象 // LayoutInflater layoutInflater=LayoutInflater.from(this.getContext()); // //使用LayoutInflater对象根据一个布局文件,生成一个View // View layoutView=layoutInflater.inflate(R.layout.dialog, null); // //生成好的TextView当中,取出响应的控件 // TextView textView=(TextView)layoutView.findViewById(R.id.usedTextId); // //设置Textview内容 // textView.setText(sb.toString()); // //生成一个对话框的Builder对象 // AlertDialog.Builder builder=new AlertDialog.Builder(this.getContext()); // //设置对话框的布局 // builder.setView(layoutView); // //创建一个对话框 // AlertDialog dialog=builder.create(); // //显示对话框 // dialog.show(); /* KeyDialog keyDialog= new KeyDialog(getContext(),used,this); keyDialog.show();*/ return true; } public void setSelectedTile(int tile) { // TODO Auto-generated method stub if(game.setTileIfValid(selectedX,selectedY,tile)){ invalidate(); } } }
MainActivity.java:
package com.example.test1; import android.os.Bundle; import android.app.Activity; import android.view.Menu; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ShuduView sView=new ShuduView(this); setContentView(sView); //setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
2、布局Layout中的配置文件:
其中activity_main.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> </RelativeLayout>
dialog.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView android:id="@+id/usedTextId" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello_world" /> </LinearLayout>
keypad.xml:
<?xml version="1.0" encoding="utf-8"?> <!-- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > </LinearLayout> --> <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 android:id="@+id/keypad_2" android:text="2"/> <Button android:id="@+id/keypad_3" android:text="3"/> </TableRow> <TableRow> <Button android:id="@+id/keypad_4" android:text="4"/> <Button android:id="@+id/keypad_5" android:text="5"/> <Button android:id="@+id/keypad_6" android:text="6"/> </TableRow> <TableRow> <Button android:id="@+id/keypad_7" android:text="7"/> <Button android:id="@+id/keypad_8" android:text="8"/> <Button android:id="@+id/keypad_9" android:text="9"/> </TableRow> </TableLayout>
3、values中的配置文件
就只有color.xml是自己写的,另外三个都是自动生成
color.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="shudu_background">#ffe6f0ff</color> <color name="shudu_dark">#64ff0000</color> <color name="shudu_light">#64ffffff</color> <color name="shudu_hilite">#6400ff00</color> </resources>
4、一切就绪直接运行就0k
加载全部内容