From b027fe81a82d21559077b5b0d6f60c938d6497de Mon Sep 17 00:00:00 2001 From: rishab Date: Thu, 2 Apr 2020 21:27:06 +0530 Subject: [PATCH] Added sliding tile puzzle game --- app/src/main/AndroidManifest.xml | 1 + .../example/alzapp/PuzzleMainActivity.java | 322 ++++++++++ .../com/example/alzapp/QuickPlayMenu.java | 20 +- .../main/res/drawable-hdpi/ic_action_name.png | Bin 430 -> 0 bytes .../main/res/drawable-mdpi/ic_action_name.png | Bin 312 -> 0 bytes .../res/drawable-xhdpi/ic_action_name.png | Bin 590 -> 0 bytes .../res/drawable-xxhdpi/ic_action_name.png | Bin 907 -> 0 bytes .../res/drawable-xxxhdpi/ic_action_name.png | Bin 1285 -> 0 bytes .../res/layout/activity_quick_play_menu.xml | 4 +- app/src/main/res/values/arrays.xml | 11 + app/src/main/res/values/colors.xml | 561 ++++++++++++++++++ 11 files changed, 914 insertions(+), 5 deletions(-) create mode 100644 app/src/main/java/com/example/alzapp/PuzzleMainActivity.java delete mode 100644 app/src/main/res/drawable-hdpi/ic_action_name.png delete mode 100644 app/src/main/res/drawable-mdpi/ic_action_name.png delete mode 100644 app/src/main/res/drawable-xhdpi/ic_action_name.png delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_action_name.png delete mode 100644 app/src/main/res/drawable-xxxhdpi/ic_action_name.png create mode 100644 app/src/main/res/values/arrays.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 7cd613d..9bf9208 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,7 @@ + diff --git a/app/src/main/java/com/example/alzapp/PuzzleMainActivity.java b/app/src/main/java/com/example/alzapp/PuzzleMainActivity.java new file mode 100644 index 0000000..223c18d --- /dev/null +++ b/app/src/main/java/com/example/alzapp/PuzzleMainActivity.java @@ -0,0 +1,322 @@ +package com.example.alzapp; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.net.Uri; +import android.os.Bundle; +import android.provider.MediaStore; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.Chronometer; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.DialogFragment; +import androidx.fragment.app.FragmentManager; + +import com.example.alzapp.A_Star_Class_Solver.model.Board; +import com.example.alzapp.A_Star_Class_Solver.model.Place; + +import java.io.FileNotFoundException; + +//import com.example.alzapp.A_Star_Class_Solver.model.R; + + +public class PuzzleMainActivity extends AppCompatActivity { + + /** The main view. */ + private ViewGroup mainView; + + /** The game board. */ + private Board board; + + /** The board view that generates the tiles and lines using 2-D graphics. */ + private BoardView boardView; + + /** Text view to show the user the number of movements. */ + private TextView moves; + + /** The board size. Default value is an 4x4 game. */ + private int boardSize = 4; + + private Chronometer chronometer; + public boolean running; + + Button b; + + /* + * (non-Javadoc) + * + * @see android.support.v7.app.ActionBarActivity#onCreate(android.os.Bundle) + */ + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_slide_tile_puzzle); + mainView = (ViewGroup) findViewById(R.id.mainLayout); + chronometer = (Chronometer) findViewById(R.id.slidingTileChronometer); + moves = (TextView) findViewById(R.id.moves); + moves.setTextColor(Color.WHITE); + moves.setTextSize(20); + this.newGame(); + + + b = findViewById(R.id.btnSelectImage); + b.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT); + photoPickerIntent.setType("image/*"); + photoPickerIntent.putExtra(Intent.EXTRA_LOCAL_ONLY, false); + startActivityForResult(Intent.createChooser(photoPickerIntent,"Complete Action Using"), 1); + } + }); + + + if (!running) { + chronometer.start(); + running = true; + } + + + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == 1 && resultCode == RESULT_OK && data != null) { + Uri pickedImage = data.getData(); + String[] filePath = { MediaStore.Images.Media.DATA }; + Bitmap bitmap = null; + try { + bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(pickedImage)); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + bitmap = resizeBitmapFitXY(this.boardView.getWidth(), this.boardView.getHeight(), bitmap); + boardView.setBitmap(bitmap); + } + } + + public Bitmap resizeBitmapFitXY(int width, int height, Bitmap bitmap){ + Bitmap background = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); + float originalWidth = bitmap.getWidth(), originalHeight = bitmap.getHeight(); + Canvas canvas = new Canvas(background); + float scale, xTranslation = 0.0f, yTranslation = 0.0f; + if (originalWidth > originalHeight) { + scale = height/originalHeight; + xTranslation = (width - originalWidth * scale)/2.0f; + } + else { + scale = width / originalWidth; + yTranslation = (height - originalHeight * scale)/2.0f; + } + Matrix transformation = new Matrix(); + transformation.postTranslate(xTranslation, yTranslation); + transformation.preScale(scale, scale); + Paint paint = new Paint(); + paint.setFilterBitmap(true); + canvas.drawBitmap(bitmap, transformation, paint); + return background; + } + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu) + */ + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + /** + * Generates a new game. + */ + private void newGame() { + this.board = new Board(this.boardSize); + this.board.addBoardChangeListener(boardChangeListener); + this.board.rearrange(); + this.mainView.removeView(boardView); + this.boardView = new BoardView(this, board); + this.mainView.addView(boardView); + this.moves.setText("Number of movements: 0"); + } + + /** + * Changes the size of the board + * + * @param newSize + */ + public void changeSize(int newSize) { + if (newSize != this.boardSize) { + this.boardSize = newSize; + this.newGame(); + boardView.invalidate(); + } + } + + /* + * (non-Javadoc) + * + * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem) + */ + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + switch (item.getItemId()) { + case R.id.action_settings: + FragmentManager fm = getSupportFragmentManager(); + SettingsDialogFragment settings = new SettingsDialogFragment( + this.boardSize); + settings.show(fm, "fragment_settings"); + break; + case R.id.action_new_game: + new AlertDialog.Builder(this) + .setTitle("New Game") + .setMessage("Are you sure you want to begin a new game?") + .setPositiveButton(android.R.string.yes, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int which) { + board.rearrange(); + } + }) + .setNegativeButton(android.R.string.no, + new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, + int which) { + // do nothing + } + }).setIcon(android.R.drawable.ic_dialog_alert) + .show(); + break; + case R.id.action_help: + boardView.autoSolve(); + break; + } + return super.onOptionsItemSelected(item); + } + + /** The board change listener. */ + private Board.BoardChangeListener boardChangeListener = new Board.BoardChangeListener() { + public void tileSlid(Place from, Place to, int numOfMoves) { + moves.setText("Number of movements: " + + Integer.toString(numOfMoves)); + } + + public void solved(int numOfMoves) { + moves.setText("Solved in " + Integer.toString(numOfMoves) + + " moves!"); + + if(running){ + chronometer.stop(); + running = false; + } + + Toast.makeText(getApplicationContext(), "You won!", + Toast.LENGTH_LONG).show(); + + finish(); + } + }; + + /** + * The Class SettingsDialogFragment. Shows the settings alert dialog in + * order to change the size of the board. + */ + public class SettingsDialogFragment extends DialogFragment { + + /** The size. */ + private int size; + + /** + * Instantiates a new settings dialog fragment. + * + * @param size + * the size + */ + public SettingsDialogFragment(int size) { + this.size = size; + } + + /** + * Sets the size. + * + * @param size + * the new size + */ + void setSize(int size) { + this.size = size; + } + + /** + * Gets the size. + * + * @return the size + */ + int getSize() { + return this.size; + } + + /* + * (non-Javadoc) + * + * @see + * android.support.v4.app.DialogFragment#onCreateDialog(android.os.Bundle + * ) + */ + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + // Set the dialog title + builder.setTitle("Define the size of the puzzle") + .setSingleChoiceItems(R.array.size_options, this.size - 2, + new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, + int which) { + setSize(which + 2); + + } + + }) + .setPositiveButton("Change", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int id) { + ((PuzzleMainActivity) getActivity()) + .changeSize(getSize()); + } + }) + .setNegativeButton("Cancel", + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, + int id) { + dialog.cancel(); + } + }); + + return builder.create(); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/alzapp/QuickPlayMenu.java b/app/src/main/java/com/example/alzapp/QuickPlayMenu.java index 77b6650..34f9f48 100644 --- a/app/src/main/java/com/example/alzapp/QuickPlayMenu.java +++ b/app/src/main/java/com/example/alzapp/QuickPlayMenu.java @@ -7,6 +7,8 @@ import android.view.View; import android.widget.Button; import android.widget.TextView; +import androidx.appcompat.app.AppCompatActivity; + import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.toolbox.Volley; @@ -14,8 +16,6 @@ import com.android.volley.toolbox.Volley; import org.json.JSONException; import org.json.JSONObject; -import androidx.appcompat.app.AppCompatActivity; - /******* Created on: 21/01/2020 @@ -29,7 +29,7 @@ public class QuickPlayMenu extends AppCompatActivity { private Button jumble; private Button tilematch; private Button quiz; - private Button game4; + private Button slidingTiles; private long jumble_elapsed_millis = 0; private String username; private TextView username_text; @@ -45,6 +45,7 @@ public class QuickPlayMenu extends AppCompatActivity { jumble = findViewById(R.id.jumble); tilematch = findViewById(R.id.tilematch); quiz = findViewById(R.id.quiz); + slidingTiles = findViewById(R.id.slidingTilesPuzzle); Intent intent = getIntent(); username = intent.getStringExtra(login.EXTRA_TEXT); @@ -80,6 +81,19 @@ public class QuickPlayMenu extends AppCompatActivity { } }); + slidingTiles.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(QuickPlayMenu.this,PuzzleMainActivity.class); + startActivity(intent); + + } + }); + + + + + Button back = (Button) findViewById(R.id.back); back.setOnClickListener(new View.OnClickListener() { diff --git a/app/src/main/res/drawable-hdpi/ic_action_name.png b/app/src/main/res/drawable-hdpi/ic_action_name.png deleted file mode 100644 index 6600483bee2814639c59844cd38a35b439479017..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 430 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