Commit f38545e9 authored by Shaun Burch's avatar Shaun Burch 💻

#2 Added classes for Board, Update, and BoardMapper; Add drawables for X, O;

parent c038fd83
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/classes" />
</component>
</project>
\ No newline at end of file
......@@ -17,10 +17,14 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
implementation 'com.android.support:design:27.1.1'
......
......@@ -8,7 +8,7 @@ public class Board {
private static final String TAG = Board.class.getSimpleName();
private Mark[][] mCells;
public Board() {
Board() {
mCells = new Mark[][]{
{Mark.EMPTY, Mark.EMPTY, Mark.EMPTY},
{Mark.EMPTY, Mark.EMPTY, Mark.EMPTY},
......@@ -16,10 +16,20 @@ public class Board {
};
}
public void markCell(Mark mark, int cellX, int cellY) {
// TODO Check if cell is empty, throw if not
mCells[cellY][cellX] = mark;
boolean markCell(Mark mark, int cellX, int cellY) {
// Check if cell is empty, return false if not
if(mCells[cellY][cellX] != Mark.EMPTY) {
return false;
}
try {
mCells[cellY][cellX] = mark;
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, String.format("Cell {x: %1d, y: %2d} is out of bounds!", cellX, cellY));
}
Log.d(TAG, Arrays.deepToString(mCells));
return true;
}
public Mark[][] getCells() {
......
package com.example.tictactoe;
import android.graphics.Point;
import android.util.Log;
public class BoardMapper {
private static final String TAG = BoardMapper.class.getSimpleName();
static Point cellToPoint(int cellID) {
int x, y;
// Map cell to X,Y
switch (cellID) {
case R.id.cell_A1:
x = 0;
y = 0;
break;
case R.id.cell_A2:
x = 1;
y = 0;
break;
case R.id.cell_A3:
x = 2;
y = 0;
break;
case R.id.cell_B1:
x = 0;
y = 1;
break;
case R.id.cell_B2:
x = 1;
y = 1;
break;
case R.id.cell_B3:
x = 2;
y = 1;
break;
case R.id.cell_C1:
x = 0;
y = 2;
break;
case R.id.cell_C2:
x = 1;
y = 2;
break;
case R.id.cell_C3:
x = 2;
y = 2;
break;
default:
Log.wtf(TAG, "That's not supposed to happen!");
throw new ArrayIndexOutOfBoundsException();
}
return new Point(x,y);
}
static int pointToCell(Point point) {
return R.id.cell_A3;
}
}
package com.example.tictactoe;
import android.util.Log;
import io.reactivex.Observable;
import io.reactivex.subjects.PublishSubject;
import java.util.List;
import java.util.Observable;
public class Game {
......@@ -11,21 +12,26 @@ public class Game {
private List<Player> mPlayers;
private Player mCurrentPlayer;
private Board mBoard;
private Observable mBoardUpdates;
private PublishSubject<Update> mBoardUpdates;
public Game(List<Player> players) {
Game(List<Player> players) {
mPlayers = players;
mCurrentPlayer = players.get(0); // Start with Player 1
mBoard = new Board();
mBoardUpdates = new Observable();
mBoardUpdates = PublishSubject.create();
}
public void selectSquare(int cellX, int cellY) {
Log.d(TAG, String.format("selectSquare: {x: %1d, y: %2d}", cellX, cellY));
mBoard.markCell(mCurrentPlayer.getMark(), cellX, cellY);
void selectSquare(int x, int y) {
Log.d(TAG, String.format("selectSquare: {x: %1d, y: %2d}", x, y));
// If move is successful, post game update
if (mBoard.markCell(mCurrentPlayer.getMark(), x, y)) {
mBoardUpdates.onNext(new Update(mCurrentPlayer, x, y, false, false));
}
}
public Observable getBoardUpdates() {
Observable<Update> getGameUpdates() {
return mBoardUpdates;
}
}
package com.example.tictactoe;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
......@@ -9,10 +11,12 @@ import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.Toast;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.disposables.Disposable;
import java.util.ArrayList;
......@@ -21,6 +25,7 @@ public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
@BindView(R.id.toolbar) Toolbar mToolbar;
private Game mGame;
private Disposable mGameUpdates;
@Override
protected void onCreate(Bundle savedInstanceState) {
......@@ -69,42 +74,46 @@ public class MainActivity extends AppCompatActivity {
players.add(new Player("Guest", Mark.O));
mGame = new Game(players);
mGameUpdates = mGame.getGameUpdates().subscribe(this::onNext, this::onError, this::onComplete);
}
@OnClick({R.id.cell_A1, R.id.cell_A2, R.id.cell_A3,
R.id.cell_B1, R.id.cell_B2, R.id.cell_B3,
R.id.cell_C1, R.id.cell_C2, R.id.cell_C3})
void onBoardTapped(View view) {
switch (view.getId()) {
case R.id.cell_A1:
mGame.selectSquare(0, 0);
break;
case R.id.cell_A2:
mGame.selectSquare(1, 0);
break;
case R.id.cell_A3:
mGame.selectSquare(2, 0);
break;
case R.id.cell_B1:
mGame.selectSquare(0, 1);
break;
case R.id.cell_B2:
mGame.selectSquare(1, 1);
break;
case R.id.cell_B3:
mGame.selectSquare(2, 1);
break;
case R.id.cell_C1:
mGame.selectSquare(0, 2);
break;
case R.id.cell_C2:
mGame.selectSquare(1, 2);
break;
case R.id.cell_C3:
mGame.selectSquare(2, 2);
break;
default:
Log.wtf(TAG, "That's not supposed to happen!");
Point point;
try {
point = BoardMapper.cellToPoint(view.getId());
} catch (Exception e) {
Log.e(TAG, e.getMessage());
Toast.makeText(this, "Invalid Move!", Toast.LENGTH_SHORT).show();
return;
}
mGame.selectSquare(point.x, point.y);
}
// GAME UPDATES
private void onNext(Update update) {
Point move = update.getMove();
Mark mark = update.getPlayer().getMark();
// TODO Check update
updateBoardView(move, mark);
}
private void onError(Throwable throwable) {
}
private void onComplete() {
}
private void updateBoardView(Point move, Mark mark) {
Log.d(TAG, String.format("updateBoardView: Move: %1s, Mark: %2s", move, mark));
int cellID = BoardMapper.pointToCell(move);
((ImageView) findViewById(cellID)).setImageResource(mark.getValue());
}
}
package com.example.tictactoe;
public enum Mark {
X, O, EMPTY
X(R.drawable.ic_x),
O(R.drawable.ic_o),
EMPTY(0);
private final int id;
Mark(int id) {
this.id = id;
}
public int getValue() {
return id;
}
}
package com.example.tictactoe;
import android.graphics.Point;
class Update {
private Player player;
private Point move;
private boolean isDraw;
private boolean isWinner;
Update(Player player, int x, int y, boolean isDraw, boolean isWinner) {
this.player = player;
this.move = new Point(x, y);
this.isDraw = isDraw;
this.isWinner = isWinner;
}
public Player getPlayer() {
return player;
}
public Point getMove() {
return move;
}
public boolean isDraw() {
return isDraw;
}
public boolean isWinner() {
return isWinner;
}
}
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#ff4081</color>
<color name="colorPrimary">#f44336</color>
<color name="colorPrimaryDark">#ba000d</color>
<color name="colorAccent">#2196f3</color>
<color name="colorCell">#eceff1</color>
</resources>
......@@ -25,7 +25,7 @@
<item name="android:layout_width">64dp</item>
<item name="android:layout_height">64dp</item>
<item name="android:layout_margin">4dp</item>
<item name="android:background">@color/colorPrimaryDark</item>
<item name="android:background">@color/colorCell</item>
<item name="android:layout_weight">1</item>
</style>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment