Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

dataBinding {
enabled = true
}
}

dependencies {
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".controller.TicTacToeActivity">
<activity android:name=".view.TicTacToeActivity" android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Expand Down

This file was deleted.

15 changes: 14 additions & 1 deletion app/src/main/java/com/acme/tictactoe/model/Board.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public Board() {
*/
public void restart() {
clearCells();
winner = null;
currentTurn = Player.X;
state = GameState.IN_PROGRESS;
}
Expand All @@ -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 ) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was really nice!


Player playerThatMoved = null;

if(isValid(row, col)) {

cells[row][col].setValue(currentTurn);
playerThatMoved = currentTurn;

if(isWinningMoveByPlayer(currentTurn, row, col)) {
state = GameState.FINISHED;
Expand All @@ -48,6 +55,12 @@ public void mark( int row, int col ) {
flipCurrentTurn();
}
}

return playerThatMoved;
}

public Player valueAtCell(int row, int col) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point of that method?

return cells[row][col].getValue();
}

public Player getWinner() {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/acme/tictactoe/model/Player.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
package com.acme.tictactoe.model;

enum Player { X , O }
public enum Player { X , O }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it not only used on /model/

61 changes: 61 additions & 0 deletions app/src/main/java/com/acme/tictactoe/view/TicTacToeActivity.java
Original file line number Diff line number Diff line change
@@ -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);
}
}

}
Original file line number Diff line number Diff line change
@@ -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<String, String> cells = new ObservableArrayMap<>();
public final ObservableField<String> 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());
}

}
10 changes: 10 additions & 0 deletions app/src/main/java/com/acme/tictactoe/viewmodel/ViewModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.acme.tictactoe.viewmodel;

public interface ViewModel {

void onCreate();
void onPause();
void onResume();
void onDestroy();

}
117 changes: 102 additions & 15 deletions app/src/main/res/layout/tictactoe.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,104 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/tictactoe"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.acme.tictactoe.controller.TicTacToeActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
</RelativeLayout>
xmlns:app="http://schemas.android.com/apk/res-auto">

<data>
<import type="android.view.View" />
<variable name="viewModel" type="com.acme.tictactoe.viewmodel.TicTacToeViewModel" />
</data>

<LinearLayout
android:id="@+id/tictactoe"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.acme.tictactoe.view.TicTacToeActivity">

<GridLayout
android:id="@+id/buttonGrid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnCount="3"
android:rowCount="3">

<Button
style="@style/tictactoebutton"
android:onClick="@{() -> viewModel.onClickedCellAt(0,0)}"
android:text='@{viewModel.cells["00"]}' />

<Button
style="@style/tictactoebutton"
android:onClick="@{() -> viewModel.onClickedCellAt(0,1)}"
android:text='@{viewModel.cells["01"]}' />

<Button
style="@style/tictactoebutton"
android:onClick="@{() -> viewModel.onClickedCellAt(0,2)}"
android:text='@{viewModel.cells["02"]}' />

<Button
style="@style/tictactoebutton"
android:onClick="@{() -> viewModel.onClickedCellAt(1,0)}"
android:text='@{viewModel.cells["10"]}' />

<Button
style="@style/tictactoebutton"
android:onClick="@{() -> viewModel.onClickedCellAt(1,1)}"
android:text='@{viewModel.cells["11"]}' />

<Button
style="@style/tictactoebutton"
android:onClick="@{() -> viewModel.onClickedCellAt(1,2)}"
android:text='@{viewModel.cells["12"]}' />

<Button
style="@style/tictactoebutton"
android:onClick="@{() -> viewModel.onClickedCellAt(2,0)}"
android:text='@{viewModel.cells["20"]}' />

<Button
style="@style/tictactoebutton"
android:onClick="@{() -> viewModel.onClickedCellAt(2,1)}"
android:text='@{viewModel.cells["21"]}' />

<Button
style="@style/tictactoebutton"
android:onClick="@{() -> viewModel.onClickedCellAt(2,2)}"
android:text='@{viewModel.cells["22"]}' />

</GridLayout>

<LinearLayout
android:id="@+id/winnerPlayerViewGroup"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:visibility="@{viewModel.winner != null ? View.VISIBLE : View.GONE}"
tools:visibility="visible">

<TextView
android:id="@+id/winnerPlayerLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:textSize="40sp"
android:text="@{viewModel.winner}"
tools:text="X" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/winner"
android:textSize="30sp" />

</LinearLayout>

</LinearLayout>
</layout>
11 changes: 11 additions & 0 deletions app/src/main/res/menu/menu_tictactoe.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".view.TicTacToeActivity">

<item android:id="@+id/action_reset"
android:title="@string/action_reset"
android:orderInCategory="100"
app:showAsAction="ifRoom" />

</menu>
2 changes: 1 addition & 1 deletion app/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="activity_vertical_margin">44dp</dimen>
</resources>
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<resources>
<string name="app_name">TicTacToe</string>
<string name="winner">Winner</string>
<string name="action_reset">Reset</string>
</resources>
6 changes: 6 additions & 0 deletions app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,10 @@
<item name="colorAccent">@color/colorAccent</item>
</style>

<style name="tictactoebutton">
<item name="android:layout_width">100dp</item>
<item name="android:layout_height">100dp</item>
<item name="android:textSize">30sp</item>
</style>

</resources>
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.acme.tictactoe.model;

import android.os.Build;

import org.junit.Before;
import org.junit.Test;

Expand Down Expand Up @@ -48,7 +46,7 @@ public void test3inRowAcrossTopForX() {


/**
* This test will simulate and verify x is the winner.
* This test will simulate and verify o is the winner.
*
* O | X | X
* | O |
Expand Down
Loading