热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

数独游戏设计与实现之第三篇——项目开发的过程

分成四个类:CrosswordsActivity,DialogView,Game,MainViewCrosswordsActivity(主类):packagecom.Crosswords.Activ

分成四个类:CrosswordsActivity,DialogView,Game,MainView

CrosswordsActivity(主类):

package com.Crosswords.Activity;

import android.app.Activity;
import android.os.Bundle;

public class CrosswordsActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MainView(this));
}
}

 DialogView(对话框的一个类):

package com.Crosswords.Activity;

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;

public class DialogView extends Dialog{
MainView mainview;
// View []views=new View[9];
View[] views=new View[12];
int []used;
public DialogView(Context context,int []used,MainView mainview) {
super(context);
this.used=used;
this.mainview=mainview;
}
@Override
public void onCreate(Bundle buildle){
super.onCreate(buildle);
setTitle("请输入数字");
setContentView(R.layout.dialog);
this.getView();
for(int i=0;iif(used[i]!=0){
views[used[i]-1].setVisibility(View.INVISIBLE);
}
}
views[9].setVisibility(View.INVISIBLE);
views[11].setVisibility(View.INVISIBLE);
setListener();
}
public void getView(){
views[0]=findViewById(R.id.keypad_1);
views[1]=findViewById(R.id.keypad_2);
views[2]=findViewById(R.id.keypad_3);
views[3]=findViewById(R.id.keypad_4);
views[4]=findViewById(R.id.keypad_5);
views[5]=findViewById(R.id.keypad_6);
views[6]=findViewById(R.id.keypad_7);
views[7]=findViewById(R.id.keypad_8);
views[8]=findViewById(R.id.keypad_9);
views[9]=findViewById(R.id.keypad_10);
views[10]=findViewById(R.id.keypad_11);
views[11]=findViewById(R.id.keypad_12);
}
public void ReturnResult(int title){
mainview.SetSelectTitle(title);
dismiss();
}
public void setListener(){
for(int i=0;i//次数的t为真实的数字
final int t=i+1;
views[i].setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {

ReturnResult(t);

}
});
}
}
}

 Game(数独的算法类):

package com.Crosswords.Activity;

public class Game {
String str=
"500200008"+
"700008400"+
"000390060"+
"001630009"+
"000000654"+
"968400000"+
"005006071"+
"609005803"+
"080903046";
//全部的数字
int []crosswords=new int[9*9];
//各个坐标已经使用的数字
int [][][]usedwords=new int[9][9][];
//用来标记能够修改
int [][]flag =new int[9][9];
public Game() {
// TODO Auto-generated constructor stub
crosswords=getCrossword(str);
flag=getflag();
//GetAllUsed();
}
//得到所有已经使用数组
public void GetAllUsed(){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
usedwords[i][j]=getUsedWords(i, j);
}
}


}

//用来计算单元格中已经使用的格子
public int[] getUsedWords(int x,int y){
int [] c=new int[9];
//计算一行
int temp;
for(int i=0;i<9;i++){
temp=gettitle(i, y);
if(x==i){
continue;
}else{
if(temp!=0){
c[temp-1]=temp;
}
}
}
//计算一列
for(int i=0;i<9;i++){
temp=gettitle(x, i);
if(y==i){
continue;
}else{
if(temp!=0){
c[temp-1]=temp;
}

}
}
//计算单元格
//这个表达式是为了求出点击事件的具体大方块位置
int stax=(x/3)*3;
int stay=(y/3)*3;
for(int i=stax;ifor(int j=stay;jtemp=gettitle(i, j);
if(x==i&&y==j){
continue;
}else{
if(temp!=0){
c[temp-1]=temp;
}
}
}
}
//进行冗余处理
int sum=0;
for(int temp1:c){//此处必须重新声明temp1
if(temp1!=0)
sum++;
}
int []usedword=new int [sum];
sum=0;
for(int temp2:c){
if(temp2!=0){
usedword[sum]=temp2;
sum++;
}
}
return usedword;
}
//得到数字板的数独
public int[] getCrossword(String str){
int []sodu=new int[str.length()];
for(int i=0;i//减去0的编码用来算出具体的值
sodu[i]=str.charAt(i)-'0';
}
return sodu;
}
public String gettitleString(int x,int y){
String a=null;
//此处不能直接调用方法 会报错
int b=gettitle(x, y);
if(b==0){
a="";
}
else{
a=String.valueOf(b);
}
return a;
}
//得到对应坐标的数字
public int gettitle(int x,int y){
int temp=crosswords[y*9+x];
return temp;
}
//分析哪些坐标不能改变
public int[][] getflag(){
int temp;
int flag[][]=new int[9][9];
for(int i=0;i//减去0的编码用来算出具体的值
temp=str.charAt(i)-'0';
if(temp==0){
flag[i%9][i/9]=1;
//System.out.println("此处可以填写:"+i%9+" "+i/9);
}
}
return flag;
}
//得到标记
public int flag(int x,int y){
return flag[x][y];
}
//用来在改变数字的时候进行更新
public void settitle(int x,int y,int title){
crosswords[y*9+x]=title;
}
//
public boolean SetTitleValid(int staX,int staY,int title){
int temp[]=getUsedWords(staX, staY);
//用来判断是不是清空按钮
if(title<=9){
for(int t:temp){
//为什么要判断
if(t==title){
System.out.println("==================="+t);
return false;
}
}
settitle(staX,staY,title);
}else{
settitle(staX,staY,0);
}
return true;
}
}

 MainView(计算单元格的一个类):

package com.Crosswords.Activity;

import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.text.style.LineBackgroundSpan;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug.FlagToString;
import android.widget.TextView;

public class MainView extends View{
float width;
float height;
int selectedX;
int selectedY;
Game game=new Game();
//画笔不能重用
public MainView(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
super.onSizeChanged(w, h, oldw, oldh);
//计算单元格
#C2E7C2"));
canvas.drawRect(0,0,getWidth(),getHeight(), backgroundpaint);

//#BFCDDB小格子颜色
Paint linepaint1=new Paint();
linepaint1.setColor(Color.parseColor("#BFCDDB"));
for (int i = 0; i <10; i++) {
canvas.drawLine(0,i*getHeight()/9, getWidth(), i*getHeight()/9, linepaint1);
canvas.drawLine(i*getWidth()/9, 0, i*getWidth()/9, getHeight(), linepaint1);
}
Paint linepaint2=new Paint();
linepaint2.setColor(Color.parseColor("#3399FF"));
for(int i=0;i<4;i++){
canvas.drawLine(0, i*getHeight()/3, getWidth(), i*getHeight()/3, linepaint2);
canvas.drawLine(i*getWidth()/3, 0, i*getWidth()/3, getHeight(), linepaint2);
}
Paint numberpaint=new Paint();
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;
String text;
for (int i = 0; i <9; i++) {
for(int j=0;j<9;j++){
text=game.gettitleString(i, j);
if(game.flag(i,j)==1){
numberpaint.setColor(Color.BLACK);
canvas.drawText(text, width*i+x, height*j+y, numberpaint);
}else{
numberpaint.setColor(Color.parseColor("#6B6743"));
canvas.drawText(text, width*i+x, height*j+y, numberpaint);
}
}
}

}
//监听点击面板事件
@Override
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 [] usedwords=game.getUsedWords(selectedX, selectedY);
StringBuffer usedstr=new StringBuffer();
for(int x:usedwords){
usedstr.append(x+" ");
}
//使用自定义的对话框
/*
LayoutInflater inflater=LayoutInflater.from(this.getContext());
View view=inflater.inflate(R.layout.dialog, null);
TextView text=(TextView)view.findViewById(R.id.used);
text.setText(usedstr.toString());
AlertDialog.Builder builder=new AlertDialog.Builder(this.getContext());
builder.setView(view);
AlertDialog dialog=builder.create();
dialog.show();
*/
//判断坐标是否是原来的数独
if(game.flag(selectedX, selectedY)==1){
DialogView dialog=new DialogView(getContext(), usedwords,this);
dialog.show();
}
return true;
}
public void SetSelectTitle(int title){
if(game.SetTitleValid(selectedX, selectedY, title)){
//刷新页面
invalidate();
}
}
}

 


推荐阅读
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 深入理解CSS中的margin属性及其应用场景
    本文主要介绍了CSS中的margin属性及其应用场景,包括垂直外边距合并、padding的使用时机、行内替换元素与费替换元素的区别、margin的基线、盒子的物理大小、显示大小、逻辑大小等知识点。通过深入理解这些概念,读者可以更好地掌握margin的用法和原理。同时,文中提供了一些相关的文档和规范供读者参考。 ... [详细]
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • SmartRefreshLayout自定义头部刷新和底部加载
    1.添加依赖implementation‘com.scwang.smartrefresh:SmartRefreshLayout:1.0.3’implementation‘com.s ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 详解Android  自定义UI模板设计_由浅入深
    学习安卓已有一些日子,前段时间整理了不少笔记,但是发现笔记不变分享与携带。今天开始整理博客,全当是与大家分享交流与自身学习理解的过程吧。结合最近在做的一个新闻类app及学习中的问题,一点一点整理一下, ... [详细]
author-avatar
wuqing0625
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有