分紅四個類:CrosswordsActivity,DialogView,Game,MainViewjava
CrosswordsActivity(主類):android
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(數獨的算法類):canvas
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(); } } }