Chess simulation

Our task

TL;DR

Write the simulation of random chess play. This task is worth 2 points but also will be graded really carefully, so please check your code before submission not to lose points for style or modifiers ๐Ÿ˜…. As a final result, show some game simulation in main method.

Description

We’re going to implement the chess play simulation with simplified rules and some console animation of the play. We don’t have to take care of:

  • mating and checking,
  • castles,
  • beating (by risers) in flight,
  • the possibility of the (first) movement of a pawn by two squares, but of course if you want you can think of including some of these features into your game models.

We would like to provide a model of chess pieces, where 2 players plays on 8x8 chess board. The first player is white player, the second is black. There can always be only a single piece on board field and players beat each other by taking the same field by some other piece.

The simulation finishes when:

  • every player used 50 moves
  • some player cannot move by any piece
  • one of the kings has been beaten

The whole simulation can be done in rando manner - there is no need to implement some player strategy for the purpose of this task.

You can use symbols from this sample board to implement your console animation:

โ•”โ•โ•คโ•โ•คโ•โ•คโ•โ•คโ•โ•คโ•โ•คโ•โ•คโ•โ•—
โ•‘โ™œโ”‚โ™žโ”‚โ™โ”‚โ™›โ”‚โ™šโ”‚โ™โ”‚โ™žโ”‚โ™œโ•‘
โ•Ÿโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ•ข
โ•‘โ™Ÿโ”‚โ™Ÿโ”‚โ™Ÿโ”‚โ™Ÿโ”‚โ™Ÿโ”‚โ™Ÿโ”‚โ™Ÿโ”‚โ™Ÿโ•‘
โ•Ÿโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ•ข
โ•‘ โ”‚โ–ˆโ”‚ โ”‚โ–ˆโ”‚ โ”‚โ–ˆโ”‚ โ”‚โ–ˆโ•‘
โ•Ÿโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ•ข
โ•‘โ–ˆโ”‚ โ”‚โ–ˆโ”‚ โ”‚โ–ˆโ”‚ โ”‚โ–ˆโ”‚ โ•‘
โ•Ÿโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ•ข
โ•‘ โ”‚โ–ˆโ”‚ โ”‚โ–ˆโ”‚ โ”‚โ–ˆโ”‚ โ”‚โ–ˆโ•‘
โ•Ÿโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ•ข
โ•‘โ–ˆโ”‚ โ”‚โ–ˆโ”‚ โ”‚โ–ˆโ”‚ โ”‚โ–ˆโ”‚ โ•‘
โ•Ÿโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ•ข
โ•‘โ™™โ”‚โ™™โ”‚โ™™โ”‚โ™™โ”‚โ™™โ”‚โ™™โ”‚โ™™โ”‚โ™™โ•‘
โ•Ÿโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ•ข
โ•‘โ™–โ”‚โ™˜โ”‚โ™—โ”‚โ™•โ”‚โ™”โ”‚โ™—โ”‚โ™˜โ”‚โ™–โ•‘
โ•šโ•โ•งโ•โ•งโ•โ•งโ•โ•งโ•โ•งโ•โ•งโ•โ•งโ•โ•

or design your own ๐Ÿ˜‰

Your task is also to start this project from empty template that is available here and send your solution as pull request to this repository.

Deadline for this task is 20.05.2022 (11:59 ๐Ÿ˜Ž)

Laboratory work results

We’ve seen that to get an effect of animation you can sleep in Java for e.g. 1 second, clear the console and then go to the move of next player by

public class Main {

  public static void main(String[] args) {
    for (String arg : new String[]{"some", "example", "strings"}) {
      sleep(1_000);
      Util.clearConsole();
      System.out.println(arg);
    }
  }

  private static void sleep(long millis) {
    try {
      Thread.sleep(millis);
    } catch (InterruptedException ignored) {
    }
  }
}

To run and see your main in terminal mode (to see the actual animation) compile and run from console by

./gradlew shadowJar && java -jar ./build/libs/oop-2022-all.jar

We’ve implemented some classes that may be used in your implementation. You can use them if you wish but be sure what you’re doing as our code may be broken ๐Ÿ™ƒ

V2.java

public final class V2 {

  public static final V2 N = v(0, 1);
  public static final V2 S = v(0, -1);
  public static final V2 E = v(1, 0);
  public static final V2 W = v(-1, 0);

  public static final V2 NE = N.plus(E);
  public static final V2 NW = N.plus(W);
  public static final V2 SE = S.plus(E);
  public static final V2 SW = S.plus(W);

  public final int x;
  public final int y;

  private V2(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public V2 plus(V2 v) {
    return v(this.x + v.x, this.y + v.y);
  }

  public V2 times(int scalar) {
    return v(this.x * scalar, this.y * scalar);
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    V2 v2 = (V2) o;
    return x == v2.x && y == v2.y;
  }

  @Override
  public int hashCode() {
    return Objects.hash(x, y);
  }

  public static V2 v(int x, int y) {
    return new V2(x, y);
  }
}

ChessColor.java

public enum ChessColor {
  BLACK, WHITE
}

ChessBoard.java

public class ChessBoard {
  public static final int BOARD_SIZE = 8;

  public static boolean isOnBoard(V2 position) {
    return position.x > -1 && position.x < BOARD_SIZE &&
      position.y > -1 && position.y < BOARD_SIZE;
  }
}

ChessPiece.java

public interface ChessPiece {

  V2 getPosition();

  void setPosition(V2 v);

  List<List<V2>> getPossibleMoves();

  String representation();
}

AbstractPiece.java

public abstract class AbstractPiece implements ChessPiece {

  private V2 position;
  private final ChessColor color;
  private final String whiteRepresentation;
  private final String blackRepresentation;

  protected AbstractPiece(V2 position, ChessColor color, String whiteRepresentation, String blackRepresentation) {
    this.position = position;
    this.color = color;
    this.whiteRepresentation = whiteRepresentation;
    this.blackRepresentation = blackRepresentation;
  }

  @Override
  public V2 getPosition() {
    return position;
  }

  @Override
  public void setPosition(V2 v) {
    this.position = v;
  }

  @Override
  public String representation() {
    switch (color) {
      case BLACK:
        return blackRepresentation;
      case WHITE:
        return whiteRepresentation;
    }
    throw new IllegalStateException("unknown color " + color);
  }
}

BishopPiece.java

public class BishopPiece extends AbstractPiece {

  private static final List<List<V2>> POSSIBLE_MOVES = generatePossibleMoves();

  public BishopPiece(V2 position, ChessColor color) {
    super(position, color, "โ™—", "โ™");
  }

  @Override
  public List<List<V2>> getPossibleMoves() {
    return POSSIBLE_MOVES;
  }

  private static List<List<V2>> generatePossibleMoves() {
    List<List<V2>> result = new ArrayList<>();
    for (final var d : new V2[]{NW, SW, NE, SE}) {
      List<V2> inDirection = new ArrayList<>();
      for (int i = 1; i < ChessBoard.BOARD_SIZE; i++) inDirection.add(d.times(i));
      result.add(inDirection);
    }
    return result;
  }
}

RookPiece.java

public class RookPiece extends AbstractPiece {

  private static final List<List<V2>> POSSIBLE_MOVES = generatePossibleMoves();

  public RookPiece(V2 position, ChessColor color) {
    super(position, color, "โ™–", "โ™œ");
  }

  @Override
  public List<List<V2>> getPossibleMoves() {
    return POSSIBLE_MOVES;
  }

  private static List<List<V2>> generatePossibleMoves() {
    List<List<V2>> result = new ArrayList<>();
    for (final var d : new V2[]{N, S, E, W}) {
      List<V2> inDirection = new ArrayList<>();
      for (int i = 1; i < ChessBoard.BOARD_SIZE; i++) inDirection.add(d.times(i));
      result.add(inDirection);
    }
    return result;
  }
}

Previous
Next