国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android自定義View實現數獨游戲

2019-10-22 18:19:53
字體:
來源:轉載
供稿:網友

先說一下數獨游戲的規則:

1.在整個橫坐標和縱坐標的9個格子上只能填土1-9的數字且不重復
2.在當前3*3 的格子上填入1-9數字且不重復

先給大家看效果圖

Android,View,數獨游戲

項目思路

1、UI呈現:這個放在 GameView 類里面
        顯示原始數據
        顯示當然用戶填寫的數據
        顯示用戶當前點擊的位置
        顯示候選區數據

2、邏輯處理:這個是放在Matrix類里面的
    原始數據:游戲開始的時候就要創建出來的,
    當前數據:用戶填寫上去的實時數據
    數據判斷:判斷這個位置可以修改數據嗎? 比如,原始數據就是不可以修改的
            判斷這個位置可以填入的數據,比如,原始數據這個位置有8了,就不能填8了。

代碼 GameView 類

public class GameView extends View { private int PhoneWidth; // 手機屏幕的寬度 private int mGridWidth; // 當前格子的寬度 private int[] mFalseNumber; // 候選區不能填寫的數字 private Paint mLinePaint; // 白線 private Paint mDarkPaint; // 淺藍色的 方格子 private Paint mOptDarkPaint; // 用戶點擊 淺綠色的格子 private Paint numberPaint; // 原始數據 數字 private Paint changePaint; // 用戶填寫的數字 private Paint mOptPaint; // 候選區數字 private Matrix M; // 用戶計算類 private float tCX;  private float tCY; private int mOptBoard; private int mOptNumber; public GameView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } public GameView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public GameView(Context context) { super(context); initView(); } private void initView() { PhoneWidth = getResources().getDisplayMetrics().widthPixels; mGridWidth = (PhoneWidth - 40) / 9; tCX = mGridWidth / 2; tCY = tCX - tCX / 2; mFalseNumber = new int[9]; for (int i = 0; i < 9; i++) {  mFalseNumber[i] = i; } M = new Matrix(); initPaint(); invalidate(); } private void initPaint() { mLinePaint = new Paint(); mLinePaint.setColor(Color.WHITE); mLinePaint.setStyle(Paint.Style.STROKE); mLinePaint.setStrokeWidth(2f); mDarkPaint = new Paint(); mDarkPaint.setColor(Color.parseColor("#52E7CD")); mDarkPaint.setStyle(Paint.Style.FILL); numberPaint = new Paint(); numberPaint.setColor(Color.WHITE); numberPaint.setTextSize(mGridWidth * 0.65f); numberPaint.setTextAlign(Paint.Align.CENTER); numberPaint.setShadowLayer(10F, -5F, 8F, Color.parseColor("#999999")); numberPaint.setAntiAlias(true); mOptPaint = new Paint(); mOptPaint.setColor(Color.WHITE); mOptPaint.setTextSize(mGridWidth * 0.65f+15); mOptPaint.setTextAlign(Paint.Align.CENTER); mOptPaint.setShadowLayer(10F, -5F, 8F, Color.parseColor("#999999")); mOptPaint.setAntiAlias(true); changePaint = new Paint(); changePaint.setColor(Color.parseColor("#FCA454")); changePaint.setTextSize(mGridWidth * 0.65f); changePaint.setTextAlign(Paint.Align.CENTER); changePaint.setShadowLayer(10F, -5F, 8F, Color.parseColor("#999999")); changePaint.setAntiAlias(true); mOptDarkPaint = new Paint(); mOptDarkPaint.setColor(Color.parseColor("#52E76E")); mOptDarkPaint.setStyle(Paint.Style.FILL); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(PhoneWidth, PhoneWidth + mGridWidth+20); } @Override protected void onDraw(Canvas canvas) { drawBoard(canvas); int x = mOptBoard / 9; int y = mOptBoard % 9; // 畫出棋盤選擇框 canvas.drawRect(x * mGridWidth+22, y * mGridWidth+22, x * mGridWidth+20 + mGridWidth, y * mGridWidth+20 + mGridWidth, mOptDarkPaint); // 當前棋盤數據 for (int i = 0; i < 9; i++) {  for (int j = 0; j < 9; j++) {  int cutData = M.getCutData(i, j);  if (M.getOnClicked(i,j) && cutData>0) {   canvas.drawText(Integer.toString(cutData), i * mGridWidth + tCX+20, j*mGridWidth + mGridWidth - tCY+20, changePaint);  }  }  } // 候選區文字 drawTrueText(canvas); } private void drawTrueText(Canvas canvas) { float startY = PhoneWidth + 30; // 畫平行四邊形 canvas.drawLine(50, startY, PhoneWidth-50, startY, mLinePaint); canvas.drawLine(10, startY + mGridWidth - 40, PhoneWidth-10, startY + mGridWidth-40, mLinePaint); canvas.drawLine(50, startY, 10, startY + mGridWidth - 40, mLinePaint); canvas.drawLine(PhoneWidth-50, startY, PhoneWidth-10, startY + mGridWidth-40, mLinePaint); float y = (mGridWidth - 30)/2.0f; for (int i = 0; i < 9; i++) {  if (mFalseNumber[i] == 0) {  canvas.drawText(Integer.toString(i+1), i * mGridWidth + tCX+ 20, startY + (mGridWidth - tCY) - y, mOptPaint);  } } } private void drawBoard(Canvas canvas) { // 畫底色 for (int i = 0; i < 9; i++) {  for (int j = 0; j < 9; j++) {  int x = i / 3;  int y = j / 3;  if ((x == 0 || x == 2) && (y == 0 || y == 2)) {   canvas.drawRect(mGridWidth * j + 20, 20 + mGridWidth * i,    mGridWidth * j + 20 + mGridWidth, 20 + mGridWidth     * i + mGridWidth, mDarkPaint);  } else if (y == 1 && x == 1) {   canvas.drawRect(mGridWidth * j + 20, 20 + mGridWidth * i,    mGridWidth * j + 20 + mGridWidth, 20 + mGridWidth     * i + mGridWidth, mDarkPaint);  }  } } // 畫白線 for (int i = 0; i < 10; i++) {  canvas.drawLine(20, mGridWidth * i + 1 + 20, 9 * mGridWidth + 20,   mGridWidth * i + 1 + 20, mLinePaint);  canvas.drawLine(mGridWidth * i + 1 + 20, 0 + 20, mGridWidth * i + 1   + 20, 9 * mGridWidth + 20, mLinePaint); } //畫初始數字 for (int i = 0; i < 9; i++) {  for (int j = 0; j < 9; j++) {  if (!M.getOnClicked(i, j)) {   canvas.drawText(M.getText(i, j), i * mGridWidth +20+tCX, mGridWidth * j + 20+mGridWidth-tCY, numberPaint);  }  } } } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() != MotionEvent.ACTION_DOWN) {  return super.onTouchEvent(event); } if (event.getX()<20 || event.getY()<20 || event.getX()>PhoneWidth-20) {  Log.e("123", "點到邊了");  return super.onTouchEvent(event); } int choX = (int) ((event.getX()-20) / mGridWidth); int choY = (int) ((event.getY()-20) / mGridWidth); Log.i("game ", "optX "+choX+" optY "+choY); if (event.getY() < PhoneWidth-20) { // 棋盤的點擊  if (M.getOnClicked(choX, choY)) {  mFalseNumber = new int[9];  int[] trueData = M.getFalseData(choY, choX);  mOptBoard = choX * 9 + choY;  for (int i : trueData) {   mFalseNumber[i - 1] = 1;  }  } } else { // 候選區點擊  Log.e("game ","opt Number " + choX + 1);  System.out.println(Arrays.toString(mFalseNumber));  if (mFalseNumber[choX] == 0) {  mOptNumber = choX;  int x = mOptBoard / 9;  int y = mOptBoard % 9;  M.setCutData(x, y, mOptNumber+1);  } } invalidate(); return true; } // 再來一局 public void play() { initView(); } // 重頭開始 public void repeat(){ M.initCutData(); invalidate(); }

代碼 Matrix類

public class Matrix { private int [][]mData ; // 原始數據 private int [][]mCutData; // 當前數據 public Matrix() { int i = (int)(Math.random()*5); switch (i) { case 1:  mData = GAMEDATA1;  break; case 2:  mData = GAMEDATA2;  break; case 3:  mData = GAMEDATA3;  break; case 4:  mData = GAMEDATA4;  break; case 0:  mData = GAMEDATA2;  break; } initCutData(); Log.e("Matrix", "random :"+i); } /** 得到當前坐標上的文字 */ public String getText(int x, int y){ String index = mData[x][y]+""; if ("0".equals(index)) {  index = ""; } return index; } /** 判斷該坐標是否可以點擊 */ public boolean getOnClicked(int x, int y){ if (mData[x][y] == 0) {  return true; } return false; } /** 判斷該坐標有哪些數不可用 */ public int[] getFalseData(int x, int y){ Set<Integer> set = new TreeSet<Integer>(); // 檢查X 軸有哪些不能點 for (int i = 0; i < 9; i++) {  int d = mData[y][i];  if (d!=0) {  set.add(d);//  LogUtils.e("x: "+d);  } } // 檢查 y 軸有哪些不能點 for (int i = 0; i < 9; i++) {  int d = mData[i][x];  if (d!=0) {  set.add(d);//  LogUtils.e("Y: "+d);  } } // 檢查 3*3 方格哪些不能點 x = x/3*3; y = y/3*3;// LogUtils.e(" x "+x+" Y "+y); for (int i = x; i < x+3; i++) {  for (int j = y; j < y+3; j++) {  int d = mData[j][i];  if (d!=0) {   set.add(d);//   LogUtils.e("i "+i+"j "+j+" xy: "+d);  }  } } Integer[] arr2 = set.toArray(new Integer[0]); // 數組的包裝類型不能轉 只能自己轉;吧Integer轉為為int數組; int[] result = new int[arr2.length]; for (int i = 0; i < result.length; i++) {  result[i] = arr2[i]; } System.out.println("false Number : "+Arrays.toString(result)); return result; } /** 當前棋盤數據 */ public void initCutData(){ mCutData = new int[9][9]; for (int i = 0; i < mData.length; i++) {  for (int j = 0; j < mData[i].length; j++) {   mCutData[i][j] = mData[i][j];  } } for (int i = 0; i < mCutData.length; i++) {  System.out.println(Arrays.toString(mCutData[i])); } } public void setCutData(int x, int y, int data){ if (getOnClicked(x, y)) {  mCutData[x][y] = data; } } public int getCutData(int x, int y){ return mCutData[x][y]; }}

代碼 MainActivity 類

public class MainActivity extends Activity { private GameView gV; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gV = (GameView) findViewById(R.id.game); } public void rePay(View v){ gV.repeat(); } public void newPay(View v){ gV.play(); }

acitivity_main.xml 文件

<LinearLayout 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:background="#0EC5A5" android:orientation="vertical" > <TextView android:layout_width="match_parent" android:layout_height="52dp" android:layout_marginTop="10dp" android:gravity="center" android:text="SUDOKU" android:textColor="@android:color/white" android:textSize="30sp" /> <com.xuan.sudokugame.GameView android:id="@+id/game" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <LinearLayout android:layout_width="match_parent" android:layout_height="60dp" android:padding="10dp" android:orientation="horizontal" > <Button  android:layout_width="0dp"  android:onClick="rePay"  android:layout_height="match_parent"  android:layout_weight="1"   android:layout_marginRight="10dp"  android:text="重新開始"  android:textColor="@android:color/white"  android:background="@drawable/radius_border_gray"/> <Button  android:onClick="newPay"  android:layout_width="0dp"  android:layout_height="match_parent"  android:layout_weight="1"   android:text="再來一局"  android:textColor="@android:color/white"  android:background="@drawable/radius_border_gray"/> </LinearLayout></LinearLayout>

然后運行起來就是這個樣子的了。

Android,View,數獨游戲

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 北川| 聂拉木县| 蕉岭县| 屯门区| 永靖县| 屯留县| 肇庆市| 江北区| 河北区| 行唐县| 永福县| 莱州市| 寿阳县| 简阳市| 栾川县| 本溪| 抚州市| 新干县| 高雄县| 新建县| 射洪县| 夏河县| 和林格尔县| 都兰县| 察雅县| 夏邑县| 华阴市| 兴化市| 容城县| 泰来县| 正定县| 扶绥县| 那曲县| 新余市| 手机| 泰宁县| 深圳市| 团风县| 治多县| 汝城县| 溆浦县|