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

分成四个类: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;i<used.length;i++){
			if(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<views.length;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;i<stax+3;i++){
			for(int j=stay;j<stay+3;j++){
				temp=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<str.length();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<str.length();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);
		//计算单元格
		width=w/9;
		height=h/9;
	}
	//画笔事件
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		Paint backgroundpaint=new Paint();
		backgroundpaint.setColor(Color.parseColor("#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();
         }
	}
}

 

posted on 2015-09-25 19:15  25廖焯燊  阅读(365)  评论(0编辑  收藏  举报

导航