update,
This commit is contained in:
54
it114105/itp4501/Assignment/21-22/README.md.original
Normal file
54
it114105/itp4501/Assignment/21-22/README.md.original
Normal file
@@ -0,0 +1,54 @@
|
||||
# ITP4501 Project
|
||||
In this assignment, you are required to develop an Android Application to play a Tic-Tac-Toe Game. This app will also record the result and corresponding time required to complete a game and use charts to show the history records.
|
||||
|
||||
You can use following link to know how to play a Tic-Tac-Teo game:
|
||||
[https://en.wikipedia.org/wiki/Tic-tac-toe](https://en.wikipedia.org/wiki/Tic-tac-toe)
|
||||
|
||||
|
||||
## Functional Requirements
|
||||
Listed below are the basic requirements of your application. You need to refer to the Local Database section for the database schema.
|
||||
|
||||
1. A main activity which contains a main menu for players to choose. The four main functions are: Play, Game Ranking, Your Records and Close.
|
||||
2. When players touch the "Play" button on the main menu, they start to play the game with CPU. Players will mark an 'O' on an available button which does not contain any mark ('O' or 'X') by touching it. After players touch on an available button, CPU will RANDOMLY to mark a 'X' on an available button. To simplify your workload, you are not required to write an AI for CPU to win the game.
|
||||
When players or CPU who succeed in placing three of their marks in a horizontal, vertical, or diagonal row is the winner. Your app will save the record of this game to the GamesLog table in a local database and then your app will show a "Continue" for players to restart the game.
|
||||
|
||||
3. When players touch the "Game Ranking" button on the main menu, your app will download a JSON from your own api server. You MUST use a ListView to show all the records in the JSON string.
|
||||
|
||||
4. When players touch the "Your Records" button on the main menu, Your app will load the records in the GamesLog table from your local database. You MUST use a ListView to show all these records. Your app will provide a button "Show in Pie Chart" which let players to show winning status (Win, Lose, Draw) by using a Pie Chart.
|
||||
|
||||
Note: You are encouraged to design and implement extra features. 10% of the total mark will be allocated on such additional functions. Refer to section 7 Marking Guidelines for more details.
|
||||
|
||||
## Local Database
|
||||
The database scheme described here is an extremely simple one. Many fields are intended not to be included in order to reduce the complexity of this assignment. You are free to add columns and tables to the database to fit for your own needs.
|
||||
```
|
||||
GamesLog (gameID, playDate, playTime, duration, winningStatus)
|
||||
```
|
||||
|
||||
## Ranking JSON Server
|
||||
You can obtain a ranking list from your own api server and the data returned is in JSON format.
|
||||
The JSON string returned is shown below:
|
||||
```
|
||||
[{"Name":"Kenny Lam","Duration":104},
|
||||
{"Name":"Peter Kwong","Duration":25},
|
||||
{"Name":"John Chan","Duration":38},
|
||||
{"Name":"Johnny Kwong","Duration":117},
|
||||
{"Name":"Mary Lam","Duration":23},
|
||||
{"Name":"David Wong","Duration":49},
|
||||
{"Name":"Alan Ma","Duration":18},
|
||||
{"Name":"Carrie Lam","Duration":68},
|
||||
{"Name":"Chris Lam","Duration":93},
|
||||
{"Name":"Mary Cheung","Duration":78}]
|
||||
```
|
||||
You need to sort the JSON data by using duration in ascending order to obtain the ranking.
|
||||
|
||||
### Marking Guidelines
|
||||
You project will be assessed according to the items below.
|
||||
➢ Database initialisation.
|
||||
➢ Level of completion.
|
||||
➢ Correctness.
|
||||
➢ UI design (no mark will be given if you are using the same design in this document).
|
||||
➢ Program design and implementation.
|
||||
➢ Program style and comments.
|
||||
➢ Driving Question: How can an organization get benefit from a central computerized management system by using a mobile app?
|
||||
Briefly discuss how ITP4510, ITP4522 and ITP4915M modules help you to finish this assignment.
|
||||
|
178
it114105/itp4501/Assignment/21-22/tictacteo/GameActivity.java
Normal file
178
it114105/itp4501/Assignment/21-22/tictacteo/GameActivity.java
Normal file
@@ -0,0 +1,178 @@
|
||||
package com.game.tictacteo;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.game.tictacteo.engine.Game;
|
||||
import com.game.tictacteo.engine.GameBoard;
|
||||
import com.game.tictacteo.engine.GameBoardPlacedException;
|
||||
import com.game.tictacteo.engine.GameStatus;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class GameActivity extends AppCompatActivity implements View.OnClickListener {
|
||||
|
||||
private HashMap<Integer, LocateButton> gameBoardMap;
|
||||
private Game game;
|
||||
private ImageView imGameMes;
|
||||
private final static byte USER_PLAYER = 1;
|
||||
private final static byte AI_PLAYER = 2;
|
||||
//private ArrayList<Integer> lockedButton;
|
||||
private ImageView imDisPlayer;
|
||||
private ImageView imDisAI;
|
||||
private Button btnContinue;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_game);
|
||||
//this.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
||||
|
||||
imGameMes = (ImageView) findViewById(R.id.txtGameMes);
|
||||
imDisPlayer = (ImageView) findViewById(R.id.imDisplayPlayer);
|
||||
imDisAI = (ImageView) findViewById(R.id.imDisplayAI);
|
||||
btnContinue = (Button) findViewById(R.id.btnContinue);
|
||||
btnContinue.setVisibility(View.GONE);
|
||||
|
||||
// Close button
|
||||
btnContinue.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
startActivity(getIntent());
|
||||
}
|
||||
});
|
||||
|
||||
// Button Map to reduce the runtime
|
||||
gameBoardMap = new HashMap<Integer, LocateButton>();
|
||||
|
||||
for(int i = 0; i < 3; i++){
|
||||
for (int j = 0; j < 3; j++){
|
||||
String buttonID = "btn_"+i+"_"+j;
|
||||
int resourceID = getResources().getIdentifier(buttonID, "id", getPackageName());
|
||||
Button button = (Button) findViewById(resourceID);
|
||||
button.setOnClickListener(this);
|
||||
Log.i("gameAc-onCreate", "refesh");
|
||||
gameBoardMap.put(resourceID, new LocateButton(button, new int[]{i, j}));
|
||||
}
|
||||
}
|
||||
Log.i("gameAc", "start");
|
||||
|
||||
game = new Game(GameActivity.this);
|
||||
//lockedButton = new ArrayList<Integer>();
|
||||
}
|
||||
|
||||
// refesh the game board
|
||||
public void refesh(byte[][] board){
|
||||
Log.i("gameAc", "refesh");
|
||||
for(int i = 0; i < board.length; i++){
|
||||
for(int j = 0; j < board[i].length; j++){
|
||||
|
||||
String mapKey = "btn_"+i+"_"+j;
|
||||
int resourceID = getResources().getIdentifier(mapKey, "id", getPackageName());
|
||||
|
||||
// Get button from hashmap
|
||||
Button button = gameBoardMap.get(resourceID).button;
|
||||
|
||||
// set button image and disable clicked button
|
||||
if(board[i][j] == USER_PLAYER){
|
||||
button.setBackgroundResource(R.drawable.ic_o);
|
||||
button.setClickable(false);
|
||||
}else if (board[i][j] == AI_PLAYER){
|
||||
button.setBackgroundResource(R.drawable.ic_x);
|
||||
button.setClickable(false);
|
||||
}else{
|
||||
button.setBackgroundResource(R.drawable.game_board_pos);
|
||||
button.setClickable(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// disable all button
|
||||
public void lockAllButton(){
|
||||
for(LocateButton lb: gameBoardMap.values())
|
||||
lb.button.setClickable(false);
|
||||
}
|
||||
|
||||
// public void unlockAllButton(){
|
||||
// for(Integer key: gameBoardMap.keySet()){
|
||||
// Button button = gameBoardMap.get(key).button;
|
||||
// if(lockedButton.contains(key))
|
||||
// button.setClickable(false);
|
||||
// else
|
||||
// button.setClickable(true);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
|
||||
Log.i("gameAc", view.getId() +"");
|
||||
if (gameBoardMap.containsKey(view.getId())) {
|
||||
LocateButton lb = gameBoardMap.get(view.getId());
|
||||
|
||||
// Player place
|
||||
lockAllButton();
|
||||
|
||||
// set clicked button UI setting
|
||||
lb.button.setBackgroundResource(R.drawable.ic_o);
|
||||
imGameMes.setImageResource(R.drawable.game_mes_2);
|
||||
imDisPlayer.setBackgroundResource(0);
|
||||
imDisAI.setBackgroundResource(R.drawable.btnranking);
|
||||
|
||||
//lockedButton.add(view.getId());
|
||||
|
||||
try {
|
||||
|
||||
// Place the index
|
||||
GameStatus gs = game.player1Place(lb.locate[0], lb.locate[1]);
|
||||
this.refesh(gs.board);
|
||||
|
||||
imGameMes.setImageResource(R.drawable.game_mes_1);
|
||||
imDisAI.setBackgroundResource(0);
|
||||
|
||||
// Check returned game statue and update the UI
|
||||
if(gs.status == GameBoard.Status.CONTINUE) {
|
||||
imDisPlayer.setBackgroundResource(R.drawable.btnranking);
|
||||
//unlockAllButton();
|
||||
}else{
|
||||
|
||||
if (gs.status == GameBoard.Status.DRAW){
|
||||
imDisPlayer.setBackgroundResource(R.drawable.btnranking);
|
||||
imGameMes.setImageResource(R.drawable.game_dis_draw);
|
||||
}else if (gs.status == GameBoard.Status.PLAYER1_WIN){
|
||||
imGameMes.setImageResource(R.drawable.game_dis_win);
|
||||
}else if(gs.status == GameBoard.Status.PLAYER2_WIN) {
|
||||
imDisPlayer.setBackgroundResource(0);
|
||||
imDisAI.setBackgroundResource(R.drawable.btnranking);
|
||||
imGameMes.setImageResource(R.drawable.game_dis_lose);
|
||||
}
|
||||
btnContinue.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
} catch (GameBoardPlacedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class LocateButton {
|
||||
Button button;
|
||||
int[] locate; // row, col index
|
||||
|
||||
LocateButton(Button button, int[]locate){
|
||||
this.button = button;
|
||||
this.locate = locate;
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
package com.game.tictacteo;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class InitActivity extends AppCompatActivity {
|
||||
|
||||
private TextView tvLoadingMes;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_init);
|
||||
// hidden Action bar
|
||||
// getSupportActionBar().hide();
|
||||
|
||||
tvLoadingMes = (TextView) findViewById(R.id.tvLoadingMes);
|
||||
// For Some setup things
|
||||
new Handler().postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Intent intent = new Intent(InitActivity.this, MainActivity.class);
|
||||
startActivity(intent);
|
||||
finish();
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
}
|
@@ -0,0 +1,40 @@
|
||||
package com.game.tictacteo;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class LoadingDialog {
|
||||
|
||||
Context context;
|
||||
Dialog dialog;
|
||||
TextView tvLoadingDailogMes;
|
||||
|
||||
public LoadingDialog(Context context){
|
||||
this.context = context;
|
||||
dialog = new Dialog(context);
|
||||
dialog.setContentView(R.layout.activity_loading_dialog);
|
||||
tvLoadingDailogMes = (TextView) dialog.findViewById(R.id.tvLoadingDialogMes);
|
||||
}
|
||||
|
||||
public void show(String message){
|
||||
|
||||
|
||||
dialog.getWindow().setBackgroundDrawable(new ColorDrawable((Color.TRANSPARENT)));
|
||||
// Disable click outside then close the loading dialog
|
||||
dialog.setCanceledOnTouchOutside(false);
|
||||
// set Header
|
||||
tvLoadingDailogMes.setText(message);
|
||||
dialog.create();
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
public void hide(){
|
||||
dialog.dismiss();
|
||||
}
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
package com.game.tictacteo;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
Button btnStartGame;
|
||||
Button btnRanking;
|
||||
Button btnRecords;
|
||||
Button btnClose;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
btnStartGame = (Button) findViewById(R.id.btnPlay);
|
||||
btnRanking = (Button) findViewById(R.id.btnRanking);
|
||||
btnRecords = (Button) findViewById(R.id.btnRec);
|
||||
btnClose = (Button) findViewById(R.id.btnClose);
|
||||
|
||||
// Start game
|
||||
btnStartGame.setOnClickListener( new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent( MainActivity.this, GameActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
// Game Ranking
|
||||
btnRanking.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent intent = new Intent( MainActivity.this, RankingActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
// Your Records
|
||||
btnRecords.setOnClickListener( new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent( MainActivity.this, RecordActivity.class);
|
||||
startActivity(intent);
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
// Close
|
||||
btnClose.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
System.out.println("click");
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@@ -0,0 +1,97 @@
|
||||
package com.game.tictacteo;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.app.ProgressDialog;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.game.tictacteo.model.UserRanking;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class RankingActivity extends AppCompatActivity {
|
||||
|
||||
private Button btnBack;
|
||||
private final static String API_ENDPOINT = "http://192.168.76.3/ranking_api.php";
|
||||
private LoadingDialog ld;
|
||||
private ArrayList<UserRanking> users;
|
||||
private RecyclerView rvRankingListView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_ranking);
|
||||
// Load Dailog
|
||||
ld = new LoadingDialog(this);
|
||||
users = new ArrayList<UserRanking>();
|
||||
|
||||
btnBack = (Button) findViewById(R.id.btnBack);
|
||||
rvRankingListView = (RecyclerView) findViewById(R.id.rvRankingList);
|
||||
btnBack.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
// show loading dialog
|
||||
ld.show("fetching...");
|
||||
new Thread(() -> {
|
||||
try{
|
||||
// fetch API
|
||||
URL url = new URL(API_ENDPOINT);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
InputStream inputStream = connection.getInputStream();
|
||||
BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream));
|
||||
String data = buffer.readLine();
|
||||
StringBuffer json = new StringBuffer();
|
||||
while(data != null){
|
||||
json.append(data);
|
||||
data = buffer.readLine();
|
||||
}
|
||||
// JSON List to ArrayList
|
||||
JSONArray jsonArray = new JSONArray(String.valueOf(json));
|
||||
for(int i = 0; i < jsonArray.length(); i++){
|
||||
JSONObject jsonObj = jsonArray.getJSONObject(i);
|
||||
String name = jsonObj.getString("Name");
|
||||
int duration = jsonObj.getInt("Duration");
|
||||
users.add(new UserRanking(name, duration));
|
||||
Log.i("ranking", "add" + name);
|
||||
}
|
||||
|
||||
runOnUiThread(() -> {
|
||||
ld.hide();
|
||||
UserRankingAdapter rankingAdapter = new UserRankingAdapter(this, users);
|
||||
rvRankingListView.setAdapter(rankingAdapter);
|
||||
rvRankingListView.setLayoutManager(new LinearLayoutManager(RankingActivity.this));
|
||||
});
|
||||
|
||||
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
).start();
|
||||
|
||||
}
|
||||
}
|
148
it114105/itp4501/Assignment/21-22/tictacteo/RecordActivity.java
Normal file
148
it114105/itp4501/Assignment/21-22/tictacteo/RecordActivity.java
Normal file
@@ -0,0 +1,148 @@
|
||||
package com.game.tictacteo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.game.tictacteo.localDB.GameLogDB;
|
||||
import com.game.tictacteo.model.GameLog;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class RecordActivity extends AppCompatActivity {
|
||||
|
||||
|
||||
private Button btnRecordBack;
|
||||
private SurfaceView winStatePieChartView;
|
||||
private SurfaceHolder holder;
|
||||
private RecyclerView rvGameLogList;
|
||||
private ArrayList<GameLog> logs;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_record);
|
||||
logs = GameLogDB.getInstance(this).readAllData();
|
||||
winStatePieChartView = (SurfaceView) findViewById(R.id.sfwinStatePieChartView);
|
||||
|
||||
// For get Canvas in SurfaceView
|
||||
holder = winStatePieChartView.getHolder();
|
||||
|
||||
if(logs.size() > 0){
|
||||
|
||||
// If not callback will throw error due to SurfaceView.canvas is not created in onCreate()
|
||||
holder.addCallback(new SurfaceHolder.Callback() {
|
||||
@Override
|
||||
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
|
||||
|
||||
float[] perc = calPercentage(logs);
|
||||
Paint paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
paint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
paint.setStrokeWidth(4);
|
||||
|
||||
Canvas canvas = holder.lockCanvas();
|
||||
|
||||
RectF rectF = new RectF(225,50,winStatePieChartView.getWidth()-225,winStatePieChartView.getHeight()-50);
|
||||
// draw the lose pie
|
||||
paint.setColor(Color.RED);
|
||||
canvas.drawArc(rectF, 0, 360*perc[0], true, paint);
|
||||
|
||||
// draw the win pie
|
||||
paint.setColor(Color.GREEN);
|
||||
canvas.drawArc(rectF, 360*perc[0], 360*perc[1], true, paint);
|
||||
|
||||
// draw the draw pie
|
||||
paint.setColor(Color.YELLOW);
|
||||
canvas.drawArc(rectF, 360*perc[0]+360*perc[1], 360*perc[2], true, paint);
|
||||
|
||||
// setup text paint
|
||||
paint.setStrokeWidth(0);
|
||||
paint.setTextSize(30);
|
||||
|
||||
// write Draw Text
|
||||
canvas.drawRect(winStatePieChartView.getWidth()-160, winStatePieChartView.getHeight()-200, winStatePieChartView.getWidth()-135, winStatePieChartView.getHeight()-175, paint);
|
||||
canvas.drawText("DRAW", winStatePieChartView.getWidth()-125, winStatePieChartView.getHeight()-177, paint);
|
||||
|
||||
// write Lose Text
|
||||
paint.setColor(Color.RED);
|
||||
canvas.drawRect(winStatePieChartView.getWidth()-160, winStatePieChartView.getHeight()-150, winStatePieChartView.getWidth()-135, winStatePieChartView.getHeight()-125, paint);
|
||||
canvas.drawText("LOSE", winStatePieChartView.getWidth()-125, winStatePieChartView.getHeight()-127, paint);
|
||||
|
||||
// write Win Text
|
||||
paint.setColor(Color.GREEN);
|
||||
canvas.drawRect(winStatePieChartView.getWidth()-160, winStatePieChartView.getHeight()-100, winStatePieChartView.getWidth()-135, winStatePieChartView.getHeight()-75, paint);
|
||||
canvas.drawText("WIN", winStatePieChartView.getWidth()-125, winStatePieChartView.getHeight()-77, paint);
|
||||
|
||||
holder.unlockCanvasAndPost(canvas);
|
||||
|
||||
//holder.lockCanvas(new Rect(0, 0, 0, 0));
|
||||
//holder.unlockCanvasAndPost(canvas);
|
||||
}
|
||||
|
||||
private float[] calPercentage(ArrayList<GameLog> data){
|
||||
int[] count = new int[3]; // 0 -> lose, 1 -> win, 2 -> draw
|
||||
int total = 0;
|
||||
for(GameLog gl: data ) {
|
||||
count[gl.getWinningStatus()]++;
|
||||
total++;
|
||||
}
|
||||
Log.i("prc1", count[0]*1.0f/total+"");
|
||||
Log.i("prc2", count[1]*1.0f/total+"");
|
||||
Log.i("prc3", count[2]*1.0f/total+"");
|
||||
return new float[]{count[0]*1.0f/total, count[1]*1.0f/total, count[2]*1.0f/total};
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int i, int i1, int i2) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
rvGameLogList = (RecyclerView) findViewById(R.id.rvGameLogList);
|
||||
|
||||
btnRecordBack = (Button) findViewById(R.id.btnRecordBack);
|
||||
btnRecordBack.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
// create adapter for attached the log list
|
||||
UserRecordAdapter rankingAdapter = new UserRecordAdapter(this, logs);
|
||||
rvGameLogList.setAdapter(rankingAdapter);
|
||||
rvGameLogList.setLayoutManager(new LinearLayoutManager(this));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,59 @@
|
||||
package com.game.tictacteo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import com.game.tictacteo.model.UserRanking;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class UserRankingAdapter extends RecyclerView.Adapter<UserRankingAdapter.Viewholder> {
|
||||
|
||||
private Context context;
|
||||
private ArrayList<UserRanking> users;
|
||||
|
||||
// Constructor
|
||||
public UserRankingAdapter(Context context, ArrayList<UserRanking> users) {
|
||||
this.context = context;
|
||||
this.users = users;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public UserRankingAdapter.Viewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_ranking_card_row, parent, false);
|
||||
return new Viewholder(view);
|
||||
}
|
||||
|
||||
|
||||
// Set Text for each row
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull UserRankingAdapter.Viewholder holder, int position) {
|
||||
UserRanking user = users.get(position);
|
||||
holder.tvRankingNo.setText(String.valueOf(position+1));
|
||||
holder.tvRankingName.setText("Name: " + user.getName());
|
||||
holder.tvRankingDuration.setText("Duration: " + String.valueOf(user.getDuration()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return users.size();
|
||||
}
|
||||
|
||||
// Init find Element ID;
|
||||
public class Viewholder extends RecyclerView.ViewHolder {
|
||||
private TextView tvRankingNo, tvRankingName, tvRankingDuration;
|
||||
|
||||
public Viewholder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
tvRankingNo = itemView.findViewById(R.id.tvRecordDateTime);
|
||||
tvRankingName = itemView.findViewById(R.id.tvRecordState);
|
||||
tvRankingDuration = itemView.findViewById(R.id.tvRecordDuration);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
package com.game.tictacteo;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.game.tictacteo.model.GameLog;
|
||||
import com.game.tictacteo.model.UserRanking;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class UserRecordAdapter extends RecyclerView.Adapter<UserRecordAdapter.Viewholder> {
|
||||
|
||||
private Context context;
|
||||
private ArrayList<GameLog> logs;
|
||||
|
||||
public UserRecordAdapter(Context context, ArrayList<GameLog> logs) {
|
||||
this.context = context;
|
||||
this.logs = logs;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public UserRecordAdapter.Viewholder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_record_card_row, parent, false);
|
||||
return new Viewholder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull UserRecordAdapter.Viewholder holder, int position) {
|
||||
GameLog log = logs.get(position);
|
||||
|
||||
SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd");
|
||||
SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm aa");
|
||||
|
||||
holder.tvRecordDateTime.setText(dateFormat.format(log.getPlayDate()) + " " + timeFormat.format(log.getPlayTime()));
|
||||
holder.tvRecordState.setText("WinState: " + log.winStateToString());
|
||||
if(log.getWinningStatus() == 0)
|
||||
holder.tvRecordState.setTextColor(Color.RED);
|
||||
else if (log.getWinningStatus() == 1)
|
||||
holder.tvRecordState.setTextColor(Color.GREEN);
|
||||
else
|
||||
holder.tvRecordState.setTextColor(Color.BLACK);
|
||||
|
||||
holder.tvRecordDuration.setText("Duration: " + String.valueOf(log.getDuration()) + " sec");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return logs.size();
|
||||
}
|
||||
|
||||
public class Viewholder extends RecyclerView.ViewHolder {
|
||||
private TextView tvRecordDateTime, tvRecordState, tvRecordDuration;
|
||||
|
||||
public Viewholder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
tvRecordDateTime = itemView.findViewById(R.id.tvRecordDateTime);
|
||||
tvRecordState = itemView.findViewById(R.id.tvRecordState);
|
||||
tvRecordDuration = itemView.findViewById(R.id.tvRecordDuration);
|
||||
}
|
||||
}
|
||||
}
|
68
it114105/itp4501/Assignment/21-22/tictacteo/engine/Game.java
Normal file
68
it114105/itp4501/Assignment/21-22/tictacteo/engine/Game.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package com.game.tictacteo.engine;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.game.tictacteo.localDB.GameLogDB;
|
||||
import com.game.tictacteo.model.GameLog;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Date;
|
||||
|
||||
public class Game {
|
||||
|
||||
private Timestamp startTime;
|
||||
private Timestamp endTime;
|
||||
private GameBoard board;
|
||||
private Context ctx;
|
||||
|
||||
|
||||
public Game(Context ctx) {
|
||||
startTime = new Timestamp(System.currentTimeMillis());
|
||||
board = new GameBoard();
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
// User move
|
||||
public GameStatus player1Place(int row, int col) throws GameBoardPlacedException {
|
||||
|
||||
GameStatus gs = place(row, col, 1);
|
||||
checkGameStatus(gs); // check status if won not need AI move
|
||||
if (gs.status == GameBoard.Status.CONTINUE) {
|
||||
gs = aiPlayerPlace();
|
||||
checkGameStatus(gs); // check status
|
||||
}
|
||||
return gs;
|
||||
}
|
||||
|
||||
private GameStatus place(int row, int col, int player) throws GameBoardPlacedException {
|
||||
|
||||
if (player == 1)
|
||||
return this.board.placePlayer1(row, col);
|
||||
else if (player == 2)
|
||||
return this.board.placePlayer2(row, col);
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkGameStatus(GameStatus gs) {
|
||||
// check status if Player1 or Player2 win need to insert the log to db
|
||||
if (gs.status != GameBoard.Status.CONTINUE) {
|
||||
endTime = new Timestamp(System.currentTimeMillis());
|
||||
int duration = (int) ((endTime.getTime() - startTime.getTime()) / 1000);
|
||||
|
||||
int winingStatus = ((gs.status == GameBoard.Status.DRAW) ? 2 : (gs.status == GameBoard.Status.PLAYER2_WIN) ? 0 : 1);
|
||||
GameLogDB.getInstance(this.ctx).addLog(new GameLog(new Date(endTime.getTime()), new Time(endTime.getTime()), duration, winingStatus));
|
||||
}
|
||||
}
|
||||
|
||||
// AI move
|
||||
private GameStatus aiPlayerPlace() throws GameBoardPlacedException {
|
||||
Log.i("game-OBJ-AI", "aiPLayerPlace");
|
||||
int[] move = GameAI.findBestMove(board.getBoard());
|
||||
return place(move[0], move[1], 2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
151
it114105/itp4501/Assignment/21-22/tictacteo/engine/GameAI.java
Normal file
151
it114105/itp4501/Assignment/21-22/tictacteo/engine/GameAI.java
Normal file
@@ -0,0 +1,151 @@
|
||||
package com.game.tictacteo.engine;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class GameAI {
|
||||
|
||||
static final byte player = 2;
|
||||
static final byte opponent = 1;
|
||||
|
||||
private static Boolean isMovesLeft(byte board[][]) {
|
||||
for (int i = 0; i < board.length; i++)
|
||||
for (int j = 0; j < board[i].length; j++)
|
||||
if (board[i][j] == 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int evaluate(byte[][] board) {
|
||||
// Checking for Rows is player or opponent victory.
|
||||
for (int row = 0; row < board.length; row++) {
|
||||
if (board[row][0] == board[row][1] &&
|
||||
board[row][1] == board[row][2]) {
|
||||
if (board[row][0] == player)
|
||||
return +10;
|
||||
else if (board[row][0] == opponent)
|
||||
return -10;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (int col = 0; col < board[0].length; col++) {
|
||||
if (board[0][col] == board[1][col] &&
|
||||
board[1][col] == board[2][col]) {
|
||||
if (board[0][col] == player)
|
||||
return +10;
|
||||
|
||||
else if (board[0][col] == opponent)
|
||||
return -10;
|
||||
}
|
||||
}
|
||||
|
||||
if (board[0][0] == board[1][1] && board[1][1] == board[2][2]) {
|
||||
if (board[0][0] == player)
|
||||
return +10;
|
||||
else if (board[0][0] == opponent)
|
||||
return -10;
|
||||
}
|
||||
|
||||
if (board[0][2] == board[1][1] && board[1][1] == board[2][0]) {
|
||||
if (board[0][2] == player)
|
||||
return +10;
|
||||
else if (board[0][2] == opponent)
|
||||
return -10;
|
||||
}
|
||||
|
||||
// Else if none of them have won then return 0
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int minimax(byte board[][], int depth, Boolean isMax) {
|
||||
int score = evaluate(board);
|
||||
|
||||
// Evaluated score if Maximizer has won the game
|
||||
if (score == 10)
|
||||
return score;
|
||||
|
||||
if (score == -10)
|
||||
return score;
|
||||
|
||||
// no winner then it is a tie if false
|
||||
if (isMovesLeft(board) == false)
|
||||
return 0;
|
||||
|
||||
if (isMax) {
|
||||
int best = -1000;
|
||||
|
||||
// Traverse all cells
|
||||
for (int i = 0; i < board.length; i++) {
|
||||
for (int j = 0; j < board[i].length; j++) {
|
||||
// Check cell is empty
|
||||
if (board[i][j] == 0) {
|
||||
// Make the move
|
||||
board[i][j] = player;
|
||||
|
||||
// calculate minimax recursively and choose
|
||||
best = Math.max(best, minimax(board, depth + 1, !isMax));
|
||||
|
||||
// Undo move
|
||||
board[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}else {
|
||||
int best = 1000;
|
||||
|
||||
// Traverse all cells
|
||||
for (int i = 0; i < board.length; i++) {
|
||||
for (int j = 0; j < board[i].length; j++) {
|
||||
// Check cell is empty
|
||||
if (board[i][j] == 0) {
|
||||
// Make the move
|
||||
board[i][j] = opponent;
|
||||
|
||||
// calculate minimax recursively and choose
|
||||
best = Math.min(best, minimax(board,
|
||||
depth + 1, !isMax));
|
||||
|
||||
// Undo move
|
||||
board[i][j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] findBestMove(byte board[][]) {
|
||||
int bestVal = -1000;
|
||||
int[] bestMove = new int[2];
|
||||
bestMove[0] = -1;
|
||||
bestMove[1] = -1;
|
||||
|
||||
// evaluate minimax func
|
||||
for (int i = 0; i < board.length; i++) {
|
||||
for (int j = 0; j < board[i].length; j++) {
|
||||
// Check cell is empty
|
||||
if (board[i][j] == 0) {
|
||||
// Make the move
|
||||
board[i][j] = player;
|
||||
|
||||
// compute evaluation function
|
||||
int moveVal = minimax(board, 0, false);
|
||||
|
||||
// Undo the move
|
||||
board[i][j] = 0;
|
||||
|
||||
// If the value of the current move is higher then best value, then update
|
||||
if (moveVal > bestVal) {
|
||||
bestMove[0] = i;
|
||||
bestMove[1] = j;
|
||||
bestVal = moveVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bestMove;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,139 @@
|
||||
package com.game.tictacteo.engine;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
public class GameBoard {
|
||||
|
||||
private final static int ROW = 3; // Game Board ROW
|
||||
private final static int COL = 3; // Game Board COL
|
||||
|
||||
private byte[][] board;
|
||||
private short step;
|
||||
private short winner; // Winner
|
||||
|
||||
public enum Status {
|
||||
CONTINUE,
|
||||
PLAYER1_WIN,
|
||||
PLAYER2_WIN,
|
||||
DRAW
|
||||
}
|
||||
|
||||
// 0 0 0
|
||||
// 0 0 0
|
||||
// 0 0 0
|
||||
|
||||
GameBoard() {
|
||||
board = new byte[ROW][COL];
|
||||
step = 0;
|
||||
winner = -1;
|
||||
}
|
||||
|
||||
public byte[][] getBoard() {
|
||||
return board;
|
||||
}
|
||||
|
||||
public GameStatus placePlayer1(int row, int col) throws GameBoardPlacedException {
|
||||
return place(row, col, 1);
|
||||
}
|
||||
|
||||
public GameStatus placePlayer2(int row, int col) throws GameBoardPlacedException{
|
||||
return place(row, col, 2);
|
||||
}
|
||||
|
||||
|
||||
private GameStatus place(int row, int col, int player) throws GameBoardPlacedException {
|
||||
if(board[row][col] != 0)
|
||||
throw new GameBoardPlacedException("The position is placed: " + row + " " + col);
|
||||
board[row][col] = (byte) player;
|
||||
step++; // count step for game
|
||||
return genGameStatus();
|
||||
}
|
||||
|
||||
private GameStatus genGameStatus(){
|
||||
|
||||
// return current game board status
|
||||
// step == board.length mean all is placed
|
||||
if(step == board[0].length * board.length)
|
||||
return new GameStatus(Status.DRAW, this.board);
|
||||
|
||||
// check has winner?
|
||||
if(winner == -1 && !checkWin())
|
||||
return new GameStatus(Status.CONTINUE, this.board);
|
||||
else
|
||||
return new GameStatus((this.winner == 1) ? Status.PLAYER1_WIN: Status.PLAYER2_WIN, this.board);
|
||||
|
||||
}
|
||||
|
||||
private boolean checkWin(){
|
||||
return (checkRows() || checkColumns() || checkDiagonals());
|
||||
}
|
||||
|
||||
|
||||
private boolean checkRows() {
|
||||
for (int i = 0; i < board.length; i++) {
|
||||
int count = 1;
|
||||
for (int j = 1; j < board[i].length; j++) {
|
||||
// compare other col is same?
|
||||
if (board[i][0] != 0 && board[i][0] == board[i][j])
|
||||
count++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (count == board[i].length){
|
||||
this.winner = board[i][0];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean checkColumns() {
|
||||
for (int i = 0; i < board[0].length; i++) {
|
||||
int count = 1;
|
||||
for (int j = 1; j < board.length; j++) {
|
||||
// compare other col is same?
|
||||
if (board[0][i] != 0 && board[0][i] == board[j][i])
|
||||
count++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (count == board.length) {
|
||||
this.winner = board[0][i];
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// checkDiagonals
|
||||
private boolean checkDiagonals() {
|
||||
int countX = 1; // for count left-top to right-bottom
|
||||
int countY = 1; // for count right-top to left-bottom
|
||||
for (int j = 1; j < board.length; j++) {
|
||||
// compare other col is same?
|
||||
if (board[0][0] != 0 && board[0][0] == board[j][j])
|
||||
countX++;
|
||||
if (board[0][board[0].length - 1] != 0 && board[0][board[0].length - 1] == board[j][board[0].length - 1 - j])
|
||||
countY++;
|
||||
}
|
||||
|
||||
|
||||
if (countX == board.length) {
|
||||
this.winner = board[0][0];
|
||||
return true;
|
||||
}
|
||||
|
||||
if (countY == board.length) {
|
||||
this.winner = board[0][board[0].length-1];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,9 @@
|
||||
package com.game.tictacteo.engine;
|
||||
|
||||
public class GameBoardPlacedException extends Exception{
|
||||
public GameBoardPlacedException(String mes){
|
||||
super(mes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -0,0 +1,12 @@
|
||||
package com.game.tictacteo.engine;
|
||||
|
||||
public class GameStatus {
|
||||
|
||||
public GameBoard.Status status;
|
||||
public byte[][] board;
|
||||
|
||||
public GameStatus(GameBoard.Status status, byte[][] board){
|
||||
this.status = status;
|
||||
this.board = board;
|
||||
}
|
||||
}
|
@@ -0,0 +1,106 @@
|
||||
package com.game.tictacteo.localDB;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.game.tictacteo.model.GameLog;
|
||||
|
||||
import java.sql.Date;
|
||||
import java.sql.Time;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GameLogDB extends SQLiteOpenHelper {
|
||||
|
||||
private static final String DATABASE_NAME = "GameLog.db";
|
||||
private static final String GAMESLOG_TABLE_NAME = "GamesLog";
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
// Singleton pattern
|
||||
private static GameLogDB instance = null;
|
||||
|
||||
public static GameLogDB getInstance(Context ctx) {
|
||||
if (instance == null)
|
||||
instance = new GameLogDB(ctx.getApplicationContext());
|
||||
return instance;
|
||||
}
|
||||
|
||||
public GameLogDB(Context context) {
|
||||
// applcation_context, db_name, factory, db_version
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
System.out.println("Database creating");
|
||||
String sql = "CREATE TABLE " + GAMESLOG_TABLE_NAME + " ( " +
|
||||
"gameID INTEGER PRIMARY KEY AUTOINCREMENT, " +
|
||||
"playDate TEXT NOT NULL, " +
|
||||
"playTime TEXT NOT NULL, " +
|
||||
"duration INTEGER NOT NULL, " +
|
||||
"winningStatus INTEGER NOT NULL);";
|
||||
|
||||
db.execSQL(sql);
|
||||
|
||||
}
|
||||
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
db.execSQL("DROP TABLE IF EXISTS " + GAMESLOG_TABLE_NAME + ";");
|
||||
onCreate(db);
|
||||
}
|
||||
|
||||
// Add log
|
||||
public void addLog(GameLog log) {
|
||||
SQLiteDatabase db = this.getWritableDatabase();
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
||||
SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm aa");
|
||||
|
||||
values.put("playDate", dateFormat.format(log.getPlayDate()));
|
||||
values.put("playTime", timeFormat.format(log.getPlayTime()));
|
||||
values.put("duration", log.getDuration());
|
||||
values.put("winningStatus", log.getWinningStatus());
|
||||
|
||||
db.insert(GAMESLOG_TABLE_NAME, null, values);
|
||||
db.close();
|
||||
}
|
||||
|
||||
// select all data
|
||||
public ArrayList<GameLog> readAllData() {
|
||||
SQLiteDatabase db = this.getReadableDatabase();
|
||||
Cursor cursor = db.query(GAMESLOG_TABLE_NAME, new String[]{"playDate", "playTime", "duration", "winningStatus"}, null, null, null, null, "gameId");
|
||||
ArrayList<GameLog> data = new ArrayList<GameLog>();
|
||||
|
||||
// Time formatter
|
||||
SimpleDateFormat timeFormat = new SimpleDateFormat("hh:mm aa");
|
||||
|
||||
try {
|
||||
while (cursor.moveToNext()) {
|
||||
|
||||
// yyyy-MM-dd striing to date object
|
||||
Date playDate = Date.valueOf(cursor.getString(0));
|
||||
Log.i("db", cursor.getString(1));
|
||||
Time playTime = new Time(timeFormat.parse(cursor.getString(1)).getTime());
|
||||
int duration = cursor.getInt(2);
|
||||
short winningStatus = cursor.getShort(3);
|
||||
|
||||
data.add(new GameLog(playDate, playTime, duration, winningStatus));
|
||||
|
||||
}
|
||||
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
db.close();
|
||||
return data;
|
||||
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user