先说一下数独游戏的规则:
1.在整个横坐标和纵坐标的9个格子上只能填土1-9的数字且不重复
2.在当前3*3 的格子上填入1-9数字且不重复
先给大家看效果图
项目思路
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()
代码 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){ Setset = new TreeSet (); // 检查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
代码 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 文件
然后运行起来就是这个样子的了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。