├── bin ├── app │ ├── Prog.class │ └── UI.class ├── chess │ ├── Color.class │ ├── ChessMatch.class │ ├── ChessPiece.class │ ├── pieces │ │ ├── King.class │ │ ├── Pawn.class │ │ ├── Queen.class │ │ ├── Rook.class │ │ ├── Bishop.class │ │ └── Knight.class │ ├── ChessException.class │ └── ChessPosition.class ├── module-info.class └── boardgame │ ├── Board.class │ ├── Piece.class │ ├── Position.class │ └── BoardException.class ├── src ├── chess │ ├── Color.java │ ├── ChessException.java │ ├── ChessPosition.java │ ├── ChessPiece.java │ ├── pieces │ │ ├── Rook.java │ │ ├── Bishop.java │ │ ├── Knight.java │ │ ├── Pawn.java │ │ ├── Queen.java │ │ └── King.java │ └── ChessMatch.java ├── module-info.java ├── boardgame │ ├── BoardException.java │ ├── Position.java │ ├── Piece.java │ └── Board.java └── app │ ├── Prog.java │ └── UI.java ├── .settings ├── org.eclipse.core.resources.prefs └── org.eclipse.jdt.core.prefs ├── .classpath ├── .project └── README.md /bin/app/Prog.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/app/Prog.class -------------------------------------------------------------------------------- /bin/app/UI.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/app/UI.class -------------------------------------------------------------------------------- /src/chess/Color.java: -------------------------------------------------------------------------------- 1 | package chess; 2 | 3 | public enum Color { 4 | 5 | BLACK, WHITE; 6 | } 7 | -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /bin/chess/Color.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/chess/Color.class -------------------------------------------------------------------------------- /bin/module-info.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/module-info.class -------------------------------------------------------------------------------- /bin/boardgame/Board.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/boardgame/Board.class -------------------------------------------------------------------------------- /bin/boardgame/Piece.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/boardgame/Piece.class -------------------------------------------------------------------------------- /bin/boardgame/Position.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/boardgame/Position.class -------------------------------------------------------------------------------- /bin/chess/ChessMatch.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/chess/ChessMatch.class -------------------------------------------------------------------------------- /bin/chess/ChessPiece.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/chess/ChessPiece.class -------------------------------------------------------------------------------- /bin/chess/pieces/King.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/chess/pieces/King.class -------------------------------------------------------------------------------- /bin/chess/pieces/Pawn.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/chess/pieces/Pawn.class -------------------------------------------------------------------------------- /bin/chess/pieces/Queen.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/chess/pieces/Queen.class -------------------------------------------------------------------------------- /bin/chess/pieces/Rook.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/chess/pieces/Rook.class -------------------------------------------------------------------------------- /src/module-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | /** 5 | * @author caual 6 | * 7 | */ 8 | module JogoDeXadrez { 9 | } -------------------------------------------------------------------------------- /bin/chess/ChessException.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/chess/ChessException.class -------------------------------------------------------------------------------- /bin/chess/ChessPosition.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/chess/ChessPosition.class -------------------------------------------------------------------------------- /bin/chess/pieces/Bishop.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/chess/pieces/Bishop.class -------------------------------------------------------------------------------- /bin/chess/pieces/Knight.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/chess/pieces/Knight.class -------------------------------------------------------------------------------- /bin/boardgame/BoardException.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Cry199/Java-Jogo-De-Xadrez/HEAD/bin/boardgame/BoardException.class -------------------------------------------------------------------------------- /src/boardgame/BoardException.java: -------------------------------------------------------------------------------- 1 | package boardgame; 2 | 3 | public class BoardException extends RuntimeException 4 | { 5 | private static final long serialVersionUID = 1L; 6 | 7 | public BoardException(String msg) 8 | { 9 | super(msg); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/chess/ChessException.java: -------------------------------------------------------------------------------- 1 | package chess; 2 | 3 | import boardgame.BoardException; 4 | 5 | public class ChessException extends BoardException 6 | { 7 | private static final long serialVersionUID = 1L; 8 | 9 | public ChessException(String msg) 10 | { 11 | super(msg); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | JogoDeXadrez 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/boardgame/Position.java: -------------------------------------------------------------------------------- 1 | package boardgame; 2 | 3 | public class Position { 4 | 5 | private int row; 6 | private int column; 7 | 8 | public Position() {} 9 | 10 | public Position(int row, int column) { 11 | this.row = row; 12 | this.column = column; 13 | } 14 | 15 | public int getRow() { 16 | return row; 17 | } 18 | 19 | public void setRow(int row) { 20 | this.row = row; 21 | } 22 | 23 | public int getColumn() { 24 | return column; 25 | } 26 | 27 | public void setColumn(int column) { 28 | this.column = column; 29 | } 30 | 31 | public void setValues(int row, int column) 32 | { 33 | this.row = row; 34 | this.column = column; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return row + " , " + column; 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=17 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=17 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled 11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 12 | org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning 13 | org.eclipse.jdt.core.compiler.release=enabled 14 | org.eclipse.jdt.core.compiler.source=17 15 | -------------------------------------------------------------------------------- /src/boardgame/Piece.java: -------------------------------------------------------------------------------- 1 | package boardgame; 2 | 3 | public abstract class Piece { 4 | 5 | protected Position position; 6 | private Board board; 7 | 8 | public Piece(Board board) { 9 | this.board = board; 10 | position = null; 11 | } 12 | 13 | protected Board getBoard() { 14 | return board; 15 | } 16 | 17 | public abstract boolean[][] possibleMoves(); 18 | 19 | public boolean possibleMove(Position position) 20 | { 21 | return possibleMoves()[position.getRow()][position.getColumn()]; 22 | } 23 | 24 | public boolean isThereAnyPossibleMove() 25 | { 26 | boolean[][] mat = possibleMoves(); 27 | 28 | for (int i = 0; i < mat.length; i++) 29 | { 30 | for (int j = 0; j < mat.length; j++) 31 | { 32 | if(mat[i][j]) 33 | { 34 | return true; 35 | } 36 | } 37 | } 38 | 39 | return false; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/chess/ChessPosition.java: -------------------------------------------------------------------------------- 1 | package chess; 2 | 3 | import boardgame.Position; 4 | 5 | public class ChessPosition { 6 | 7 | private char column; 8 | private int row; 9 | 10 | public ChessPosition(char column, int row) 11 | { 12 | if(column < 'a' || column > 'h' || row < 1 || row > 8) 13 | { 14 | throw new ChessException("Error instantiating ChessPosition."); 15 | } 16 | 17 | this.column = column; 18 | this.row = row; 19 | } 20 | 21 | public char getColumn() { 22 | return column; 23 | } 24 | 25 | public int getRow() { 26 | return row; 27 | } 28 | 29 | protected Position toPosition() 30 | { 31 | return new Position(8 - row, column - 'a'); 32 | } 33 | 34 | protected static ChessPosition fromPosition(Position position) 35 | { 36 | return new ChessPosition((char)('a' + position.getColumn()), 8 - position.getRow()); 37 | } 38 | 39 | @Override 40 | public String toString() 41 | { 42 | return "" + column + row; 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/chess/ChessPiece.java: -------------------------------------------------------------------------------- 1 | package chess; 2 | 3 | import boardgame.Board; 4 | import boardgame.Piece; 5 | import boardgame.Position; 6 | 7 | public abstract class ChessPiece extends Piece { 8 | 9 | private Color color; 10 | private int moveCount; 11 | 12 | public ChessPiece(Board board, Color color) { 13 | super(board); 14 | this.color = color; 15 | } 16 | 17 | public Color getColor() { 18 | return color; 19 | } 20 | 21 | public int getMoveCount() { 22 | return moveCount; 23 | } 24 | 25 | public void increaseMoveCount() 26 | { 27 | moveCount++; 28 | } 29 | 30 | public void decreaseMoveCount() 31 | { 32 | moveCount--; 33 | } 34 | 35 | public ChessPosition getChessPosition() 36 | { 37 | return ChessPosition.fromPosition(position); 38 | } 39 | 40 | protected boolean isThereOpponentPiece(Position position) 41 | { 42 | ChessPiece p = (ChessPiece) getBoard().piece(position); 43 | 44 | return p != null && p.getColor() != color; 45 | } 46 | 47 | 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/app/Prog.java: -------------------------------------------------------------------------------- 1 | package app; 2 | 3 | import java.util.ArrayList; 4 | import java.util.InputMismatchException; 5 | import java.util.List; 6 | import java.util.Scanner; 7 | 8 | import chess.ChessException; 9 | import chess.ChessMatch; 10 | import chess.ChessPiece; 11 | import chess.ChessPosition; 12 | 13 | public class Prog { 14 | 15 | public static void main(String[] args) 16 | { 17 | Scanner sc = new Scanner(System.in); 18 | ChessMatch chessMatch = new ChessMatch(); 19 | List captured = new ArrayList<>(); 20 | 21 | while (!chessMatch.getCheckMate()) 22 | { 23 | try 24 | { 25 | UI.clearScreen(); 26 | UI.printMatch(chessMatch, captured); 27 | 28 | System.out.println(); 29 | System.out.print("Source: "); 30 | ChessPosition source = UI.readChessPosition(sc); 31 | 32 | boolean[][] possibleMoves = chessMatch.possibleMoves(source); 33 | UI.clearScreen(); 34 | UI.printBoard(chessMatch.getPieces(), possibleMoves); 35 | 36 | System.out.println(); 37 | System.out.print("Target: "); 38 | ChessPosition target = UI.readChessPosition(sc); 39 | 40 | ChessPiece capturedPiece = chessMatch.performChessMove(source, target); 41 | 42 | if(capturedPiece != null) 43 | { 44 | captured.add(capturedPiece); 45 | } 46 | } 47 | catch (ChessException e) 48 | { 49 | System.out.println(e.getMessage()); 50 | sc.nextLine(); 51 | } 52 | catch (InputMismatchException e) 53 | { 54 | System.out.println(e.getMessage()); 55 | sc.nextLine(); 56 | } 57 | } 58 | UI.clearScreen(); 59 | UI.printMatch(chessMatch, captured); 60 | sc.nextLine(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Jogo De Xadrez em Java 2 | Clique aqui para jogar: https://replit.com/@Caua2/Java-Jogo-De-Xadrez 3 | 4 | Este é um jogo de xadrez completo implementado em Java. 5 | O jogo segue todas as regras de xadrez e permite jogadas comuns como roque, 6 | captura en passant e promoção de peão. 7 | 8 | # Funcionalidades 9 | Jogo completo de xadrez com todas as regras e movimentos 10 | Jogadores humanos vs. humanos (ainda sem IA) 11 | Regras de movimento de cada peça implementadas 12 | Validação de movimentos e posições inválidas 13 | Roque, captura en passant e promoção de peão 14 | Detecção de cheque e xeque-mate 15 | 16 | # Estrutura de Classes 17 | O projeto contém as seguintes classes principais: 18 | 19 | ChessMatch: Gerencia o jogo e controle de turnos 20 | ChessBoard: Representa o tabuleiro e posições das peças 21 | ChessPiece: Superclasse para todas as peças 22 | ConcretePiece: Classes para cada tipo de peça (Rei, Rainha, etc) 23 | UI: Interface de usuário básica para entrada/saída 24 | Foi utilizado um array 2D para representar o tabuleiro e as posições. Cada peça é uma instância das classes concretas de peça. 25 | 26 | # Como Jogar 27 | O jogo permite que dois jogadores humanos joguem um contra o outro. Cada jogador faz uma jogada por turno. 28 | 29 | O usuário deve inserir a posição de origem e destino no formato "coluna linha" (por exemplo "e2 e4"). O jogo gerencia turnos, valida movimentos e atualiza o tabuleiro. 30 | 31 | O objetivo é fazer xeque-mate no rei adversário. 32 | # Possíveis Melhorias 33 | Algumas possíveis extensões e melhorias: 34 | 35 | Adicionar inteligência artificial para jogar contra o computador 36 | Permitir jogo em rede entre dois jogadores 37 | Desenvolver uma interface gráfica com animações 38 | Suporte a jogadas com tempo limitado 39 | Salvar/carregar jogos 40 | Modos de visualização e análise de jogadas 41 | 42 | -------------------------------------------------------------------------------- /src/chess/pieces/Rook.java: -------------------------------------------------------------------------------- 1 | package chess.pieces; 2 | 3 | import boardgame.Board; 4 | import boardgame.Position; 5 | import chess.ChessPiece; 6 | import chess.Color; 7 | 8 | public class Rook extends ChessPiece { 9 | 10 | public Rook(Board board, Color color) { 11 | super(board, color); 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "♖"; 17 | } 18 | 19 | @Override 20 | public boolean[][] possibleMoves() { 21 | boolean[][] mat = new boolean[getBoard().getRows()][getBoard().getColumns()]; 22 | 23 | Position p = new Position(0, 0); 24 | 25 | // above 26 | p.setValues(position.getRow() - 1, position.getColumn()); 27 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) { 28 | mat[p.getRow()][p.getColumn()] = true; 29 | p.setRow(p.getRow() - 1); 30 | } 31 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) { 32 | mat[p.getRow()][p.getColumn()] = true; 33 | } 34 | 35 | // left 36 | p.setValues(position.getRow(), position.getColumn() - 1); 37 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) { 38 | mat[p.getRow()][p.getColumn()] = true; 39 | p.setColumn(p.getColumn() - 1); 40 | } 41 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) { 42 | mat[p.getRow()][p.getColumn()] = true; 43 | } 44 | 45 | // right 46 | p.setValues(position.getRow(), position.getColumn() + 1); 47 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) { 48 | mat[p.getRow()][p.getColumn()] = true; 49 | p.setColumn(p.getColumn() + 1); 50 | } 51 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) { 52 | mat[p.getRow()][p.getColumn()] = true; 53 | } 54 | 55 | // below 56 | p.setValues(position.getRow() + 1, position.getColumn()); 57 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) { 58 | mat[p.getRow()][p.getColumn()] = true; 59 | p.setRow(p.getRow() + 1); 60 | } 61 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) { 62 | mat[p.getRow()][p.getColumn()] = true; 63 | } 64 | 65 | return mat; 66 | } 67 | } -------------------------------------------------------------------------------- /src/chess/pieces/Bishop.java: -------------------------------------------------------------------------------- 1 | package chess.pieces; 2 | 3 | import boardgame.Board; 4 | import boardgame.Position; 5 | import chess.ChessPiece; 6 | import chess.Color; 7 | 8 | public class Bishop extends ChessPiece { 9 | 10 | public Bishop(Board board, Color color) { 11 | super(board, color); 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "♗"; 17 | } 18 | 19 | @Override 20 | public boolean[][] possibleMoves() 21 | { 22 | boolean[][] mat = new boolean[getBoard().getRows()][getBoard().getColumns()]; 23 | 24 | Position p = new Position(0, 0); 25 | 26 | // nw 27 | p.setValues(position.getRow() - 1, position.getColumn() - 1); 28 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 29 | { 30 | mat[p.getRow()][p.getColumn()] = true; 31 | p.setValues(p.getRow() - 1, p.getColumn() - 1); 32 | } 33 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 34 | { 35 | mat[p.getRow()][p.getColumn()] = true; 36 | } 37 | 38 | // ne 39 | p.setValues(position.getRow() - 1, position.getColumn() + 1); 40 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 41 | { 42 | mat[p.getRow()][p.getColumn()] = true; 43 | p.setValues(p.getRow() - 1, p.getColumn() + 1); 44 | } 45 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 46 | { 47 | mat[p.getRow()][p.getColumn()] = true; 48 | } 49 | 50 | // se 51 | p.setValues(position.getRow() + 1, position.getColumn() + 1); 52 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 53 | { 54 | mat[p.getRow()][p.getColumn()] = true; 55 | p.setValues(p.getRow() + 1, p.getColumn() + 1); 56 | } 57 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 58 | { 59 | mat[p.getRow()][p.getColumn()] = true; 60 | } 61 | 62 | // sw 63 | p.setValues(position.getRow() + 1, position.getColumn() - 1); 64 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 65 | { 66 | mat[p.getRow()][p.getColumn()] = true; 67 | p.setValues(p.getRow() + 1, p.getColumn() - 1); 68 | } 69 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 70 | { 71 | mat[p.getRow()][p.getColumn()] = true; 72 | } 73 | 74 | return mat; 75 | } 76 | } -------------------------------------------------------------------------------- /src/chess/pieces/Knight.java: -------------------------------------------------------------------------------- 1 | package chess.pieces; 2 | 3 | import boardgame.Board; 4 | import boardgame.Position; 5 | import chess.ChessPiece; 6 | import chess.Color; 7 | 8 | public class Knight extends ChessPiece { 9 | 10 | public Knight(Board board, Color color) 11 | { 12 | super(board, color); 13 | } 14 | 15 | @Override 16 | public String toString() 17 | { 18 | return "♘"; 19 | } 20 | 21 | private boolean canMove(Position position) 22 | { 23 | ChessPiece p = (ChessPiece)getBoard().piece(position); 24 | return p == null || p.getColor() != getColor(); 25 | } 26 | 27 | @Override 28 | public boolean[][] possibleMoves() { 29 | boolean[][] mat = new boolean[getBoard().getRows()][getBoard().getColumns()]; 30 | 31 | Position p = new Position(0, 0); 32 | 33 | p.setValues(position.getRow() - 1, position.getColumn() - 2); 34 | if (getBoard().positionExists(p) && canMove(p)) 35 | { 36 | mat[p.getRow()][p.getColumn()] = true; 37 | } 38 | 39 | p.setValues(position.getRow() - 2, position.getColumn() - 1); 40 | if (getBoard().positionExists(p) && canMove(p)) 41 | { 42 | mat[p.getRow()][p.getColumn()] = true; 43 | } 44 | 45 | p.setValues(position.getRow() - 2, position.getColumn() + 1); 46 | if (getBoard().positionExists(p) && canMove(p)) 47 | { 48 | mat[p.getRow()][p.getColumn()] = true; 49 | } 50 | 51 | p.setValues(position.getRow() - 1, position.getColumn() + 2); 52 | if (getBoard().positionExists(p) && canMove(p)) 53 | { 54 | mat[p.getRow()][p.getColumn()] = true; 55 | } 56 | 57 | p.setValues(position.getRow() + 1, position.getColumn() + 2); 58 | if (getBoard().positionExists(p) && canMove(p)) 59 | { 60 | mat[p.getRow()][p.getColumn()] = true; 61 | } 62 | 63 | p.setValues(position.getRow() + 2, position.getColumn() + 1); 64 | if (getBoard().positionExists(p) && canMove(p)) 65 | { 66 | mat[p.getRow()][p.getColumn()] = true; 67 | } 68 | 69 | p.setValues(position.getRow() + 2, position.getColumn() - 1); 70 | if (getBoard().positionExists(p) && canMove(p)) 71 | { 72 | mat[p.getRow()][p.getColumn()] = true; 73 | } 74 | 75 | p.setValues(position.getRow() + 1, position.getColumn() - 2); 76 | if (getBoard().positionExists(p) && canMove(p)) 77 | { 78 | mat[p.getRow()][p.getColumn()] = true; 79 | } 80 | 81 | return mat; 82 | } 83 | } -------------------------------------------------------------------------------- /src/boardgame/Board.java: -------------------------------------------------------------------------------- 1 | package boardgame; 2 | 3 | public class Board { 4 | 5 | private int rows; 6 | private int columns; 7 | private Piece[][] pieces; 8 | 9 | public Board(int rows, int columns) 10 | { 11 | if (rows < 1 || columns < 1) 12 | { 13 | throw new BoardException("Error creating board: there must be at least 1 row and 1 column"); 14 | } 15 | 16 | this.rows = rows; 17 | this.columns = columns; 18 | pieces = new Piece[rows][columns]; 19 | } 20 | 21 | public int getRows() { 22 | return rows; 23 | } 24 | 25 | public int getColumns() { 26 | return columns; 27 | } 28 | 29 | public Piece piece(int row, int column) 30 | { 31 | if (!positionExists(row, column)) 32 | { 33 | throw new BoardException("Position not on the board"); 34 | } 35 | 36 | return pieces[row][column]; 37 | } 38 | 39 | public Piece piece(Position position) 40 | { 41 | if (!positionExists(position)) 42 | { 43 | throw new BoardException("Position not on the board"); 44 | } 45 | 46 | return pieces[position.getRow()][position.getColumn()]; 47 | } 48 | 49 | public void placePiece(Piece piece, Position position) 50 | { 51 | if (thereIsAPiece(position)) 52 | { 53 | throw new BoardException("There is already a piece on position " + position); 54 | } 55 | 56 | pieces[position.getRow()][position.getColumn()] = piece; 57 | piece.position = position; 58 | } 59 | 60 | private boolean positionExists(int row, int column) 61 | { 62 | return row >= 0 && row < rows && column >= 0 && column < columns; 63 | } 64 | 65 | public boolean positionExists(Position position) 66 | { 67 | return positionExists(position.getRow(), position.getColumn()); 68 | } 69 | 70 | public boolean thereIsAPiece(Position position) 71 | { 72 | if (!positionExists(position)) 73 | { 74 | throw new BoardException("Position not on the board"); 75 | } 76 | 77 | return piece(position) != null; 78 | } 79 | 80 | public Piece removePiece(Position position) 81 | { 82 | if (!positionExists(position)) 83 | { 84 | throw new BoardException("Position not on the board"); 85 | } 86 | 87 | if(piece(position) == null) 88 | { 89 | return null; 90 | } 91 | 92 | Piece aux = piece(position); 93 | aux.position = null; 94 | 95 | pieces[position.getRow()][position.getColumn()] = null; 96 | 97 | return aux; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/chess/pieces/Pawn.java: -------------------------------------------------------------------------------- 1 | package chess.pieces; 2 | 3 | import boardgame.Board; 4 | import boardgame.Position; 5 | import chess.ChessPiece; 6 | import chess.Color; 7 | 8 | public class Pawn extends ChessPiece { 9 | 10 | public Pawn(Board board, Color color) 11 | { 12 | super(board, color); 13 | } 14 | 15 | @Override 16 | public boolean[][] possibleMoves() { 17 | boolean[][] mat = new boolean[getBoard().getRows()][getBoard().getColumns()]; 18 | 19 | Position p = new Position(0, 0); 20 | 21 | if (getColor() == Color.WHITE) 22 | { 23 | p.setValues(position.getRow() - 1, position.getColumn()); 24 | if (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 25 | { 26 | mat[p.getRow()][p.getColumn()] = true; 27 | } 28 | p.setValues(position.getRow() - 2, position.getColumn()); 29 | Position p2 = new Position(position.getRow() - 1, position.getColumn()); 30 | if (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p) 31 | && getBoard().positionExists(p2) && !getBoard().thereIsAPiece(p2) && getMoveCount() == 0) 32 | { 33 | mat[p.getRow()][p.getColumn()] = true; 34 | } 35 | p.setValues(position.getRow() - 1, position.getColumn() - 1); 36 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 37 | { 38 | mat[p.getRow()][p.getColumn()] = true; 39 | } 40 | p.setValues(position.getRow() - 1, position.getColumn() + 1); 41 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 42 | { 43 | mat[p.getRow()][p.getColumn()] = true; 44 | } 45 | } 46 | else 47 | { 48 | p.setValues(position.getRow() + 1, position.getColumn()); 49 | if (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 50 | { 51 | mat[p.getRow()][p.getColumn()] = true; 52 | } 53 | p.setValues(position.getRow() + 2, position.getColumn()); 54 | Position p2 = new Position(position.getRow() + 1, position.getColumn()); 55 | if (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p) 56 | && getBoard().positionExists(p2) && !getBoard().thereIsAPiece(p2) && getMoveCount() == 0) 57 | { 58 | mat[p.getRow()][p.getColumn()] = true; 59 | } 60 | p.setValues(position.getRow() + 1, position.getColumn() - 1); 61 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 62 | { 63 | mat[p.getRow()][p.getColumn()] = true; 64 | } 65 | p.setValues(position.getRow() + 1, position.getColumn() + 1); 66 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 67 | { 68 | mat[p.getRow()][p.getColumn()] = true; 69 | } 70 | } 71 | return mat; 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return "♙"; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/chess/pieces/Queen.java: -------------------------------------------------------------------------------- 1 | package chess.pieces; 2 | 3 | import boardgame.Board; 4 | import boardgame.Position; 5 | import chess.ChessPiece; 6 | import chess.Color; 7 | 8 | public class Queen extends ChessPiece { 9 | 10 | public Queen(Board board, Color color) { 11 | super(board, color); 12 | } 13 | 14 | @Override 15 | public String toString() { 16 | return "♕"; 17 | } 18 | 19 | @Override 20 | public boolean[][] possibleMoves() { 21 | boolean[][] mat = new boolean[getBoard().getRows()][getBoard().getColumns()]; 22 | 23 | Position p = new Position(0, 0); 24 | 25 | // above 26 | p.setValues(position.getRow() - 1, position.getColumn()); 27 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 28 | { 29 | mat[p.getRow()][p.getColumn()] = true; 30 | p.setRow(p.getRow() - 1); 31 | } 32 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 33 | { 34 | mat[p.getRow()][p.getColumn()] = true; 35 | } 36 | 37 | // left 38 | p.setValues(position.getRow(), position.getColumn() - 1); 39 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 40 | { 41 | mat[p.getRow()][p.getColumn()] = true; 42 | p.setColumn(p.getColumn() - 1); 43 | } 44 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 45 | { 46 | mat[p.getRow()][p.getColumn()] = true; 47 | } 48 | 49 | // right 50 | p.setValues(position.getRow(), position.getColumn() + 1); 51 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 52 | { 53 | mat[p.getRow()][p.getColumn()] = true; 54 | p.setColumn(p.getColumn() + 1); 55 | } 56 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 57 | { 58 | mat[p.getRow()][p.getColumn()] = true; 59 | } 60 | 61 | // below 62 | p.setValues(position.getRow() + 1, position.getColumn()); 63 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 64 | { 65 | mat[p.getRow()][p.getColumn()] = true; 66 | p.setRow(p.getRow() + 1); 67 | } 68 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) { 69 | mat[p.getRow()][p.getColumn()] = true; 70 | } 71 | 72 | // nw 73 | p.setValues(position.getRow() - 1, position.getColumn() - 1); 74 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 75 | { 76 | mat[p.getRow()][p.getColumn()] = true; 77 | p.setValues(p.getRow() - 1, p.getColumn() - 1); 78 | } 79 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 80 | { 81 | mat[p.getRow()][p.getColumn()] = true; 82 | } 83 | 84 | // ne 85 | p.setValues(position.getRow() - 1, position.getColumn() + 1); 86 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 87 | { 88 | mat[p.getRow()][p.getColumn()] = true; 89 | p.setValues(p.getRow() - 1, p.getColumn() + 1); 90 | } 91 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 92 | { 93 | mat[p.getRow()][p.getColumn()] = true; 94 | } 95 | 96 | // se 97 | p.setValues(position.getRow() + 1, position.getColumn() + 1); 98 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 99 | { 100 | mat[p.getRow()][p.getColumn()] = true; 101 | p.setValues(p.getRow() + 1, p.getColumn() + 1); 102 | } 103 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 104 | { 105 | mat[p.getRow()][p.getColumn()] = true; 106 | } 107 | 108 | // sw 109 | p.setValues(position.getRow() + 1, position.getColumn() - 1); 110 | while (getBoard().positionExists(p) && !getBoard().thereIsAPiece(p)) 111 | { 112 | mat[p.getRow()][p.getColumn()] = true; 113 | p.setValues(p.getRow() + 1, p.getColumn() - 1); 114 | } 115 | if (getBoard().positionExists(p) && isThereOpponentPiece(p)) 116 | { 117 | mat[p.getRow()][p.getColumn()] = true; 118 | } 119 | 120 | return mat; 121 | } 122 | } -------------------------------------------------------------------------------- /src/chess/pieces/King.java: -------------------------------------------------------------------------------- 1 | package chess.pieces; 2 | 3 | import boardgame.Board; 4 | import boardgame.Position; 5 | import chess.ChessMatch; 6 | import chess.ChessPiece; 7 | import chess.Color; 8 | 9 | public class King extends ChessPiece 10 | { 11 | 12 | private ChessMatch chessMatch; 13 | 14 | public King(Board board, Color color, ChessMatch chessMatch) 15 | { 16 | super(board, color); 17 | this.chessMatch = chessMatch; 18 | } 19 | 20 | @Override 21 | public String toString() 22 | { 23 | return "♚"; 24 | } 25 | 26 | private boolean canMove(Position position) 27 | { 28 | ChessPiece p = (ChessPiece)getBoard().piece(position); 29 | return p == null || p.getColor() != getColor(); 30 | } 31 | 32 | private boolean testRookCastling(Position position) 33 | { 34 | ChessPiece p = (ChessPiece)getBoard().piece(position); 35 | return p != null && p instanceof Rook && p.getColor() == getColor() && p.getMoveCount() == 0; 36 | } 37 | 38 | @Override 39 | public boolean[][] possibleMoves() 40 | { 41 | boolean[][] mat = new boolean[getBoard().getRows()][getBoard().getColumns()]; 42 | 43 | Position p = new Position(0, 0); 44 | 45 | // above 46 | p.setValues(position.getRow() - 1, position.getColumn()); 47 | if (getBoard().positionExists(p) && canMove(p)) { 48 | mat[p.getRow()][p.getColumn()] = true; 49 | } 50 | 51 | // below 52 | p.setValues(position.getRow() + 1, position.getColumn()); 53 | if (getBoard().positionExists(p) && canMove(p)) { 54 | mat[p.getRow()][p.getColumn()] = true; 55 | } 56 | 57 | // left 58 | p.setValues(position.getRow(), position.getColumn() - 1); 59 | if (getBoard().positionExists(p) && canMove(p)) { 60 | mat[p.getRow()][p.getColumn()] = true; 61 | } 62 | 63 | // right 64 | p.setValues(position.getRow(), position.getColumn() + 1); 65 | if (getBoard().positionExists(p) && canMove(p)) { 66 | mat[p.getRow()][p.getColumn()] = true; 67 | } 68 | 69 | // nw 70 | p.setValues(position.getRow() - 1, position.getColumn() - 1); 71 | if (getBoard().positionExists(p) && canMove(p)) { 72 | mat[p.getRow()][p.getColumn()] = true; 73 | } 74 | 75 | // ne 76 | p.setValues(position.getRow() - 1, position.getColumn() + 1); 77 | if (getBoard().positionExists(p) && canMove(p)) { 78 | mat[p.getRow()][p.getColumn()] = true; 79 | } 80 | 81 | // sw 82 | p.setValues(position.getRow() + 1, position.getColumn() - 1); 83 | if (getBoard().positionExists(p) && canMove(p)) { 84 | mat[p.getRow()][p.getColumn()] = true; 85 | } 86 | 87 | // se 88 | p.setValues(position.getRow() + 1, position.getColumn() + 1); 89 | if (getBoard().positionExists(p) && canMove(p)) { 90 | mat[p.getRow()][p.getColumn()] = true; 91 | } 92 | 93 | // #specialmove castling 94 | if (getMoveCount() == 0 && !chessMatch.getCheck()) 95 | { 96 | // #specialmove castling kingside rook 97 | Position posT1 = new Position(position.getRow(), position.getColumn() + 3); 98 | if (testRookCastling(posT1)) 99 | { 100 | Position p1 = new Position(position.getRow(), position.getColumn() + 1); 101 | Position p2 = new Position(position.getRow(), position.getColumn() + 2); 102 | if (getBoard().piece(p1) == null && getBoard().piece(p2) == null) 103 | { 104 | mat[position.getRow()][position.getColumn() + 2] = true; 105 | } 106 | } 107 | // #specialmove castling queenside rook 108 | Position posT2 = new Position(position.getRow(), position.getColumn() - 4); 109 | if (testRookCastling(posT2)) 110 | { 111 | Position p1 = new Position(position.getRow(), position.getColumn() - 1); 112 | Position p2 = new Position(position.getRow(), position.getColumn() - 2); 113 | Position p3 = new Position(position.getRow(), position.getColumn() - 3); 114 | if (getBoard().piece(p1) == null && getBoard().piece(p2) == null && getBoard().piece(p3) == null) 115 | { 116 | mat[position.getRow()][position.getColumn() - 2] = true; 117 | } 118 | } 119 | } 120 | 121 | return mat; 122 | } 123 | } -------------------------------------------------------------------------------- /src/app/UI.java: -------------------------------------------------------------------------------- 1 | package app; 2 | 3 | import java.util.Arrays; 4 | import java.util.InputMismatchException; 5 | import java.util.List; 6 | import java.util.Scanner; 7 | import java.util.stream.Collectors; 8 | 9 | import chess.ChessMatch; 10 | import chess.ChessPiece; 11 | import chess.ChessPosition; 12 | import chess.Color; 13 | 14 | public class UI { 15 | 16 | // https://stackoverflow.com/questions/5762491/how-to-print-color-in-console-using-system-out-println 17 | 18 | public static final String ANSI_RESET = "\u001B[0m"; 19 | public static final String ANSI_BLACK = "\u001B[30m"; 20 | public static final String ANSI_RED = "\u001B[31m"; 21 | public static final String ANSI_GREEN = "\u001B[32m"; 22 | public static final String ANSI_YELLOW = "\u001B[33m"; 23 | public static final String ANSI_BLUE = "\u001B[34m"; 24 | public static final String ANSI_PURPLE = "\u001B[35m"; 25 | public static final String ANSI_CYAN = "\u001B[36m"; 26 | public static final String ANSI_WHITE = "\u001B[37m"; 27 | 28 | public static final String ANSI_BLACK_BACKGROUND = "\u001B[40m"; 29 | public static final String ANSI_RED_BACKGROUND = "\u001B[41m"; 30 | public static final String ANSI_GREEN_BACKGROUND = "\u001B[42m"; 31 | public static final String ANSI_YELLOW_BACKGROUND = "\u001B[43m"; 32 | public static final String ANSI_BLUE_BACKGROUND = "\u001B[44m"; 33 | public static final String ANSI_PURPLE_BACKGROUND = "\u001B[45m"; 34 | public static final String ANSI_CYAN_BACKGROUND = "\u001B[46m"; 35 | public static final String ANSI_WHITE_BACKGROUND = "\u001B[47m"; 36 | 37 | // https://stackoverflow.com/questions/2979383/java-clear-the-console 38 | public static void clearScreen() { 39 | System.out.print("\033[H\033[2J"); 40 | System.out.flush(); 41 | } 42 | 43 | public static void printMatch(ChessMatch chessMatch, List captured) 44 | { 45 | printBoard(chessMatch.getPieces()); 46 | 47 | System.out.println(); 48 | printCapturedPieces(captured); 49 | 50 | System.out.println(); 51 | System.out.println("Turn : " + chessMatch.getTurn()); 52 | System.out.println("Waiting player: " + chessMatch.getCurrentPlayer()); 53 | 54 | if(!chessMatch.getCheckMate()) 55 | { 56 | if(chessMatch.getCheck()) 57 | System.out.println("CHECK!"); 58 | } 59 | else 60 | { 61 | System.out.println("CHECKMATE!!!"); 62 | System.out.println("Winner: " + chessMatch.getCurrentPlayer()); 63 | } 64 | } 65 | 66 | public static ChessPosition readChessPosition(Scanner sc) 67 | { 68 | try 69 | { 70 | String s = sc.nextLine(); 71 | char column = s.charAt(0); 72 | int row = Integer.parseInt(s.substring(1)); 73 | return new ChessPosition(column, row); 74 | } 75 | catch (RuntimeException e) 76 | { 77 | throw new InputMismatchException("Error reading ChessPosition. Valid values are from a1 to h8."); 78 | } 79 | } 80 | 81 | public static void printBoard(ChessPiece[][] pieces) { 82 | for (int i = 0; i < pieces.length; i++) 83 | { 84 | System.out.print((8 - i) + " "); 85 | for (int j = 0; j < pieces.length; j++) 86 | { 87 | printPiece(pieces[i][j], false); 88 | } 89 | System.out.println(); 90 | } 91 | System.out.println(" A B C D E F G H"); 92 | } 93 | 94 | public static void printBoard(ChessPiece[][] pieces, boolean[][] possibleMoves) 95 | { 96 | for (int i = 0; i < pieces.length; i++) 97 | { 98 | System.out.print((8 - i) + " "); 99 | for (int j = 0; j < pieces.length; j++) 100 | { 101 | printPiece(pieces[i][j], possibleMoves[i][j]); 102 | } 103 | System.out.println(); 104 | } 105 | System.out.println(" A B C D E F G H"); 106 | } 107 | 108 | private static void printPiece(ChessPiece piece, boolean background) 109 | { 110 | if (background) 111 | { 112 | System.out.print(ANSI_PURPLE_BACKGROUND); 113 | } 114 | 115 | if (piece == null) 116 | { 117 | System.out.print("♜" + ANSI_RESET); 118 | } 119 | else 120 | { 121 | if (piece.getColor() == Color.WHITE) 122 | { 123 | System.out.print(ANSI_CYAN + piece + ANSI_RESET); 124 | } 125 | else 126 | { 127 | System.out.print(ANSI_GREEN + piece + ANSI_RESET); 128 | } 129 | } 130 | System.out.print(" "); 131 | } 132 | 133 | private static void printCapturedPieces(List captured) { 134 | List white = captured.stream() 135 | .filter(x -> x.getColor() == Color.WHITE).collect(Collectors.toList()); 136 | List black = captured.stream() 137 | .filter(x -> x.getColor() == Color.BLACK).collect(Collectors.toList()); 138 | 139 | System.out.println("Captured pieces:"); 140 | System.out.print("White: "); 141 | System.out.print(ANSI_CYAN); 142 | System.out.println(Arrays.toString(white.toArray())); 143 | System.out.print(ANSI_RESET); 144 | 145 | System.out.print("Black: "); 146 | System.out.print(ANSI_GREEN); 147 | System.out.println(Arrays.toString(black.toArray())); 148 | System.out.print(ANSI_RESET); 149 | } 150 | } -------------------------------------------------------------------------------- /src/chess/ChessMatch.java: -------------------------------------------------------------------------------- 1 | package chess; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import boardgame.Board; 8 | import boardgame.Piece; 9 | import boardgame.Position; 10 | import chess.pieces.Bishop; 11 | import chess.pieces.King; 12 | import chess.pieces.Knight; 13 | import chess.pieces.Pawn; 14 | import chess.pieces.Queen; 15 | import chess.pieces.Rook; 16 | 17 | public class ChessMatch 18 | { 19 | 20 | private int turn; 21 | private Color currentPlayer; 22 | private Board board; 23 | private boolean check; 24 | private boolean checkMate; 25 | 26 | private List piecesOnTheBoard = new ArrayList<>(); 27 | private List capturedPieces = new ArrayList<>(); 28 | 29 | public ChessMatch() 30 | { 31 | board = new Board(8, 8); 32 | turn = 1; 33 | currentPlayer = Color.WHITE; 34 | initialSetup(); 35 | } 36 | 37 | public int getTurn() 38 | { 39 | return turn; 40 | } 41 | 42 | public Color getCurrentPlayer() 43 | { 44 | return currentPlayer; 45 | } 46 | 47 | public boolean getCheck() 48 | { 49 | return check; 50 | } 51 | 52 | public boolean getCheckMate() 53 | { 54 | return checkMate; 55 | } 56 | 57 | public ChessPiece[][] getPieces() 58 | { 59 | ChessPiece[][] mat = new ChessPiece[board.getRows()][board.getColumns()]; 60 | for (int i=0; i list = piecesOnTheBoard.stream() 212 | .filter(x -> ((ChessPiece)x).getColor() == color).collect(Collectors.toList()); 213 | for (Piece p : list) { 214 | if (p instanceof King) { 215 | return (ChessPiece)p; 216 | } 217 | } 218 | throw new IllegalStateException("There is no " + color + " king on the board"); 219 | } 220 | 221 | private boolean testCheck(Color color) { 222 | Position kingPosition = king(color).getChessPosition().toPosition(); 223 | List opponentPieces = piecesOnTheBoard.stream() 224 | .filter(x -> ((ChessPiece)x).getColor() == opponent(color)).collect(Collectors.toList()); 225 | for (Piece p : opponentPieces) { 226 | boolean[][] mat = p.possibleMoves(); 227 | if (mat[kingPosition.getRow()][kingPosition.getColumn()]) { 228 | return true; 229 | } 230 | } 231 | return false; 232 | } 233 | 234 | private boolean testCheckMate(Color color) 235 | { 236 | if (!testCheck(color)) 237 | { 238 | return false; 239 | } 240 | List list = piecesOnTheBoard.stream() 241 | .filter(x -> ((ChessPiece)x).getColor() == color).collect(Collectors.toList()); 242 | for (Piece p : list) 243 | { 244 | boolean[][] mat = p.possibleMoves(); 245 | for (int i=0; i