diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e9f394d..5ec53a6 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,7 +8,7 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - + diff --git a/app/src/main/java/com/acme/tictactoe/model/Board.java b/app/src/main/java/com/acme/tictactoe/model/Board.java index b3919c9..50aaaf0 100644 --- a/app/src/main/java/com/acme/tictactoe/model/Board.java +++ b/app/src/main/java/com/acme/tictactoe/model/Board.java @@ -1,9 +1,12 @@ package com.acme.tictactoe.model; +import android.os.Parcel; +import android.os.Parcelable; + import static com.acme.tictactoe.model.Player.O; import static com.acme.tictactoe.model.Player.X; -public class Board { +public class Board implements Parcelable { private Cell[][] cells = new Cell[3][3]; @@ -11,12 +14,58 @@ public class Board { private GameState state; private Player currentTurn; - private enum GameState { IN_PROGRESS, FINISHED }; + private enum GameState { IN_PROGRESS, FINISHED } public Board() { restart(); } + private Board(Parcel in) + { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + cells[i][j].setValue(Player.fromInt(in.readInt())); + } + } + winner = Player.fromInt(in.readInt()); + state = (in.readInt() == 0 ? GameState.IN_PROGRESS : GameState.FINISHED); + currentTurn = Player.fromInt(in.readInt()); + } + + @Override + public void writeToParcel(Parcel dest, int flags) + { + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + dest.writeInt(cells[i][j].getValue().id); + } + } + dest.writeInt(winner.id); + dest.writeInt(state.ordinal()); + dest.writeInt(currentTurn.id); + } + + @Override + public int describeContents() + { + return 0; + } + + public static final Creator CREATOR = new Creator() + { + @Override + public Board createFromParcel(Parcel in) + { + return new Board(in); + } + + @Override + public Board[] newArray(int size) + { + return new Board[size]; + } + }; + /** * Restart or start a new game, will clear the board and win status */ diff --git a/app/src/main/java/com/acme/tictactoe/model/Cell.java b/app/src/main/java/com/acme/tictactoe/model/Cell.java index 16125e9..ff9f562 100644 --- a/app/src/main/java/com/acme/tictactoe/model/Cell.java +++ b/app/src/main/java/com/acme/tictactoe/model/Cell.java @@ -4,10 +4,38 @@ * Created by ericmaxwell on 1/19/17. */ -public class Cell { +import android.os.Parcel; +import android.os.Parcelable; + +public class Cell implements Parcelable +{ private Player value; + protected Cell(Parcel in) + { + value = Player.fromInt(in.readInt()); + } + + public static final Creator CREATOR = new Creator() + { + @Override + public Cell createFromParcel(Parcel in) + { + return new Cell(in); + } + + @Override + public Cell[] newArray(int size) + { + return new Cell[size]; + } + }; + + public Cell() + { + } + public Player getValue() { return value; } @@ -15,4 +43,16 @@ public Player getValue() { public void setValue(Player value) { this.value = value; } -} + + @Override + public int describeContents() + { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) + { + dest.writeInt(value.id); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/acme/tictactoe/model/Player.java b/app/src/main/java/com/acme/tictactoe/model/Player.java index 3be3b79..16e31ba 100644 --- a/app/src/main/java/com/acme/tictactoe/model/Player.java +++ b/app/src/main/java/com/acme/tictactoe/model/Player.java @@ -1,3 +1,29 @@ package com.acme.tictactoe.model; -public enum Player { X , O } +import android.util.SparseArray; + +public enum Player { + X(0), + O(1), + NO(2); + + int id; + + Player(int id) + { + this.id = id; + } + + static SparseArray cache; + + static Player fromInt(int id) { + if (cache == null) { + cache = new SparseArray<>(); + Player[] players = Player.values(); + for (Player value : players) { + cache.put(value.id, value); + } + } + return cache.get(id); + } +} diff --git a/app/src/main/java/com/acme/tictactoe/view/TicTacToeActivity.java b/app/src/main/java/com/acme/tictactoe/view/TicTacToeActivity.java index a5a057b..975c2f3 100644 --- a/app/src/main/java/com/acme/tictactoe/view/TicTacToeActivity.java +++ b/app/src/main/java/com/acme/tictactoe/view/TicTacToeActivity.java @@ -21,6 +21,10 @@ protected void onCreate(Bundle savedInstanceState) { TictactoeBinding binding = DataBindingUtil.setContentView(this, R.layout.tictactoe); binding.setViewModel(viewModel); viewModel.onCreate(); + + if (savedInstanceState != null) { + viewModel.loadFromSavedInstanceState(savedInstanceState); + } } @Override @@ -35,6 +39,13 @@ protected void onResume() { viewModel.onResume(); } + @Override + protected void onSaveInstanceState(Bundle outState) + { + super.onSaveInstanceState(outState); + viewModel.onSaveInstanceState(outState); + } + @Override protected void onDestroy() { super.onDestroy(); diff --git a/app/src/main/java/com/acme/tictactoe/viewmodel/TicTacToeViewModel.java b/app/src/main/java/com/acme/tictactoe/viewmodel/TicTacToeViewModel.java index d37b334..91213f3 100644 --- a/app/src/main/java/com/acme/tictactoe/viewmodel/TicTacToeViewModel.java +++ b/app/src/main/java/com/acme/tictactoe/viewmodel/TicTacToeViewModel.java @@ -2,12 +2,15 @@ import android.databinding.ObservableArrayMap; import android.databinding.ObservableField; +import android.os.Bundle; import com.acme.tictactoe.model.Board; import com.acme.tictactoe.model.Player; public class TicTacToeViewModel implements ViewModel { + private static final String SAVED_TTT_VIEWMODEL = "TicTacToeViewModel_SaveBundle"; + private Board model; public final ObservableArrayMap cells = new ObservableArrayMap<>(); @@ -32,6 +35,29 @@ public void onResume() { } + @Override + public void onSaveInstanceState(Bundle bundle) + { + bundle.putParcelable(SAVED_TTT_VIEWMODEL, model); + } + + @Override + public void loadFromSavedInstanceState(Bundle bundle) + { + model = bundle.getParcelable(SAVED_TTT_VIEWMODEL); + // update the view + if (model != null) { + for (int row = 0; row < 3; row++) { + for (int col = 0; col < 3; col++) { + if (model.valueAtCell(row, col) != null) { + cells.put("" + row + col, model.valueAtCell(row, col).toString()); + } + } + } + winner.set(model.getWinner() == null ? null : model.getWinner().toString()); + } + } + @Override public void onDestroy() { diff --git a/app/src/main/java/com/acme/tictactoe/viewmodel/ViewModel.java b/app/src/main/java/com/acme/tictactoe/viewmodel/ViewModel.java index 63bcc09..9fb5a7d 100644 --- a/app/src/main/java/com/acme/tictactoe/viewmodel/ViewModel.java +++ b/app/src/main/java/com/acme/tictactoe/viewmodel/ViewModel.java @@ -1,10 +1,17 @@ package com.acme.tictactoe.viewmodel; +import android.os.Bundle; + public interface ViewModel { void onCreate(); void onPause(); void onResume(); + + void onSaveInstanceState(Bundle bundle); + + void loadFromSavedInstanceState(Bundle bundle); + void onDestroy(); }