From 5dda85248ec9e8e860e66af9ebbfb19c061655a0 Mon Sep 17 00:00:00 2001 From: Ticho Hidding Date: Thu, 9 Oct 2025 15:27:58 +0200 Subject: [PATCH] legal moves now get highlighted in red --- .../java/org/toop/app/canvas/GameCanvas.java | 1 + .../org/toop/app/canvas/ReversiCanvas.java | 5 +- .../app/layer/layers/game/ReversiLayer.java | 1 + .../java/org/toop/game/reversi/Reversi.java | 104 +++++++++++++++++- 4 files changed, 104 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/org/toop/app/canvas/GameCanvas.java b/app/src/main/java/org/toop/app/canvas/GameCanvas.java index 048d184..b24fe15 100644 --- a/app/src/main/java/org/toop/app/canvas/GameCanvas.java +++ b/app/src/main/java/org/toop/app/canvas/GameCanvas.java @@ -104,6 +104,7 @@ public abstract class GameCanvas { graphics.setFill(color); graphics.fillOval(x, y, width, height); + IO.println("gothere"); } public void resize(int width, int height) { diff --git a/app/src/main/java/org/toop/app/canvas/ReversiCanvas.java b/app/src/main/java/org/toop/app/canvas/ReversiCanvas.java index 4ad51da..64703a9 100644 --- a/app/src/main/java/org/toop/app/canvas/ReversiCanvas.java +++ b/app/src/main/java/org/toop/app/canvas/ReversiCanvas.java @@ -22,13 +22,14 @@ public class ReversiCanvas extends GameCanvas{ public void drawLegalMoves(Game.Move[] moves){ mostRecentLegalMoves = moves; for(Game.Move move : moves){ - drawDot(Color.RED,move.position()); + IO.println("Legal Moves:" + move.position()); + drawDot(new Color(1f,0,0,0.25f),move.position()); } } public void removeLegalMoves(){ if (mostRecentLegalMoves != null){ for(Game.Move move : mostRecentLegalMoves){ - drawDot(Color.GRAY,move.position()); //todo get current background color + drawDot(Color.GRAY,move.position()); //todo get current background color or make this redraw the entire board } } mostRecentLegalMoves = null; diff --git a/app/src/main/java/org/toop/app/layer/layers/game/ReversiLayer.java b/app/src/main/java/org/toop/app/layer/layers/game/ReversiLayer.java index 1e524f3..e0db80c 100644 --- a/app/src/main/java/org/toop/app/layer/layers/game/ReversiLayer.java +++ b/app/src/main/java/org/toop/app/layer/layers/game/ReversiLayer.java @@ -26,6 +26,7 @@ public class ReversiLayer extends Layer{ reload(); + canvas.drawLegalMoves(reversi.getLegalMoves()); } @Override diff --git a/game/src/main/java/org/toop/game/reversi/Reversi.java b/game/src/main/java/org/toop/game/reversi/Reversi.java index 59dcdae..7e94d0a 100644 --- a/game/src/main/java/org/toop/game/reversi/Reversi.java +++ b/game/src/main/java/org/toop/game/reversi/Reversi.java @@ -4,10 +4,16 @@ import org.toop.game.Game; import org.toop.game.TurnBasedGame; import org.toop.game.tictactoe.TicTacToe; +import java.awt.*; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + + public final class Reversi extends TurnBasedGame { private int movesTaken; public static final char FIRST_MOVE = 'B'; - + private Set filledCells = new HashSet(); public Reversi() { super(8, 8, 2); @@ -17,6 +23,7 @@ public final class Reversi extends TurnBasedGame { public Reversi(Reversi other) { super(other); this.movesTaken = other.movesTaken; + this.filledCells = other.filledCells; } @@ -25,18 +32,99 @@ public final class Reversi extends TurnBasedGame { board[28] = 'B'; board[35] = 'B'; board[36] = 'W'; - + updateFilledCellsSet(); + } + private void updateFilledCellsSet() { + for (int i = 0; i < 64; i++) { + if (board[i] == 'W' || board[i] == 'B') { + filledCells.add(new Point(i / 8, i % 8)); + } + } } @Override public Move[] getLegalMoves() { + final ArrayList legalMoves = new ArrayList<>(); char[][] boardGrid = makeBoardAGrid(); - if(currentTurn == 1){ - + char currentPlayer = (currentTurn==0) ? 'B' : 'W'; + Set adjCell = getAdjacentCells(boardGrid); + for (Point point : adjCell){ + int score = getScoreForPotentialMove(point,boardGrid,currentPlayer); + if (score > 0){ + legalMoves.add(new Move(point.x + point.y * 8, currentPlayer)); + } } - return new Move[0]; + return legalMoves.toArray(new Move[0]); } + private Set getAdjacentCells(char[][] boardGrid) { + Set possibleCells = new HashSet<>(); + for (Point point : filledCells) { //for every filled cell + for (int deltaColumn = -1; deltaColumn <= 1; deltaColumn++){ //check adjacent cells + for (int deltaRow = -1; deltaRow <= 1; deltaRow++){ //orthogonally and diagonally + int newX = point.x + deltaColumn, newY = point.y + deltaRow; + if (deltaColumn == 0 || deltaRow == 0 //continue if out of bounds + || !isOnBoard(newX, newY)) { + continue; + } + if (boardGrid[newX][newY] == Game.EMPTY) { //check if the cell is empty + possibleCells.add(new Point(newX, newY)); //and then add it to the set of possible moves + } + } + } + } + return possibleCells; + } + + public int getScoreForPotentialMove(Point point, char[][] boardGrid, char currentPlayer) { + int score = 0; + for (int deltaColumn = -1; deltaColumn <= 1; deltaColumn++) { + for (int deltaRow = -1; deltaRow <= 1; deltaRow++) { + if (deltaColumn == 0 && deltaRow == 0){ + continue; + } + score += getScoreInDirection(point,boardGrid,currentPlayer,deltaColumn,deltaRow); + } + } + return score; + } + + private int getScoreInDirection(Point point, char[][] boardGrid, char currentPlayer, int dirX, int dirY) { + char opponent = getOpponent(currentPlayer); + int x = point.x + dirX; + int y = point.y + dirY; + + int count = 0; + if (!isOnBoard(x, y) || boardGrid[y][x] != opponent) { + return 0; + } + + while (isOnBoard(x, y) && boardGrid[y][x] == opponent) { + count++; + x += dirX; + y += dirY; + } + + if (isOnBoard(x, y) && boardGrid[y][x] == currentPlayer) { + return count; + } + + return 0; + } + + private boolean isOnBoard(int x, int y) { + return x >= 0 && x < 8 && y >= 0 && y < 8; + } + + private char getOpponent(char currentPlayer){ + if (currentPlayer == 'B') { + return 'W'; + } + else { + return 'B'; + } + } + public char[][] makeBoardAGrid() { char[][] boardGrid = new char[8][8]; for (int i = 0; i < 64; i++) { @@ -46,9 +134,15 @@ public final class Reversi extends TurnBasedGame { } @Override public State play(Move move) { + filledCells.add(new Point(move.position() / 8, move.position() % 8)); + nextTurn(); return null; } + public void skipMyTurn(){ + nextTurn(); + } + public char getCurrentPlayer() { if (currentTurn == 0){ return 'B';