diff --git a/app/build.gradle b/app/build.gradle index a33aa16..df785b6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -17,6 +17,10 @@ android { proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } + + dataBinding { + enabled = true + } } dependencies { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 6ae66cc..e9f394d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,10 +8,9 @@ android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> - + - diff --git a/app/src/main/java/com/acme/tictactoe/controller/TicTacToeActivity.java b/app/src/main/java/com/acme/tictactoe/controller/TicTacToeActivity.java deleted file mode 100644 index 84ba558..0000000 --- a/app/src/main/java/com/acme/tictactoe/controller/TicTacToeActivity.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.acme.tictactoe.controller; - -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; - -import com.acme.tictactoe.R; - -public class TicTacToeActivity extends AppCompatActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.tictactoe); - } -} 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 e65bab0..b3919c9 100644 --- a/app/src/main/java/com/acme/tictactoe/model/Board.java +++ b/app/src/main/java/com/acme/tictactoe/model/Board.java @@ -22,6 +22,7 @@ public Board() { */ public void restart() { clearCells(); + winner = null; currentTurn = Player.X; state = GameState.IN_PROGRESS; } @@ -33,11 +34,17 @@ public void restart() { * * @param row 0..2 * @param col 0..2 + * @return the player that moved or null if we did not move anything. * */ - public void mark( int row, int col ) { + public Player mark( int row, int col ) { + + Player playerThatMoved = null; + if(isValid(row, col)) { + cells[row][col].setValue(currentTurn); + playerThatMoved = currentTurn; if(isWinningMoveByPlayer(currentTurn, row, col)) { state = GameState.FINISHED; @@ -48,6 +55,12 @@ public void mark( int row, int col ) { flipCurrentTurn(); } } + + return playerThatMoved; + } + + public Player valueAtCell(int row, int col) { + return cells[row][col].getValue(); } public Player getWinner() { 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 73130f8..3be3b79 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,3 @@ package com.acme.tictactoe.model; -enum Player { X , O } +public enum Player { X , O } diff --git a/app/src/main/java/com/acme/tictactoe/view/TicTacToeActivity.java b/app/src/main/java/com/acme/tictactoe/view/TicTacToeActivity.java new file mode 100644 index 0000000..a5a057b --- /dev/null +++ b/app/src/main/java/com/acme/tictactoe/view/TicTacToeActivity.java @@ -0,0 +1,61 @@ +package com.acme.tictactoe.view; + +import android.databinding.DataBindingUtil; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; + +import com.acme.tictactoe.R; +import com.acme.tictactoe.databinding.TictactoeBinding; +import com.acme.tictactoe.viewmodel.TicTacToeViewModel; + +public class TicTacToeActivity extends AppCompatActivity { + + TicTacToeViewModel viewModel = new TicTacToeViewModel(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + TictactoeBinding binding = DataBindingUtil.setContentView(this, R.layout.tictactoe); + binding.setViewModel(viewModel); + viewModel.onCreate(); + } + + @Override + protected void onPause() { + super.onPause(); + viewModel.onPause(); + } + + @Override + protected void onResume() { + super.onResume(); + viewModel.onResume(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + viewModel.onDestroy(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_tictactoe, menu); + return true; + } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_reset: + viewModel.onResetSelected(); + return true; + default: + return super.onOptionsItemSelected(item); + } + } + +} diff --git a/app/src/main/java/com/acme/tictactoe/viewmodel/TicTacToeViewModel.java b/app/src/main/java/com/acme/tictactoe/viewmodel/TicTacToeViewModel.java new file mode 100644 index 0000000..d37b334 --- /dev/null +++ b/app/src/main/java/com/acme/tictactoe/viewmodel/TicTacToeViewModel.java @@ -0,0 +1,52 @@ +package com.acme.tictactoe.viewmodel; + +import android.databinding.ObservableArrayMap; +import android.databinding.ObservableField; + +import com.acme.tictactoe.model.Board; +import com.acme.tictactoe.model.Player; + +public class TicTacToeViewModel implements ViewModel { + + private Board model; + + public final ObservableArrayMap cells = new ObservableArrayMap<>(); + public final ObservableField winner = new ObservableField<>(); + + public TicTacToeViewModel() { + model = new Board(); + } + + @Override + public void onCreate() { + + } + + @Override + public void onPause() { + + } + + @Override + public void onResume() { + + } + + @Override + public void onDestroy() { + + } + + public void onResetSelected() { + model.restart(); + winner.set(null); + cells.clear(); + } + + public void onClickedCellAt(int row, int col) { + Player playerThatMoved = model.mark(row, col); + cells.put("" + row + col, playerThatMoved == null ? null : playerThatMoved.toString()); + winner.set(model.getWinner() == null ? null : model.getWinner().toString()); + } + +} diff --git a/app/src/main/java/com/acme/tictactoe/viewmodel/ViewModel.java b/app/src/main/java/com/acme/tictactoe/viewmodel/ViewModel.java new file mode 100644 index 0000000..63bcc09 --- /dev/null +++ b/app/src/main/java/com/acme/tictactoe/viewmodel/ViewModel.java @@ -0,0 +1,10 @@ +package com.acme.tictactoe.viewmodel; + +public interface ViewModel { + + void onCreate(); + void onPause(); + void onResume(); + void onDestroy(); + +} diff --git a/app/src/main/res/layout/tictactoe.xml b/app/src/main/res/layout/tictactoe.xml index d97f0f8..e97c1e4 100644 --- a/app/src/main/res/layout/tictactoe.xml +++ b/app/src/main/res/layout/tictactoe.xml @@ -1,17 +1,104 @@ - - - - + xmlns:app="http://schemas.android.com/apk/res-auto"> + + + + + + + + + + +