Commit 6721f061 authored by Shaun Burch's avatar Shaun Burch 💻

#3 Add player entry, display them above board

parent 29d9ca6f
Pipeline #22997359 passed with stages
in 8 minutes and 21 seconds
package com.example.tictactoe;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import java.util.Locale;
public class AddPlayerDialog extends DialogFragment {
private static final String ARG_PLAYER_POS = "ARG_PLAYER_POS";
private static final String ARG_MARK_TAKEN = "ARG_MARK_TAKEN";
private AddPlayerDialogListener mListener;
private Mark mChosenMark = Mark.X; // Defaulting to X in the event they just click ready
@BindView(R.id.input_name)
EditText mNameInput;
@BindView(R.id.image_o)
ImageView mImageO;
@BindView(R.id.image_x)
ImageView mImageX;
@BindView(R.id.label_or)
TextView mLabelOr;
/**
* Static action to hide views
*/
static final ButterKnife.Action<View> HIDE = (view, index) -> view.setVisibility(View.GONE);
/**
* Interface for passing back {@link Player}
*/
public interface AddPlayerDialogListener {
void onPlayerAdded(Player player);
}
/**
* Static initializer for {@link AddPlayerDialog}.
*
* @param playerPos Player position, e.g. Player _1_
* @return returns instance of {@link AddPlayerDialog}
*/
public static AddPlayerDialog getInstance(int playerPos, Mark markTaken) {
AddPlayerDialog dialog = new AddPlayerDialog();
// Bundle args
Bundle args = new Bundle();
args.putInt(ARG_PLAYER_POS, playerPos);
// Bundle mark if present
if (markTaken != null) {
args.putSerializable(ARG_MARK_TAKEN, markTaken);
}
dialog.setArguments(args);
return dialog;
}
public static AddPlayerDialog getInstance(int playerPos) {
return getInstance(playerPos, null);
}
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_add_player, null);
ButterKnife.bind(this, view);
// Get Args
Bundle arguments = getArguments();
int playerPos = arguments.getInt(ARG_PLAYER_POS, 1);
// If a mark is taken, only one choice
if (arguments.containsKey(ARG_MARK_TAKEN)) {
Mark taken = (Mark) arguments.getSerializable(ARG_MARK_TAKEN);
onOneOption(view, taken);
}
// Build Dialog
builder.setView(view)
.setPositiveButton(R.string.button_ready, this::onReady)
.setTitle(formatTitle(playerPos));
return builder.create();
}
/**
* Handle when there is only one {@link Mark} to choose from.
*
* @param view parent view
* @param taken {@link Mark} that's been chosen
*/
private void onOneOption(View view, Mark taken) {
// Hide OR
ButterKnife.apply(mLabelOr, HIDE);
// Hide already chosen mark
if (taken == Mark.O) {
ButterKnife.apply(mImageO, HIDE);
mChosenMark = Mark.X;
} else {
ButterKnife.apply(mImageX, HIDE);
mChosenMark = Mark.O;
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
// Check that parent implements listener
try {
mListener = (AddPlayerDialogListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement NoticeDialogListener");
}
}
/**
* Click handler for positive button.
*
* @param dialog calling dialog
* @param which id of pressed button
*/
private void onReady(DialogInterface dialog, int which) {
// Build Player
String name = mNameInput.getText().toString();
mListener.onPlayerAdded(new Player(name, mChosenMark));
// Close
dismiss();
}
/**
* Given player position, returns formatted title.
*
* @param playerPos Player position, e.g. Player _1_
* @return formatted title
*/
private String formatTitle(int playerPos) {
return String.format(Locale.getDefault(), getString(R.string.title_player_x), playerPos);
}
/**
* Listen to image clicks
*
* @param view calling view
*/
@OnClick({R.id.image_x, R.id.image_o})
void onMarkChosen(View view) {
// Save & highlight choice
if (view.getId() == R.id.image_o) {
mChosenMark = Mark.O;
ButterKnife.apply(mImageO, View.ALPHA, 1f);
ButterKnife.apply(mImageX, View.ALPHA, 0.1f);
} else {
mChosenMark = Mark.X;
ButterKnife.apply(mImageO, View.ALPHA, 0.1f);
ButterKnife.apply(mImageX, View.ALPHA, 1f);
}
}
}
......@@ -7,10 +7,11 @@ import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import butterknife.BindView;
import butterknife.ButterKnife;
......@@ -18,14 +19,22 @@ import butterknife.OnClick;
import io.reactivex.disposables.Disposable;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
public class MainActivity extends AppCompatActivity implements AddPlayerDialog.AddPlayerDialogListener {
private static final String TAG = MainActivity.class.getSimpleName();
@BindView(R.id.toolbar)
Toolbar mToolbar;
private Game mGame;
private Disposable mGameUpdates;
private List<Player> mPlayers = new ArrayList<>();
@BindView(R.id.toolbar)
Toolbar mToolbar;
@BindView(R.id.name_player_1)
TextView mPlayerOne;
@BindView(R.id.name_player_2)
TextView mPlayerTwo;
@Override
protected void onCreate(Bundle savedInstanceState) {
......@@ -34,8 +43,7 @@ public class MainActivity extends AppCompatActivity {
ButterKnife.bind(this);
setSupportActionBar(mToolbar);
// Start new game
onNewGame();
getPlayer(1);
}
@Override
......@@ -74,17 +82,30 @@ public class MainActivity extends AppCompatActivity {
.setAction("Action", null).show();
}
private void onNewGame() {
// TODO Prompt for player entry & mark selection
ArrayList<Player> players = new ArrayList<>();
players.add(new Player("Shaun", Mark.X));
players.add(new Player("Guest", Mark.O));
private void getPlayer(int player) {
AddPlayerDialog dialog;
if (player == 1) {
dialog = AddPlayerDialog.getInstance(player);
} else {
Mark taken = mPlayers.get(0).getMark();
dialog = AddPlayerDialog.getInstance(player, taken);
}
dialog.show(getSupportFragmentManager(), "PlayerDialog");
}
mGame = new Game(players);
mGameUpdates = mGame.getGameUpdates().subscribe(this::onNext, this::onError, this::onComplete);
private void startGame() {
mGame = new Game(mPlayers);
mGameUpdates = mGame.getGameUpdates().subscribe(this::onNext);
showPlayers();
}
private void showPlayers() {
mPlayerOne.setText(mPlayers.get(0).getName());
mPlayerTwo.setText(mPlayers.get(1).getName());
}
// TODO See if I can move these to a field w/ ButterKnife
@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})
......@@ -97,8 +118,6 @@ public class MainActivity extends AppCompatActivity {
}
}
// GAME UPDATES
private void onNext(Update update) {
checkForGameOver(update);
// Update Board
......@@ -123,17 +142,21 @@ public class MainActivity extends AppCompatActivity {
}
}
private void onError(Throwable throwable) {
}
private void onComplete() {
}
private void updateBoardView(Point point, Mark mark) {
Log.d(TAG, String.format("updateBoardView: Move: %1s, Mark: %2s", point, mark));
int cellID = BoardMapper.pointToView(point);
((ImageView) findViewById(cellID)).setImageResource(mark.getValue());
}
@Override
public void onPlayerAdded(Player player) {
mPlayers.add(player);
// Ask if we don't have two players
if (mPlayers.size() < 2) {
getPlayer(2);
} else {
startGame();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/input_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:ems="10"
android:hint="Name"
android:inputType="textPersonName"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/image_x"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toStartOf="@+id/label_or"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/input_name"
app:srcCompat="@drawable/ic_x" />
<ImageView
android:id="@+id/image_o"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/label_or"
app:layout_constraintTop_toBottomOf="@+id/input_name"
app:srcCompat="@drawable/ic_o" />
<TextView
android:id="@+id/label_or"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="OR"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
app:layout_constraintBottom_toBottomOf="@+id/image_x"
app:layout_constraintEnd_toStartOf="@+id/image_o"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/image_x"
app:layout_constraintTop_toTopOf="@+id/image_x" />
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
......@@ -4,4 +4,10 @@
<string name="player_1">Player 1:</string>
<string name="player_2">Player 2:</string>
<string name="unknown">Unknown</string>
<string name="title_player_x">Player %1d</string>
<string name="button_ready">Ready!</string>
<string-array name="mark_options">
<item>X</item>
<item>O</item>
</string-array>
</resources>
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