Added Error Highlighting

This commit is contained in:
Christopher Beckmann 2016-02-02 16:14:31 +01:00
parent 0fd676ffff
commit e5404acd4d
9 changed files with 110 additions and 35 deletions

View file

@ -67,9 +67,11 @@
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/debug" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
@ -80,15 +82,19 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/libs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/mockable-android-23.jar" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/ndk" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/proguard" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/tmp" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" /> <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" /> <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content> </content>

View file

@ -5,28 +5,27 @@ import android.content.SharedPreferences;
import android.os.Handler; import android.os.Handler;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.util.Log;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import org.secuso.privacyfriendlysudoku.controller.helper.GameInfoContainer; import org.secuso.privacyfriendlysudoku.controller.helper.GameInfoContainer;
import org.secuso.privacyfriendlysudoku.game.CellConflict;
import org.secuso.privacyfriendlysudoku.game.CellConflictList; import org.secuso.privacyfriendlysudoku.game.CellConflictList;
import org.secuso.privacyfriendlysudoku.game.GameBoard; import org.secuso.privacyfriendlysudoku.game.GameBoard;
import org.secuso.privacyfriendlysudoku.game.GameCell; import org.secuso.privacyfriendlysudoku.game.GameCell;
import org.secuso.privacyfriendlysudoku.game.GameDifficulty; import org.secuso.privacyfriendlysudoku.game.GameDifficulty;
import org.secuso.privacyfriendlysudoku.game.GameType; import org.secuso.privacyfriendlysudoku.game.GameType;
import org.secuso.privacyfriendlysudoku.game.ICellAction; import org.secuso.privacyfriendlysudoku.game.ICellAction;
import org.secuso.privacyfriendlysudoku.game.listener.IGameErrorListener;
import org.secuso.privacyfriendlysudoku.game.listener.IGameSolvedListener; import org.secuso.privacyfriendlysudoku.game.listener.IGameSolvedListener;
import org.secuso.privacyfriendlysudoku.game.listener.IHighlightChangedListener; import org.secuso.privacyfriendlysudoku.game.listener.IHighlightChangedListener;
import org.secuso.privacyfriendlysudoku.game.listener.IHintListener; import org.secuso.privacyfriendlysudoku.game.listener.IHintListener;
import org.secuso.privacyfriendlysudoku.game.listener.IModelChangedListener; import org.secuso.privacyfriendlysudoku.game.listener.IModelChangedListener;
import org.secuso.privacyfriendlysudoku.game.listener.ITimerListener; import org.secuso.privacyfriendlysudoku.game.listener.ITimerListener;
import java.util.LinkedList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
/** /**
* Created by Chris on 06.11.2015. * Created by Chris on 06.11.2015.
*/ */
@ -45,6 +44,7 @@ public class GameController implements IModelChangedListener, Parcelable {
private LinkedList<IHighlightChangedListener> highlightListeners = new LinkedList<>(); private LinkedList<IHighlightChangedListener> highlightListeners = new LinkedList<>();
private LinkedList<IGameSolvedListener> solvedListeners = new LinkedList<>(); private LinkedList<IGameSolvedListener> solvedListeners = new LinkedList<>();
private LinkedList<IHintListener> hintListener = new LinkedList<>(); private LinkedList<IHintListener> hintListener = new LinkedList<>();
private LinkedList<IGameErrorListener> errorListeners = new LinkedList<>();
private boolean notifiedOnSolvedListeners = false; private boolean notifiedOnSolvedListeners = false;
// Game // Game
@ -306,7 +306,7 @@ public class GameController implements IModelChangedListener, Parcelable {
return 0 < val && val <= size; return 0 < val && val <= size;
} }
public List<CellConflict> getErrorList() { public CellConflictList getErrorList() {
return errorList; return errorList;
} }
@ -507,23 +507,24 @@ public class GameController implements IModelChangedListener, Parcelable {
@Override @Override
public void onModelChange(GameCell c) { public void onModelChange(GameCell c) {
if(gameBoard.isFilled()) { if(gameBoard.isFilled()) {
List<CellConflict> errorList = new LinkedList<>(); errorList = new CellConflictList();
if(gameBoard.isSolved(errorList)) { if(gameBoard.isSolved(errorList)) {
if(!notifiedOnSolvedListeners) { if(!notifiedOnSolvedListeners) {
notifiedOnSolvedListeners = true; notifiedOnSolvedListeners = true;
notifySolvedListeners(); notifySolvedListeners();
resetSelects(); resetSelects();
} }
} else { }// else {
// notifyErrorListener(); // errorList now holds all the errors => display errors
// TODO: errorList now holds all the errors => display errors .. notify some view? //notifyErrorListener(errorList);
} //resetSelects();
//}
} else { } else {
notifiedOnSolvedListeners = false; notifiedOnSolvedListeners = false;
} }
} }
private void resetSelects() { public void resetSelects() {
selectedCol = -1; selectedCol = -1;
selectedRow = -1; selectedRow = -1;
selectedValue = 0; selectedValue = 0;
@ -543,6 +544,12 @@ public class GameController implements IModelChangedListener, Parcelable {
} }
} }
/*public void registerGameErrorListener(IGameErrorListener l) {
if(!errorListeners.contains(l)) {
errorListeners.add(l);
}
}*/
public void removeGameSolvedListener(IGameSolvedListener l) { public void removeGameSolvedListener(IGameSolvedListener l) {
if(solvedListeners.contains(l)) { if(solvedListeners.contains(l)) {
solvedListeners.remove(l); solvedListeners.remove(l);
@ -578,6 +585,12 @@ public class GameController implements IModelChangedListener, Parcelable {
} }
} }
/*public void notifyErrorListener(List<CellConflict> errorList) {
for (IGameErrorListener listener : errorListeners){
listener.onGameFilledWithErrors(errorList);
}
}*/
public void registerHintListener(IHintListener listener){ public void registerHintListener(IHintListener listener){
if (!hintListener.contains(listener)){ if (!hintListener.contains(listener)){
hintListener.add(listener); hintListener.add(listener);
@ -756,6 +769,7 @@ public class GameController implements IModelChangedListener, Parcelable {
solvedListeners = new LinkedList<>(); solvedListeners = new LinkedList<>();
hintListener = new LinkedList<>(); hintListener = new LinkedList<>();
timerListeners = new LinkedList<>(); timerListeners = new LinkedList<>();
errorListeners = new LinkedList<>();
} }
public void setContextAndSettings(Context applicationContext, SharedPreferences sharedPref) { public void setContextAndSettings(Context applicationContext, SharedPreferences sharedPref) {

View file

@ -11,6 +11,19 @@ public class CellConflict {
private GameCell c1 = null; private GameCell c1 = null;
private GameCell c2 = null; private GameCell c2 = null;
public int getRowCell1() {
return c1.getRow();
}
public int getRowCell2() {
return c2.getRow();
}
public int getColCell1() {
return c1.getCol();
}
public int getColCell2() {
return c2.getCol();
}
public CellConflict(GameCell first, GameCell second) { public CellConflict(GameCell first, GameCell second) {
c1 = first; c1 = first;

View file

@ -3,11 +3,11 @@ package org.secuso.privacyfriendlysudoku.game;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import org.secuso.privacyfriendlysudoku.game.listener.IModelChangedListener;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.secuso.privacyfriendlysudoku.game.listener.IModelChangedListener;
/** /**
* Created by Christopher Beckmann on 06.11.2015. * Created by Christopher Beckmann on 06.11.2015.
*/ */
@ -127,7 +127,7 @@ public class GameBoard implements Cloneable, Parcelable {
return existing; return existing;
} }
public boolean isSolved(final List<CellConflict> errorList) { public boolean isSolved(final CellConflictList errorList) {
boolean solved = true; boolean solved = true;
if(errorList == null) { if(errorList == null) {

View file

@ -0,0 +1,12 @@
package org.secuso.privacyfriendlysudoku.game.listener;
import org.secuso.privacyfriendlysudoku.game.CellConflict;
import java.util.List;
/**
* Created by Chris on 02.02.2016.
*/
public interface IGameErrorListener {
public void onGameFilledWithErrors(List<CellConflict> errorList);
}

View file

@ -3,32 +3,30 @@ package org.secuso.privacyfriendlysudoku.ui;
import android.content.Context; import android.content.Context;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.support.design.widget.TabLayout; import android.support.design.widget.TabLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.os.Bundle; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.RatingBar; import android.widget.RatingBar;
import android.widget.TextView; import android.widget.TextView;
import java.util.List;
import org.secuso.privacyfriendlysudoku.controller.SaveLoadStatistics; import org.secuso.privacyfriendlysudoku.controller.SaveLoadStatistics;
import org.secuso.privacyfriendlysudoku.controller.helper.HighscoreInfoContainer; import org.secuso.privacyfriendlysudoku.controller.helper.HighscoreInfoContainer;
import org.secuso.privacyfriendlysudoku.game.GameType; import org.secuso.privacyfriendlysudoku.game.GameType;
import org.secuso.privacyfriendlysudoku.ui.view.R; import org.secuso.privacyfriendlysudoku.ui.view.R;
import java.util.List;
public class StatsActivity extends AppCompatActivity { public class StatsActivity extends AppCompatActivity {
/** /**
@ -198,14 +196,14 @@ public class StatsActivity extends AppCompatActivity {
private String formatTime(int totalTime){ private String formatTime(int totalTime){
if (totalTime==0) return "/"; if (totalTime==0) return "-";
int seconds = totalTime % 60; int seconds = totalTime % 60;
int minutes = ((totalTime -seconds)/60)%60 ; int minutes = ((totalTime -seconds)/60)%60 ;
int hours = (totalTime - minutes - seconds)/(3600); int hours = (totalTime - minutes - seconds)/(3600);
String h,m,s; String h,m,s;
s = (seconds< 10)? "0"+String.valueOf(seconds):String.valueOf(seconds); s = (seconds < 10)? "0"+String.valueOf(seconds):String.valueOf(seconds);
m = (minutes< 10)? "0"+String.valueOf(minutes):String.valueOf(minutes); m = (minutes < 10)? "0"+String.valueOf(minutes):String.valueOf(minutes);
h = (hours< 10)? "0"+String.valueOf(hours):String.valueOf(hours); h = (hours < 10)? "0"+String.valueOf(hours):String.valueOf(hours);
return (h + ":" + m + ":" + s); return (h + ":" + m + ":" + s);
} }

View file

@ -10,8 +10,8 @@ import android.util.AttributeSet;
import android.view.View; import android.view.View;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import org.secuso.privacyfriendlysudoku.game.GameCell;
import org.secuso.privacyfriendlysudoku.controller.Symbol; import org.secuso.privacyfriendlysudoku.controller.Symbol;
import org.secuso.privacyfriendlysudoku.game.GameCell;
/** /**
* Created by TMZ_LToP on 10.11.2015. * Created by TMZ_LToP on 10.11.2015.
@ -116,6 +116,7 @@ public class SudokuCellView extends View {
drawBackground(canvas, 3, 3, mWidth - 3, mHeight - 3, p); drawBackground(canvas, 3, 3, mWidth - 3, mHeight - 3, p);
// if there is no mGameCell .. we can not retrieve the information to draw // if there is no mGameCell .. we can not retrieve the information to draw
if(mGameCell != null) { if(mGameCell != null) {
drawValue(canvas); drawValue(canvas);

View file

@ -10,14 +10,15 @@ import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import java.util.LinkedList;
import org.secuso.privacyfriendlysudoku.controller.GameController; import org.secuso.privacyfriendlysudoku.controller.GameController;
import org.secuso.privacyfriendlysudoku.controller.Symbol; import org.secuso.privacyfriendlysudoku.controller.Symbol;
import org.secuso.privacyfriendlysudoku.game.CellConflict;
import org.secuso.privacyfriendlysudoku.game.GameCell; import org.secuso.privacyfriendlysudoku.game.GameCell;
import org.secuso.privacyfriendlysudoku.game.ICellAction; import org.secuso.privacyfriendlysudoku.game.ICellAction;
import org.secuso.privacyfriendlysudoku.game.listener.IHighlightChangedListener; import org.secuso.privacyfriendlysudoku.game.listener.IHighlightChangedListener;
import java.util.LinkedList;
/** /**
* Created by Timm Lippert on 11.11.2015. * Created by Timm Lippert on 11.11.2015.
*/ */
@ -29,6 +30,7 @@ public class SudokuFieldLayout extends RelativeLayout implements IHighlightChang
private int gameCellWidth; private int gameCellWidth;
private int gameCellHeight; private int gameCellHeight;
private SharedPreferences settings; private SharedPreferences settings;
private Paint p = new Paint();
private OnTouchListener listener = new OnTouchListener() { private OnTouchListener listener = new OnTouchListener() {
@Override @Override
@ -46,14 +48,13 @@ public class SudokuFieldLayout extends RelativeLayout implements IHighlightChang
} }
}; };
private Paint p = new Paint();
public SudokuCellView [][] gamecells; public SudokuCellView [][] gamecells;
AttributeSet attrs; AttributeSet attrs;
public SudokuFieldLayout(Context context, AttributeSet attrs) { public SudokuFieldLayout(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
this.attrs=attrs; this.attrs=attrs;
setWillNotDraw(false);
setBackgroundColor(Color.argb(255, 200, 200, 200)); setBackgroundColor(Color.argb(255, 200, 200, 200));
} }
@ -198,6 +199,35 @@ public class SudokuFieldLayout extends RelativeLayout implements IHighlightChang
gamecells[i][j].invalidate(); gamecells[i][j].invalidate();
} }
} }
}
@Override
public void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
// draw error list
p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(4);
p.setColor(Color.RED);
for(CellConflict conflict : gameController.getErrorList()) {
//gamecells[conflict.getRowCell1()][conflict.getColCell1()].
int row = conflict.getRowCell1();
int col = conflict.getColCell1();
canvas.drawCircle(gameCellWidth * col + gameCellWidth / 2, gameCellHeight * row + gameCellHeight / 2, gameCellWidth/2 - gameCellWidth / 8, p);
int row2 = conflict.getRowCell2();
int col2 = conflict.getColCell2();
canvas.drawCircle(gameCellWidth * col2 + gameCellWidth / 2, gameCellHeight * row2 + gameCellHeight / 2, gameCellWidth/2 - gameCellWidth / 8, p);
canvas.drawLine(
gameCellWidth * col + gameCellWidth / 2,
gameCellHeight * row + gameCellHeight / 2,
gameCellWidth * col2 + gameCellWidth / 2,
gameCellHeight * row2 + gameCellHeight / 2, p);
}
} }
} }

View file

@ -39,7 +39,7 @@
<string name="hint_usage">Выбери поле которое должно быть решено.</string> <string name="hint_usage">Выбери поле которое должно быть решено.</string>
<string name="loadgame_delete_confirm">Удалить</string> <string name="loadgame_delete_confirm">Удалить</string>
<string name="loadgame_delete_confirmation">Ты уверен что хочеш удалить эту игру?</string> <string name="loadgame_delete_confirmation">Ты уверен что хочеш удалить эту игру?</string>
<string name="menu_about">О</string> <string name="menu_about">О нас</string>
<string name="menu_continue_game">Продолжить игру</string> <string name="menu_continue_game">Продолжить игру</string>
<string name="total_of_time">Общее время:</string> <string name="total_of_time">Общее время:</string>
<string name="title_activity_settings">Настройки</string> <string name="title_activity_settings">Настройки</string>
@ -72,4 +72,5 @@
<string name="menu_settings">Настройки</string> <string name="menu_settings">Настройки</string>
<string name="min_time">Лучшее время:</string> <string name="min_time">Лучшее время:</string>
<string name="more_info">Больше информации на:</string> <string name="more_info">Больше информации на:</string>
<string name="help_privacyInfo">Информация конфиденциальности</string>
</resources> </resources>