Skip to content
Snippets Groups Projects
Commit 3730e352 authored by ACIKBAS TUNA's avatar ACIKBAS TUNA
Browse files

Merge branch 'main' of git.unistra.fr:tacikbas/projet_jv

parents 7448762b f7896831
Branches
No related merge requests found
......@@ -7,7 +7,7 @@ import java.util.ArrayList;
public class Game {
private int status;
public static final int WHITE_TURN = 1, BLACK_TURN = 2, GAME_OVER = 3;
public static final int WHITE_TURN = 1, BLACK_TURN = 2, WHITE_WON = 3, BLACK_WON = 4;
public Game() {
status = WHITE_TURN;
......@@ -37,9 +37,9 @@ public class Game {
public void nextTurn() {
if(isWhiteTurn())
setStatus(Game.BLACK_TURN);
else if(isBlackTurn())
setStatus(Game.WHITE_TURN);
setStatus(BLACK_TURN);
else
setStatus(WHITE_TURN);
}
public void clickPiece(PieceView clickedPiece, Board board, BoardView boardView, CustomMaterial material, Custom3dModel model, Log log, HUD hud) {
......@@ -58,7 +58,7 @@ public class Game {
// clicking a piece will ask her available moves
Position position = clickedPiece.getPosition();
board.setSelected(position);
boardView.resetColor(material);
boardView.resetTileColorAll(material);
boardView.setColor(material, position, CustomMaterial.SELECTED_TILE);
ArrayList<Position> moves = board.getPiece(position).getAvailableMoves(board);
......@@ -73,23 +73,15 @@ public class Game {
// shows all available moves on the tiles, with colors, each tile-color having a meaning
for (Position move : moves) {
if (board.isFree(move)) {
boardView.setColor(material, move, CustomMaterial.MOVABLE_TILE);
// test for "en passant"
if (board.isPawn(position) || board.isNwap(position)) {
if (board.isPawn(position)) {
Position enemy = new Position(move.getX(), position.getY());
boolean isEnPassant = false;
if (board.isEnemy(enemy, position)) {
if (board.isPawn(enemy)) {
if (((Pawn) board.getPiece(enemy)).isEnPassant()) {
isEnPassant = true;
}
}
if (board.isNwap(enemy)) {
if (((Nwap) board.getPiece(enemy)).isEnPassant()) {
isEnPassant = true;
}
if (board.isEnemy(enemy, position) && board.isPawn(enemy)) {
if (((Pawn) board.getPiece(enemy)).isEnPassant()) {
isEnPassant = true;
}
}
if (isEnPassant) {
......@@ -106,10 +98,22 @@ public class Game {
boardView.getPiece(move.getID()).setTargeted(material, CustomMaterial.SPECIAL_TILE);
}
// PROMOTION (attacking or not)
if ((board.isPawn(position) || board.isNwap(position)) && (move.getY() == 8 || move.getY() == 1)) {
if ((board.isPawn(position)) && (move.getY() == 8 || move.getY() == 1)) {
boardView.setColor(material, move, CustomMaterial.SPECIAL_TILE);
}
}
// Prevent available moves that let the king in check state
ArrayList<Position> toPrevent = new ArrayList<>();
for (Position move : moves) {
boolean selfCheck = applyMoveAndCheckVerification(board, boardView, getStatus(), move);
if(selfCheck) {
toPrevent.add(move); // Prevents the move
}
}
for (Position elem : toPrevent) {
boardView.resetTileColor(material, elem);
}
}
}
......@@ -136,7 +140,7 @@ public class Game {
}
// --- ALL SPECIAL MOVES ---
if(state == TileView.SPECIAL) {
if(board.isPawn(selected) || board.isNwap(selected)) {
if(board.isPawn(selected)) {
// --- PROMOTION ---
if(arrival.getY() == 8 || arrival.getY() == 1) {
// --- ATTACK (while doing promotion) ---
......@@ -244,13 +248,154 @@ public class Game {
}
}
// --- Resets board coloring, doing any action or not ---
boardView.resetColor(material);
boardView.resetTileColorAll(material);
// updates game status
if(moved) {
nextTurn(); // change player turn
log.save(board, boardView); // saves current board
hud.rollbackShow(); // show rollback button (if not showed already)
// signals if there is a check !
boolean echec = checkVerification(board, getStatus()); // test the opponent check (turn just changed)
if(echec) {
if (isWhiteTurn()) {
System.out.println("echec white");
}
if (isBlackTurn()) {
System.out.println("echec black");
}
}
}
}
public boolean checkVerification(Board board, int color){
boolean isCheck = false;
for (int i = 0 ; i < 64 ; i++){
Piece p = board.getPiece(i);
if(p != null && p.getColor() != color) {
// get all moves
ArrayList<Position> moves = p.getAvailableMoves(board);
// if kamikaze adds explosion moves
if(p.getClass() == Kamikaze.class) {
ArrayList<Position> explosions = ((Kamikaze) p).getExplosion();
moves.addAll(explosions);
}
// if it kills the king of specified color, check !
for (Position move : moves) {
if (board.isKing(move) && board.getPiece(move).getColor() == color) {
isCheck = true;
}
}
}
}
return isCheck;
}
public boolean applyMoveAndCheckVerification(Board originalBoard, BoardView boardView, int color, Position emulatedMove) {
Board board = originalBoard.newInstanceCopy(); // create a copy, to do tests on it
board.setSelected(originalBoard.getSelected());
TileView clickedTile = boardView.getTile(emulatedMove.getID());
// --- EMULATES THE MOVEMENT -----------------------------------------------
// --- Analyses the clicked tile type, and executes related actions ---
int state = clickedTile.getState();
Position selected = board.getSelected();
Position arrival = clickedTile.getPosition();
if(state != TileView.NORMAL && state != TileView.SELECTED) {
// --- Resets enPassant ---
for(int j = 1 ; j <= 8 ; j++) {
for(int i = 1 ; i <= 8 ; i++) {
Position p = new Position(i, j);
if (board.isPawn(p)) {
((Pawn) board.getPiece(p)).setEnPassant(false);
}
if (board.isNwap(p)) {
((Nwap) board.getPiece(p)).setEnPassant(false);
}
}
}
// --- ALL SPECIAL MOVES ---
if(state == TileView.SPECIAL) {
if(board.isPawn(selected)) {
// --- PROMOTION ---
if(arrival.getY() == 8 || arrival.getY() == 1) {
// Promotion to Queen (by default, Queen for now)
board.mutationOfSelectedPiece(Board.QUEEN);
board.movePiece(selected, arrival);
}
// --- PRISE EN PASSANT ---
else {
Position enemy = new Position(arrival.getX(), selected.getY());
board.killPiece(enemy.getID()); // because we don't move "on it", we need to kill it manually (model)
Position enPassantArrival = new Position(arrival.getX(), selected.getY()+1);
if(board.getSelectedPiece().getColor() == Piece.BLACK) {
enPassantArrival.setY(selected.getY()-1);
}
board.movePiece(selected, enPassantArrival);
}
}
// --- CASTLING (from king) ---
if(board.isKing(selected)) {
int x = Board.D; // king x arrival, for west-rook
if(arrival.getX() == Board.H) {
x = Board.F; // king x arrival, for east-rook
}
Position kingArrival = new Position(x, selected.getY());
board.movePiece(selected, kingArrival); // move king
board.movePiece(arrival, selected); // move rook
}
// --- CASTLING (from rook) ---
else if(board.isRook(selected)) {
int x = Board.D; // king x arrival, for west-rook
if (selected.getX() == Board.H) {
x = Board.F; // king x arrival, for east-rook
}
Position kingArrival = new Position(x, arrival.getY());
board.movePiece(arrival, kingArrival); // move king
board.movePiece(selected, arrival); // move rook
}
}
// --- EXPLOSION MOVES ---
else if (state == TileView.EXPLOSION) {
for(int n = 0 ; n < 64 ; n++) {
if(boardView.getTile(n).getState() == TileView.EXPLOSION) {
if(boardView.getPiece(n) != null) {
board.killPiece(n);
}
}
}
}
// --- STANDARD MOVES ---
else {
// --- ATTACK ---
if(state == TileView.ATTACK) {
// --- MAGICIAN CHANGE ---
if(board.isMagician(selected)) {
Magician magician = (Magician) board.getPiece(selected);
Piece enemy = board.getPiece(arrival);
magician.steal(enemy); // muahaha
}
}
// --- EN PASSANT activation ---
if(Math.abs(selected.getY() - arrival.getY()) == 2) {
if(board.isPawn(selected)) {
((Pawn) board.getPiece(selected)).setEnPassant(true);
}
if(board.isNwap(selected)) {
((Nwap) board.getPiece(selected)).setEnPassant(true);
}
}
// --- MOVE ---
board.movePiece(selected, arrival); // move piece
}
}
// --- END OF EMULATION -------------------------------------------------
return checkVerification(board, color); // we test the board after emulating a move
}
}
......@@ -19,14 +19,8 @@ public class Log {
}
public void save(Board board, BoardView boardView) {
Board copy = new Board();
for(int n = 0 ; n < 64 ; n++) {
// we make a NEW COPY, not just getting pointer !
Piece piece = board.getPiece(n);
if(piece != null) {
copy.setPiece(piece.newInstanceCopy());
}
}
// we make a NEW COPY, not just getting pointer !
Board copy = board.newInstanceCopy();
int id = logPieces.size();
logPieces.add(id, copy.getAllPieces());
// for graveyards, we don't need a copy, because pieces aren't moving at all once inside, so there will be no issues
......
......@@ -3,8 +3,6 @@ package controller;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.scene.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.AnchorPane;
......@@ -12,7 +10,6 @@ import javafx.stage.Stage;
import model.*;
import view.*;
import java.util.ArrayList;
public class Main extends Application {
......@@ -136,7 +133,7 @@ public class Main extends Application {
// event - rollback
hud.getRollback().addEventHandler(MouseEvent.MOUSE_CLICKED, event -> {
boardView.resetColor(material);
boardView.resetTileColorAll(material);
log.rollback(board, boardView, material, model, group3d, game, hud);
});
......
......@@ -209,4 +209,14 @@ public class Board {
pieces[i] = null;
}
}
public Board newInstanceCopy() {
Board copy = new Board();
for(int n = 0 ; n < 64 ; n++) {
Piece piece = getPiece(n);
if(piece != null) {
copy.setPiece(piece.newInstanceCopy());
}
}
return copy;
}
}
......@@ -2,31 +2,12 @@ package model;
import java.util.ArrayList;
public class Kamikaze extends Pawn { // aka Trojan knight :P
public class Kamikaze extends Knight { // aka Trojan knight :P
public Kamikaze(Position p, int color) {
super(p, color);
}
@Override
public ArrayList<Position> getAvailableMoves(Board b) {
ArrayList<Position> moves = new ArrayList<>();
Position arrival;
// list of the 8 kamikaze-knight specific movements
int[] all_x = {1, 2, 2, 1, -1, -2, -2, -1};
int[] all_y = {2, 1, -1, -2, -2, -1, 1, 2};
for(int n = 0 ; n < all_x.length ; n++) { // for each direction
int x = all_x[n];
int y = all_y[n];
arrival = new Position(p.getX() + x, p.getY() + y);
if (b.isEnemy(arrival, p) || b.isFree(arrival)) {
moves.add(arrival);
}
}
return moves;
}
// getAvailableMoves is in Knight already
public ArrayList<Position> getExplosion() {
......
......@@ -13,71 +13,69 @@ public class Nwap extends Pawn {
@Override
public ArrayList<Position> getAvailableMoves(Board b) {
ArrayList<Position> moves = new ArrayList<Position>();
ArrayList<Position> moves = new ArrayList<>();
Position arrival;
Position arrival2;
if(color == Piece.WHITE) { // black and white have an opposite direction behavior
if(!hasBeenMoved){
// up left 2
// up right 2
}
// up left 1
// up left
arrival = new Position(p.getX()-1, p.getY() +1);
if(arrival.isCorrect() && b.isFree(arrival)) {
moves.add(arrival);
if(!hasBeenMoved) {
arrival2 = new Position(p.getX() - 2, p.getY() + 2);
if (arrival2.isCorrect() && b.isFree(arrival2)) {
moves.add(arrival2);
}
}
}
arrival2 = new Position(p.getX()-2, p.getY() +2);
if(arrival2.isCorrect() && b.isFree(arrival2)) { moves.add(arrival2); }
moves.add(arrival); }
// up right 1
// up right
arrival = new Position(p.getX()+1, p.getY() +1);
if(arrival.isCorrect() && b.isFree(arrival)) {
arrival2 = new Position(p.getX()+2, p.getY() +2);
if(arrival2.isCorrect() && b.isFree(arrival2)) { moves.add(arrival2); }
moves.add(arrival); }
moves.add(arrival);
if (!hasBeenMoved) {
arrival2 = new Position(p.getX() + 2, p.getY() + 2);
if (arrival2.isCorrect() && b.isFree(arrival2)) {
moves.add(arrival2);
}
}
}
// up attack
arrival = new Position(p.getX(),p.getY()+1);
if(b.isEnemy(arrival,p)) {moves.add(arrival);}
}
else {
if(!hasBeenMoved){
}
// up left 1
// down left
arrival = new Position(p.getX()-1, p.getY() -1);
if(arrival.isCorrect() && b.isFree(arrival)) {
// up left 2
arrival2 = new Position(p.getX()-2, p.getY() -2);
if(arrival2.isCorrect() && b.isFree(arrival2)) { moves.add(arrival2); }
moves.add(arrival); }
moves.add(arrival);
if (!hasBeenMoved) {
arrival2 = new Position(p.getX() - 2, p.getY() - 2);
if (arrival2.isCorrect() && b.isFree(arrival2)) {
moves.add(arrival2);
}
}
}
// up left 1
// down right
arrival = new Position(p.getX()+1, p.getY() -1);
if(arrival.isCorrect() && b.isFree(arrival)) {
moves.add(arrival);
if (!hasBeenMoved) {
arrival2 = new Position(p.getX() + 2, p.getY() - 2);
if (arrival2.isCorrect() && b.isFree(arrival2)) {
moves.add(arrival2);
}
}
}
// up left 2
arrival2 = new Position(p.getX()+2, p.getY() -2);
if(arrival2.isCorrect() && b.isFree(arrival2)) { moves.add(arrival2); }moves.add(arrival); }
// down attack
arrival = new Position(p.getX(),p.getY()-1);
if(b.isEnemy(arrival,p)) {moves.add(arrival);}
}
return moves;
}
......
......@@ -6,8 +6,6 @@ import javafx.scene.shape.*;
import model.*;
import javafx.util.Duration;
import java.util.ArrayList;
public class BoardView {
public static final int BOARD_SIZE = 16, CENTERED_ORIGIN = -BOARD_SIZE*7/2, BOARD_HEIGHT = -5, GRAVEYARD_HEIGHT = -1;
......@@ -46,7 +44,7 @@ public class BoardView {
blackGraveyard = new PieceView[16]; // 16 is maximum kills
whiteGraveyard = new PieceView[16];
resetColor(material); // init/reset the board squares with black and white
resetTileColorAll(material); // init/reset the board squares with black and white
// creates the board visual border
border = new Box[4];
......@@ -179,23 +177,28 @@ public class BoardView {
piece.getObj().setTranslateY(GRAVEYARD_HEIGHT); // place at right height (Y axis) on table
}
public void resetColor(CustomMaterial material) {
public void resetTileColorAll(CustomMaterial material) {
for(int n = 0, j = 1 ; j <= 8 ; j++) {
for (int i = 1; i <= 8; i++, n++) {
// resets board with black and white - bottom left (first case) is black, then alternates
if((i + j) % 2 == 0) {
getTileObj(n).setMaterial(material.get(CustomMaterial.BLACK_TILE)); // (visually)
} else {
getTileObj(n).setMaterial(material.get(CustomMaterial.WHITE_TILE)); // (visually)
}
getTile(n).setState(TileView.NORMAL); // (on 'state' attribute)
if(getPiece(n) != null) {
getPiece(n).resetTargeted(material); // reset the 3d pieces color too (visual)
}
resetTileColor(material, new Position(i, j));
}
}
}
public void resetTileColor(CustomMaterial material, Position p) {
int i = p.getX(), j = p.getY(), n = p.getID();
// resets board with black and white - bottom left (first case) is black, then alternates
if((i + j) % 2 == 0) {
getTileObj(n).setMaterial(material.get(CustomMaterial.BLACK_TILE)); // (visually)
} else {
getTileObj(n).setMaterial(material.get(CustomMaterial.WHITE_TILE)); // (visually)
}
getTile(n).setState(TileView.NORMAL); // (on 'state' attribute)
if(getPiece(n) != null) {
getPiece(n).resetTargeted(material); // reset the 3d pieces color too (visual)
}
}
public void setColor(CustomMaterial material, Position position, int type) {
int id = position.getID();
// set the new color-type (visually)
......
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