I need some help developing this Android application. I could use some reference
ID: 3916147 • Letter: I
Question
I need some help developing this Android application. I could use some reference code.
Operation
This app maintains the 2 players for a 2-player game. Each player must specify a name.
The Main Menu activity provides 5 buttons for starting the 5 activities of the app.
The Game Emulator activity displays player 1 and 2 and provides 3 buttons that can be used
to specify who won, lost, or tied the game.
The Scoreboard activity displays all players that are stored in the database as well as their
wins, losses, and ties.
The Select Player activity allows the user to select player 1 or 2 from a list of players that’s
stored in the database.
The Add Player activity allows the user to add a new player to the database.
This is an android studio application.
Page 1
Main Menu activity
Start Game
(Button)
View Scoreboard
(Button)
Select Player 1
(Button)
Select Player 2
(Button)
Add Player
(Button)
Game Emulator activity
Player 1
Joel
(TextViews)
Player 2
Ray
(TextViews)
Joel wins!
(Button)
Ray wins!
(Button)
It's a tie!
(Button)
Scoreboard activity
Player Wins Losses Ties
(TextViews)
Joel 4 1 5 (ListView with TextViews)
Ray 3 7 10
Mike 3 2 5
Select Player 1 and
Select Player 2 activities
Select Player 1
(TextView)
Joel
(ListView)
Ray
Mike
Add Player activity
Name
___________ (EditText)
Specifications
When the Game Emulator activity starts, it should check to make sure players 1 and 2 have
been selected. If a player has not been selected, this activity should display the Select Player
activity for the unselected player.
If the user clicks on a button on the Game Emulator activity, the app should display the
Scoreboard activity.
The Scoreboard activity should sort the players by the number of wins in descending order.
Database table
The database should have a single table named player with 5 columns like this:
player
======
_id
name
wins
losses
ties
Enhancements
Anytime:
Modify the app to make it easier to navigate between its activities. For example,
you may want to add menus or buttons to the activities. As a part of that process, you may
want to restructure the app so it uses fewer activities. For example, you may want to remove
the Main Menu activity and display the Game Emulator activity when the app starts.
Anytime:
Add a way to update a player’s name and/or a way to delete a player.
Anytime:
Convert the activities to fragments and add multi-pane layouts that allow the app to
work better for large screens.
Remember to have the app display your name somehow.
Explanation / Answer
Board class
package com.ssaurel.tictactoe;
import java.util.Random;
public class Board {
private static final Random RANDOM = new Random();
private char[] elts;
private char currentPlayer;
private boolean ended;
public Board() {
elts = new char[9];
newGame();
}
public boolean isEnded() {
return ended;
}
public char play(int x, int y) {
if (!ended && elts[3 * y + x] == ' ') {
elts[3 * y + x] = currentPlayer;
changePlayer();
}
return checkEnd();
}
public void changePlayer() {
currentPlayer = (currentPlayer == 'X' ? 'O' : 'X');
}
public char getElt(int x, int y) {
return elts[3 * y + x];
}
public void newGame() {
for (int i = 0; i < elts.length; i++) {
elts[i] = ' ';
}
currentPlayer = 'X';
ended = false;
}
public char checkEnd() {
for (int i = 0; i < 3; i++) {
if (getElt(i, 0) != ' ' &&
getElt(i, 0) == getElt(i, 1) &&
getElt(i, 1) == getElt(i, 2)) {
ended = true;
return getElt(i, 0);
}
if (getElt(0, i) != ' ' &&
getElt(0, i) == getElt(1, i) &&
getElt(1, i) == getElt(2, i)) {
ended = true;
return getElt(0, i);
}
}
if (getElt(0, 0) != ' ' &&
getElt(0, 0) == getElt(1, 1) &&
getElt(1, 1) == getElt(2, 2)) {
ended = true;
return getElt(0, 0);
}
if (getElt(2, 0) != ' ' &&
getElt(2, 0) == getElt(1, 1) &&
getElt(1, 1) == getElt(0, 2)) {
ended = true;
return getElt(2, 0);
}
for (int i = 0; i < 9; i++) {
if (elts[i] == ' ')
return ' ';
}
return 'T';
}
public char computer() {
if (!ended) {
int position = -1;
do {
position = RANDOM.nextInt(9);
} while (elts[position] != ' ');
elts[position] = currentPlayer;
changePlayer();
}
return checkEnd();
}
}
BoardView object
package com.ssaurel.tictactoe;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class BoardView extends View {
private static final int LINE_THICK = 5;
private static final int ELT_MARGIN = 20;
private static final int ELT_STROKE_WIDTH = 15;
private int width, height, eltW, eltH;
private Paint gridPaint, oPaint, xPaint;
private GameEngine gameEngine;
private MainActivity activity;
public BoardView(Context context) {
super(context);
}
public BoardView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
gridPaint = new Paint();
oPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
oPaint.setColor(Color.RED);
oPaint.setStyle(Paint.Style.STROKE);
oPaint.setStrokeWidth(ELT_STROKE_WIDTH);
xPaint = new Paint(oPaint);
xPaint.setColor(Color.BLUE);
}
public void setMainActivity(MainActivity a) {
activity = a;
}
public void setGameEngine(GameEngine g) {
gameEngine = g;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
height = View.MeasureSpec.getSize(heightMeasureSpec);
width = View.MeasureSpec.getSize(widthMeasureSpec);
eltW = (width - LINE_THICK) / 3;
eltH = (height - LINE_THICK) / 3;
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
drawGrid(canvas);
drawBoard(canvas);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!gameEngine.isEnded() && event.getAction() == MotionEvent.ACTION_DOWN) {
int x = (int) (event.getX() / eltW);
int y = (int) (event.getY() / eltH);
char win = gameEngine.play(x, y);
invalidate();
if (win != ' ') {
activity.gameEnded(win);
} else {
// computer plays ...
win = gameEngine.computer();
invalidate();
if (win != ' ') {
activity.gameEnded(win);
}
}
}
return super.onTouchEvent(event);
}
private void drawBoard(Canvas canvas) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
drawElt(canvas, gameEngine.elt(i, j), i, j);
}
}
}
private void drawGrid(Canvas canvas) {
for (int i = 0; i < 2; i++) {
// vertical lines
float left = eltW * (i + 1);
float right = left + LINE_THICK;
float top = 0;
float bottom = height;
canvas.drawRect(left, top, right, bottom, gridPaint);
// horizontal lines
float left2 = 0;
float right2 = width;
float top2 = eltH * (i + 1);
float bottom2 = top2 + LINE_THICK;
canvas.drawRect(left2, top2, right2, bottom2, gridPaint);
}
}
private void drawElt(Canvas canvas, char c, int x, int y) {
if (c == 'O') {
float cx = (eltW * x) + eltW / 2;
float cy = (eltH * y) + eltH / 2;
canvas.drawCircle(cx, cy, Math.min(eltW, eltH) / 2 - ELT_MARGIN * 2, oPaint);
} else if (c == 'X') {
float startX = (eltW * x) + ELT_MARGIN;
float startY = (eltH * y) + ELT_MARGIN;
float endX = startX + eltW - ELT_MARGIN * 2;
float endY = startY + eltH - ELT_MARGIN;
canvas.drawLine(startX, startY, endX, endY, xPaint);
float startX2 = (eltW * (x + 1)) - ELT_MARGIN;
float startY2 = (eltH * y) + ELT_MARGIN;
float endX2 = startX2 - eltW + ELT_MARGIN * 2;
float endY2 = startY2 + eltH - ELT_MARGIN;
canvas.drawLine(startX2, startY2, endX2, endY2, xPaint);
}
}
}
MainActivity
package com.ssaurel.tictactoe;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import static com.ssaurel.tictactoe.R.id.board;
public class MainActivity extends AppCompatActivity {
private BoardView boardView;
private GameEngine gameEngine;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
boardView = (BoardView) findViewById(board);
gameEngine = new GameEngine();
boardView.setGameEngine(gameEngine);
boardView.setMainActivity(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_new_game) {
newGame();
}
return super.onOptionsItemSelected(item);
}
public void gameEnded(char c) {
String msg = (c == 'T') ? "Game Ended. Tie" : "GameEnded. " + c + " win";
new AlertDialog.Builder(this).setTitle("Tic Tac Toe").
setMessage(msg).
setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialogInterface) {
newGame();
}
}).show();
}
private void newGame() {
gameEngine.newGame();
boardView.invalidate();
}
}