From 5e8c1bd2b1fff11deb6513b4700117bad81f137b Mon Sep 17 00:00:00 2001 From: Gongxter Date: Thu, 26 Nov 2015 13:21:44 +0100 Subject: [PATCH] Stats added --- app/src/main/AndroidManifest.xml | 6 + .../sudoku/controller/GameController.java | 19 + .../sudoku/controller/SaveLoadStatistics.java | 127 ++++++- .../helper/HighscoreInfoContainer.java | 131 ++++++- .../controller/helper/TimeContainer.java | 14 - .../sudoku/game/listeners/IStatsListener.java | 8 + .../tu_darmstadt/sudoku/ui/GameActivity.java | 9 +- .../tu_darmstadt/sudoku/ui/MainActivity.java | 2 +- .../tu_darmstadt/sudoku/ui/StatsActivity.java | 272 +++++++++++++++ .../ui/view/SudokuSpecialButtonLayout.java | 6 +- app/src/main/res/layout/activity_stats.xml | 31 ++ app/src/main/res/layout/fragment_stats.xml | 327 ++++++++++++++++++ app/src/main/res/menu/menu_stats.xml | 9 + app/src/main/res/values/strings.xml | 13 + 14 files changed, 948 insertions(+), 26 deletions(-) delete mode 100644 app/src/main/java/tu_darmstadt/sudoku/controller/helper/TimeContainer.java create mode 100644 app/src/main/java/tu_darmstadt/sudoku/game/listeners/IStatsListener.java create mode 100644 app/src/main/java/tu_darmstadt/sudoku/ui/StatsActivity.java create mode 100644 app/src/main/res/layout/activity_stats.xml create mode 100644 app/src/main/res/layout/fragment_stats.xml create mode 100644 app/src/main/res/menu/menu_stats.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1fe669b..d97885d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,7 @@ android:theme="@style/AppTheme.NoActionBar" > + @@ -32,6 +33,11 @@ + + diff --git a/app/src/main/java/tu_darmstadt/sudoku/controller/GameController.java b/app/src/main/java/tu_darmstadt/sudoku/controller/GameController.java index 0724abe..d8ff5d7 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/controller/GameController.java +++ b/app/src/main/java/tu_darmstadt/sudoku/controller/GameController.java @@ -28,6 +28,7 @@ public class GameController implements IModelChangedListener { private int size; private int sectionHeight; private int sectionWidth; + private int numbOfHints=0; private GameBoard gameBoard; private int[] solution; private GameType gameType; @@ -143,6 +144,21 @@ public class GameController implements IModelChangedListener { return solution; } + /*public boolean loadLevel(GameBoard level) { + if(GameBoard.isValid(level)) { + gameBoard = level; + } + }*/ + + public void hint(){ + + int[] solved = solve(); + // TODO test every placed value so far + // and reveal the selected value. + selectValue(solved[selectedRow * getSize() + selectedCol]); + numbOfHints++; + } + private void setGameType(GameType type) { this.gameType = type; this.size = type.getSize(); @@ -441,6 +457,9 @@ public class GameController implements IModelChangedListener { timerListeners.add(listener); } } + public int getNumbOfHints(){ + return numbOfHints; + } private void initTimer() { timerTask = new TimerTask() { diff --git a/app/src/main/java/tu_darmstadt/sudoku/controller/SaveLoadStatistics.java b/app/src/main/java/tu_darmstadt/sudoku/controller/SaveLoadStatistics.java index 0d4071b..3d35999 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/controller/SaveLoadStatistics.java +++ b/app/src/main/java/tu_darmstadt/sudoku/controller/SaveLoadStatistics.java @@ -1,14 +1,135 @@ package tu_darmstadt.sudoku.controller; -import tu_darmstadt.sudoku.controller.helper.TimeContainer; +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import tu_darmstadt.sudoku.controller.helper.GameInfoContainer; +import tu_darmstadt.sudoku.controller.helper.HighscoreInfoContainer; import tu_darmstadt.sudoku.game.GameDifficulty; +import tu_darmstadt.sudoku.game.GameType; /** * Created by TMZ_LToP on 19.11.2015. */ public class SaveLoadStatistics { - //GameDifficulty, time, gamemode, #hints, AvTime, amountOf Games per GameDifficulty, - public SaveLoadStatistics(TimeContainer t,GameDifficulty difficulty,int hints){ + + + private static String FILE_EXTENSION = ".txt"; + private static String SAVE_PREFIX = "stat"; + private static String SAVES_DIR = "stats"; + + Context context; + private int numberOfArguents = 2; + + //GameDifficulty, time, gamemode, #hints, AvTime, amountOf Games per GameDifficulty, + public SaveLoadStatistics(Context context){ + this.context = context; + } + + public List loadStats(GameType t) { + File dir = context.getDir(SAVES_DIR, 0); + List difficulties = GameDifficulty.getValidDifficultyList(); + List result = new ArrayList<>(); + HighscoreInfoContainer infos; + byte[] bytes; + FileInputStream inputStream; + File file; + for (GameDifficulty dif : difficulties){ + file = new File(dir,SAVE_PREFIX+t.name()+"_"+dif.name()+FILE_EXTENSION); + bytes = new byte[(int)file.length()]; + try { + inputStream = new FileInputStream(file); + try { + inputStream.read(bytes); + }finally { + inputStream.close(); + } + } catch (IOException e) { + Log.e("Failed to read file","File could not be read"); + } + infos = new HighscoreInfoContainer(t,dif); + infos.setInfosFromFile(new String(bytes)); + result.add(infos); + } + + + + return result; + } + + public static void resetStats(Context context) { + + + File dir = context.getDir(SAVES_DIR, 0); + File file; + for(GameType t: GameType.getValidGameTypes()){ + for(GameDifficulty d : GameDifficulty.getValidDifficultyList()){ + file = new File(dir,SAVE_PREFIX+t.name()+"_"+d.name()+FILE_EXTENSION); + file.delete(); + } + } } + + + public void saveGameStats(GameController gameController) { + + + HighscoreInfoContainer infoContainer = new HighscoreInfoContainer(); + + // Read existing stats + File dir = context.getDir(SAVES_DIR, 0); + + File file = new File(dir, SAVE_PREFIX+gameController.getGameType().name()+"_"+gameController.getDifficulty().name()+FILE_EXTENSION); + + + if (file.isFile()){ + byte[] bytes = new byte[(int)file.length()]; + try { + FileInputStream stream = new FileInputStream(file); + try { + stream.read(bytes); + } finally { + stream.close(); + } + }catch (IOException e) { + Log.e("Stats load to save game","error while load old game Stats"); + } + + String fileStats = new String(bytes); + if (!fileStats.isEmpty()) { + try { + infoContainer.setInfosFromFile(fileStats); + + } catch (IllegalArgumentException e) { + Log.e("Parse Error","Illegal Atgumanet"); + } + } + + } + + //add stats of current game stats or create init stats + infoContainer.add(gameController); + + String stats = infoContainer.getActualStats(); + try { + FileOutputStream stream = new FileOutputStream(file); + try { + stream.write(stats.getBytes()); + } finally { + stream.close(); + } + } catch(IOException e) { + Log.e("File Manager", "Could not save game. IOException occured."); + } + } } diff --git a/app/src/main/java/tu_darmstadt/sudoku/controller/helper/HighscoreInfoContainer.java b/app/src/main/java/tu_darmstadt/sudoku/controller/helper/HighscoreInfoContainer.java index c57dd31..789724c 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/controller/helper/HighscoreInfoContainer.java +++ b/app/src/main/java/tu_darmstadt/sudoku/controller/helper/HighscoreInfoContainer.java @@ -1,8 +1,137 @@ package tu_darmstadt.sudoku.controller.helper; +import tu_darmstadt.sudoku.controller.GameController; +import tu_darmstadt.sudoku.game.GameDifficulty; +import tu_darmstadt.sudoku.game.GameType; + /** * Created by Chris on 18.11.2015. */ + public class HighscoreInfoContainer { - //TODO: Holds the data for Highscores. + + private GameType type = null; + private GameDifficulty difficulty = null; + private int minTime = Integer.MAX_VALUE; + private int time=0; + private int numberOfHintsUsed =0; + private int numberOfGames=0; + + private int amountOfSavedArguments = 6; + + public HighscoreInfoContainer(){ + + } + public HighscoreInfoContainer(GameType t, GameDifficulty diff){ + type =(type == null)?t:type; + difficulty = (difficulty == null)?diff: difficulty; + } + + public void add(GameController gc){ + //add all wanted Game Stats + difficulty = (difficulty== null)?gc.getDifficulty():difficulty; + type = (type == null)?gc.getGameType():type; + time += gc.getTime(); + numberOfHintsUsed += gc.getNumbOfHints(); + numberOfGames++; + minTime = (gc.getTime()< minTime) ? gc.getTime() : minTime; + } + + public void setInfosFromFile(String s){ + if(s.isEmpty()) return; + String [] strings = s.split("/"); + if (strings.length != amountOfSavedArguments) { + throw new IllegalArgumentException("Argument Exception"); + } + try { + time = parseTime(strings[0]); + numberOfHintsUsed = parseHints(strings[1]); + numberOfGames = parseNumberOfGames(strings[2]); + minTime = parseTime(strings[3]); + type = parseGameType(strings[4]); + difficulty = parsDifficulty(strings[5]); + } catch (IllegalArgumentException e){ + throw new IllegalArgumentException("Could not set Infoprmation illegal Arguments"); + } + } + + public GameDifficulty getDifficulty(){ + return difficulty; + } + public GameType getGameType(){ + return type; + } + public int getTime(){ + return time; + } + public int getMinTime(){ + return minTime; + } + public int getNumberOfHintsUsed(){ + return numberOfHintsUsed; + } + public int getNumberOfGames(){ + return numberOfGames; + } + + private GameType parseGameType(String s){ + return GameType.valueOf(s); + } + private GameDifficulty parsDifficulty(String s) { + return GameDifficulty.valueOf(s); + } + + private int parseTime(String s){ + int ret = Integer.valueOf(s); + if (ret<0){ + throw new IllegalArgumentException("Parser Exception wrong Integer"); + } + return ret; + } + private int parseHints(String s){ + int ret = Integer.valueOf(s); + if (ret<0){ + throw new IllegalArgumentException("Parser Exception wrong Integer"); + } + return ret; + + } + private int parseNumberOfGames(String s) { + int ret = Integer.valueOf(s); + if (ret<0){ + throw new IllegalArgumentException("Parser Exception wrong Integer"); + } + return ret; + } + + public String getActualStats(){ + StringBuilder sb = new StringBuilder(); + sb.append(time); + sb.append("/"); + sb.append(numberOfHintsUsed); + sb.append("/"); + sb.append(numberOfGames); + sb.append("/"); + sb.append(minTime); + sb.append("/"); + sb.append(type.name()); + sb.append("/"); + sb.append(difficulty.name()); + + + return sb.toString(); + } + + public static String getStats(int time,GameDifficulty gd, int numberOfHints, GameType gt){ + StringBuilder sb = new StringBuilder(); + sb.append(time); + sb.append("/"); + sb.append(gd.name()); + sb.append("/"); + sb.append(numberOfHints); + sb.append("/"); + sb.append(gt.name()); + + return sb.toString(); + } } diff --git a/app/src/main/java/tu_darmstadt/sudoku/controller/helper/TimeContainer.java b/app/src/main/java/tu_darmstadt/sudoku/controller/helper/TimeContainer.java deleted file mode 100644 index 3463648..0000000 --- a/app/src/main/java/tu_darmstadt/sudoku/controller/helper/TimeContainer.java +++ /dev/null @@ -1,14 +0,0 @@ -package tu_darmstadt.sudoku.controller.helper; - -/** - * Created by TMZ_LToP on 19.11.2015. - */ -public class TimeContainer { - int hours,minutes,seconds; - public TimeContainer(int hours, int minutes, int seconds){ - this.hours=hours; - this.minutes=minutes; - this.seconds=seconds; - } - -} diff --git a/app/src/main/java/tu_darmstadt/sudoku/game/listeners/IStatsListener.java b/app/src/main/java/tu_darmstadt/sudoku/game/listeners/IStatsListener.java new file mode 100644 index 0000000..ec479d6 --- /dev/null +++ b/app/src/main/java/tu_darmstadt/sudoku/game/listeners/IStatsListener.java @@ -0,0 +1,8 @@ +package tu_darmstadt.sudoku.game.listeners; + +/** + * Created by TMZ_LToP on 25.11.2015. + */ +public interface IStatsListener { + public void refresh(); +} diff --git a/app/src/main/java/tu_darmstadt/sudoku/ui/GameActivity.java b/app/src/main/java/tu_darmstadt/sudoku/ui/GameActivity.java index 74edbd9..8bdccad 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/ui/GameActivity.java +++ b/app/src/main/java/tu_darmstadt/sudoku/ui/GameActivity.java @@ -20,8 +20,10 @@ import java.util.List; import tu_darmstadt.sudoku.controller.GameStateManager; import tu_darmstadt.sudoku.controller.GameController; +import tu_darmstadt.sudoku.controller.SaveLoadStatistics; import tu_darmstadt.sudoku.controller.helper.GameInfoContainer; import tu_darmstadt.sudoku.game.GameDifficulty; +import tu_darmstadt.sudoku.game.GameStatus; import tu_darmstadt.sudoku.game.GameType; import tu_darmstadt.sudoku.game.listener.IGameSolvedListener; import tu_darmstadt.sudoku.game.listener.ITimerListener; @@ -198,8 +200,9 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On case R.id.nav_highscore: // see highscore list - //intent = new Intent(this, HighscoreActivity.class); - //startActivity(intent); + + intent = new Intent(this, StatsActivity.class); + startActivity(intent); break; case R.id.menu_about: @@ -225,6 +228,8 @@ public class GameActivity extends AppCompatActivity implements NavigationView.On public void onSolved() { Toast t = Toast.makeText(this,"Congratulations you have solved the puzzle!", Toast.LENGTH_SHORT); t.show(); + SaveLoadStatistics s = new SaveLoadStatistics(this); + s.saveGameStats(gameController); // TODO: WE WON.. do something awesome :) } diff --git a/app/src/main/java/tu_darmstadt/sudoku/ui/MainActivity.java b/app/src/main/java/tu_darmstadt/sudoku/ui/MainActivity.java index bf10752..be15ffe 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/ui/MainActivity.java +++ b/app/src/main/java/tu_darmstadt/sudoku/ui/MainActivity.java @@ -120,7 +120,7 @@ public class MainActivity extends AppCompatActivity { i = new Intent(this, LoadGameActivity.class); break; case R.id.highscoreButton: - // TODO: create highscore screen + i = new Intent(this,StatsActivity.class); break; case R.id.settingsButton: i = new Intent(this, SettingsActivity.class); diff --git a/app/src/main/java/tu_darmstadt/sudoku/ui/StatsActivity.java b/app/src/main/java/tu_darmstadt/sudoku/ui/StatsActivity.java new file mode 100644 index 0000000..8610011 --- /dev/null +++ b/app/src/main/java/tu_darmstadt/sudoku/ui/StatsActivity.java @@ -0,0 +1,272 @@ +package tu_darmstadt.sudoku.ui; + +import android.content.Context; +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.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; + +import android.widget.ImageView; +import android.widget.RatingBar; +import android.widget.TextView; + +import java.util.List; + +import tu_darmstadt.sudoku.controller.SaveLoadStatistics; +import tu_darmstadt.sudoku.controller.helper.HighscoreInfoContainer; +import tu_darmstadt.sudoku.game.GameType; +import tu_darmstadt.sudoku.ui.view.R; + +public class StatsActivity extends AppCompatActivity { + + /** + * The {@link android.support.v4.view.PagerAdapter} that will provide + * fragments for each of the sections. We use a + * {@link FragmentPagerAdapter} derivative, which will keep every + * loaded fragment in memory. If this becomes too memory intensive, it + * may be best to switch to a + * {@link android.support.v4.app.FragmentStatePagerAdapter}. + */ + private SectionsPagerAdapter mSectionsPagerAdapter; + + /** + * The {@link ViewPager} that will host the section contents. + */ + private ViewPager mViewPager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_stats); + + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + // Create the adapter that will return a fragment for each of the three + // primary sections of the activity. + mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); + + // Set up the ViewPager with the sections adapter. + mViewPager = (ViewPager) findViewById(R.id.container); + mViewPager.setAdapter(mSectionsPagerAdapter); + + TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs); + tabLayout.setupWithViewPager(mViewPager); + + } + + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_stats, menu); + //getMenuInflater().inflate(R.menu.menu_stats, menu); + return true; + //return false; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_reset) { + SaveLoadStatistics.resetStats(this); + mSectionsPagerAdapter.refresh(this); + return true; + } + + return super.onOptionsItemSelected(item); + } + + + /** + * A {@link FragmentPagerAdapter} that returns a fragment corresponding to + * one of the sections/tabs/pages. + */ + public class SectionsPagerAdapter extends FragmentPagerAdapter { + + + private FragmentManager fm; + + public SectionsPagerAdapter(FragmentManager fm) { + super(fm); + this.fm = fm; + } + + @Override + public Fragment getItem(int position) { + // getItem is called to instantiate the fragment for the given page. + // Return a PlaceholderFragment (defined as a static inner class below). + + return PlaceholderFragment.newInstance(position); + } + + @Override + public int getCount() { + return GameType.getValidGameTypes().size(); + } + + @Override + public CharSequence getPageTitle(int position) { + return getString(GameType.getValidGameTypes().get(position).getStringResID()); + } + public void refresh(Context context){ + for (Fragment f : fm.getFragments()){ + if(f instanceof PlaceholderFragment){ + ((PlaceholderFragment) f).refresh(context); + } + } + } + } + + /** + * A placeholder fragment containing a simple view. + */ + public static class PlaceholderFragment extends Fragment { + /** + * The fragment argument representing the section number for this + * fragment. + */ + private static final String ARG_SECTION_NUMBER = "section_number"; + private View rootView; + private TextView difficultyView,averageTimeView,minTimeView; + private RatingBar difficultyBarView; + private String s; + private int totalTime =0; + private int totalGames =0; + private int totalHints =0; + + + /** + * Returns a new instance of this fragment for the given section + * number. + */ + public static PlaceholderFragment newInstance(int sectionNumber) { + PlaceholderFragment fragment = new PlaceholderFragment(); + Bundle args = new Bundle(); + args.putInt(ARG_SECTION_NUMBER, sectionNumber); + fragment.setArguments(args); + return fragment; + } + + public void refresh(Context context){ + resetGeneral(); + SaveLoadStatistics s = new SaveLoadStatistics(context); + List stats = s.loadStats(GameType.getValidGameTypes().get(getArguments().getInt(ARG_SECTION_NUMBER))); + int j =0; + for (HighscoreInfoContainer i : stats){ + updateGeneralIfo(i.getTime(), i.getNumberOfGames(), i.getNumberOfHintsUsed()); + setStats(i,j++); + } + setGeneralInfo(); + } + + private void resetGeneral(){ + totalTime=0; + totalHints=0; + totalGames=0; + } + + public PlaceholderFragment() { + } + + + private String formatTime(int totalTime){ + int seconds = totalTime % 60; + int minutes = ((totalTime -seconds)/60)%60 ; + int hours = (totalTime - minutes - seconds)/(3600); + String h,m,s; + s = (seconds< 10)? "0"+String.valueOf(seconds):String.valueOf(seconds); + m = (minutes< 10)? "0"+String.valueOf(minutes):String.valueOf(minutes); + h = (hours< 10)? "0"+String.valueOf(hours):String.valueOf(hours); + return (h + ":" + m + ":" + s); + + } + private void updateGeneralIfo(int time, int games, int hints){ + totalHints +=hints; + totalGames +=games; + totalTime +=time; + } + private void setGeneralInfo(){ + TextView generalInfoView; + + generalInfoView = (TextView)rootView.findViewById(R.id.numb_of_hints); + generalInfoView.setText(String.valueOf(totalHints)); + generalInfoView = (TextView)rootView.findViewById(R.id.numb_of_total_games); + generalInfoView.setText(String.valueOf(totalGames)); + generalInfoView = (TextView)rootView.findViewById(R.id.numb_of_total_time); + generalInfoView.setText(formatTime(totalTime)); + + } + + private void setStats(HighscoreInfoContainer infos, int pos){ + + switch (pos) { + case 0 : + difficultyBarView = (RatingBar) rootView.findViewById(R.id.first_diff_bar); + difficultyView = (TextView) rootView.findViewById(R.id.first_diff_text); + averageTimeView = (TextView) rootView.findViewById(R.id.first_ava_time); + minTimeView = (TextView) rootView.findViewById(R.id.first_min_time); + break; + case 1: + difficultyBarView = (RatingBar) rootView.findViewById(R.id.second_diff_bar); + difficultyView = (TextView) rootView.findViewById(R.id.second_diff_text); + averageTimeView = (TextView) rootView.findViewById(R.id.second_ava_time); + minTimeView = (TextView) rootView.findViewById(R.id.second_min_time); + break; + case 2: + difficultyBarView = (RatingBar) rootView.findViewById(R.id.third_diff_bar); + difficultyView = (TextView) rootView.findViewById(R.id.third_diff_text); + averageTimeView = (TextView) rootView.findViewById(R.id.third_ava_time); + minTimeView = (TextView) rootView.findViewById(R.id.third_min_time); + break; + default: return; + } + difficultyBarView.setRating(pos+1); + difficultyView.setText(rootView.getResources().getString(infos.getDifficulty().getStringResID())); + s= (infos.getTime() == 0)?"/":String.valueOf(infos.getTime() / infos.getNumberOfGames()); + averageTimeView.setText(s); + s = (infos.getMinTime()==Integer.MAX_VALUE)? "/":String.valueOf(infos.getMinTime()); + minTimeView.setText(s); + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + View rootView = inflater.inflate(R.layout.fragment_stats, container, false); + this.rootView = rootView; + TextView textView = (TextView) rootView.findViewById(R.id.section_label); + + SaveLoadStatistics s = new SaveLoadStatistics(this.getContext()); + List stats = s.loadStats(GameType.getValidGameTypes().get(getArguments().getInt(ARG_SECTION_NUMBER))); + + + int j =0; + for (HighscoreInfoContainer i : stats){ + updateGeneralIfo(i.getTime(), i.getNumberOfGames(), i.getNumberOfHintsUsed()); + setStats(i,j++); + } + setGeneralInfo(); + + ImageView imageView = (ImageView) rootView.findViewById(R.id.statistic_image); + imageView.setImageResource(GameType.getValidGameTypes().get(getArguments().getInt(ARG_SECTION_NUMBER)).getResIDImage()); + + return rootView; + } + } +} diff --git a/app/src/main/java/tu_darmstadt/sudoku/ui/view/SudokuSpecialButtonLayout.java b/app/src/main/java/tu_darmstadt/sudoku/ui/view/SudokuSpecialButtonLayout.java index 7953361..f3daf60 100644 --- a/app/src/main/java/tu_darmstadt/sudoku/ui/view/SudokuSpecialButtonLayout.java +++ b/app/src/main/java/tu_darmstadt/sudoku/ui/view/SudokuSpecialButtonLayout.java @@ -51,11 +51,7 @@ public class SudokuSpecialButtonLayout extends LinearLayout { break; case Hint: if(gameController.isValidCellSelected()) { - int[] solved = gameController.solve(); - // TODO test every placed value so far? Or just reveal current selected? - - // and reveal the selected value. - gameController.selectValue(solved[row * gameController.getSize() + col]); + gameController.hint(); } break; case NumberOrCellFirst: diff --git a/app/src/main/res/layout/activity_stats.xml b/app/src/main/res/layout/activity_stats.xml new file mode 100644 index 0000000..9cfec92 --- /dev/null +++ b/app/src/main/res/layout/activity_stats.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/fragment_stats.xml b/app/src/main/res/layout/fragment_stats.xml new file mode 100644 index 0000000..6f782fd --- /dev/null +++ b/app/src/main/res/layout/fragment_stats.xml @@ -0,0 +1,327 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/menu/menu_stats.xml b/app/src/main/res/menu/menu_stats.xml new file mode 100644 index 0000000..db2b079 --- /dev/null +++ b/app/src/main/res/menu/menu_stats.xml @@ -0,0 +1,9 @@ + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index fe0a79f..2a9a99f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -61,11 +61,24 @@ Standart Sudoku 12x12 X Sudoku 9x9 Hyper Sudoku 9x9 + StatsGameActivity + Hello World from section: %1$d Are you sure you want to delete this save? Delete Cancel + StatsActivity + + + Statistics + Number of Hints Used: + #Games: + Total time Played: + Av time: + Min time: + reset stats +