mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 02:44:50 +00:00
better human/ai selector with bot selection and depth on TicTacToeAIR
This commit is contained in:
@@ -199,7 +199,7 @@ public final class Server {
|
||||
|
||||
switch (type){
|
||||
case TICTACTOE ->{
|
||||
players[myTurn] = new ArtificialPlayer<>(new TicTacToeAIR(), user);
|
||||
players[myTurn] = new ArtificialPlayer<>(new TicTacToeAIR(9), user);
|
||||
}
|
||||
case REVERSI ->{
|
||||
players[myTurn] = new ArtificialPlayer<>(new ReversiAIR(), user);
|
||||
|
||||
@@ -5,10 +5,13 @@ import org.toop.app.widget.Primitive;
|
||||
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.text.Text;
|
||||
|
||||
public class PlayerInfoWidget {
|
||||
private final GameInformation.Player information;
|
||||
private final VBox container;
|
||||
private Text playerName;
|
||||
private boolean hasSet;
|
||||
|
||||
public PlayerInfoWidget(GameInformation.Player information) {
|
||||
this.information = information;
|
||||
@@ -16,6 +19,7 @@ public class PlayerInfoWidget {
|
||||
buildToggle().getNode(),
|
||||
buildContent()
|
||||
);
|
||||
this.playerName = null;
|
||||
}
|
||||
|
||||
private ToggleWidget buildToggle() {
|
||||
@@ -33,51 +37,69 @@ public class PlayerInfoWidget {
|
||||
}
|
||||
|
||||
private Node buildContent() {
|
||||
if (information.isHuman) {
|
||||
var nameInput = new LabeledInputWidget(
|
||||
"name",
|
||||
"enter-your-name",
|
||||
information.name,
|
||||
newName -> information.name = newName
|
||||
);
|
||||
if (information.isHuman) {
|
||||
var nameInput = new LabeledInputWidget(
|
||||
"name",
|
||||
"enter-your-name",
|
||||
information.name,
|
||||
newName -> information.name = newName
|
||||
);
|
||||
|
||||
return nameInput.getNode();
|
||||
} else {
|
||||
if (information.name == null || information.name.isEmpty()) {
|
||||
information.name = "Pism Bot";
|
||||
}
|
||||
return nameInput.getNode();
|
||||
} else {
|
||||
var AIBox = Primitive.vbox(
|
||||
makeAIButton(0, 1, "zwartepiet"),
|
||||
makeAIButton(2, 1, "sinterklaas"),
|
||||
makeAIButton(9, 1, "santa")
|
||||
);
|
||||
|
||||
var playerName = Primitive.text("");
|
||||
playerName.setText(information.name);
|
||||
this.playerName = Primitive.text("");
|
||||
playerName.setText(information.name);
|
||||
|
||||
var nameDisplay = Primitive.vbox(
|
||||
Primitive.text("name"),
|
||||
playerName
|
||||
);
|
||||
var nameDisplay = Primitive.vbox(
|
||||
Primitive.text("name"),
|
||||
playerName
|
||||
);
|
||||
|
||||
var difficultySlider = new LabeledSliderWidget(
|
||||
"computer-difficulty",
|
||||
0, 5,
|
||||
information.computerDifficulty,
|
||||
newVal -> information.computerDifficulty = newVal
|
||||
);
|
||||
if (!hasSet) {
|
||||
doDefault();
|
||||
hasSet = true;
|
||||
}
|
||||
|
||||
var thinkTimeSlider = new LabeledSliderWidget(
|
||||
"computer-think-time",
|
||||
0, 5,
|
||||
information.computerThinkTime,
|
||||
newVal -> information.computerThinkTime = newVal
|
||||
);
|
||||
return Primitive.vbox(
|
||||
AIBox,
|
||||
nameDisplay
|
||||
);
|
||||
|
||||
return Primitive.vbox(
|
||||
nameDisplay,
|
||||
difficultySlider.getNode(),
|
||||
thinkTimeSlider.getNode()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Node getNode() {
|
||||
return container;
|
||||
}
|
||||
|
||||
private Node makeAIButton(int depth, int thinktime, String name) {
|
||||
return Primitive.button(name, () -> {
|
||||
information.name = getName(name);
|
||||
information.computerDifficulty = depth;
|
||||
information.computerThinkTime = thinktime;
|
||||
this.playerName.setText(getName(name));
|
||||
});
|
||||
}
|
||||
|
||||
private String getName(String name) {
|
||||
return switch (name) {
|
||||
case "sinterklaas" -> "Sint. R. Klaas";
|
||||
case "zwartepiet" -> "Zwarte Piet";
|
||||
case "santa" -> "Santa";
|
||||
default -> "Default";
|
||||
};
|
||||
}
|
||||
|
||||
private void doDefault() {
|
||||
information.name = getName("zwartepiet");
|
||||
information.computerDifficulty = 0;
|
||||
information.computerThinkTime = 1;
|
||||
this.playerName.setText(getName("zwartepiet"));
|
||||
}
|
||||
}
|
||||
@@ -52,12 +52,12 @@ public class LocalMultiplayerView extends ViewWidget {
|
||||
if (information.players[0].isHuman) {
|
||||
players[0] = new LocalPlayer<>(information.players[0].name);
|
||||
} else {
|
||||
players[0] = new ArtificialPlayer<>(new TicTacToeAIR(), information.players[0].name);
|
||||
players[0] = new ArtificialPlayer<>(new TicTacToeAIR(information.players[0].computerDifficulty), information.players[0].name);
|
||||
}
|
||||
if (information.players[1].isHuman) {
|
||||
players[1] = new LocalPlayer<>(information.players[1].name);
|
||||
} else {
|
||||
players[1] = new ArtificialPlayer<>(new TicTacToeAIR(), information.players[1].name);
|
||||
players[1] = new ArtificialPlayer<>(new TicTacToeAIR(information.players[1].computerDifficulty), information.players[1].name);
|
||||
}
|
||||
if (AppSettings.getSettings().getTutorialFlag() && AppSettings.getSettings().getFirstTTT()) {
|
||||
new ShowEnableTutorialWidget(
|
||||
|
||||
@@ -86,6 +86,9 @@ tutorialstring=\u0627\u0644\u062f\u0631\u0633 \u0627\u0644\u062a\u0648\u0636\u06
|
||||
startgame=\u0627\u0628\u062f\u0623 \u0627\u0644\u0644\u0639\u0628\u0629!
|
||||
goback=\u0627\u0631\u062c\u0639
|
||||
turnof=\u062F\u0648\u0631\u0647
|
||||
zwartepiet=\u0633\u0647\u0644: Zwarte Piet
|
||||
sinterklaas=\u0645\u062a\u0648\u0633\u0637: Sint R. Klaas
|
||||
santa=\u0635\u0639\u0628: Santa
|
||||
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629
|
||||
|
||||
@@ -88,6 +88,9 @@ tutorialstring=Tutorial
|
||||
startgame=Spiel starten!
|
||||
goback=Zur<EFBFBD>ck
|
||||
turnof=ist dran
|
||||
zwartepiet=Leicht: Zwarte Piet
|
||||
sinterklaas=Mittel: Sint R. Klaas
|
||||
santa=Schwer: Santa
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabisch)
|
||||
chinese=\u4e2d\u6587 (Chinesisch)
|
||||
|
||||
@@ -89,6 +89,9 @@ tutorialstring=Tutorial
|
||||
startgame=Start game!
|
||||
goback=Go back
|
||||
turnof='s turn
|
||||
zwartepiet=Easy: Zwarte Piet
|
||||
sinterklaas=Medium: Sint R. Klaas
|
||||
santa=Hard:Santa
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabic)
|
||||
chinese=\u4e2d\u6587 (Chinese)
|
||||
|
||||
@@ -87,7 +87,9 @@ tutorialstring=Tutorial
|
||||
startgame=\u00a1Iniciar juego!
|
||||
goback=Volver
|
||||
turnof=le toca
|
||||
|
||||
zwartepiet=F\u00e1cil: Zwarte Piet
|
||||
sinterklaas=Medio: Sint R. Klaas
|
||||
santa=Dif\u00edcil: Santa
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Ar\u00e1bigo)
|
||||
chinese=\u4e2d\u6587 (Chino)
|
||||
|
||||
@@ -87,6 +87,9 @@ tutorialstring=Tutoriel
|
||||
startgame=D\u00e9marrer le jeu!
|
||||
goback=Retour
|
||||
turnof=\u00E0 son tour
|
||||
zwartepiet=Facile: Zwarte Piet
|
||||
sinterklaas=Moyen : Sint R. Klaas
|
||||
santa=Difficile: Santa
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabe)
|
||||
chinese=\u4e2d\u6587 (Chinois)
|
||||
|
||||
@@ -87,6 +87,9 @@ tutorialstring=\u0924\u0942\u091f\u0949\u0930\u093f\u092f\u0932
|
||||
startgame=\u0916\u0947\u0932 \u0936\u0941\u0930\u0942 \u0915\u0930\u0947\u0902!
|
||||
goback=\u0935\u093e\u092a\u0938 \u091c\u093e\u090f\u0901
|
||||
turnof=\u0915\u0940 \u092C\u093E\u0930\u0940
|
||||
zwartepiet=\u0905\u0938\u093e\u0928: Zwarte Piet
|
||||
sinterklaas=\u092e\u0927\u094d\u092f\u092e: Sint R. Klaas
|
||||
santa=\u0915\u0924\u093f\u0928: Santa
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0905\u0930\u092c\u0940)
|
||||
chinese=\u4e2d\u6587 (\u091a\u0940\u0928\u0940)
|
||||
|
||||
@@ -86,6 +86,9 @@ tutorialstring=Tutorial
|
||||
startgame=Avvia il gioco!
|
||||
goback=Indietro
|
||||
turnof=\u00E8 il suo turno
|
||||
zwartepiet=Facile: Zwarte Piet
|
||||
sinterklaas=Medio: Sint R. Klaas
|
||||
santa=Difficile: Santa
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabo)
|
||||
chinese=\u4e2d\u6587 (Cinese)
|
||||
|
||||
@@ -86,6 +86,9 @@ tutorialstring=\u30c1\u30e5\u30fc\u30c8\u30ea\u30a2\u30eb
|
||||
startgame=\u30b2\u30fc\u30e0\u3092\u958b\u59cb\uff01
|
||||
goback=\u623b\u308b
|
||||
turnof=\u306E\u756A
|
||||
zwartepiet=\u7c21\u5358: Zwarte Piet
|
||||
sinterklaas=\u4e2d\u7d1a: Sint R. Klaas
|
||||
santa=\u96e3\u3057\u3044: Santa
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u30a2\u30e9\u30d3\u30a2\u8a9e)
|
||||
chinese=\u4e2d\u6587 (\u4e2d\u6587)
|
||||
|
||||
@@ -86,6 +86,9 @@ tutorialstring=\ud14c\ud2b8\ub9ad
|
||||
startgame=\uac8c\uc784 \uc2dc\uc791!
|
||||
goback=\ub4a4\ub85c \uac00\uae30
|
||||
turnof=\uC758 \uCC28\uB840
|
||||
zwartepiet=\uc218\uc601: Zwarte Piet
|
||||
sinterklaas=\ubcf4\ud1b5: Sint R. Klaas
|
||||
santa=\uc5d0\uc18c: Santa
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0639\u0631\u0628\u064a\u0629)
|
||||
chinese=\u4e2d\u6587 (\u4e2d\u6587)
|
||||
|
||||
@@ -86,6 +86,9 @@ tutorialstring=Tutorial
|
||||
startgame=Spel starten!
|
||||
goback=Ga terug
|
||||
turnof=is aan de beurt
|
||||
zwartepiet=Makkelijk: Zwarte Piet
|
||||
sinterklaas=Gemiddeld: Sint R. Klaas
|
||||
santa=Moeilijk: Santa
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (Arabisch)
|
||||
chinese=\u4e2d\u6587 (Chinees)
|
||||
|
||||
@@ -86,6 +86,9 @@ tutorialstring=\u0423\u0447\u0435\u0431\u043d\u0438\u043a
|
||||
startgame=\u041d\u0430\u0447\u0430\u0442\u044c \u0438\u0433\u0440\u0443!
|
||||
goback=\u041d\u0430\u0437\u0430\u0434
|
||||
turnof=\u0445\u043E\u0434\u0438\u0442
|
||||
zwartepiet=\u041b\u0435\u0433\u043a\u043e: Zwarte Piet
|
||||
sinterklaas=\u0421\u0440\u0435\u0434\u043d\u0438\u0439: Sint R. Klaas
|
||||
santa=\u0421\u043b\u043e\u0436\u043d\u043e: Santa
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u0410\u0440\u0430\u0431\u0441\u043a\u0438\u0439)
|
||||
chinese=\u4e2d\u6587 (\u041a\u0438\u0442\u0430\u0439\u0441\u043a\u0438\u0439)
|
||||
|
||||
@@ -86,6 +86,9 @@ tutorialstring=\u6559\u7a0b
|
||||
startgame=\u5f00\u59cb\u6e38\u620f\uff01
|
||||
goback=\u8fd4\u56de
|
||||
turnof=\u7684\u56DE\u5408
|
||||
zwartepiet=\u7b80\u5355: Zwarte Piet
|
||||
sinterklaas=\u4e2d\u7b49: Sint R. Klaas
|
||||
santa=\u56f0\u96be: Santa
|
||||
|
||||
arabic=\u0627\u0644\u0639\u0631\u0628\u064a\u0629 (\u963f\u62c9\u4f2f\u8bed)
|
||||
chinese=\u4e2d\u6587
|
||||
|
||||
@@ -25,10 +25,10 @@ public final class ReversiR extends AbstractGame<ReversiR> {
|
||||
// TODO: Don't hardcore for two players :)
|
||||
public record Score(int player1Score, int player2Score) {}
|
||||
|
||||
public ReversiR(Player<ReversiR>[] players) {
|
||||
super(8, 8, 2, players);
|
||||
public ReversiR(Player<ReversiR>[] players) {
|
||||
super(8, 8, 2, players);
|
||||
addStartPieces();
|
||||
}
|
||||
}
|
||||
|
||||
public ReversiR(ReversiR other) {
|
||||
super(other);
|
||||
@@ -53,8 +53,8 @@ public final class ReversiR extends AbstractGame<ReversiR> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getLegalMoves() {
|
||||
@Override
|
||||
public int[] getLegalMoves() {
|
||||
final ArrayList<Integer> legalMoves = new ArrayList<>();
|
||||
int[][] boardGrid = makeBoardAGrid();
|
||||
int currentPlayer = this.getCurrentTurn();
|
||||
@@ -67,7 +67,7 @@ public final class ReversiR extends AbstractGame<ReversiR> {
|
||||
}
|
||||
}
|
||||
return legalMoves.stream().mapToInt(Integer::intValue).toArray();
|
||||
}
|
||||
}
|
||||
|
||||
private Set<Point> getAdjacentCells(int[][] boardGrid) {
|
||||
Set<Point> possibleCells = new HashSet<>();
|
||||
@@ -76,7 +76,7 @@ public final class ReversiR extends AbstractGame<ReversiR> {
|
||||
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)) {
|
||||
|| !isOnBoard(newX, newY)) {
|
||||
continue;
|
||||
}
|
||||
if (boardGrid[newY][newX] == EMPTY) { //check if the cell is empty
|
||||
|
||||
@@ -26,9 +26,15 @@ public final class TicTacToeAIR extends AbstractAI<TicTacToeR> {
|
||||
* @param game the current Tic-Tac-Toe game state
|
||||
* @param depth the depth of lookahead for evaluating moves (non-negative)
|
||||
* @return the index of the best move, or -1 if no moves are available
|
||||
*
|
||||
*/
|
||||
|
||||
private int depth;
|
||||
|
||||
public TicTacToeAIR(int depth) {
|
||||
this.depth = depth;
|
||||
}
|
||||
public int getMove(TicTacToeR game) {
|
||||
int depth = 9;
|
||||
assert game != null;
|
||||
final int[] legalMoves = game.getLegalMoves();
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
final class TicTacToeAIRTest {
|
||||
|
||||
private final TicTacToeAIR ai = new TicTacToeAIR();
|
||||
private final TicTacToeAIR ai = new TicTacToeAIR(9);
|
||||
|
||||
// Helper: play multiple moves in sequence on a fresh board
|
||||
private TicTacToeR playSequence(int... moves) {
|
||||
|
||||
Reference in New Issue
Block a user