/src/clarknova/software/sumdokusolver/AndroidSumdokuSolver.java
Java | 1343 lines | 1028 code | 183 blank | 132 comment | 128 complexity | 8a4c1aa08e5499e55f6218793bc96c1c MD5 | raw file
package clarknova.software.sumdokusolver; import java.util.Vector; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.Display; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.view.Window; import android.widget.Button; import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import android.widget.Toast; public class AndroidSumdokuSolver extends Activity { public final static String MODE = "clarknova.software.sumdokusolver.mode"; private boolean isReleaseVersion = true; // private boolean isReleaseVersion = false; public final static int SAVE = 1; public final static int LOAD = 2; public static Activity activity; public final static String TAG = "sumdoku"; public static final String NAME = "name"; private static final String FIELDSTATE = "field state"; public static final int NOTCOMPLETE = 0; public static final int SOLVED = 1; public static final int EMPTYCELL = -1; public static final int WRONGTOTALSUM = -2; private static final int OK = 1; public Calculate calculate = new Calculate(); public Solve solve = new Solve(this); public Toast toast; public Button get_sum_button, remove_button, solve_button; private int sumdoku_size=Calculate.SUMDOKU_SIZE; private int fieldwidth; public TableLayout field; public RelativeLayout rLayout; private int current_sum; private Sum sum_back = new Sum(0, this); public Data data = new Data(this); public Vector<Integer> selected_cells = new Vector<Integer>(); public Vector<CellView> cells = new Vector<CellView>(); private View sumbuttonsLayout; private DBAdapter db = new DBAdapter(this); private SolveTask solution; private GetField getfield; private SaveField savefield; public Dialog waitdialog; private Data data_back = new Data(this); private boolean doubleBackToExitPressedOnce; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); activity = this; toast = Toast.makeText(getApplicationContext(), "",Toast.LENGTH_SHORT); toast.setText(""); toast.show(); toast.cancel(); setContentView(R.layout.main); presetScreen(); loadsavedstate(); } private void loadsavedstate() { loadfield(FIELDSTATE); } // @Override // public void onPause(){ // super.onPause(); // InputMethodManager imm = (InputMethodManager) getSystemService (Context.INPUT_METHOD_SERVICE); // imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); // } // @Override public void onActivityResult(int requestCode,int resultCode,Intent data) { super.onActivityResult(requestCode, resultCode, data); if (data == null){ Log.v(TAG, "No result data"); return; } String save_name = data.getStringExtra(NAME); Log.d("myLogs", "requestCode = " + requestCode + ", resultCode = " + resultCode); if (resultCode == RESULT_OK) { switch (requestCode) { case SAVE: Log.v(TAG, "onActivityResult save "+save_name); savefield(save_name); break; case LOAD: Log.v(TAG, "onActivityResult load "+save_name); loadfield(save_name); break; default: Log.v(TAG, "Use requestCodes!"); } } else { Log.v(TAG, "Wrong result"); } } // @Override // public boolean onKeyDown(int keycode, KeyEvent e) { // switch(keycode) { // case KeyEvent.KEYCODE_BACK: // if (!selected_cells.isEmpty()){ // cancel_selection(); // } // else this.finish(); // return true; // } // // return super.onKeyDown(keycode, e); // } @Override public void onBackPressed() { if (!selected_cells.isEmpty()){ cancel_selection(); return; } if (doubleBackToExitPressedOnce) { super.onBackPressed(); return; } this.doubleBackToExitPressedOnce = true; Toast.makeText(this, "Please click BACK again to exit", Toast.LENGTH_SHORT).show(); new Handler().postDelayed(new Runnable() { @Override public void run() { doubleBackToExitPressedOnce=false; } }, 2000); } //----=== START FUNCTIONS ===---- // @SuppressWarnings("deprecation") private void presetScreen() { Display display = getWindowManager().getDefaultDisplay(); rLayout = (RelativeLayout) findViewById(R.id.mainLayout); /*if (android.os.Build.VERSION.SDK_INT >= 13){ Point size = new Point(); display.getSize(size); fieldwidth = Math.min(size.x,size.y); }*/ //else { fieldwidth = Math.min(display.getHeight(), display.getWidth()); //} createtable(); sumbuttonsLayout=findViewById(R.id.sum_buttons); get_sum_button = (Button) findViewById(R.id.button_get_sum); remove_button = (Button) findViewById(R.id.button_remove); solve_button = (Button) findViewById(R.id.button_solve); get_sum_button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Log.v(TAG, "USER ACTION: OkClick"); okClick(v);} }); remove_button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Log.v(TAG, "USER ACTION: ClearClick"); removeClick(v);} }); solve_button.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { Log.v(TAG, "USER ACTION: SolveClick"); solveClick(v); } }); } private void createtable() { int cellsize = (fieldwidth-sumdoku_size-1)/(sumdoku_size); int fieldsize = sumdoku_size*cellsize+sumdoku_size+1; Log.v(TAG, "fieldwidth: "+fieldwidth+", fieldsize:"+fieldsize+", cellsize:"+cellsize); field = new TableLayout(this); rLayout.addView(field); RelativeLayout.LayoutParams tParams = (RelativeLayout.LayoutParams)field.getLayoutParams(); tParams.width=fieldsize; tParams.height=fieldwidth; field.setLayoutParams(tParams); cells.clear(); View b = new View(this); field.addView(b,new TableLayout.LayoutParams (fieldsize,(fieldwidth-fieldsize)/2)); b.setBackgroundColor(Color.WHITE); b = new View(this); field.addView(b,new TableLayout.LayoutParams (fieldsize,1)); b.setBackgroundColor(Color.BLACK); for (int i=0;i<sumdoku_size;i++){ TableRow row = new TableRow(this); b = new View(this); row.addView(b,new TableRow.LayoutParams (1,cellsize)); b.setBackgroundColor(Color.BLACK); for(int k=0; k<sumdoku_size; k++){ final CellView cell = new CellView(this); cell.setTag(""+i+""+k); cells.add(cell); row.addView(cell); TableRow.LayoutParams params = (TableRow.LayoutParams)cell.getLayoutParams(); params.width = cellsize; params.height = cellsize; cell.setLayoutParams(params); b = new View(this); row.addView(b,new TableRow.LayoutParams (1,cellsize)); if ((k+1)%3==0){ b.setBackgroundColor(Color.BLACK); } else {b.setBackgroundColor(Color.LTGRAY);} } field.addView(row, new TableLayout.LayoutParams (LayoutParams.WRAP_CONTENT ,LayoutParams.WRAP_CONTENT)); b = new View(this); field.addView(b,new TableLayout.LayoutParams (fieldsize, 1)); if ((i+1)%3==0){ b.setBackgroundColor(Color.BLACK); } // if (i==sumdoku_size/3-1 ||i==2*sumdoku_size/3-1){ // b.setBackgroundColor(Color.BLACK); // } else {b.setBackgroundColor(Color.LTGRAY);} } b = new View(this); field.addView(b,new TableLayout.LayoutParams (fieldsize,(fieldwidth-fieldsize)/2)); b.setBackgroundColor(Color.WHITE); RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) field.getLayoutParams(); params.addRule(RelativeLayout.CENTER_HORIZONTAL); field.setLayoutParams(params); field.invalidate(); //Log.v(TAG, "Table is set"); } //----=== USER ACTIONS ===---- public void removeClick(View v) { //TODO: do different things! AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.title_remove_sum) .setItems(R.array.array_remove_sum, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { switch (which) { case 0: //Remove Sum if (!selected_cells.isEmpty()){ Sum sum = data.getsum(selected_cells.firstElement()); data.getsums().removeElement(sum); disborder(selected_cells); //clearselection(); } dialog.cancel(); break; case 1: //Remove Values for (int cell_num : selected_cells) { data.setValue(0, cell_num); cells.elementAt(calculate.num_to_location(cell_num)).clearvalue(); } // clearselection(); dialog.cancel(); break; case 2: //Remove all if (!selected_cells.isEmpty()){ for (int cell_num : selected_cells) { data.setValue(0, cell_num); cells.elementAt(calculate.num_to_location(cell_num)).clearvalue(); } Sum sum = data.getsum(selected_cells.firstElement()); data.getsums().removeElement(sum); clearselection(); } dialog.cancel(); break; default: dialog.cancel(); break; } } }); AlertDialog clearField = builder.create(); clearField.show(); } void cancel_selection(){ Log.v(TAG, "cancel_selection()"); // Log.v(TAG, "last_sum: "+last_sum.sum+" ("+last_sum.cell_nums+"), selected_cells: "+selected_cells); // if (!data.sums.contains(last_sum)){ // clearselection(); // if (noneinsums(last_sum.cell_nums)){ // setsum(last_sum); // } // } Log.v(TAG, "sum_back: "+sum_back.sum+" ("+sum_back.cell_nums+"), selected_cells: "+selected_cells); if (!data.sums.contains(sum_back)){ clearselection(); if (noneinsums(sum_back.cell_nums)){ setsum(sum_back); } } get_sum_button.setEnabled(false); remove_button.setEnabled(false); } private boolean noneinsums(Vector<Integer> cell_nums){ for (int cellnum : cell_nums) { if (data.getsum(cellnum)!=null){ return false; } } return true; } private void clearselection() { for (int cellnum:selected_cells){ int n=calculate.num_to_location(cellnum); CellView cell = cells.elementAt(n); cell.clear(); } selected_cells.clear(); get_sum_button.setEnabled(false); remove_button.setEnabled(false); } public void okClick(View v) { if (cells_connected(selected_cells)){ Vector<Integer> alone_cells = alone_cells_near(selected_cells); if (alone_cells==null || alone_cells.size()==0){ getsum(); } else { //TODO: change toast by highlighting alone cells toast.setText("Alone cells: "+alone_cells); toast.show(); } } else { //TODO: do not allow user to set a sum by interface toast.setText("Cells in selection should be connected"); toast.show(); } } /** * Shows user a dialog where they can select a value of sum in selected cells */ private void getsum() { current_sum = 0; final int min_sum=calculate.minsum(selected_cells.size()); int max_sum=calculate.maxsum(selected_cells.size()); final Dialog dialog = new Dialog(this,R.style.myBackgroundStyle); dialog.setContentView(R.layout.dialog_pick_a_sum); dialog.setTitle(R.string.text_sum); // WindowManager.LayoutParams lp = dialog.getWindow().getAttributes(); // lp.dimAmount=0.1f; // lp.alpha=0.7f; // // dialog.getWindow().setAttributes(lp); // dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); final TextView sum_text = (TextView) dialog.findViewById(R.id.editText_sum); TextView min_sumTextView = (TextView) dialog.findViewById(R.id.min_sum); TextView max_sumTextView = (TextView) dialog.findViewById(R.id.max_sum); min_sumTextView.setText(""+min_sum); max_sumTextView.setText(""+max_sum); Button done = (Button) dialog.findViewById(R.id.button_sum_done); done.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { if (sum_text.getText().length()>0){ current_sum = Integer.parseInt(sum_text.getText().toString()); setsum(current_sum); Log.v(TAG, "sum="+current_sum); dialog.dismiss(); } else { //TODO: check if it happens Log.e(TAG, "WTF? No sum?"); toast.setText("Enter Sum!"); toast.show(); } } }); //done.getBackground().setAlpha(100); SeekBar seek_sum = (SeekBar) dialog.findViewById(R.id.seekBar_sum); seek_sum.setMax(max_sum-min_sum); sum_text.setText(""+min_sum); // int lastsum =getLast_sum().sum; // if (lastsum!=0 && lastsum>=min_sum && lastsum<=max_sum){ // sum_text.setText(""+lastsum); // seek_sum.setProgress(lastsum-min_sum); // } seek_sum.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { //@Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { sum_text.setText(String.valueOf(progress+min_sum)); } //@Override public void onStartTrackingTouch(SeekBar seekBar) { } //@Override public void onStopTrackingTouch(SeekBar seekBar) { } }); //dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); dialog.show(); } private void setsum(int sum){ Sum s = new Sum(sum, this); for (int cell_num : selected_cells) { s.cell_nums.add(cell_num); } data.addtosums(s); if (sum_back.sum!=0){ disborder(sum_back.cell_nums); } border(sum); // setLast_sum(s); if (!selected_cells.isEmpty()){ Log.v(TAG, "Sum: "+data.getsum(selected_cells.firstElement()).sum+", " + "cells:"+data.getsum(selected_cells.firstElement()).cell_nums+"\n");} selected_cells.clear(); get_sum_button.setEnabled(false); remove_button.setEnabled(false); // Log.v(TAG,"new cells:"+new_cells); if (total_sums_size()==sumdoku_size*sumdoku_size){ all_sums_filled(); } } private int total_sums_size(){ int size=0; for (Sum s : data.getsums()) { size+=s.cell_nums.size(); } Log.v(TAG, "total sums size = "+size); return size; } private void setsum(Sum sum){ while (!selected_cells.isEmpty()){ int cellnum = selected_cells.remove(0); CellView cell = cells.elementAt(calculate.num_to_location(cellnum)); View b = cell.findViewById(R.id.back); b.setBackgroundColor(Color.WHITE); b.invalidate(); } selected_cells.addAll(sum.cell_nums); setsum(sum.sum); } public void editSum(int num) { Sum sum = data.getsum(num); if (sum.sum==0){return;} //setLast_sum(sum); set_sum_back(sum); hidesolvebutton(); // Log.v(TAG,"Cell: num="+cell.num+", sum="+cell.sum+", sum_area="+cell.sum_area); for (int cell_num : sum.cell_nums) { int location = calculate.num_to_location(cell_num); CellView cellView = cells.elementAt(location); cellView.findViewById(R.id.back).setBackgroundColor(Color.GRAY); selected_cells.add(cell_num); } data.getsums().removeElement(sum); tempborder(selected_cells); get_sum_button.setEnabled(selected_cells.size()>1); remove_button.setEnabled(selected_cells.size()>0); } private void disborder(Vector<Integer> cell_nums) { sum_back = new Sum(0, this); for (int cellnum : cell_nums) { int n=calculate.num_to_location(cellnum); CellView cell = cells.elementAt(n); TextView sum_textview = (TextView) cell.findViewById(R.id.sum); sum_textview.setText(""); cell.hideborders(); } } private void tempborder(Vector<Integer> cell_nums){ for (int cellnum:selected_cells){ int n=calculate.num_to_location(cellnum); CellView cell = cells.elementAt(n); View t = cell.findViewById(R.id.tempback); t.setVisibility(View.VISIBLE); } } private void border(int sum) { // Log.v(TAG, "border()"); int min = calculate.min(selected_cells); // Log.v(TAG, "Sum: "+sum+", selected_cells="+AndroidSumdokuSolver.selected_cells); for (int cellnum:selected_cells){ int i=cellnum/10; int k=cellnum%10; int n=calculate.num_to_location(cellnum); // Log.v(TAG, " cellnum: "+cellnum+", n="+n); CellView cell = cells.elementAt(n); // Log.v(TAG, " cell.getTag().toString(): "+cell.getTag().toString()); View b = cell.findViewById(R.id.back); b.setBackgroundColor(Color.WHITE); b.invalidate(); if(cellnum==min){ TextView t = (TextView) cell.findViewById(R.id.sum); t.setText(""+sum); } if (!selected_cells.contains(10*(i-1)+k)){ cell.findViewById(R.id.border_top).setVisibility(View.VISIBLE); if (selected_cells.contains(10*i+k-1)){ cell.findViewById(R.id.border_top_rl).setVisibility(View.VISIBLE); } if (selected_cells.contains(10*i+k+1)){ cell.findViewById(R.id.border_top_lr).setVisibility(View.VISIBLE); } } else{ if (!selected_cells.contains(10*(i-1)+k-1)){ cell.findViewById(R.id.border_left_bt).setVisibility(View.VISIBLE); } if (!selected_cells.contains(10*(i-1)+k+1)){ cell.findViewById(R.id.border_right_bt).setVisibility(View.VISIBLE); } } if (!selected_cells.contains(10*i+k-1)){ cell.findViewById(R.id.border_left).setVisibility(View.VISIBLE); if (selected_cells.contains(10*(i+1)+k)){ cell.findViewById(R.id.border_left_tb).setVisibility(View.VISIBLE); } if (selected_cells.contains(10*(i-1)+k)){ cell.findViewById(R.id.border_left_bt).setVisibility(View.VISIBLE); } } else{ if (!selected_cells.contains(10*(i-1)+k-1)){ cell.findViewById(R.id.border_top_rl).setVisibility(View.VISIBLE); } if (!selected_cells.contains(10*(i+1)+k-1)){ cell.findViewById(R.id.border_bottom_rl).setVisibility(View.VISIBLE); } } if (!selected_cells.contains(10*(i+1)+k)){ cell.findViewById(R.id.border_bottom).setVisibility(View.VISIBLE); if (selected_cells.contains(10*i+k-1)){ cell.findViewById(R.id.border_bottom_rl).setVisibility(View.VISIBLE); } if (selected_cells.contains(10*i+k+1)){ cell.findViewById(R.id.border_bottom_lr).setVisibility(View.VISIBLE); } } else{ if (!selected_cells.contains(10*(i+1)+k-1)){ cell.findViewById(R.id.border_left_tb).setVisibility(View.VISIBLE); } if (!selected_cells.contains(10*(i+1)+k+1)){ cell.findViewById(R.id.border_right_tb).setVisibility(View.VISIBLE); } } if (!selected_cells.contains(10*i+k+1)){ cell.findViewById(R.id.border_right).setVisibility(View.VISIBLE); if (selected_cells.contains(10*(i+1)+k)){ cell.findViewById(R.id.border_right_tb).setVisibility(View.VISIBLE); } if (selected_cells.contains(10*(i-1)+k)){ cell.findViewById(R.id.border_right_bt).setVisibility(View.VISIBLE); } } else{ if (!selected_cells.contains(10*(i-1)+k+1)){ cell.findViewById(R.id.border_top_lr).setVisibility(View.VISIBLE); } if (!selected_cells.contains(10*(i+1)+k+1)){ cell.findViewById(R.id.border_bottom_lr).setVisibility(View.VISIBLE); } } cell.invalidate(); } field.invalidate(); } // MENU @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { if (isReleaseVersion){ menu.findItem(R.id.printfield).setVisible(false); } else menu.findItem(R.id.helpscreen).setVisible(false); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menuclear: Log.v(TAG, "USER ACTION: Menu - ClearField"); menuclear(); return true; case R.id.printfield: Log.v(TAG, "USER ACTION: Menu - PrintField"); data.printfield(); return true; case R.id.helpscreen: Log.v(TAG, "USER ACTION: Menu - PrintField"); helpscreen(); return true; case R.id.getexample: Log.v(TAG, "USER ACTION: Menu - getExample"); //clearfield(); clearAll(); example(); return true; case R.id.savefield: Log.v(TAG, "USER ACTION: Menu - saveField"); savefield(); return true; case R.id.loadfield: Log.v(TAG, "USER ACTION: Menu - loadField"); loadfield(); return true; default: // return super.onOptionsItemSelected(item); return false; } } private void helpscreen() { Intent helpscreen = new Intent(this, HelpScreen.class); startActivity(helpscreen); } private void menuclear() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle(R.string.title_clear_field) .setItems(R.array.array_clear_field, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { switch (which) { case 0: clearSums(); dialog.cancel(); break; case 1: clearValues(); dialog.cancel(); break; case 2: clearAll(); dialog.cancel(); break; default: dialog.cancel(); break; } } }); AlertDialog clearField = builder.create(); clearField.show(); } private void clearAll(){ for (int cell_num : selected_cells) { int location = calculate.num_to_location(cell_num); CellView cellView = cells.elementAt(location); cellView.clear(); } selected_cells.clear(); clearSums(); clearValues(); hidesolvebutton(); get_sum_button.setEnabled(false); remove_button.setEnabled(false); } private void clearValues() { for (int cell_num : selected_cells) { int location = calculate.num_to_location(cell_num); CellView cellView = cells.elementAt(location); cellView.clear(); } selected_cells.clear(); get_sum_button.setEnabled(false); remove_button.setEnabled(false); for (int i=0;i<sumdoku_size;i++) { for (int k=0;k<sumdoku_size;k++) { int cell_num=10*i+k; data.setValue(0, cell_num); cells.elementAt(calculate.num_to_location(cell_num)).clearvalue(); } } } private void clearSums() { for (int cell_num : selected_cells) { int location = calculate.num_to_location(cell_num); CellView cellView = cells.elementAt(location); cellView.clear(); } selected_cells.clear(); get_sum_button.setEnabled(false); remove_button.setEnabled(false); while (!data.sums.isEmpty()){ removesums(); } sum_back = new Sum(0,this); hidesolvebutton(); } private void suggsolve() { Data data_back = new Data(this); data_back.copy_from(data); data=data.solving_by_suggestions(); Log.v(TAG, ""); Log.v(TAG, "BEFORE SOLVING BY SUGESTIONS (data_back):"); data_back.printfield(); Log.v(TAG, "AFTER SOLVING BY SUGESTIONS (data):"); data.printfield(); // showresult(); } private void removesums() { //TODO: Check if realization of this is not stupid if (!data.sums.isEmpty()){ // Log.v(TAG,"sumnumber=="+sumnumber+", getsums.size=="+data.getsums().size()); Log.v(TAG,"sums was: "+data.getsums().size()); Sum sum = data.getsums().lastElement(); if (sum.cell_nums.isEmpty()){ data.getsums().removeElement(sum); removesums(); return; } for (int cell_num : sum.cell_nums){ int location = calculate.num_to_location(cell_num); CellView cellView = cells.elementAt(location); // Cell cell = data.getcell(location); cellView.findViewById(R.id.back).setBackgroundColor(Color.WHITE); TextView oldsum = (TextView) cellView.findViewById(R.id.sum); oldsum.setText(""); cellView.hideborders(); // Log.v(TAG,"cleared cell #"+cell.num+", cell.sum="+cell.sum+", cell.sum_area="+cell.sum_area); // done_cells.removeElement(cell_num); //new_cells.add(cell_num); } data.getsums().removeElement(sum); // last_sum.sum=0; // last_sum.cell_nums.clear(); sum_back = new Sum (0,this); Log.v(TAG,"sums remains: "+data.getsums().size()); // toast.setText("removed sum area : "+sum.sum_area); // toast.show(); } } //----=== SOLVING ===---- private void all_sums_filled() { Log.v(TAG, "All sums filled"); findViewById(R.id.sum_buttons).setVisibility(View.INVISIBLE); solve_button.setVisibility(View.VISIBLE); } public void solveClick(View v) { int checkfield = fieldIsOk(); switch (checkfield) { case OK: solution = new SolveTask(); solution.execute(data); break; case WRONGTOTALSUM: somethingwrong(R.string.message_wrong_total_sum); break; default: somethingwrong(R.string.message_wrong_field); break; } } private int fieldIsOk(){ int total_sum=0; for (Sum sum:data.sums){ total_sum+=sum.sum; } if (total_sum!=calculate.totalsum()) { Log.v(TAG, "total_sum="+total_sum+", calculate.totalsum()="+calculate.totalsum()); return WRONGTOTALSUM;} return OK; } //----=== SHOW RESULT ===---- private void showresult() { //System.out.println(cells); int i=0; for (CellView cellview : cells) { //Log.v(TAG, "result: "); Cell cell = data.field[i]; TextView value_textview = (TextView) cellview.findViewById(R.id.value); TextView vars_textview = (TextView) cellview.findViewById(R.id.vars); if (value_textview.getText()=="" || value_textview.getText()==null){ if (cell.getValue()>0){ vars_textview.setVisibility(View.INVISIBLE); value_textview.setTextAppearance(this, android.R.style.TextAppearance_Large); value_textview.setTextColor(Color.BLACK); value_textview.setText(""+cell.getValue());} else { vars_textview.setVisibility(View.VISIBLE); vars_textview.setTextAppearance(this, android.R.style.TextAppearance_Small_Inverse); vars_textview.setTextColor(Color.GREEN); String s=""; for (int n = 0; n < sumdoku_size; n++) { if (((1 << n) & cell.var_value) == (1<<n)) { s += (n + 1); } } vars_textview.setText(""+s); } } i++; } } //----=== OTHER ===---- private void hidesolvebutton() { sumbuttonsLayout.setVisibility(View.VISIBLE); solve_button.setVisibility(View.INVISIBLE); } private boolean cells_connected(Vector<Integer> cells) { boolean connection = (cells.size()>1); if (connection){ Vector<Integer> nearfirst = new Vector<Integer>(); Vector<Integer> checked = new Vector<Integer>(); nearfirst.addAll(near(cells.firstElement(),checked,cells)); connection=(nearfirst.size()==cells.size()); } return connection; } private Vector <Integer> alone_cells_near(Vector<Integer> selected_cells){ Vector<Integer> alone_cells = new Vector<Integer>(); Vector<Integer> near_cells = new Vector<Integer>(); for (int cell_num : selected_cells) { near_cells.addAll(near_cells(cell_num)); } for (int cell_num : near_cells) { Vector<Integer> n_cells = near_cells(cell_num); if (((n_cells==null || n_cells.size()==0))&& !alone_cells.contains(cell_num)){ alone_cells.add(cell_num); Log.v(TAG, "alone cell detected: "+cell_num); } else Log.v(TAG, cell_num+" is not alone: "+n_cells); } Log.v(TAG, "selected cells:"+selected_cells+ ", near cells:"+near_cells+ ", alone cells:"+alone_cells); return alone_cells; } private Vector<Integer> near_cells(int cell_num) { Vector<Integer> near_cells = new Vector<Integer>(); if (cell_num/10>=1 && !selected_cells.contains(cell_num-10) && !near_cells.contains(cell_num-10) && data.getsum(cell_num-10)==null) {near_cells.add(cell_num-10);} if (cell_num/10<sumdoku_size-1 && !selected_cells.contains(cell_num+10) && !near_cells.contains(cell_num+10) && data.getsum(cell_num+10)==null) {near_cells.add(cell_num+10);} if (cell_num%10>=1 && !selected_cells.contains(cell_num-1) && !near_cells.contains(cell_num-1) && data.getsum(cell_num-1)==null) {near_cells.add(cell_num-1);} if (cell_num%10<sumdoku_size-1 && !selected_cells.contains(cell_num+1) && !near_cells.contains(cell_num+1) && data.getsum(cell_num+1)==null) {near_cells.add(cell_num+1);} return near_cells; } private Vector<Integer> near(Integer firstElement, Vector<Integer> checked, Vector<Integer> cells) { Vector<Integer> n = new Vector<Integer>(); n.add(firstElement); int i=firstElement/10; int k=firstElement%10; checked.add(firstElement); if (i>=1){ int num=(i-1)*10+k; if (!checked.contains(num)&&cells.contains(num)){ n.addAll(near(num,checked,cells)); } } if (i<sumdoku_size-1){ int num=(i+1)*10+k; if (!checked.contains(num)&&cells.contains(num)){ n.addAll(near(num,checked,cells)); } } if (k>=1){ int num=i*10+k-1; if (!checked.contains(num)&&cells.contains(num)){ n.addAll(near(num,checked,cells)); } } if (k<sumdoku_size-1){ int num=i*10+k+1; if (!checked.contains(num)&&cells.contains(num)){ n.addAll(near(num,checked,cells)); } } return n; } // public Sum getLast_sum() { // return last_sum; // } // public void setLast_sum(Sum sum) { // last_sum = new Sum(sum.sum, this); // last_sum.cell_nums.addAll(sum.cell_nums); // } public void set_sum_back(Sum sum) { sum_back = new Sum(sum.sum, this); sum_back.cell_nums.addAll(sum.cell_nums); } // ---=== EXAMPLE ===--- private void example() { exSaveValue(6, 4); exSaveValue(20, 4); //exSaveValue(68, 7); exSaveValue(82, 9); selected_cells.clear(); get_sum_button.setEnabled(false); remove_button.setEnabled(false); exSaveSum(new int[] {0, 10,20,30}, 22); exSaveSum(new int[] {1, 2, 3, 11}, 26); exSaveSum(new int[] {4, 5, 6, 15}, 21); exSaveSum(new int[] {7, 8, 16, 17, 26}, 26); exSaveSum(new int[] {12, 13, 14}, 7); exSaveSum(new int[] {18, 27, 28}, 15); exSaveSum(new int[] {21, 31, 32}, 10); exSaveSum(new int[] {22, 23, 33}, 17); exSaveSum(new int[] {24, 25}, 9); exSaveSum(new int[] {34, 44, 54}, 9); exSaveSum(new int[] {35, 45}, 14); exSaveSum(new int[] {36, 37}, 13); exSaveSum(new int[] {38, 48}, 3); exSaveSum(new int[] {40, 50}, 9); exSaveSum(new int[] {41, 42}, 11); exSaveSum(new int[] {43, 53}, 14); exSaveSum(new int[] {46, 47}, 16); exSaveSum(new int[] {51, 52}, 14); exSaveSum(new int[] {55, 65, 66}, 11); exSaveSum(new int[] {56, 57, 67}, 19); exSaveSum(new int[] {58, 68, 78, 88}, 20); exSaveSum(new int[] {60, 61, 70}, 13); exSaveSum(new int[] {62, 71, 72, 80, 81}, 23); exSaveSum(new int[] {63, 64}, 8); exSaveSum(new int[] {73, 82, 83, 84}, 19); exSaveSum(new int[] {74, 75, 76}, 16); exSaveSum(new int[] {77, 85, 86, 87}, 20); } private void exSaveValue(int cell_num, int value){ int location = calculate.num_to_location(cell_num); CellView cellView = cells.elementAt(location); cellView.setvalue(value); } private void exSaveSum(int[] cellnums, int sum){ for (int cell_num : cellnums) { selected_cells.add(cell_num); } setsum(sum); } public void sumtofield(Sum sum){ selected_cells.clear(); selected_cells.addAll(sum.cell_nums); setsum(sum); } public void cellToField(Cell cell){ int location = calculate.num_to_location(cell.num); CellView cellView = cells.elementAt(location); if (cell.getValue()!=0){cellView.setvalue(cell.getValue());} data.field[location]=cell; } //---===SAVE/LOAD field===--- private void savefield() { Intent saveload = new Intent(this, SaveAndLoad.class); saveload.putExtra(MODE, SAVE); startActivityForResult(saveload,SAVE); } private void savefield(String save_name) { //Log.v(TAG, "SAving to "+save_name+"..."); savefield = new SaveField(); savefield.execute(save_name); } private void savefieldstate(){ db.clearSaving(FIELDSTATE); db.savedata(data, FIELDSTATE); // db.savefield(data.field,FIELDSTATE); // db.saveSums(data.sums,FIELDSTATE); } private void loadfield() { selected_cells.clear(); get_sum_button.setEnabled(selected_cells.size()>1); remove_button.setEnabled(selected_cells.size()>0); Intent saveload = new Intent(this, SaveAndLoad.class); saveload.putExtra(MODE, LOAD); startActivityForResult(saveload, LOAD); } class StringContext{ String string; Context context; public StringContext(String s, Context c) { string=s; context=c; } } private void loadfield(String save_name) { getfield = new GetField(); StringContext name_context = new StringContext(save_name,activity); getfield.execute(name_context); } public class SolveTask extends AsyncTask<Data,Void,Integer> { Context context; @Override protected void onPreExecute() { super.onPreExecute(); context = data.getcontext(); data_back.copy_from(data); setWaitDialog("Solving"); waitdialog.show(); } @Override protected Integer doInBackground(Data... d) { int result =NOTCOMPLETE; try { Data data = d[0]; result = data.solving(); Log.v(TAG, "solving() is "+ result); if (result==NOTCOMPLETE){ suggsolve(); } } catch (Exception e) { Log.e(TAG, "Error: "+ e.getMessage()); } return result; } @Override protected void onPostExecute(Integer result) { super.onPostExecute(result); Log.v(TAG, "onPostExecute(result) : "+result); if (result!=EMPTYCELL) { showresult(); waitdialog.cancel();} else{ waitdialog.cancel(); data.copy_from(data_back); somethingwrong(R.string.message_empty_cell); } } } private void setWaitDialog(String message) { waitdialog = new Dialog(this); waitdialog.requestWindowFeature(Window.FEATURE_NO_TITLE); waitdialog.setContentView(R.layout.dialog_progress); TextView dialogmessage = (TextView) waitdialog.findViewById(R.id.message); dialogmessage.setText(message); waitdialog.setCancelable(false); } public class GetField extends AsyncTask<StringContext,Void,Data> { @Override protected void onPreExecute() { super.onPreExecute(); setWaitDialog("Loading"); waitdialog.show(); } @Override protected Data doInBackground(StringContext... sc) { Vector<Sum> sums = new Vector<Sum>(); Cell[] field = null; Data fromdb=null; try { String save_name = sc[0].string; Context context = sc[0].context; fromdb=new Data(context); Log.v(TAG, "Loading from \""+save_name+"\"..."); // Log.i(TAG,"SUMS..."); sums = db.loadSums(save_name); // Log.i(TAG,"CELLS..."); field = db .loadfield(save_name); } catch (Exception e) { Log.e(TAG, "Error: "+ e.getMessage()); } if (sums!=null) fromdb.sums.addAll(sums); fromdb.field = field; return fromdb; } @Override protected void onPostExecute(Data fromdb) { super.onPostExecute(fromdb); clearAll(); if ((fromdb.sums!=null) && (!fromdb.sums.isEmpty())){ for (Sum sum : fromdb.sums) { sumtofield(sum); // Log.i(TAG," "+sum.sum+"("+sum.cell_nums+")"); } } // else Log.v(TAG, "No sums in save"); if (fromdb.field!=null && fromdb.field.length!=0){ for (Cell cell : fromdb.field) { cellToField(cell); } } waitdialog.cancel(); // else {Log.v(TAG, "No cells in save");} } } public class SaveField extends AsyncTask<String,Void,Integer> { @Override protected void onPreExecute() { super.onPreExecute(); setWaitDialog("Saving"); waitdialog.show(); } @Override protected Integer doInBackground(String... s) { String save_name=""; try { save_name = s[0]; Log.v(TAG, "Saving to \""+save_name+"\"..."); // db.clearSaving(save_name); // db.savefield(data.field,save_name); // db.saveSums(data.sums,save_name); db.savedata(data, save_name); } catch (Exception e) { Log.e(TAG, "Error: "+ e.getMessage()); } return 1; } @Override protected void onPostExecute(Integer result) { super.onPostExecute(result); waitdialog.cancel(); } } public void somethingwrong(int couse) { // String message = ""; // switch (couse) { // case EMPTYCELL: // message="This field can not be solved. Check all values you set"; // break; // // default: // message="Something wrong"; // break; // } AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage(couse) .setTitle(R.string.title_somethingwrong); builder.setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); }}); AlertDialog messagedialog = builder.create(); messagedialog.show(); } @Override protected void onStop() { super.onStop(); Log.v(TAG, "onStop()"); //cancel_selection(); //solution.cancel(true); } @Override protected void onDestroy() { super.onDestroy(); Log.v(TAG, "onDestroy()"); //solution.cancel(true); cancel_selection(); savefieldstate(); } }