taha1992's picture
Upload 695 files
2311079 verified
raw
history blame
11.4 kB
package com.tacticmaster.board;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.tacticmaster.R;
import com.tacticmaster.puzzle.Puzzle;
public class ChessboardView extends View {
public interface PuzzleFinishedListener {
void onPuzzleSolved(Puzzle puzzle);
void onPuzzleNotSolved(Puzzle puzzle);
}
private static final int NEXT_PUZZLE_DELAY = 3000;
private Puzzle puzzle;
private Chessboard chessboard;
private static final int BOARD_SIZE = 8;
private Paint lightBrownPaint;
private Paint darkBrownPaint;
private Paint bitmapPaint;
private Paint selectionPaint;
private Bitmap whiteKing, blackKing, whiteQueen, blackQueen, whiteRook, blackRook, whiteBishop, blackBishop, whiteKnight, blackKnight, whitePawn, blackPawn;
private Bitmap scaledWhiteKing, scaledBlackKing, scaledWhiteQueen, scaledBlackQueen, scaledWhiteRook, scaledBlackRook, scaledWhiteBishop, scaledBlackBishop, scaledWhiteKnight, scaledBlackKnight, scaledWhitePawn, scaledBlackPawn;
private ImageView playerTurnIcon;
private int selectedRow = -1;
private int selectedCol = -1;
private Paint textPaint;
private final Handler handler = new Handler(Looper.getMainLooper());
private PuzzleFinishedListener puzzleFinishedListener;
private boolean puzzleSolved = false;
public ChessboardView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
lightBrownPaint = new Paint();
lightBrownPaint.setColor(Color.parseColor("#D2B48C")); // Light brown color
darkBrownPaint = new Paint();
darkBrownPaint.setColor(Color.parseColor("#8B4513")); // Darker brown color
textPaint = new Paint();
textPaint.setColor(Color.BLACK);
textPaint.setTextSize(30);
textPaint.setAntiAlias(true);
bitmapPaint = new Paint();
bitmapPaint.setAntiAlias(true);
bitmapPaint.setFilterBitmap(true);
bitmapPaint.setDither(true);
selectionPaint = new Paint();
selectionPaint.setColor(Color.YELLOW);
selectionPaint.setStyle(Paint.Style.STROKE);
selectionPaint.setStrokeWidth(5);
whiteKing = BitmapFactory.decodeResource(getResources(), R.drawable.wk);
blackKing = BitmapFactory.decodeResource(getResources(), R.drawable.bk);
whiteQueen = BitmapFactory.decodeResource(getResources(), R.drawable.wq);
blackQueen = BitmapFactory.decodeResource(getResources(), R.drawable.bq);
whiteRook = BitmapFactory.decodeResource(getResources(), R.drawable.wr);
blackRook = BitmapFactory.decodeResource(getResources(), R.drawable.br);
whiteBishop = BitmapFactory.decodeResource(getResources(), R.drawable.wb);
blackBishop = BitmapFactory.decodeResource(getResources(), R.drawable.bb);
whiteKnight = BitmapFactory.decodeResource(getResources(), R.drawable.wn);
blackKnight = BitmapFactory.decodeResource(getResources(), R.drawable.bn);
whitePawn = BitmapFactory.decodeResource(getResources(), R.drawable.wp);
blackPawn = BitmapFactory.decodeResource(getResources(), R.drawable.bp);
}
private void updatePlayerTurnIcon(boolean isWhiteTurn) {
if (isWhiteTurn) {
playerTurnIcon.setImageResource(R.drawable.ic_white_turn);
} else {
playerTurnIcon.setImageResource(R.drawable.ic_black_turn);
}
}
public void setPlayerTurnIcon(ImageView playerTurnIcon) {
this.playerTurnIcon = playerTurnIcon;
}
public void setPuzzle(Puzzle puzzle) {
this.puzzle = puzzle;
this.chessboard = new Chessboard(puzzle);
this.selectedRow = -1;
this.selectedCol = -1;
this.puzzleSolved = false;
invalidate();
handler.postDelayed(() -> {
this.chessboard.makeFirstMove();
invalidate();
}, 2000);
}
public void setPuzzleSolvedListener(PuzzleFinishedListener listener) {
this.puzzleFinishedListener = listener;
}
public Puzzle getPuzzle() {
return puzzle;
}
public Chessboard getChessboard() {
return chessboard;
}
public int getSelectedCol() {
return selectedCol;
}
public int getSelectedRow() {
return selectedRow;
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int width = getWidth();
int height = getHeight();
int tileSize = Math.min(width, height) / BOARD_SIZE;
int col = (int) (event.getX() / tileSize);
int row = (int) (event.getY() / tileSize);
char piece = chessboard.getBoard()[row][col];
boolean isWhiteToMove = chessboard.isWhiteToMove();
if (selectedRow == -1 && selectedCol == -1) {
if (piece != ' ' && ((isWhiteToMove && Character.isUpperCase(piece)) || (!isWhiteToMove && Character.isLowerCase(piece)))) {
selectedRow = row;
selectedCol = col;
}
} else if (chessboard.isFirstMoveDone()) {
if (chessboard.isCorrectMove(selectedRow, selectedCol, row, col)) {
if (chessboard.movePiece(selectedRow, selectedCol, row, col)) {
selectedRow = -1;
selectedCol = -1;
handler.postDelayed(() -> {
chessboard.makeNextMove();
invalidate();
}, 1300);
}
} else {
Toast.makeText(getContext(), "Wrong solution", Toast.LENGTH_SHORT).show();
handler.postDelayed(() -> {
puzzleFinishedListener.onPuzzleNotSolved(this.puzzle);
}, NEXT_PUZZLE_DELAY);
}
}
invalidate();
performClick();
return true;
}
return super.onTouchEvent(event);
}
@Override
public boolean performClick() {
return super.performClick();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int tileSize = (int) ((Math.min(w, h) * 0.95f / BOARD_SIZE));
scaledWhiteKing = Bitmap.createScaledBitmap(whiteKing, tileSize, tileSize, true);
scaledBlackKing = Bitmap.createScaledBitmap(blackKing, tileSize, tileSize, true);
scaledWhiteQueen = Bitmap.createScaledBitmap(whiteQueen, tileSize, tileSize, true);
scaledBlackQueen = Bitmap.createScaledBitmap(blackQueen, tileSize, tileSize, true);
scaledWhiteRook = Bitmap.createScaledBitmap(whiteRook, tileSize, tileSize, true);
scaledBlackRook = Bitmap.createScaledBitmap(blackRook, tileSize, tileSize, true);
scaledWhiteBishop = Bitmap.createScaledBitmap(whiteBishop, tileSize, tileSize, true);
scaledBlackBishop = Bitmap.createScaledBitmap(blackBishop, tileSize, tileSize, true);
scaledWhiteKnight = Bitmap.createScaledBitmap(whiteKnight, tileSize, tileSize, true);
scaledBlackKnight = Bitmap.createScaledBitmap(blackKnight, tileSize, tileSize, true);
scaledWhitePawn = Bitmap.createScaledBitmap(whitePawn, tileSize, tileSize, true);
scaledBlackPawn = Bitmap.createScaledBitmap(blackPawn, tileSize, tileSize, true);
invalidate();
}
@Override
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
int width = getWidth();
int height = getHeight();
int tileSize = Math.min(width, height) / BOARD_SIZE;
boolean isWhiteToMove = chessboard.isWhiteToMove();
updatePlayerTurnIcon(isWhiteToMove);
for (int row = 0; row < BOARD_SIZE; row++) {
for (int col = 0; col < BOARD_SIZE; col++) {
var colorChoice = (col + row) % 2 == 0;
if (!isWhiteToMove)
colorChoice = !colorChoice;
Paint paint = colorChoice ? lightBrownPaint : darkBrownPaint;
int left = col * tileSize;
int top = row * tileSize;
int right = left + tileSize;
int bottom = top + tileSize;
canvas.drawRect(left, top, right, bottom, paint);
}
}
if (selectedRow != -1 && selectedCol != -1) {
int left = selectedCol * tileSize;
int top = selectedRow * tileSize;
int right = left + tileSize;
int bottom = top + tileSize;
canvas.drawRect(left, top, right, bottom, selectionPaint);
}
for (int col = 0; col < BOARD_SIZE; col++) {
String label = String.valueOf((char) ('a' + col));
float x = col * tileSize + ((float) tileSize / 2 - textPaint.measureText(label) / 2) * 1.9f;
float y = height - 10;
canvas.drawText(label, x, y, textPaint);
}
for (int row = 0; row < BOARD_SIZE; row++) {
String label = isWhiteToMove ? String.valueOf(BOARD_SIZE - row) : String.valueOf(row + 1);
float x = 10;
float y = row * tileSize + ((float) tileSize / 2 + textPaint.getTextSize() / 2) * .4f;
canvas.drawText(label, x, y, textPaint);
}
if (chessboard != null) {
for (int row = 0; row < BOARD_SIZE; row++) {
for (int col = 0; col < BOARD_SIZE; col++) {
char piece = chessboard.getBoard()[row][col];
if (piece != ' ') {
Bitmap pieceBitmap = getPieceBitmap(piece);
if (pieceBitmap != null) {
float left = col * tileSize;
float top = row * tileSize;
canvas.drawBitmap(pieceBitmap, left, top, bitmapPaint);
}
}
}
}
if (chessboard.solved() && puzzleFinishedListener != null && !puzzleSolved) {
puzzleSolved = true;
handler.postDelayed(() -> puzzleFinishedListener.onPuzzleSolved(this.puzzle), NEXT_PUZZLE_DELAY);
}
}
}
private Bitmap getPieceBitmap(char piece) {
return switch (piece) {
case 'K' -> scaledWhiteKing;
case 'k' -> scaledBlackKing;
case 'Q' -> scaledWhiteQueen;
case 'q' -> scaledBlackQueen;
case 'R' -> scaledWhiteRook;
case 'r' -> scaledBlackRook;
case 'B' -> scaledWhiteBishop;
case 'b' -> scaledBlackBishop;
case 'N' -> scaledWhiteKnight;
case 'n' -> scaledBlackKnight;
case 'P' -> scaledWhitePawn;
case 'p' -> scaledBlackPawn;
default -> null;
};
}
}