android游戏开发项目实战——数独
生活随笔
收集整理的這篇文章主要介紹了
android游戏开发项目实战——数独
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
分享一下我老師大神的人工智能教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
一、程序運行效果圖
二、代碼實現
1、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>2、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>3、keypad1.xml
xml version="1.0" encoding="utf-8"<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"??? android:layout_width="wrap_content"??? android:layout_height="wrap_content" ??? android:id="@+id/keypad"??? android:orientation="vertical"??? >??? ??? <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>4、MainActivity
package com.njupt.shudu;import android.os.Bundle;import android.app.Activity;import android.view.Menu;public class MainActivity extends Activity {??protected void onCreate(Bundle savedInstanceState) {??super.onCreate(savedInstanceState);??setContentView(new ShuduView(this));?}??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;?}}5、ShuduView
package com.njupt.shudu;import android.app.AlertDialog;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.Paint.FontMetrics;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;??private Game game = new Game();?private int selectedX;?private int selectedY;??public ShuduView(Context context) {??super(context);???}??/**? * w:當前view的寬度? * h:當前view的高度? * ? */??protected void onSizeChanged(int w, int h, int oldw, int oldh) {??//計算當前單元格的寬度和高度??this.width = w / 9f;??this.height = h / 9f;????super.onSizeChanged(w, h, oldw, oldh);?}???protected void onDraw(Canvas canvas) {??//生成用于繪制背景色的畫筆??Paint backgroundPaint = new Paint();??//設置畫筆的顏色??backgroundPaint.setColor(getResources().getColor(R.color.shudu_background));??//繪制背景色??canvas.drawRect(0, 0,getWidth(),getHeight(),backgroundPaint);????Paint darkPaint = new Paint();??darkPaint.setColor(getResources().getColor(R.color.shudu_dark));????Paint hilitePaint = new Paint();??hilitePaint.setColor(getResources().getColor(R.color.shudu_hilite));????Paint lightPaint = new Paint();??lightPaint.setColor(getResources().getColor(R.color.shudu_light));????/**?? * 繪制用于分割小九宮格的線(即將屏幕分成81個格子)?? */??for(int i = 0 ; i < 9 ; ++i){???/**??? * canvas.drawLine(0, i*height, getWidth(),i*height, lightPaint)??? * 第1、2個參數: 起點的坐標??? * 第3、4個參數: 終點的坐標??? * 第5個參數: 所使用的畫筆??? */???canvas.drawLine(0, i*height, getWidth(),i*height, lightPaint);//劃橫線???canvas.drawLine(0, i*height + 1, getWidth(), i*height + 1, hilitePaint);//也是劃橫線,為了對比突出那種"刻出來"的效果???canvas.drawLine(i*width, 0, i*width, getHeight(), lightPaint);???canvas.drawLine(i*width + 1, 0, i*width + 1, getHeight() , hilitePaint);?????}????/**?? * 繪制用于將屏幕分成9個大九宮格的線?? */??for(int i = 0 ; i < 9 ; ++i){???if(i % 3 == 0){????continue;???}??????canvas.drawLine(0, i*height, getWidth(),i*height, darkPaint);//劃橫線???canvas.drawLine(0, i*height + 1, getWidth(), i*height + 1, hilitePaint);//也是劃橫線,為了對比突出那種"刻出來"的效果???canvas.drawLine(i*width, 0, i*width, getHeight(), darkPaint);???canvas.drawLine(i*width + 1, 0, i*width + 1, 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);//設置對齊方式????FontMetrics fm = numberPaint.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), i*width + x, j*height + y, numberPaint);???}??}????super.onDraw(canvas);?}???public boolean onTouchEvent(MotionEvent event) {??if(event.getAction() != MotionEvent.ACTION_DOWN){???return super.onTouchEvent(event);??}????//判斷用戶點擊的是哪一個單元格??selectedX = (int)(event.getX() / width);??selectedY = (int)(event.getY() / height);????int used[] = game.getUsedTilesByCoor(selectedX, selectedY);??StringBuffer sb = new StringBuffer();??for(int i = 0 ; i < used.length ; ++i){//用來驗證一下看對不對???sb.append(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) {??if(game.setTileIfValid(selectedX,selectedY,tile)){???invalidate();??}?}}7、Game
package com.njupt.shudu;public class Game {?//數獨初始化數據的基礎?private final String str = "360000000004230800000004200"???+"070460003820000014500013020"???+"001900000007048300000000045";??private int sudoku[] = new int[9*9];?//用于存儲每個單元格已經不可用的數據?private int used[][][] = new int[9][9][];??public Game() {??sudoku = fromPuzzleString(str);??calculateAllUsedTiles();?}???/**? * 根據九宮格當中的坐標,返回該坐標所應該填寫的數字? * @param x? * @param y? * @return? */?private int getTile(int x, int y){??return sudoku[y*9 + x];?}??/**? * 根據x軸坐標和y軸坐標得到這一單元格不可用的數據? * @param x? * @param y? * @return? */?public String getTileString(int x, int y){??int v = getTile(x,y);??if(v == 0){???return "";??}else{???return String.valueOf(v);??}?}??/**? * 根據一個字符串數據,生成一個整型數組,所謂數獨游戲的初始化數據? * @param src? * @return? */?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 calculateAllUsedTiles(){??for(int x = 0 ; x < 9 ; ++x){???for(int y = 0 ; y < 9 ; ++y){????used[x][y] = calculateUsedTiles(x, y);???}??}?}???/**? * 取出某一單元格中已經不可用的數據? * @param x? * @param y? * @return? */?public int[] getUsedTilesByCoor(int x, int y){??return used[x][y];?}???/**? * 計算某一單元格之中已經不可用的數據? * @param x? * @param y? */?public int[] calculateUsedTiles(int x,int y) {??int c[] = new int[9];????/**?? * 計算在y軸(列)方向上那些數字不可用...?? */??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給去掉?? */??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;?????}?public boolean setTileIfValid(int x, int y, int value) {??int tiles[] = getUesdTiles(x,y);??if(value != 0){???for(int tile : tiles){????if(tile == value){?????return false;????}???}??}????setTile(x,y,value);//把用戶輸入的數字添加到九宮格中??calculateAllUsedTiles();//更新該單元格可以使用的數字??return true;?}?protected int[] getUesdTiles(int x, int y) {??return used[x][y];?}??private void setTile(int x, int y, int value){??sudoku[y*9 + x] = value;?}}8、KeyDialog
package com.njupt.shudu;import android.app.Dialog;import android.content.Context;import android.os.Bundle;import android.view.View;/**?* 該類用于實現Dialog,實現自定義的對話框功能...?* @author Administrator?*?*/public class KeyDialog extends Dialog{?//用來存放代表對話框當中按鈕的對象?private final View keys[] = new View[9];?private final int used[];??private ShuduView shuduView;?/**? * ? * 構造函數的第二個參數中保存著當前單元格已經使用過的數字? * @param context? * @param used? */?public KeyDialog(Context context , int[] used , ShuduView shuduView) {??super(context);??this.used = used;??this.shuduView = shuduView;?}??/**? * 當一個Dialog第一次顯示的時候,會調用其onCreate方法? */??protected void onCreate(Bundle savedInstanceState) {??super.onCreate(savedInstanceState);????//設置對話框的標題??setTitle("KeyDialog");??//用于為該Dialog設置布局文件??setContentView(R.layout.keypad1);??findViews();????//顯示某一單元格中可用的數字??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);???}??/**? * 通知ShuduView對象,刷新掙個九宮格顯示的數據? * @param tile? */?private void returnResult(int tile){??System.out.println("shuduView: " + shuduView);??shuduView.setSelectedTile(tile);??dismiss();//取消對話框的顯示?}??private void setListeners(){??for(int i = 0 ; i < keys.length ; ++i){???final int t = i + 1;???keys[i].setOnClickListener(new View.OnClickListener() {????????????public void onClick(View v) {?????returnResult(t);????}???});??}?}}本項目源碼下載:http://download.csdn.net/detail/caihongshijie6/6883785
???????????給我老師的人工智能教程打call!http://blog.csdn.net/jiangjunshow
總結
以上是生活随笔為你收集整理的android游戏开发项目实战——数独的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 交换机分布缓存_细解网络设备缓存技术
- 下一篇: 【欧拉函数】 欧拉函数计算及打表