diff --git a/.idea/misc.xml b/.idea/misc.xml index 72be14a..97dd9e8 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -13,7 +13,7 @@ - + \ No newline at end of file diff --git a/app/src/main/resources/image/game/battleship.png b/app/src/main/resources/image/game/battleship.png new file mode 100644 index 0000000..813893f Binary files /dev/null and b/app/src/main/resources/image/game/battleship.png differ diff --git a/app/src/main/resources/image/game/other.png b/app/src/main/resources/image/game/other.png new file mode 100644 index 0000000..6bd4167 Binary files /dev/null and b/app/src/main/resources/image/game/other.png differ diff --git a/app/src/main/resources/image/game/reversi.png b/app/src/main/resources/image/game/reversi.png new file mode 100644 index 0000000..bd9252f Binary files /dev/null and b/app/src/main/resources/image/game/reversi.png differ diff --git a/app/src/main/resources/image/game/sudoku.png b/app/src/main/resources/image/game/sudoku.png new file mode 100644 index 0000000..ec88234 Binary files /dev/null and b/app/src/main/resources/image/game/sudoku.png differ diff --git a/app/src/main/resources/image/game/tictactoe.png b/app/src/main/resources/image/game/tictactoe.png new file mode 100644 index 0000000..2a81e05 Binary files /dev/null and b/app/src/main/resources/image/game/tictactoe.png differ diff --git a/app/src/main/resources/style/main.css b/app/src/main/resources/style/main.css new file mode 100644 index 0000000..99e8087 --- /dev/null +++ b/app/src/main/resources/style/main.css @@ -0,0 +1,33 @@ +.main-button { + -fx-background-color: transparent; + -fx-background-image: url("card-default.jpg"); /* fallback image */ + -fx-background-size: cover; + -fx-background-position: center; + -fx-pref-width: 250px; + -fx-pref-height: 180px; + -fx-border-radius: 15; + -fx-background-radius: 15; + -fx-effect: dropshadow(gaussian, rgba(0,0,0,0.3), 15, 0.4, 0, 4); + -fx-cursor: hand; + -fx-padding: 0; +} + +.card-label { + -fx-background-color: rgba(0, 0, 0, 0.5); + -fx-font-size: 20px; + -fx-font-weight: bold; + -fx-text-fill: white; + -fx-padding: 10px; + -fx-alignment: top-center; + -fx-background-radius: 15 15 0 0; + -fx-opacity: 0; + -fx-transition: all 0.3s ease; +} + +.main-button:hover { + -fx-effect: dropshadow(gaussian, #00ffff, 15, 0.5, 0, 0); +} + +.main-button:hover .card-label { + -fx-opacity: 1; +} \ No newline at end of file diff --git a/app/src/main/resources/style/quit.css b/app/src/main/resources/style/quit.css new file mode 100644 index 0000000..59c72a3 --- /dev/null +++ b/app/src/main/resources/style/quit.css @@ -0,0 +1,33 @@ +.quit-background { + -fx-background-color: rgba(0, 0, 0, 0.6); +} + +.quit-box { + -fx-background-color: rgba(30, 30, 30, 0.95); + -fx-background-radius: 15; + -fx-padding: 30; + -fx-effect: dropshadow(gaussian, black, 20, 0.6, 0, 4); +} + +.quit-text { + -fx-fill: white; + -fx-font-size: 28px; + -fx-font-weight: 600; + -fx-font-family: "Segoe UI", sans-serif; +} + +.quit-button { + -fx-font-size: 16px; + -fx-text-fill: white; + -fx-background-color: transparent; + -fx-border-color: white; + -fx-border-radius: 5; + -fx-padding: 8 20; + -fx-cursor: hand; +} + +.quit-button:hover { + -fx-text-fill: #00ffff; + -fx-border-color: #00ffff; + -fx-effect: dropshadow(gaussian, #00ffff, 8, 0.5, 0, 0); +} \ No newline at end of file diff --git a/app/src/main/resources/style/style.css b/app/src/main/resources/style/style.css new file mode 100644 index 0000000..c09d516 --- /dev/null +++ b/app/src/main/resources/style/style.css @@ -0,0 +1,20 @@ +.root { + -fx-background-color: #2d2d2d; + + -fx-font-size: 28px; + -fx-font-weight: 600; + -fx-font-family: "Segoe UI", sans-serif; +} + +.button { + -fx-background-color: transparent; + -fx-text-fill: white; + -fx-border-color: transparent; + -fx-padding: 10 20; + -fx-cursor: hand; + -fx-effect: null; +} + +.button:hover { + -fx-effect: dropshadow(gaussian, #00ffff, 10, 0.3, 0, 0); +} \ No newline at end of file diff --git a/game/src/main/java/org/toop/game/tictactoe/TicTacToe.java b/game/src/main/java/org/toop/game/tictactoe/TicTacToe.java index 4b39df2..cce644f 100644 --- a/game/src/main/java/org/toop/game/tictactoe/TicTacToe.java +++ b/game/src/main/java/org/toop/game/tictactoe/TicTacToe.java @@ -6,79 +6,103 @@ import org.toop.game.Player; import java.util.ArrayList; public final class TicTacToe extends Game { - private int movesLeft; + private int movesLeft; - public TicTacToe(String player1, String player2) { - super(3, 3, new Player(player1, 'X'), new Player(player2, 'O')); - movesLeft = board.length; - } + public TicTacToe(String player1, String player2) { + super(3, 3, new Player(player1, 'X'), new Player(player2, 'O')); + movesLeft = board.length; + } - public TicTacToe(TicTacToe other) { - super(other); - movesLeft = other.movesLeft; - } + public TicTacToe(TicTacToe other) { + super(other); + movesLeft = other.movesLeft; + } - @Override - public Move[] getLegalMoves() { - final ArrayList legalMoves = new ArrayList<>(); + @Override + public Move[] getLegalMoves() { + final ArrayList legalMoves = new ArrayList<>(); - for (int i = 0; i < board.length; i++) { - if (board[i] == EMPTY) { - legalMoves.add(new Move(i, getCurrentPlayer().values()[0])); - } - } + for (int i = 0; i < board.length; i++) { + if (board[i] == EMPTY) { + legalMoves.add(new Move(i, getCurrentPlayer().values()[0])); + } + } - return legalMoves.toArray(new Move[0]); - } + return legalMoves.toArray(new Move[0]); + } - @Override - public State play(Move move) { - assert move != null; - assert move.position() >= 0 && move.position() < board.length; - assert move.value() == getCurrentPlayer().values()[0]; + @Override + public State play(Move move) { + assert move != null; + assert move.position() >= 0 && move.position() < board.length; + assert move.value() == getCurrentPlayer().values()[0]; - board[move.position()] = move.value(); - movesLeft--; + board[move.position()] = move.value(); + movesLeft--; - if (checkForWin()) { - return State.WIN; - } + if (checkForWin()) { + return State.WIN; + } - if (movesLeft <= 0) { - return State.DRAW; - } + nextPlayer(); - nextPlayer(); - return State.NORMAL; - } + if (movesLeft <= 2) { + if (checkDraw(new TicTacToe(this))) { + return State.DRAW; + } + } + return State.NORMAL; + } - private boolean checkForWin() { - // Horizontal - for (int i = 0; i < 3; i++) { - final int index = i * 3; + private boolean checkForWin() { + // Horizontal + for (int i = 0; i < 3; i++) { + final int index = i * 3; - if (board[index] != EMPTY - && board[index] == board[index + 1] - && board[index] == board[index + 2]) { - return true; - } - } + if (board[index] != EMPTY + && board[index] == board[index + 1] + && board[index] == board[index + 2]) { + return true; + } + } - // Vertical - for (int i = 0; i < 3; i++) { - if (board[i] != EMPTY - && board[i] == board[i + 3] - && board[i] == board[i + 6]) { - return true; - } - } + // Vertical + for (int i = 0; i < 3; i++) { + if (board[i] != EMPTY + && board[i] == board[i + 3] + && board[i] == board[i + 6]) { + return true; + } + } - // B-Slash - if (board[0] != EMPTY && board[0] == board[4] && board[0] == board[8]) { - return true; - } + // B-Slash + if (board[0] != EMPTY && board[0] == board[4] && board[0] == board[8]) { + return true; + } - // F-Slash - return board[2] != EMPTY && board[2] == board[4] && board[2] == board[6]; - } + // F-Slash + return board[2] != EMPTY && board[2] == board[4] && board[2] == board[6]; + } + + public boolean checkDraw(TicTacToe game) { + if (game.checkForWin()) { + return false; + } + if (game.movesLeft == 0) { + return true; + } + // try every move on a legal copy + for (Move move : game.getLegalMoves()) { + TicTacToe copy = new TicTacToe(game); + State result = copy.play(move); + + if (result == State.WIN) { + return false; + } + if (!checkDraw(copy)) { + return false; + } + } + return true; + } } \ No newline at end of file