Skip to content

Content of file VGStateImpl.java

package de.fhdw.gaming.ipspiel22.vierGewinnt.domain.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import de.fhdw.gaming.core.domain.GameException;
import de.fhdw.gaming.core.domain.PlayerState;
import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGBoard;
import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGField;
import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGFieldState;
import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGPlayer;
import de.fhdw.gaming.ipspiel22.vierGewinnt.domain.VGState;

/**
 * Implements {@link VGState}.
 */
public class VGStateImpl implements VGState {

    /**
     * The board.
     */
    private final VGBoard board;
    /**
     * The first player.
     */
    private final VGPlayer redPlayer;
    /**
     * The second player.
     */
    private final VGPlayer yellowPlayer;
    /**
     * The current player.
     */
    private VGPlayer currentPlayer;

    /**
     * Creates a Vier gewinnt state.
     *
     * @param board        A board.s
     * @param redPlayer    The first player.
     * @param yellowPlayer The second player.
     * @param redIsNext    Is red next.
     * @throws GameException if the state cannot be created according to the rules of the game.
     */
    public VGStateImpl(final VGBoard board, final VGPlayer redPlayer, final VGPlayer yellowPlayer,
            final boolean redIsNext)
            throws GameException {

        this.board = Objects.requireNonNull(board, "board");
        this.redPlayer = Objects.requireNonNull(redPlayer, "redPlayerBuilder");
        this.yellowPlayer = Objects.requireNonNull(yellowPlayer, "yellowPlayerBuilder");
        this.currentPlayer = redIsNext ? this.redPlayer : this.yellowPlayer;

        if (!this.redPlayer.isUsingRedChips()) {
            throw new IllegalArgumentException(
                    String.format("Red player %s does not use red chips.", this.redPlayer));
        }
        if (this.yellowPlayer.isUsingRedChips()) {
            throw new IllegalArgumentException(
                    String.format("Yellow player %s does not use yellow tokens.", this.yellowPlayer));
        }
        if (this.redPlayer.getName().equals(this.yellowPlayer.getName())) {
            throw new IllegalArgumentException(
                    String.format("Both players have the same name '%s'.", this.redPlayer.getName()));
        }
    }

    /**
     * Creates a Vier gewinnt state by copying an existing one.
     *
     * @param source The state to copy.
     */
    VGStateImpl(final VGStateImpl source) {
        this.board = source.board.deepCopy();
        this.redPlayer = source.redPlayer.deepCopy();
        this.yellowPlayer = source.yellowPlayer.deepCopy();
        this.currentPlayer = source.isRedPlayerCurrent() ? this.redPlayer : this.yellowPlayer;
    }

    @Override
    public String toString() {
        return String.format(
                "VGState[board=%s, redPlayer=%s, yellowPlayer=%s, currentPlayer=%s]",
                this.board,
                this.redPlayer,
                this.yellowPlayer,
                this.currentPlayer.isUsingRedChips() ? VGFieldState.RED : VGFieldState.YELLOW);
    }

    @Override
    public boolean equals(final Object obj) {
        if (obj instanceof VGStateImpl) {
            final VGStateImpl other = (VGStateImpl) obj;
            return this.board.equals(other.board)
                    && this.redPlayer.equals(other.redPlayer)
                    && this.yellowPlayer.equals(other.yellowPlayer)
                    && this.isRedPlayerCurrent() == other.isRedPlayerCurrent();
        }
        return false;
    }

    @Override
    public VGState deepCopy() {
        return new VGStateImpl(this);
    }

    @Override
    public int hashCode() {
        return Objects.hash(this.board, this.redPlayer, this.yellowPlayer, this.isRedPlayerCurrent());
    }

    @Override
    public Map<String, VGPlayer> getPlayers() {
        final Map<String, VGPlayer> result = new LinkedHashMap<>();
        result.put(this.redPlayer.getName(), this.redPlayer);
        result.put(this.yellowPlayer.getName(), this.yellowPlayer);
        return result;
    }

    @Override
    public Set<VGPlayer> computeNextPlayers() {
        return Collections.singleton(this.currentPlayer);
    }

    @Override
    public void nextTurn() {
        final List<VGField> allFields = new ArrayList<>();
        this.getBoard().getFields().forEach(allFields::addAll);

        if (allFields.stream().noneMatch(vgField -> vgField.getState().equals(VGFieldState.EMPTY))) {

            System.out.println("Board ist voll");

            if (this.checkWinner(this.currentPlayer)) {
                this.currentPlayer.setState(PlayerState.WON);
                System.out.println(this.currentPlayer.getName() + " hat gewonnen, mit der Farbe: "
                        + (this.currentPlayer.isUsingRedChips()
                                ? VGFieldState.RED.toString()
                                : VGFieldState.YELLOW.toString()));
                this.getOtherPlayer().setState(PlayerState.LOST);
                System.out.println(this.getOtherPlayer().getName() + " hat verloren, mit der Farbe: "
                        + (this.currentPlayer.isUsingRedChips()
                                ? VGFieldState.YELLOW.toString()
                                : VGFieldState.RED.toString()));
            } else {
                this.gameOver();
            }
        } else if (this.checkWinner(this.currentPlayer)) {
            this.currentPlayer.setState(PlayerState.WON);
            System.out.println(this.currentPlayer.getName() + " hat gewonnen, mit der Farbe: "
                    + (this.currentPlayer.isUsingRedChips()
                            ? VGFieldState.RED.toString()
                            : VGFieldState.YELLOW.toString()));
            this.getOtherPlayer().setState(PlayerState.LOST);
            System.out.println(this.getOtherPlayer().getName() + " hat verloren, mit der Farbe: "
                    + (this.currentPlayer.isUsingRedChips()
                            ? VGFieldState.YELLOW.toString()
                            : VGFieldState.RED.toString()));
        }
        this.currentPlayer = this.getOtherPlayer();
    }
The method 'nextTurn()' has a cognitive complexity of 15, current threshold is 15.
Methods that are highly complex are difficult to read and more costly to maintain. If you include too much decisional logic within a single method, you make its behavior hard to understand and more difficult to modify. Cognitive complexity is a measure of how difficult it is for humans to read and understand a method. Code that contains a break in the control flow is more complex, whereas the use of language shorthands doesn't increase the level of complexity. Nested control flows can make a method more difficult to understand, with each additional nesting of the control flow leading to an increase in cognitive complexity. Information about Cognitive complexity can be found in the original paper here: By default, this rule reports methods with a complexity of 15 or more. Reported methods should be broken down into less complex components.
    
        
            
public class Foo {
  // Has a cognitive complexity of 0
  public void createAccount() {
    Account account = new Account("PMD");
    // save account
  }

  // Has a cognitive complexity of 1
  public Boolean setPhoneNumberIfNotExisting(Account a, String phone) {
    if (a.phone == null) {                          // +1
      a.phone = phone;
      return true;
    }

    return false;
  }

  // Has a cognitive complexity of 4
  public void updateContacts(List<Contact> contacts) {
    List<Contact> contactsToUpdate = new ArrayList<Contact>();

    for (Contact contact : contacts) {                           // +1
      if (contact.department.equals("Finance")) {                // +2 (nesting = 1)
        contact.title = "Finance Specialist";
        contactsToUpdate.add(contact);
      } else if (contact.department.equals("Sales")) {           // +1
        contact.title = "Sales Specialist";
        contactsToUpdate.add(contact);
      }
    }
    // save contacts
  }
}

        
    
See PMD documentation.
/** * Returns boolean, if Player has won. * * @param player The current player. */ public boolean checkWinner(final VGPlayer player) { VGFieldState state = VGFieldState.YELLOW; if (player.isUsingRedChips()) { state = VGFieldState.RED; } return this.checkVertical(state); } /** * Returns boolean, if Player has won. * * @param state The chips color of the current player. */ private Boolean checkVertical(final VGFieldState state) { for (int i = 0; i < this.board.getColumns(); i++) { for (int j = 0; j < 3; j++) { if (this.board.getFields().get(i).get(j).getState().equals(state) && this.board.getFields().get(i).get(j + 1).getState().equals(state) && this.board.getFields().get(i).get(j + 2).getState().equals(state) && this.board.getFields().get(i).get(j + 3).getState().equals(state)) { System.out.println( "Vertikal: " + this.board.getFields().get(i).get(j).getPosition() + this.board.getFields().get(i).get(j + 1).getPosition() + this.board.getFields().get(i).get(j + 2).getPosition() + this.board.getFields().get(i).get(j + 3).getPosition()); return true; } } } return this.checkHorizontal(state); } /** * Returns boolean, if Player has won. * * @param state The chips color of the current player. */ private Boolean checkHorizontal(final VGFieldState state) { for (int i = 0; i < this.board.getRows(); i++) { // Für Zeilen for (int j = 0; j < 4; j++) { // Für Spalten if (this.board.getFields().get(j).get(i).getState().equals(state) && this.board.getFields().get(j + 1).get(i).getState().equals(state) && this.board.getFields().get(j + 2).get(i).getState().equals(state) && this.board.getFields().get(j + 3).get(i).getState().equals(state)) { System.out.println( "Horizontal: " + this.board.getFields().get(j).get(i).getPosition() + this.board.getFields().get(j + 1).get(i).getPosition() + this.board.getFields().get(j + 2).get(i).getPosition() + this.board.getFields().get(j + 3).get(i).getPosition()); return true; } } } return this.checkDiagonalLeftToRight(state); } /** * Returns boolean, if Player has won. * * @param state The chips color of the current player. */ private Boolean checkDiagonalLeftToRight(final VGFieldState state) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { if (this.board.getFields().get(j).get(i).getState().equals(state) && this.board.getFields().get(j + 1).get(i + 1).getState().equals(state) && this.board.getFields().get(j + 2).get(i + 2).getState().equals(state) && this.board.getFields().get(j + 3).get(i + 3).getState().equals(state)) { System.out.println("Diagonal von links nach rechts: " + this.board.getFields().get(j).get(i).getPosition() + this.board.getFields().get(j + 1).get(i + 1).getPosition() + this.board.getFields().get(j + 2).get(i + 2).getPosition() + this.board.getFields().get(j + 3).get(i + 3).getPosition()); return true; } } } return this.checkDiagonalRightToLeft(state); } /** * Returns boolean, if Player has won. * * @param state The chips color of the current player. */ private Boolean checkDiagonalRightToLeft(final VGFieldState state) { for (int i = 0; i < 3; i++) { for (int j = 3; j < 7; j++) { if (this.board.getFields().get(j).get(i).getState().equals(state) && this.board.getFields().get(j - 1).get(i + 1).getState().equals(state) && this.board.getFields().get(j - 2).get(i + 2).getState().equals(state) && this.board.getFields().get(j - 3).get(i + 3).getState().equals(state)) { System.out.println("Diagonal von links nach rechts: " + this.board.getFields().get(j).get(i).getPosition() + this.board.getFields().get(j - 1).get(i + 1).getPosition() + this.board.getFields().get(j - 2).get(i + 2).getPosition() + this.board.getFields().get(j - 3).get(i + 3).getPosition()); return true; } } } return false; } @Override public VGBoard getBoard() { return this.board; } @Override public VGPlayer getRedPlayer() { return this.redPlayer; } @Override public VGPlayer getYellowPlayer() { return this.yellowPlayer; } @Override public VGPlayer getCurrentPlayer() { return this.currentPlayer; } /** * Returns the currently inactive player. */ private VGPlayer getOtherPlayer() { if (this.isRedPlayerCurrent()) { return this.yellowPlayer; } return this.redPlayer; } /** * Returns id the current player is the red Player. */ private boolean isRedPlayerCurrent() { return this.currentPlayer.equals(this.redPlayer); } @Override public void gameOver() { this.redPlayer.setState(PlayerState.DRAW); this.yellowPlayer.setState(PlayerState.DRAW); System.out.println("Es ist untenschieden. "); } }