Skip to content

Commit

Permalink
highlight winner move and bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
SrinSS01 committed Sep 16, 2022
1 parent 371535d commit 6150bb8
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 31 deletions.
14 changes: 7 additions & 7 deletions src/main/java/com/tictactoebot/Events.java
Original file line number Diff line number Diff line change
Expand Up @@ -269,10 +269,10 @@ public void onButtonClick(@NotNull ButtonClickEvent event) {
Game game = matchData.acknowledge();
File boardImage = game.getBoardImage();

event.deferEdit()
event.editMessage("game started")
.setEmbeds(game.getEmbed())
.addFile(boardImage)
.setActionRows(game.getRows()).queue(hook -> hook.editOriginal("_ _").queue());
.setActionRows(game.getRows()).queue();
} catch (Exception e) { LOGGER.error(e.getMessage(), e); } }
case "not-ready" -> {
if (!user.equals(challengeAccepter)) {
Expand All @@ -297,7 +297,7 @@ public void onButtonClick(@NotNull ButtonClickEvent event) {
File boardImage = game.getBoardImage();
MessageEmbed embed = game.getEmbed();
switch (result) {
case WIN -> event.deferEdit().queue(hook -> {
case WIN -> event.editMessage("game ended").queue(hook -> {
User winner = game.getCurrentUser();
User loser = winner.getIdLong() == challenger.getIdLong() ? challengeAccepter : challenger;
hook.editOriginalComponents(List.of())
Expand Down Expand Up @@ -325,8 +325,8 @@ public void onButtonClick(@NotNull ButtonClickEvent event) {

Database.MATCH_DATA_MAP.remove(messageID);
});
case DRAW -> event.deferEdit().queue(hook -> {
hook.editOriginalComponents(board)
case DRAW -> event.editMessage("game ended").queue(hook -> {
hook.editOriginalComponents(List.of())
.setEmbeds(embed)
.retainFilesById(List.of())
.addFile(boardImage)
Expand Down Expand Up @@ -359,7 +359,7 @@ public void onButtonClick(@NotNull ButtonClickEvent event) {
.addFile(boardImage).queue());
case INVALID -> event.deferEdit().queue();
}
} catch (IOException ignore) {} }
} catch (IOException e) { LOGGER.error(e.getMessage(), e); } }
case "resign" -> {
Game game = matchData.getGame();
if (!game.contains(user.getIdLong())) {
Expand All @@ -369,7 +369,7 @@ public void onButtonClick(@NotNull ButtonClickEvent event) {
game.resign(user);
MessageEmbed embed = game.getEmbed();
game.disableButtons();
event.editMessage("game ended").setEmbeds(embed).setActionRows(game.getRows()).queue();
event.deferEdit().queue(hook -> hook.editOriginal("game ended").setActionRows(List.of()).setEmbeds(embed).queue());
Database.MATCH_DATA_MAP.remove(messageID);
}
}
Expand Down
18 changes: 15 additions & 3 deletions src/main/java/com/tictactoebot/game/Game.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,17 +79,27 @@ public static Game start(Pair<User, Player.Type> challenger, Pair<User, Player.T
}
public TicTacToe.Move select(String cell, Player.Type type) {
int pos = Integer.parseInt(cell);
TicTacToe.Move move = ticTacToe.place(pos, type);
Pair<TicTacToe.Move, TicTacToe.WinCells> moveWinCellsPair = ticTacToe.place(pos, type);
TicTacToe.Move move = moveWinCellsPair.getLeft();
if (move == TicTacToe.Move.INVALID) return TicTacToe.Move.INVALID;
draw(pos, type);
int row = 2 - pos / 3;
ActionRow buttons = rows.get(row);
Button newButton = Button.primary(cell, type.toString());
buttons.updateComponent(cell, newButton.asDisabled());
rows.set(row, buttons);
TicTacToe.WinCells cells = moveWinCellsPair.getRight();
draw(pos, type);
switch (move) {
case WIN -> {
embedBuilder.setDescription(description.setWinner(getCurrentUser()).toString());
for (int winCell : cells.getCells()) {
Pair<Integer, Integer> coordXY = coordinates.get(8 - winCell);
int x = coordXY.getLeft() - 70;
int y = coordXY.getRight() - 70;
graphics.setColor(Color.GREEN);
graphics.setStroke(new BasicStroke(10));
graphics.drawRect(x, y, 140, 140);
}
disableButtons();
}
case DRAW -> {
Expand All @@ -106,7 +116,9 @@ public TicTacToe.Move select(String cell, Player.Type type) {

private void draw(int pos, Player.Type type) {
Pair<Integer, Integer> xy = coordinates.get(8 - pos);
graphics.drawImage(type == Player.Type.CROSS? cross: naught, xy.getLeft() - 50, xy.getRight() - 50, 100, 100, null);
int x = xy.getLeft() - 50;
int y = xy.getRight() - 50;
graphics.drawImage(type == Player.Type.CROSS? cross: naught, x, y, 100, 100, null);
}

public boolean contains(long playerID) {
Expand Down
85 changes: 64 additions & 21 deletions src/main/java/com/tictactoebot/game/TicTacToe.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.tictactoebot.game;

import net.dv8tion.jda.internal.utils.tuple.Pair;

import java.util.Map;

import static com.tictactoebot.game.Player.Type.CROSS;
import static com.tictactoebot.game.Player.Type.NAUGHT;

Expand All @@ -18,7 +22,7 @@ public class TicTacToe {
private int x_board;
private int o_board;
private final Player currentPlayer;
private final int[] winCombinations;
private final Map<Integer, WinCells> winCombinations;
/*
+-----------+
| 8 | 7 | 6 |
Expand All @@ -32,52 +36,61 @@ public TicTacToe() {
this.x_board = 0;
this.o_board = 0;
this.currentPlayer = new Player(CROSS);
this.winCombinations = new int[] {
ROW_0, ROW_1, ROW_2, // rows
COLUMN_2, COLUMN_1, COLUMN_0, // columns
DIAGONAL_RIGHT, DIAGONAL_LEFT // diagonals
};
this.winCombinations = Map.of(
ROW_0, WinCells.ROW_0,
ROW_1, WinCells.ROW_1,
ROW_2, WinCells.ROW_2,
COLUMN_2, WinCells.COLUMN_2,
COLUMN_1, WinCells.COLUMN_1,
COLUMN_0, WinCells.COLUMN_0,
DIAGONAL_RIGHT, WinCells.DIAGONAL_RIGHT,
DIAGONAL_LEFT, WinCells.DIAGONAL_LEFT
);
}

public Player getCurrentPlayer() {
return currentPlayer;
}

public Move place(int pos, Player.Type player) {
if (player != currentPlayer.get()) return Move.INVALID;
public Pair<Move, WinCells> place(int pos, Player.Type player) {
if (player != currentPlayer.get()) return Pair.of(Move.INVALID, null);
int cell = 1 << pos;
if (cell > LAST_INDEX || cell < 0 || ((x_board | o_board) & cell) == cell) return Move.INVALID;
if (cell > LAST_INDEX || cell < 0 || ((x_board | o_board) & cell) == cell) return Pair.of(Move.INVALID, null);
switch (currentPlayer.get()) {
case CROSS -> {
x_board |= cell;
if (isWin(CROSS)) return Move.WIN;
Pair<Boolean, WinCells> win = isWin(CROSS);
if (win.getLeft()) return Pair.of(Move.WIN, win.getRight());
}
case NAUGHT -> {
o_board |= cell;
if (isWin(NAUGHT)) return Move.WIN;
Pair<Boolean, WinCells> win = isWin(NAUGHT);
if (win.getLeft()) return Pair.of(Move.WIN, win.getRight());
}
}
if (isDraw()) return Move.DRAW;
return Move.NONE;
if (isDraw()) return Pair.of(Move.DRAW, null);
return Pair.of(Move.NONE, null);
}

private boolean isWin(Player.Type type) {
private Pair<Boolean, WinCells> isWin(Player.Type type) {
return switch (type) {
case NAUGHT -> {
for (int winCombination : winCombinations) {
if ((o_board & winCombination) == winCombination) yield true;
for (var set : winCombinations.entrySet()) {
int winCombination = set.getKey();
if ((o_board & winCombination) == winCombination) yield Pair.of(true, set.getValue());
}
currentPlayer.set(CROSS);
yield false;
yield Pair.of(false, null);
}
case CROSS -> {
for (int winCombination : winCombinations) {
if ((x_board & winCombination) == winCombination) yield true;
for (var set : winCombinations.entrySet()) {
int winCombination = set.getKey();
if ((x_board & winCombination) == winCombination) yield Pair.of(true, set.getValue());
}
currentPlayer.set(NAUGHT);
yield false;
yield Pair.of(false, null);
}
default -> false;
default -> Pair.of(false, null);
};
}

Expand All @@ -88,4 +101,34 @@ private boolean isDraw() {
public enum Move {
WIN, DRAW, NONE, INVALID
}

/*
+-----------+
| 8 | 7 | 6 |
|-----------|
| 5 | 4 | 3 |
|-----------|
| 2 | 1 | 0 |
+-----------+
*/
public enum WinCells {
ROW_0(0, 1, 2),
ROW_1(3, 4, 5),
ROW_2(6, 7, 8),
COLUMN_2(6, 3, 0),
COLUMN_1(7, 4, 1),
COLUMN_0(8, 5, 2),
DIAGONAL_RIGHT(6, 4, 2),
DIAGONAL_LEFT(8, 4, 0);

private final int[] cells;

WinCells(int... cells) {
this.cells = cells;
}

public int[] getCells() {
return cells;
}
}
}

0 comments on commit 6150bb8

Please sign in to comment.