Fix NullPointerException when using Window view + improve lisibility + fix Triplet.equals + add View.displayWinner

This commit is contained in:
Quentin Legot 2021-04-07 16:47:59 +02:00
parent 28a1702bfd
commit dfe1c2ff72
8 changed files with 92 additions and 79 deletions

View File

@ -54,6 +54,8 @@ public class Main {
view = new Terminal(game); view = new Terminal(game);
else else
view = new Window(game); view = new Window(game);
} else {
view = new Window(game);
} }
} else } else
throw new NoSuchElementException("Pas assez d'arguments"); throw new NoSuchElementException("Pas assez d'arguments");

View File

@ -28,43 +28,31 @@ public class Game {
} }
public void changeCurrentPlayer(){ public void changeCurrentPlayer(){
currentPlayer = (currentPlayer == players[1])? players[0] : players[1]; currentPlayer = getOtherPlayer();
} }
public void checkDrownedShips(){ public void checkDrownedShips(){
Player otherPlayer = (currentPlayer == players[1])? players[0] : players[1]; Player otherPlayer = getOtherPlayer();
for(Ship ship : currentPlayer.getShips()){ for(Ship ship : currentPlayer.getShips()){
if(!ship.isDrown()) if(!ship.isDrown())
otherPlayer.isItDrown(ship); otherPlayer.updateIsDrown(ship);
} }
} }
public Player getWinner(){ public Player getWinner(){
int cpt = 0; Ship remainingShip = players[0].getShips().parallelStream().filter(ship -> !ship.isDrown()).findFirst().orElse(null);
for(Ship ship : players[0].getShips()){ if(remainingShip == null)
if(!ship.isDrown()) return players[1];
break; remainingShip = players[1].getShips().parallelStream().filter(ship -> !ship.isDrown()).findFirst().orElse(null);
else if(remainingShip == null)
cpt ++;
}
if(cpt == 5)
return players[1]; return players[1];
cpt = 0;
for(Ship ship : players[1].getShips()){
if(!ship.isDrown())
break;
else
cpt ++;
}
if(cpt == 5)
return players[0];
return null; return null;
} }
public void move(Pair<Integer,Integer> move){ public void move(Pair<Integer,Integer> move){
boolean bool = false; boolean bool = false;
Player player = (currentPlayer == players[1])? players[0] : players[1]; Player otherPlayer = getOtherPlayer();
for (Ship ship : player.getShips()) { for (Ship ship : otherPlayer.getShips()) {
for(Pair<Integer,Integer> pair : ship.getCoordsArray()){ for(Pair<Integer,Integer> pair : ship.getCoordsArray()){
if ((pair.getRight().equals(move.getRight())) && (pair.getLeft().equals(move.getLeft()))) { if ((pair.getRight().equals(move.getRight())) && (pair.getLeft().equals(move.getLeft()))) {
bool = true; bool = true;
@ -72,22 +60,21 @@ public class Game {
} }
} }
} }
currentPlayer.addMove(new Triplet<>(move.getLeft(),move.getRight(),bool)); currentPlayer.addMove(new Triplet<>(move, bool));
} }
public Player Play(View view){ public void Play(View view){
view.setShips(players[0]); view.setShips(players[0]);
view.setShips(players[1]); view.setShips(players[1]);
System.out.println(view.toString()); Player winner = null;
while(getWinner() == null) { while(winner == null) {
System.out.println(view); view.displayBoard();
Pair<Integer,Integer> move = currentPlayer.chooseMove(); move(currentPlayer.chooseMove());
move(move);
changeCurrentPlayer(); changeCurrentPlayer();
checkDrownedShips(); checkDrownedShips();
winner = getWinner();
} }
return getWinner(); view.displayWinner(winner);
} }

View File

@ -22,7 +22,8 @@ public class Human extends Player {
} }
return new Pair<>(x,y); return new Pair<>(x,y);
} }
public boolean areValid(int x,int y){
public boolean areValid(int x, int y){
if(x <0 || x >10 || y <0 || y >10) if(x <0 || x >10 || y <0 || y >10)
return false; return false;
for(Triplet<Integer,Integer,Boolean> move : moves){ for(Triplet<Integer,Integer,Boolean> move : moves){

View File

@ -46,23 +46,20 @@ public abstract class Player {
return this; return this;
} }
public boolean isItDrown(Ship ship) { public void updateIsDrown(Ship ship) {
int cpt = 0; int cpt = 0;
for(Triplet<Integer,Integer,Boolean> move : moves){ for(Triplet<Integer,Integer,Boolean> move : moves){
for(int i = 1; i <= ship.getSize(); i++){ for(int i = 1; i <= ship.getSize(); i++){
int x = ship.getCoords().getLeft()+ i * ship.getDirection().getDirection().getLeft(); int x = ship.getCoords().getLeft() + i * ship.getDirection().getDirection().getLeft();
int y = ship.getCoords().getRight()+ i * ship.getDirection().getDirection().getRight(); int y = ship.getCoords().getRight()+ i * ship.getDirection().getDirection().getRight();
if((move.getLeft() == x) && (move.getMiddle() == y)){ if(move.getLeft() == x && move.getMiddle() == y){
cpt += 1; cpt += 1;
break; break;
} }
} }
} }
if(cpt == ship.getSize()) { if(cpt == ship.getSize())
ship.setDrown(); ship.setDrown();
return true;
}
return false;
} }
public ArrayList<Ship> getShips(){ public ArrayList<Ship> getShips(){
return this.ships; return this.ships;
@ -76,10 +73,11 @@ public abstract class Player {
public ArrayList<Pair<Integer,Integer>> validMoves() { public ArrayList<Pair<Integer,Integer>> validMoves() {
ArrayList<Pair<Integer,Integer>> validMovesList = new ArrayList<>(); ArrayList<Pair<Integer,Integer>> validMovesList = new ArrayList<>();
for(Integer i = 0; i<10;i++){ for(int x = 0; x < 10; x++){
for(Integer y = 0;y<10;y++) { for(int y = 0; y < 10; y++) {
if(!moves.contains(new Triplet<>(i,y,true)) ||!moves.contains(new Triplet<>(i,y,false))){ Pair<Integer, Integer> coords = new Pair<>(x,y);
validMovesList.add(new Pair<>(i,y)); if(!moves.contains(new Triplet<>(coords, true)) || !moves.contains(new Triplet<>(coords, false))){
validMovesList.add(new Pair<>(x,y));
} }
} }
} }

View File

@ -20,6 +20,10 @@ public class Triplet<U, K, V> {
this.right = right; this.right = right;
} }
public Triplet(Pair<U, K> pair, V right) {
this(pair.getLeft(), pair.getRight(), right);
}
public U getLeft() { public U getLeft() {
return left; return left;
} }
@ -44,7 +48,7 @@ public class Triplet<U, K, V> {
return false; return false;
} }
final Triplet<?, ?, ?> other = (Triplet<?, ?, ?>) obj; final Triplet<?, ?, ?> other = (Triplet<?, ?, ?>) obj;
return this.left.equals(other.getLeft()) && this.middle.equals(other.getMiddle()) && this.left.equals(other.getRight()); return this.left.equals(other.getLeft()) && this.middle.equals(other.getMiddle()) && this.right.equals(other.getRight());
} }
@Override @Override

View File

@ -65,4 +65,9 @@ public class Terminal extends View {
System.out.println(toString()); System.out.println(toString());
} }
@Override
public void displayWinner(Player winner) {
System.out.println("Le joueur " + winner.getId() + " a gagné");
}
} }

View File

@ -41,7 +41,10 @@ public abstract class View {
for(Ship ship : ships) { for(Ship ship : ships) {
if(isShipPosition(ship, pair)) { if(isShipPosition(ship, pair)) {
isPosition = true; isPosition = true;
if(isPositionDrowned(game.players[u == 0 ? 1 : 0], ship, pair)) { int result = isPositionDrowned(game.players[u == 0 ? 1 : 0], ship, pair);
if(result == 1) {
chain += " X";
} else if (result == 2){
chain += " !"; chain += " !";
} else { } else {
chain += " ."; chain += " .";
@ -49,8 +52,14 @@ public abstract class View {
break; break;
} }
} }
if(!isPosition) if(!isPosition) {
chain += " _"; if(isPositionDrowned(game.players[u == 0 ? 1 : 0], pair) == 2) {
chain += " ?";
} else {
chain += " _";
}
}
} }
chain += " |\n"; chain += " |\n";
} }
@ -72,19 +81,27 @@ public abstract class View {
} }
private boolean isPositionDrowned(Player other, Pair<Integer, Integer> pair) { private int isPositionDrowned(Player other, Pair<Integer, Integer> pair) {
for(Triplet<Integer, Integer, Boolean> move : other.getMoves()) { for(Triplet<Integer, Integer, Boolean> move : other.getMoves()) {
if(move.getRight() && pair.getLeft().equals(move.getLeft()) && pair.getRight().equals(move.getMiddle())) { if(pair.getLeft().equals(move.getLeft()) && pair.getRight().equals(move.getMiddle())) {
return true; return 2;
} }
} }
return false; return 0;
} }
private boolean isPositionDrowned(Player other, Ship ship, Pair<Integer, Integer> pair) { /**
*
* @param other other than the current player
* @param ship check if this ship at this position is touch
* @param pair coords
* @return 1 if ship fully drowned, 2 if only damaged, 0 if not
*/
private int isPositionDrowned(Player other, Ship ship, Pair<Integer, Integer> pair) {
if(ship.isDrown()) if(ship.isDrown())
return true; return 1;
return isPositionDrowned(other, pair); return isPositionDrowned(other, pair);
} }
public abstract void displayWinner(Player winner);
} }

View File

@ -3,31 +3,40 @@ package battleship.view;
import battleship.model.Game; import battleship.model.Game;
import battleship.model.player.Player; import battleship.model.player.Player;
import java.awt.Color;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import javax.swing.*; import javax.swing.*;
import java.awt.*; import java.awt.*;
public class Window extends View { public class Window extends View {
private JFrame frame; private JFrame frame;
private final int hauteur = 600;
private final int largeur = 1200; private final int height = 600;
private final int width = 1200;
public Window(Game game) { public Window(Game game) {
super(game); super(game);
this.frame = new JFrame("Battleship"); this.frame = new JFrame("Battleship");
frame.setSize(largeur+largeur/38,hauteur+hauteur/13); frame.setSize(width + width / 13, height + height / 4);
frame.setContentPane(new Draw()); frame.setContentPane(new Draw());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true); frame.setVisible(true);
} }
@Override @Override
public void setShips(Player player) { public void setShips(Player player) {
}
@Override
public void displayBoard() {
frame.paintComponents(frame.getGraphics());
}
@Override
public void displayWinner(Player winner) {
// TODO: 07/04/2021 afficher un dialog
} }
class Draw extends JPanel { class Draw extends JPanel {
@ -36,29 +45,19 @@ public class Window extends View {
area.setBounds(20,10,400,20); area.setBounds(20,10,400,20);
//area.append("A B C D E F G H I J"); //area.append("A B C D E F G H I J");
frame.add(area);*/ frame.add(area);*/
for (int abscisse=largeur/24; abscisse<largeur+1; abscisse+=largeur/24) { for (int abscisse = width / 24; abscisse< width +1; abscisse+= width / 24) {
g.drawLine(abscisse, hauteur/6, abscisse, hauteur); g.drawLine(abscisse, height /6, abscisse, height);
if ( largeur*0.44167 < abscisse && abscisse < largeur/2) { if ( width * 0.44167 < abscisse && abscisse < (width >> 1)) {
abscisse += largeur/24 ; abscisse += width / 24 ;
} }
} }
for (int ordonnee=hauteur/6; ordonnee<hauteur+1; ordonnee+=hauteur/12) { for (int ordonnee = height / 6; ordonnee< height +1; ordonnee+= height / 12) {
g.drawLine(largeur/24, ordonnee, (int) (largeur/2.18), ordonnee); g.drawLine(width / 24, ordonnee, (int) (width /2.18), ordonnee);
g.drawLine((int) (largeur/1.845), ordonnee, largeur, ordonnee); g.drawLine((int) (width / 1.845), ordonnee, width, ordonnee);
} }
TextArea a = new TextArea("Aouiuxdytftgykhulijhguhghf"); TextArea a = new TextArea("Aouiuxdytftgykhulijhguhghf");
setLayout(new GridLayout(largeur, hauteur)); setLayout(new GridLayout(width, height));
a.replaceRange("dqsdqsfdqsd", 0, 1); a.replaceRange("dqsdqsfdqsd", 0, 1);
} }
}
public void designBoard(Graphics g) {
frame.paintComponents(g);
} }
@Override
public void displayBoard() {
// TODO Auto-generated method stub
}
} }