必威体育Betway必威体育官网
当前位置:首页 > IT技术

android游戏开发项目实战——数独

时间:2019-08-03 21:13:15来源:IT技术作者:seo实验室小编阅读:83次「手机版」
 

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 {@Overrideprotected void onCreate(Bundle savedinstanceState) {super.onCreate(savedInstanceState);setContentView(new ShuduView(this));}@Overridepublic 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的高度 *  */@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {//计算当前单元格的宽度和高度this.width = w / 9f;this.height = h / 9f;super.onSizeChanged(w, h, oldw, oldh);}@Overrideprotected 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);}@Overridepublic 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方法 */@Overrideprotected 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() {@Overridepublic void onClick(View v) {returnResult(t);}});}}}

项目源码下载:http://download.csdn.net/detail/caihongshijie6/6883785

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow

这里写图片描述

相关阅读

Android——动态设置view背景颜色setBackgroundColor

setBackgroundColor 用于动态设置view背景颜色 今天写代码的时候遇到个小问题 动态设置的时候用Color.GRAY,系统自己带着的颜色

Android Studio菜鸟开发————RelativeLayout相对布

相对布局是通过相对定位的方式让控件出现在布局任意位置; 在相对布局中如果不指定控件摆放的位置,那么控件都会被默认放在Relative

超简单集成Android Zxing实现扫一扫二维码

2017-10-20更新最新版本的请看 超简单一句话依赖使用二维码扫描,优化了扫描速度,修复了一些bug,增加了闪光灯,解析二维码图片,生成二维

APP设计在iOS和Android操作系统中的差异

要想设计出优秀的原生APP,就要牢记iOS和Android间的差异。这些差异除了体现在APP的视觉方面,还体现在APP的结构以及流程上。因此只

Android游戏开发之2048游戏简单实现

没玩过2048的可以自己下一个玩玩,挺有趣的益智游戏。 本文实现了其简单的游戏逻辑,能够进行记分,游戏结束判断功能。重新开始以及保

分享到:

栏目导航

推荐阅读

热门阅读